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

Incomplete Data at write to peripheral with ATT_MTU=247 and DATA_LENGTH=251

SDK 15.2, S132 6.1, nRF52832

I have a characteristics to write data to a peripheral, using variable length up to 507 bytes and authorization.

Writing to the peripheral works fine with ATT_MTU=23 and DATA_LENGTH=27

When I establish a connection with ATT_MTU=247 and DATA_LENGTH=251, writing returns bad data after 28 bytes!

Data on wire: 122808021a241a2212200102030405060708091011121314151617181920212223242526272829303132

Data in buffer:122808021A241A22122001020304050607080910111213141516171801000000354D0300D1A90200A5A5

When writing from the central to the peripheral, the data is correct transmitted over the air to the peripheral (logged with wire shark).

In the peripheral, I get the event for receiving the written data. The length of the data is indicated correctly, but the data in the buffer in the BLE stack are incorrect.

The data I copy from the BLE stack to my local buffer are only correct for the first 28 byte! The remaining bytes are in the most cases constant memory garbage.

For me it looks like the BLE stacks doesn't handle all data.

Characteristic:

static uint32_t toolCommandCharAdd(tBlePowerTool * prtToBlePowerTool, const tBlePressGunSrvInit * ptrToBlePressGunSrvInit)
{
    ble_gatts_char_md_t gatts_char_md;
    ble_gatts_attr_t    gatts_attr;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t gatts_attr_md;

    // setup the char attr meta data
    memset(&gatts_char_md, 0, sizeof(gatts_char_md));
    gatts_char_md.char_props.write = true;
    gatts_char_md.char_ext_props.reliable_wr = true; // Queued write operation permmited

    // setup the characteristic attr 
    ble_uuid.type = prtToBlePowerTool->pressGunSrv.uuid_type;
    ble_uuid.uuid = PRESSGUNSRV_UUID_TOOL_COMMAND_CHAR;

    memset(&gatts_attr_md, 0, sizeof(gatts_attr_md));
    gatts_attr_md.read_perm  = ptrToBlePressGunSrvInit->payload_writeonly_attr_md.read_perm;
    gatts_attr_md.write_perm = ptrToBlePressGunSrvInit->payload_writeonly_attr_md.write_perm;
    gatts_attr_md.vlen       = true; // support of variable len 
    gatts_attr_md.vloc       = BLE_GATTS_VLOC_USER;
    gatts_attr_md.rd_auth    = true;
    gatts_attr_md.wr_auth    = true;

    memset(&gatts_attr, 0, sizeof(gatts_attr));
    gatts_attr.p_uuid    = &ble_uuid;
    gatts_attr.p_attr_md = &gatts_attr_md;
    gatts_attr.init_len  = 0;
    gatts_attr.init_offs = 0;
    gatts_attr.max_len   = sizeof BlePwrBrdCommEventDataWrite.dataBuf;
    gatts_attr.p_value   = (uint8_t *) BlePwrBrdCommEventDataWrite.dataBuf;

    return sd_ble_gatts_characteristic_add(prtToBlePowerTool->pressGunSrv.service_handle,
                                           &gatts_char_md,
                                           &gatts_attr,
                                           &prtToBlePowerTool->pressGunSrv.toolCommandHandles);
}

Event for Receiving:

        case BLE_GATTS_OP_WRITE_REQ:
            NRF_LOG_DEBUG("BLE_GATTS_OP_WRITE_REQ: len: %d", p_evt_write->len );
            memset( BlePwrBrdCommEventDataWrite.dataBuf, 0 , sizeof BlePwrBrdCommEventDataWrite.dataBuf );
            memcpy( BlePwrBrdCommEventDataWrite.dataBuf, &p_evt_write->data[0], p_evt_write->len );
            BlePwrBrdCommEventDataWrite.size = p_evt_write->len;

Debug Log:

