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.

CC2640R2F: BLE-Stack: read attribute callback - long characteristic read / write

Part Number: CC2640R2F
Other Parts Discussed in Thread: BLE-STACK

Hi,

I'm currently trying to implement a long characteristic in the BLE-Stack and have some questions about it.

I generated a new service via the code generator available form the example description ()

I did not find any possibility to set a certain length of a characteristic in the Attribute Table (gattAttribute_t largeData_AttrTbl[] = ... )

So as I found out BTool, issues as long read commands on a certain characteristic as the packet size is same size as MTU in the readCallback function.

bStatus_t largeData_ReadAttrCB( uint16_t connHandle, gattAttribute_t *pAttr,
                                       uint8_t *pValue, uint16_t *pLen, uint16_t offset,
                                       uint16_t maxLen, uint8_t method )

I did not find any #defines which I could use with parameter "method". However I saw in the first run it is given a 0x10 there (is this --> #define ATT_READ_BY_GRP_TYPE_REQ         0x10   <-- the correct define?

On a read access of BTool to this characteristic an issue is reported. Is this the usual way, which happens on reading a long characteristic or what do I have to adjust to issue the correct command immediately (so BTool recognizes the characteristic correctly)? (--> GATT_ReadLongCharValue)

--------------------------------------------------------------------
[57] : <Info> - 10:32:14.618
GATT_ReadCharValue Response Issue
AttReadRsp Length Exceeds The Max Safe Length Of 21
AttReadRsp Will Be Ignored
A New GATT_ReadLongCharValue Is Being Queued Up For Tx
--------------------------------------------------------------------
[58] : <Rx> - 10:32:14.618
-Type           : 0x04 (Event)
-EventCode      : 0x00FF (HCI_LE_ExtEvent)
-Data Length    : 0x1C (28) bytes(s)
 Event          : 0x050B (1291) (ATT_ReadRsp)
 Status         : 0x00 (0) (SUCCESS)
 ConnHandle     : 0x0000 (0)
 PduLen         : 0x16 (22)
 Value          : 80:81:82:83:84:85:86:87:88:89:8A:8B:8C:8D:8E:8F:
                  90:91:92:93:94:95
Dump(Rx):
0000:04 FF 1C 0B 05 00 00 00 16 80 81 82 83 84 85 86 ................
0010:87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95    ...............
--------------------------------------------------------------------
[59] : <Tx> - 10:32:14.618
-Type           : 0x01 (Command)
-OpCode         : 0xFD8C (GATT_ReadLongCharValue)
-Data Length    : 0x06 (6) byte(s)
 ConnHandle     : 0x0000 (0)
 Handle         : 0x002F (47)
 Offset         : 0x0000 (0)
Dump(Tx):
0000:01 8C FD 06 00 00 2F 00 00 00                   ....../...
--------------------------------------------------------------------
[60] : <Rx> - 10:32:14.665
-Type           : 0x04 (Event)
-EventCode      : 0x00FF (HCI_LE_ExtEvent)
-Data Length    : 0x06 (6) bytes(s)
 Event          : 0x067F (1663) (GAP_HCI_ExtentionCommandStatus)
 Status         : 0x00 (0) (SUCCESS)
 OpCode         : 0xFD8C (GATT_ReadLongCharValue)
 DataLength     : 0x00 (0)
Dump(Rx):
0000:04 FF 06 7F 06 00 8C FD 00                      .........
--------------------------------------------------------------------
[61] : <Rx> - 10:32:14.816
-Type           : 0x04 (Event)
-EventCode      : 0x00FF (HCI_LE_ExtEvent)
-Data Length    : 0x18 (24) bytes(s)
 Event          : 0x050D (1293) (ATT_ReadBlobRsp)
 Status         : 0x00 (0) (SUCCESS)
 ConnHandle     : 0x0000 (0)
 PduLen         : 0x12 (18)
 Value          : 00:01:02:03:04:05:06:07:08:09:0A:0B:0C:0D:0E:0F:
                  10:11
Dump(Rx):
0000:04 FF 18 0D 05 00 00 00 12 00 01 02 03 04 05 06 ................
0010:07 08 09 0A 0B 0C 0D 0E 0F 10 11

Why is there only one Command (0x01 value) and the others are Type Event (0x04) e.g. HCI_LE_ExtEvent? (What for is the event between the command and the data?)

I would be happy if you can answer my question directly or refere to a bluetooth specification where certain things are explained regarding message flow or command issuing.

best regards

Andreas

  • Hi Andreas,

    Assigning an expert to help you out.

  • Hi Joakim

    thanks for forwarding the issue!

    looking forward to the answer.
    kind regards
    Andreas

  • Hello Andreas,

    You can refer to simpleProfileChar5 simple_gatt_profile.c (simple_peripheral) on how to define characteristics with more than 1 byte. There is only units of bytes/octets and not long/int etc. So a single byte or an array of bytes.

    I tested GATT_ReadLongCharValue on simpleProfileChar5 without any issues on simplelink_cc2640r2_sdk_3_10_00_15.

    Which SDK do you use?

    What kind of characteristic and size did you read from?  

  • Hi Eirik,

    thanks for the reply. I already saw the example of character-5 in simple profile.
    My question is mainly how it is handled if the characteristic size is higher than the MTU size configured in the stack.

    e.g. charcteristic size is 40 and MTU is 22

    1. read (BTool issues command: GATT_ReadCharValue(..))  --> callback is executed with maxLen = 22, offset = 0, method 0x10
    2. read (BTool issues command: GATT_ReadLongCharValue(..))  --> callback is executed with maxLen = 22, offset = 22, method 0x12

    I already used "Bluetooth LE Explorer"-tool to read the characteristic --> it shows the correct data. Until now I don't know exactly what for the parameter 'method' could be used, neither which defines in the source reflect the possible values.


    As the read-command works with Bluetooth LE Explorer-Windows tool I do not have a problem here anymore.

    More interesting to me is now the wirte procedure / respectively the corresponding callback.

    static bStatus_t SLOC_largeData_WriteAttrCB( uint16_t connHandle, gattAttribute_t *pAttr,
                                            uint8_t *pValue, uint16_t len, uint16_t offset,
                                            uint8_t method )

    If a characteristic is written (in the above segmented way) where from do I know that the wirte procedure is completed?
    Does a client always have to write the full ammount of bytes the characteristic has? (So is it allowed that a client only writes 38 bytes, if the full characteristic has 40 bytes?)

    In the write callback I miss the maxLen parameter, so I do not know the MTU size inside this function. --> For a write procedure I would have to save the currently written length and double check with the given offset if everything is correct.

    --> could I use the 'method' parameter to recognize that a certain packet is the last one of a write procedure.
    It would be really nice to know where are the defined values which can be used with this parameter 'method'


    So basically the question is, can a (long) characteristic use variable length or is it intended to always write / read the same ammount of bytes in one write- or read-procedure. --> This question targets compatibility to other applications e.g. mobile apps

    best regards

    Andreas U

  • Hello Andreas,

    Refer to BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G section 4.9.4  Write Long Characteristic Values. 

    The Attribute protocol Prepare Write Request and Execute Write Request are used to perform this sub-procedure.

    This means that the stack will split up the GATT_WriteLongCharValue in to several prepare write requests and at the end will send the Execute Write Request. Therefore you do not rely on any maxLen. I believe you can identify the execute write request in the method argument of SLOC_largeData_WriteAttrCB. I believe you can find all method defined in att.h. You can also find the opcode values in the BT Core spec.

    I am not sure if we have example for this.

    relevant threads for the topic:

    https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/538/p/221165/1350585#1350585