Problems in Receiving Notifications from Server

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
BrSg_4288716
Level 1
Level 1

Hello,

I'm Having some problems with the Notification functions on BLE.

My project is a BLE Client that is trying to subscribe to some notification characteristics of a Server.

If I'm following the examples right the way to enable notifications on a characteristic is:

void Send_EMG_Subscribe(CYBLE_CONN_HANDLE_T connHandle,uint16 EMG_attrCCDhandle)

{

    CYBLE_API_RESULT_T apiResult;

    CYBLE_GATTC_WRITE_REQ_T ReqParam;

    uint8 value = 0x0001;

    ReqParam.attrHandle = EMG_attrCCDhandle;

    ReqParam.value.val = &value;

    ReqParam.value.len = 1;

    enableNotificationReqParam.attrHandle = EMG_attrCCDhandle;  

    apiResult = CyBle_GattcWriteCharacteristicDescriptors(connHandle,&ReqParam); 

    BLE_Error_Handler(apiResult);

}

After calling this function i receive a event CYBLE_EVT_GATTC_WRITE_RSP. This should indicate that the subscription was successful.

But i don't start receiving new events with information lime CYBLE_EVT_GATTC_HANDLE_VALUE_NTF.

What am i doing wrong?

Thanks!

0 Likes
1 Solution
Yugandhar
Moderator
Moderator
Moderator
500 solutions authored 1000 replies posted 5 likes given

Hello,

On enabling notification successfully for a specific attribute, if the GATT server has an updated value to be notified to the GATT Client, it sends out a 'Handle Value Notification' which results in CYBLE_EVT_GATTC_HANDLE_VALUE_NTF event at the GATT Client's end.

Could you please let me know whether the server is sending the notification (using CyBle_GattsNotification() API with success return) after enabling the notify ?

Please check the GATT_Throughput example in the GitHub for a reference.

Thanks,

P Yugandhar.

View solution in original post

0 Likes
5 Replies
Yugandhar
Moderator
Moderator
Moderator
500 solutions authored 1000 replies posted 5 likes given

Hello,

On enabling notification successfully for a specific attribute, if the GATT server has an updated value to be notified to the GATT Client, it sends out a 'Handle Value Notification' which results in CYBLE_EVT_GATTC_HANDLE_VALUE_NTF event at the GATT Client's end.

Could you please let me know whether the server is sending the notification (using CyBle_GattsNotification() API with success return) after enabling the notify ?

Please check the GATT_Throughput example in the GitHub for a reference.

Thanks,

P Yugandhar.

0 Likes

Hello,

Thanks for the answer.

I'm sorry but it looks like i wasn't very clear in my question. I tried to post only a resume of my problem and forgot to specify that I'm only developing the Client side of the GATT. The server GAT  is a commercial product called Myo Armband (support.getmyo.com).

My aim if this is to be able to talk to this device without having to use the proprietary SDK they have for PC.

Most of the BLE protocol for the Myo was publicly released by the developer to support this kind of use.(myo-bluetooth/myohw.h at master · thalmiclabs/myo-bluetooth · GitHub)

Nonetheless, i have no way to interact with the Myo system and see what it is doing, all debug has to be made via Events and so on. So i can not see if the Server side is successfully sending notifications. i assume its not as the client is not receiving any CYBLE_EVT_GATTC_HANDLE_VALUE_NTF events.

I did also tried to reed de CCCD of the Notification characteristic and saw that it was  set as 0001 as it was supposed to be for a subscribed notification.

Thanks!

0 Likes

Hello,

Could you please check your server project with any BLE App and see whether you can able to read the notification data in BLE App after enabling the notify.

Please check the server project if there is any problem in sending the notifications successfully.

Thanks,

P Yugandhar.

0 Likes

Hello Py_21,

Thank you for the comment, reading it made me remember that the Myo has a battery service that can be subscribed to!

So i tried to sub to the battery service and saw that the subscription is working because i started to receive some notifications about battery status!!

This makes me conclude that the problem is in the next step. According to the documentation to receive EMG data not only i have to subscribe to the service i also have to send a "command" as a write to one of the characteristics to Activate the reading of EMG.

According to the documentation this is the Struct i'am suposed to send:

typedef struct MYOHW_PACKED {

    myohw_command_header_t header; ///< command == myohw_command_set_mode. payload_size = 3.

    uint8_t emg_mode;              ///< EMG sensor mode. See myohw_emg_mode_t.

    uint8_t imu_mode;              ///< IMU mode. See myohw_imu_mode_t.

    uint8_t classifier_mode;      ///< Classifier mode. See myohw_classifier_mode_t.

} myohw_command_set_mode_t;

MYOHW_STATIC_ASSERT_SIZED(myohw_command_set_mode_t, 5);

typedef struct MYOHW_PACKED {

    uint8_t command;        ///< Command to send. See myohw_command_t.

    uint8_t payload_size;  ///< Number of bytes in payload.

} myohw_command_header_t;

MYOHW_STATIC_ASSERT_SIZED(myohw_command_header_t, 2);

My function is like this:

void Send_EMG_Comand(CYBLE_CONN_HANDLE_T connHandle)

{

    CYBLE_API_RESULT_T apiResult;

    CYBLE_GATTC_WRITE_REQ_T writeReqParam;

    myohw_command_set_mode_t cmd;

    CYBLE_GATT_DB_ATTR_HANDLE_T  handle;

  

    cmd.header.command = 0x01u;

    cmd.header.payload_size = 0x03u;

    cmd.emg_mode = 0x02u;

    cmd.imu_mode = 0x00u;

    cmd.classifier_mode = 0x00u;

    handle = Myo_Control_AttrHandle;

    writeReqParam.attrHandle = handle;

    writeReqParam.value.val = &cmd;

    writeReqParam.value.len =  sizeof(cmd);

   

    apiResult = CyBle_GattcWriteCharacteristicValue(connHandle, &writeReqParam);   

    BLE_Error_Handler(apiResult);       

}

If Anyone has any idea why this command is not working but a very similar one( that sends vibrations) is i would love the feedback.

I understand that my problem now is kind of very specific and not reproducible or debug-gable at all by anyone without a MYO. But any help is appreciated.

Thanks!

0 Likes

Hello,

With the below structure:

typedef struct MYOHW_PACKED { 
    uint8_t command;        ///< Command to send. See myohw_command_t. 
    uint8_t payload_size;  ///< Number of bytes in payload. 
} myohw_command_header_t;

typedef struct MYOHW_PACKED {
    myohw_command_header_t header; ///< command == myohw_command_set_mode. payload_size = 3. 
    uint8_t emg_mode;              ///< EMG sensor mode. See myohw_emg_mode_t. 
    uint8_t imu_mode;              ///< IMU mode. See myohw_imu_mode_t. 
    uint8_t classifier_mode;      ///< Classifier mode. See myohw_classifier_mode_t. 
} myohw_command_set_mode_t;

Above defined function(void Send_EMG_Comand(CYBLE_CONN_HANDLE_T connHandle) ) will send the values as writeReqParam.value.val[0]=0x01,writeReqParam.value.val[1]=0x03,writeReqParam.value.val[2]=0x02,writeReqParam.value.val[3]=0x00,writeReqParam.value.val[4]=0x00 to the peripheral device.

Please check these values at the peripheral device and update to the structure accordingly.

Thanks,

P Yugandhar.