<debug> nrf_ble_gatt: max_tx_time: 2120
<debug> nrf_sdh_ble: BLE event: 0x51.
<debug> app: BLE_GATTS_AUTHORIZE_TYPE_WRITE with BLE_GATTS_OP_WRITE_REQ
<debug> app: BLE_GATTS_OP_WRITE_REQ: len: 11
<debug> app: BlePwrBrdCommEventBleWrite
<debug> app: DATA BUFFER: 0A0908FA0710021A020816
<debug> nrf_sdh_ble: BLE event: 0x51.
<debug> app: BLE_GATTS_AUTHORIZE_TYPE_WRITE with BLE_GATTS_OP_WRITE_REQ
<debug> app: BLE_GATTS_OP_WRITE_REQ: len: 8
<debug> app: BlePwrBrdCommEventBleWrite
<debug> app: DATA BUFFER: 120608011A025200
<debug> nrf_sdh_ble: BLE event: 0x51.
<debug> app: BLE_GATTS_AUTHORIZE_TYPE_READ
<debug> app: FrameRead reply offset 0 (16 bytes) with SUCCESS.
<debug> nrf_sdh_ble: BLE event: 0x51.
<debug> app: BLE_GATTS_AUTHORIZE_TYPE_WRITE with BLE_GATTS_OP_WRITE_REQ
<debug> app: BLE_GATTS_OP_WRITE_REQ: len: 42
<debug> app: BlePwrBrdCommEventBleWrite
<debug> app: DATA BUFFER: 122808021A241A22122001020304050607080910111213141516171801000000354D0300D1A90200A5A5

Parents
  • Hi,

    Where/how do you declare BlePwrBrdCommEventDataWrite? It is important that BlePwrBrdCommEventDataWrite.dataBuf is valid for the lifetime of the characteristic (typically forever) since you use BLE_GATTS_VLOC_USER. It will be written to directly from the SoftDevice.

  • Hi

    This is the global declaration:

    tBlePwrBrdCommEventData     BlePwrBrdCommEventDataWrite;    ///< Write event data

    But I think it is not true that the data is copied directly to the gatts_attr.p_value location when "Write Authorization" is used.

    When I comment out the memset(..) and memcpy(..) calls in my BLE_GATTS_OP_WRITE_REQ handler, the data in my buffer is and stays always all zeros.

  • Some more information to my modified code:

    You can set the define on line 486 in the main.c of the RTE_ble_app_hrs_freeRTOS to zero to have only the original code.

    // RTE_START
    #define PRESSGUN_SERVICE 0

    If the mtu_size and data_length are set to larger values than default, the original code crashes already when connecting. There is a separate case for this issue:

    example-ble_app_hrs_freertos-crashing-with-max_mtu_size-247-and-data_length-251

  • Hi,

    I am sorry for the late reply. You may have spotted it already, but the problem here is that the example (like most SDK examples) use the QWR module. This module handles the BLE_EVT_USER_MEM_REQUEST before your application does, so when you handle the BLE_EVT_USER_MEM_REQUEST event and call sd_ble_user_mem_reply() again it returns NRF_ERROR_INVALID_STATE. To fix this issue you should either use only the QWR module or remove it altogether.

  • Hi Einar

    I have defined away the QWR module, I think it is only used when bonding.

    RTE_ble_app_hrs-hrs_freertos_2019-03-04.zip

    Now the RTE_ble_app_hrs works with maximum length, but with strange reporting:

    It is interchanged a max size of 123, but also longer payloads are exchanged in one telegram. This is strange.

    <debug> nrf_ble_lesc: Initialized nrf_crypto.
    <debug> nrf_ble_lesc: Initialized nrf_ble_lesc.
    <debug> nrf_ble_lesc: Generating ECC key pair
    <info> app: Heart Rate Sensor example started.
    <info> app: Fast advertising.
    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
    <debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
    <info> app: Connected.
    <debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
    <info> app: GATT ATT MTU on connection 0x0 changed to 247.
    <debug> nrf_ble_gatt: Data length updated to 123 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 123
    <debug> nrf_ble_gatt: max_tx_octets: 123
    <debug> nrf_ble_gatt: max_rx_time: 1096
    <debug> nrf_ble_gatt: max_tx_time: 1096
    <debug> nrf_ble_gatt: Peer on connection 0x0 requested a data length of 123 bytes.
    <debug> nrf_ble_gatt: Updating data length to 123 on connection 0x0.
    <debug> nrf_ble_gatt: Data length updated to 123 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 123
    <debug> nrf_ble_gatt: max_tx_octets: 123
    <debug> nrf_ble_gatt: max_rx_time: 1096
    <debug> nrf_ble_gatt: max_tx_time: 1096
    <debug> app: BLE_GATTS_AUTHORIZE_TYPE_WRITE with BLE_GATTS_OP_WRITE_REQ
    <debug> app: BLE_GATTS_OP_WRITE_REQ: len: 128
    <debug> app: BlePwrBrdCommEventBleWrite
    <debug> app: DATA BUFFER: 112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00
    <debug> app: BLE_GATTS_AUTHORIZE_TYPE_WRITE with BLE_GATTS_OP_WRITE_REQ
    <debug> app: BLE_GATTS_OP_WRITE_REQ: len: 96
    <debug> app: BlePwrBrdCommEventBleWrite
    <debug> app: DATA BUFFER: 112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00
    <debug> app: BLE_GATTS_AUTHORIZE_TYPE_WRITE with BLE_GATTS_OP_WRITE_REQ
    <debug> app: BLE_GATTS_OP_WRITE_REQ: len: 128
    <debug> app: BlePwrBrdCommEventBleWrite
    <debug> app: DATA BUFFER: 112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00
    <debug> app: BLE_GATTS_AUTHORIZE_TYPE_WRITE with BLE_GATTS_OP_WRITE_REQ
    <debug> app: BLE_GATTS_OP_WRITE_REQ: len: 144
    <debug> app: BlePwrBrdCommEventBleWrite
    <debug> app: DATA BUFFER: 112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00
    

    The example RTE_ble_app_hrs_freertos works fine only with 

    #define NRF_SDH_BLE_GAP_DATA_LENGTH 127 /* */
    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 123 /* */

    Higher values have crashed the BLE stack on my Android phone and I have to restart the Android phone to get a connection again.

    Please advise!

    Happy coding
    Christian

  • Hi Christian,

    It might be better to create a new question, as this does not seem directly related to your original question. Then I suggest you include a sniffer trace so that we can see what actually happens on the BLE link. Also, it would be good if you can compare with another peer device (for instance the nRF Connect for Desktop BLE app or an iOS device).

  • Hello Einar

    I have sent you my updated example. You have for sure the current SDK and a Segger IDE.

    Please compile my example, take a PCA10040 board to load it and then you can use your sniffer and "nRf connect for Desktop" live in your lab.

    I am not willing to debug your examples and BLE stack implementation!! And it is annoying that the first answer from Nordic is always a question for more action.

    Hope you can soon confirm my observations and suggest a solution or work around.

    Happy coding
    Christian

