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.

simpleGATTProfile modification question

Hi.

I want to read an attribute value from inside itself.

Usually when I read an attribute, I format the output in the simpleProfile_ReadAttrCB method.

Now, my desire is to trigger a read from inside the gattprofile (or really just anywhere inside the embedded system). My approach so far was to modify the simpleProfile_HandleConnStatusCB to handle whenever a connection is initialized, and read the value in a way that would trigger the callback and propagate the answer out like this:

static void simpleProfile_HandleConnStatusCB( uint16 connHandle, uint8 changeType )
{
// Make sure this is not loopback connection
if ( connHandle != LOOPBACK_CONNHANDLE )
{
if( changeType == LINKDB_STATUS_UPDATE_NEW)
{
// DO A READ HERE THAT IS DESIRED TO TRIGGER A NEW PACKAGE AS SHOWN BELOW
}

// Reset Client Char Config if connection has dropped
if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED ) ||
( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&
( !linkDB_Up( connHandle ) ) ) )
{
GATTServApp_InitCharCfg( connHandle, simpleProfileChar4Config );
}
}
}
I usually get this output whenever I establish a connection:

[19] : <Tx> - 01:14:18.652
-Type : 0x01 (Command)
-Opcode : 0xFE09 (GAP_EstablishLinkRequest)
-Data Length : 0x09 (9) byte(s)
HighDutyCycle : 0x00 (Disable)
WhiteList : 0x00 (Disable)
AddrTypePeer : 0x00 (Public)
PeerAddr : E3:EE:84:B7:2D:3C
Dump(Tx):
01 09 FE 09 00 00 00 E3 EE 84 B7 2D 3C

------------------------------------------------------------------------------------------------------------------------

[20] : <Rx> - 01:14:18.742
-Type : 0x04 (Event)
-EventCode : 0xFF (HCI_LE_ExtEvent)
-Data Length : 0x06 (6) bytes(s)
Event : 0x067F (GAP_HCI_ExtentionCommandStatus)
Status : 0x00 (Success)
OpCode : 0xFE09 (GAP_EstablishLinkRequest)
DataLength : 0x00 (0)
Dump(Rx):
04 FF 06 7F 06 00 09 FE 00

------------------------------------------------------------------------------------------------------------------------
[21] : <Rx> - 01:14:18.930
-Type : 0x04 (Event)
-EventCode : 0xFF (HCI_LE_ExtEvent)
-Data Length : 0x13 (19) bytes(s)
Event : 0x0605 (GAP_EstablishLink)
Status : 0x00 (Success)
DevAddrType : 0x00 (Public)
DevAddr : 3C:2D:B7:84:EE:E3
ConnHandle : 0x0000 (0)
ConnInterval : 0x0050 (80)
ConnLatency : 0x0000 (0)
ConnTimeout : 0x07D0 (2000)
ClockAccuracy : 0x00 (0)
Dump(Rx):
04 FF 13 05 06 00 00 E3 EE 84 B7 2D 3C 00 00 50
00 00 00 D0 07 00

------------------------------------------------------------------------------------------------------------------------
[22] : <Rx> - 01:14:19.583
-Type : 0x04 (Event)
-EventCode : 0xFF (HCI_LE_ExtEvent)
-Data Length : 0x0B (11) bytes(s)
Event : 0x0607 (GAP_LinkParamUpdate)
Status : 0x00 (Success)
ConnHandle : 0x0000 (0)
ConnInterval : 0x0020 (32)
ConnLatency : 0x0000 (0)
ConnTimeout : 0x012C (300)
Dump(Rx):
04 FF 0B 07 06 00 00 00 20 00 00 00 2C 01

And I would then like to have the read that I meantioned, trigger the GATT to write out at least the data package containing the read, or simply the value as an addition to the other data in the link establish package [21].

Something like this, in case it should come in its own package:

[25] : <Rx> - 01:16:00.217
-Type : 0x04 (Event)
-EventCode : 0xFF (HCI_LE_ExtEvent)
-Data Length : 0x0B (11) bytes(s)
Event : 0x0509 (ATT_ReadByTypeRsp)
Status : 0x00 (Success)
ConnHandle : 0x0000 (0)
PduLen : 0x05 (5)
Length : 0x04 (4)
Handle : 0x004C
Data : FC:03
Dump(Rx):
04 FF 0B 09 05 00 00 00 05 04 4C 00 FC 03

Any ideas on how to do this / what to add in the code part that I marked with red? (or other places, in case the call should be done somewhere else).

  • Hi Jesper,

    I am not sure what you are trying to do but If you are using a single-chip solution (Application and stack on the same chip), you can access attributes by using for example SimpleProfile_GetParameter().

    Best Regards

  • I'm trying to do exactly that.

    Forgive my lacking C skills, but if I want to call SimpleProfile_GetParameter(), it requires 2 parameters: 

    uint8 param

    void *value


    If i know the UUID (in this case b1:bb) and the handle for this is (0x004C), how would I format the method call?

  • Hi Jesper,

    Handles does not exist until the device is running and has performed the enumeration of handles. To use the XXX_SetParameter() command, have a look at the performPeriodicTask() that contains the call:

    uint8 valueToCopy;

    SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR3, &valueToCopy);

    Copy Paste is you friend... but be careful :)

    Best Regards

  • Ah that is shedding some light over how *_GetParameter works, thank you :)  

    However, what I need to do is send the data out to the client:

    So instead of setting the parameter like this;

      SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof(uint8), &valueToCopy);

    I need to replace that line with some code that sends out the data I read through the serial connetion. Just like if I did a Read Characteristic value/descriptor using Btool, except I dont want the user to have to ask for the value, it should happen automatically.

    How do I do this?

  • Hi Jesper,

    To simply send stuff over the air from a server, you can use GATT_Notification or GATT_Indication. The latter one is used when acknowledgement on application layer is needed. 

    The notification/indication includes the data you want to send but also handle and authentication info. Authentication info is a 1 byte value (0x00 for no, 0x01 for yes) to indicate if a an authenticated link is required. The handle depends on which attribute you want it to track back to, but in practice it does not matter as long as you Client can identify it.

    Note that "characteristic 4" in simpleGATTprofile uses notifications, so data is sent over the air as soon as *_SetParameter() had updated the value.

    Best Regards

  • It works! Thank you so much :)