This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

GATT_Notification vs. GATTServApp_ProcessCharCfg

Other Parts Discussed in Thread: CC2540

I have been reading various posts that state that using notifications (when using a CC254x) will increase the amount of data that can be transferred from a peripheral server to a client.

Various examples have been given:  Some use GATT_Notification while others use GATTServApp_ProcessCharCfg to invoke the notification.    It appears that GATT_Notification is more direct, while GATTServApp_ProcessCharCfg is intended to be used in the "SetParameter" function.

It sounds like folks have gotten both methods to work.   Which is the preferred way?   Which yields better performance?    Will both methods permit multiple notifications to be transmitted in a single connection interval?

Most examples that use GATT_Notification show the use of a "dummy" handle.   Is this just for the example?  Shouldn't this point back to the characteristic attribute?

IAny enlightenment would be appreciated!

Thanks!

  • Hi,

    GATT_Notification is a technique to send data from Server(peer device normally) to Client(Host/Master normally) without the Client requesting for updated data value by the method of polling. The server informs the client whenever the data value changes by the way of GATT_Notifications.

    These notifications are send during connection events and hence only maximum one notification will be send during one connection event. The client can decide to not send notifications during connection events if there are no changes in characteristic data value. Hence the maximum frequency of notifications depends upon the connection interval, You can set a smaller connection interval with larger slave latency, so that the client is notified of any value change frequently(due to small connection interval) but when there is no change in data value, the client responds(to maintain connection) only during (SlaveLatency +1)*ConnectionInterval to save power.

    Normally the characteristic notification would not be enabled by default. The Client can write to the client characteristic configuration descriptor (CCCD) to enable/disable  notification. This call(GATT_writeReq) is translated to GATTServApp_ProcessCharCfg on the server side to change the notification settings. 

    Hence its better to write to the CCCD from client to enable notification instead of hacking the  server to send notifications always. 

    Regards,

    Arun

     

  • Arun,

    Thanks for your reply.   But I'm still confused.

    In the thread "CC2540 multiple notifications per connection event" the writers state that 4 packets are sent (via the use of multiple GATT_Notifications) in a single connection interval.    This is also stated in the thread "How to send 4 packets in one connection eveny?".

    Some threads also mention the "overlap" feature to increase the number of Notifications above the 4 that seems to be the limit (without overlaps).  (See thread "Guarantee Packet Count During Connection Event".

    I do understand that notifications are used by (for example) the server to send information to the client without the client requesting it.   And that no response is necessary.  And I understand that the client needs to "enable" the reception of notifications. 

    My question is how the notification is "launched".   In many threads, GATT_Notification is called (but the values of the arguments don't always make sense to me) directly.    In other threads (and in SIMPLEPROFILE_CHAR4 of the SimplePeripheral example), it appears that the notification is automatically sent when the peripheral app calls the SetParameter function (to set CHAR4).   Here the GATTServApp_ProcessCharCfg function is called, which I assume checks to see if the client has given permission, then does the equivalent of GATT_Notification.  (The assumption being that the characteristic has been set up (via its definition) to use notifications (GATT_PROP_NOTIFY), and the client has (at some earlier point) written the configuration to give permission.  Then, when the characteristic value is changed in the peripheral (server), it is automatically sent to the client.)

    So I'm writing a new application, and I have a lot of data to send from the peripheral server to the client.   I want to use notifications and get the highest data throughput that I can.    From the threads I've been reading, it seems that GATT_notification is the way to go, but I'm confused with the calling arguments.  The SimplePeripheral example seems to prefer using the GATTServApp_ProcessCharCfg method.

    What am I missing?

    Thanks for your assistance!

  • Hi,

    Sorry for the confusion, I was under the impression that you were taking about only one characteristic and enabling notifications for the same. In CC2540 a connection event can have up to 6 packets(by overlapped processing) and each of this packet can be maximum 23 bytes long(MTU). So notification for each characteristic has to be below this MTU-3 bytes. So you could send 4-6 notifications in total during a connection event. 

    Now, once the client has enabled notifications on the server, it completely up to the client implementation on how and when to send notifications. Simple BLE peripheral is just an example code and you don't have to stipulate to the mechanism used in that. in SimplleBLEPeripheral, notifications(of Char 4) are send periodically to by calling simpleProfile_setParameter. In simpleGATTProfile , the Set parameter API checks whether client had enabled notifications to by calling GATTServApp_ProcessCharCfg as you had understood and only send notifications, if client had enabled notifications. 

    But you don't have to stick to that method(although recommended for a cleaner and easier to develop code & better power consumption). You can very well enable notifications from your application directly and send them without checking if notifications is enabled by client(again not recommended by nothing wrong in doing so). 

    Do note that notifications do not generate response back to application on whether host received (although host will receive it from LL perceptive ) and understood(captured) it. So send notifications only at a rate so that host captures all packets.

    Regards,

    Arun

  • Arun,

    Thanks very much!

    Can you elaborate on the arguments for the GATT_notification API call?    The online manual says:

    bStatus_t GATT_Notification (uint16 connHandle, attHandleValueNoti_t *pNoti, uint8 authenticated)

    In many examples, connHandle is set to 0.   I assume that this is OK since the peripheral server doesn't necessarily know what the connection will actually be at the time that the notification is requested.  (And I further assume that the Notifications are queued.)      

    "authenticated" is understood.  

    "pNoti" a pointer to the attHandleValueNoti_t structure.   In that structure, what is handle?   It is not a pointer to the  characteristic (or it would be a pointer type).   How is the handle determined?   Note that in the manual, "clicking" on the handle variable name brings you back to the same page!

    Thanks again!

  • Hi,

    The GATT_Notification is normally used to send notification from a peripheral device to a host device.

    So connHandle is the connection handle given by GAP  profile for the connection between the peripheral device and Master device. Since peripheral device can be used to connect to only one master/host device, for peripheral devices the connection handle will mostly be zero. Your application will obtain the connection handle from the GAP event callback(by calling 

    // Get connection handle.

    GAPRole_GetParameter(GAPROLE_CONNHANDLE, &gapConnHandle);when the newState value is GAPROLE_CONNECTED)

    Bur if GATT_notification is used from a Host device(which can connect to multiple peripheral devices), the connHandle will be different for each BLE connection between the Master device and individual peripheral devices.

    Now 'pNoti' Handle is the pointer to the attribute table item containing  the characteristic value. For example pNoti will be the address of this structure for characteristic 4. 

    // Characteristic Value 4
    {
        { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
        0,
        0,
        &simpleProfileChar4
    },

    Lets say this structure 11th member of the Attribute table simpleProfileAttrTbl then

    pNoti = &simpleProfileAttrTbl[11];

    Regards,

    Arun

  • Thanks for your help!

  • Hi,

    This post provided very usefull information on GATT_Notification. LAstly, Arun mentioned that pNoti is the pointer to the attribute table item containing the characteristic value. However, in this example, processors.wiki.ti.com/.../CC2540_Data_Throughput, I was not able to trace back the nData to any characteristic value. Does osal_memcpy handles it internally?

    Thanks
  • Hi,

    I think I've understood it. In the example they have set the handle to fix value to 20. But one can approach like this also, github.com/.../simpleBLEPeripheral.c

    Take a look at periodictask().
  • Hello everyone,

    I am new to BLE programming so sorry for very basic question.

    I am trying to send GATT notification from peripheral using GATT_Notification API using GATT_Notification( 0 , pChar1_Noti, 0 );

    Where  pChar1_Noti = &AK_Profile_AttrTbl[2];  as suggested by Arun in his post.

    But when I build it, I get an error that " a value of type "gattAttribute_t *" cannot be assigned to an entity of type "struct <unnamed> *" which is understandable for me because AK_Profile_AttrTbl and attHandleValueNoti_t have different types of structures. How can we assign the address of attHandleValueNoti_t to the pointer of an element of Profile_AttrTbl.

    Please help me in sending my first GATT_Notification to the client.

    Thanks