This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Long Attributes

Hi, I need to have long attributes. So I need 'Read Blob' operation for read and Queued writes ('Prepare Write' and 'Execute Write'). Does Soft Device for nrf51822 support mentioned commands?

Best regards, Artem Zemlyanukhin

  • Hi,

    Last post is mine, forgot login.

    I understood my 1 and 2 questions. Those BLE_GATTS_EVT_WRITE/BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events with len = 0, data = 0 were 'BLE_GATTS_OP_EXEC_WRITE_REQ_NOW'.

    And I want to expand 4 question. Not only 'BLE_EVT_USER_MEM_REQUEST' event stack generates after 'Execute Write Request'. If I use Authorization for attribute, stack generates BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST(BLE_GATTS_OP_EXEC_WRITE_REQ) events also only after 'Execute Write Request'.

    But in your documentation I saw Message Sequence Charts, where was following sequence:

    -client send PrepWriteReq1 -stack generates BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST -server send PrepWriteResp1 -client send PrepWriteReq2 -stack generates BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST -server send PrepWriteResp2 -client send PrepWriteReq3 -stack generates BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST -server send PrepWriteResp3 -client send ExecWriteReq -stack generates BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST -server send ExecWriteResp

    In fact I have following sequence:

    -client send PrepWriteReq1 -client send PrepWriteReq2 -client send PrepWriteReq3 -client send ExecWriteReq -stack generates BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST (BLE_GATTS_OP_PREP_WRITE_REQ) -stack generates BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST (BLE_GATTS_OP_PREP_WRITE_REQ) -stack generates BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST (BLE_GATTS_OP_PREP_WRITE_REQ) -stack generates BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST (BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)

    And I don't know when stack send PrepWriteResps and ExecWriteResp

    Best Regards, Artem Zemlyanukhin

  • When testing with an iPhone, I don't have as fine-grained control as you have on when the different requests are sent, so I can unfortunately not duplicate your testing exactly.

    However, I can't understand how what you say about the sequence of events is possible, since the stack will have no memory or anywhere to store the queued writes if the application haven't provided a memory buffer.

    Are you sure that the TI tool you're using isn't buffering the writes somewhere and send them all at once when you do the execute? If you have access to a sniffer, can you see the packets going over the air, without the corresponding events on the nRF51 side?

    When I sniff a link while doing a long write, I can see that there are Prepare Write Responses sent for each Prepare Write Request, and then an Execute Write Response for the last Execute Request, but since all the events happen automatically, it isn't easily possible for me to correlate the time in the sniffer and the time on the serial interface.

  • For completeness, I'll try to answer these questions separately:

    1. This is to be expected, as it is the Execute Write event, as you can see in the op field of ble_gatts_evt_write_t. This event will never have a length or a value, and if you need to see the values written, you'll have to either parse the memory buffer you provided yourself (see the format description in the softdevice headers) or use sd_ble_gatts_value_get() as you've done.

    2. This extra write is the Execute Write.

    3. This is actually a bug in my code that I didn't notice when testing. The intention was just to see that the same memory area was released afterwards, but to check this, you have to compare the actual memory pointer, i.e. p_data field of the memory block. However, since the memory allocation is static anyway, it doesn't really matter in my case.

    4. See my comment on your other reply below.

    5. This shouldn't be possible. When I sniff the link, I can see responses going over the air. Not sending such responses would be a spec violation, and trigger a GATT timeout, most likely causing a disconnect, so I believe this must be a bug in the TI tool.

  • Thank you,

    You are right, TI software buffers PrepareWritesReqs and sends after I send ExecuteWriteReq. I checked this with sniffer, thank you for advice!

  • Hi,

    I have an issue with Read Blob, could you help to solve it please?

    I have attribute 'att1' with 64 bytes length allocated in user ram (BLE_GATTS_VLOC_USER). I use authorized read.

    For example, 'att1' contains zeroes. Because MTU = 23, I need 3 ReadBlobRequests to read it.

    In BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event handler I must set parameters for 'sd_ble_gatts_rw_authorize_reply' and call it.

    At first, I used following parameters:

    auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
    auth_reply.params.read.offset = offset;
    auth_reply.params.read.p_data = data;
    auth_reply.params.read.update = 1;
    

    'data' and 'att1' is not the same (so I set update = 1). For example 'data' points to array that contains numbers from 0x00 to 0x3F.

    Here are the results from Master Control Panel:

    [17:15:26.5] Received Read Blob Response, offset 0, value (0x): 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10-11-12-13-14-15 [17:15:26.5] Received Read Blob Response, offset 22, value (0x): 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10-11-12-13-14-15 [17:15:26.5] Received Read Blob Response, offset 44, value (0x): 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10-11-12-13

    If you can see melody_offset does not matter...

    Then I changed parameters to:

    auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
    auth_reply.params.read.offset = 0;
    auth_reply.params.read.p_data = data + offset;
    auth_reply.params.read.update = 1;
    

    then:

    [17:17:37.2] Received Read Blob Response, offset 0, value (0x): 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10-11-12-13-14-15 [17:17:37.3] Received Read Blob Response, offset 22, value (0x): 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 [17:17:37.3] Received Read Blob Response, offset 44, value (0x): 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

    And at the end:

    auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
    auth_reply.params.read.offset = offset;
    auth_reply.params.read.p_data = data + offset;
    auth_reply.params.read.update = 1;
    

    And after that I got results that I need:

    [17:19:09.5] Received Read Blob Response, offset 0, value (0x): 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10-11-12-13-14-15 [17:19:09.6] Received Read Blob Response, offset 22, value (0x): 16-17-18-19-1A-1B-1C-1D-1E-1F-20-21-22-23-24-25-26-27-28-29-2A-2B [17:19:09.6] Received Read Blob Response, offset 44, value (0x): 2C-2D-2E-2F-30-31-32-33-34-35-36-37-38-39-3A-3B-3C-3D-3E-3F

    But why do I have to set p_data = data + offset? I already set offset..

    Also I tried to reset update field and assign to auth_reply.params.read.p_data pointer to 'att1'. In this case, all three are correct methods. So I guess if update = 0, p_data and offset values do not matter. But I need to use update = 1 because actually I have array strings (each of 64 bytes) and in different cases I want to point in 'sd_ble_gatts_rw_authorize_reply' different rows fo my array.

Related