Reply
  • Hello Einar

    I have sent you my updated example. You have for sure the current SDK and a Segger IDE.

    Please compile my example, take a PCA10040 board to load it and then you can use your sniffer and "nRf connect for Desktop" live in your lab.

    I am not willing to debug your examples and BLE stack implementation!! And it is annoying that the first answer from Nordic is always a question for more action.

    Hope you can soon confirm my observations and suggest a solution or work around.

    Happy coding
    Christian

Children
  • Hi Christian,

    I am sorry you feel that way. We try to help as best as we can, but it is often useful to have more information before going into the details. Here you have an SDK example you have modified that does not behave like you want, and you describe an unspecified issue with a particular peer OS (that par is not entirely clear from your question, though). Therefor it is useful to see what is actually happening on the link, and to know whether this depend on the peer or not.

  • Hello Einar

    The software is exactly what you requested 22 day ago: e minimal example that runs on the DK!

    In the uploaded version from 2 days ago, I have commented out the QWR module, and the problem still exists.

    As peer I use Android 8.0.0 on a One+ 3T smartphone with OxygenOs 5.0.8 and the Nordic "nRf Connect for Mobile" Version 4.22.3 (most recent in Android App store).

    So please tell me whether you are still waiting for more input from me or you can start now to reproduce my problem!

    Happy coding
    Christian

  • Hi,

    Unfortunately we will not have time to debug this case until end of the week, the reason for this is that we need someone with freertos experience, since the issue seems to be related to freertos initialization from initial tests (hardfault in xPortPendSVHandler() when increasing NRF_SDH_BLE_GAP_DATA_LENGTH and NRF_SDH_BLE_GATT_MAX_MTU_SIZE).

    Best regards,
    Kenneth

Related