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,

    I can take a look at this issue today, can you please attach your minimalist project for me to reproduce it.

    I do not like to construct the project myself as it might lead to some differences in our setups.

  • 2211.RTE_ble_app_hrs-hrs_freertos_2019-03-04.zip

    You can copy this file to the nrf5_sdk_15.2.0 to "examples\ble_peripheral\RTE_ble_app_hrs_freertos"

    I use the SEGGER IDE and the PCA10040 as target.

    Happy coding

    Christian

  • Hello Susheel

    I have the following settings in my "local" sdk_config.h "D:\Projekte\Nordic\nRF5_SDK_15.2.0_9412b96\examples\ble_peripheral\RTE_ble_app_hrs_freertos\pca10040\s132\config\sdk_config.h"

    With these settings I can connect with nRf Go from Android without problems.

    Using higher values for NRF_SDH_BLE_GAP_DATA_LENGTH and NRF_SDH_BLE_GATT_MAX_MTU_SIZE crashes the app and the BLE stack on the Android phone.

    // <i> Expressed in number of 4-byte words.
    // <i> By default, a virtual page is the same size as a physical page.
    // <i> The size of a virtual page must be a multiple of the size of a physical page.
    // <1024=> 1024 
    // <2048=> 2048 
    
    #ifndef FDS_VIRTUAL_PAGE_SIZE
    #define FDS_VIRTUAL_PAGE_SIZE 1024
    #endif
    
    // </h> 
    //==========================================================
    
    // <h> Backend - Backend configuration
    
    // <i> Configure which nrf_fstorage backend is used by FDS to write to flash.
    //==========================================================
    // <o> FDS_BACKEND  - FDS flash backend.
     
    
    // <i> NRF_FSTORAGE_SD uses the nrf_fstorage_sd backend implementation using the SoftDevice API. Use this if you have a SoftDevice present.
    // <i> NRF_FSTORAGE_NVMC uses the nrf_fstorage_nvmc implementation. Use this setting if you don't use the SoftDevice.
    // <1=> NRF_FSTORAGE_NVMC 
    // <2=> NRF_FSTORAGE_SD 
    
    #ifndef FDS_BACKEND
    #define FDS_BACKEND 2
    #endif
    

    // <i> Requested BLE GAP data length to be negotiated.
    
    // RTE_MODIFICATION
    #ifndef NRF_SDH_BLE_GAP_DATA_LENGTH
    //#define NRF_SDH_BLE_GAP_DATA_LENGTH 27 /* OK */
    // #define NRF_SDH_BLE_GAP_DATA_LENGTH 54 /* OK */
    //#define NRF_SDH_BLE_GAP_DATA_LENGTH 108 /* OK */
    //#define NRF_SDH_BLE_GAP_DATA_LENGTH 123 /* OK */
    #define NRF_SDH_BLE_GAP_DATA_LENGTH 127 /*  */
    
    //#define NRF_SDH_BLE_GAP_DATA_LENGTH 216 /* CRASH on connect */ 
    //#define NRF_SDH_BLE_GAP_DATA_LENGTH 251 /* CRASH on connect */
    #endif
    
    

    // RTE_MODIFICATION
    // <o> NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. 
    #ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
    //#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 23 /* OK */
    //#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 50 /* OK */
    //#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 104 /* OK */
    //#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 119 /* OK */
    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 123 /*  */
    
    //#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 212 /* CRASH on connect */
    //#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247 /* CRASH on connect */
    #endif

  • first of all compiling you code for debug makes the executable too large to fit in PCA10040 (nRF52832)

    There are a lot of memory corruption when initializing FDS.

    I think you might very well be having a stack overflow in your RAM.

    Why did you code size increase so much compared to ble_app_hrs_freertos?

  • I have no problems with compiling, loading and running my example in "Debug" and "Release" target!

    On Line 491 in the main file of my example there is a define:

    #define PRESSGUN_SERVICE 1

    If you set this to #define PRESSGUN_SERVICE 0, then you have the original hrs_freertos example.

    #define PRESSGUN_SERVICE 0

    The memory usage of the Debug target is: FLASH 222.9 KB, RAM 34.1 KB

    #define PRESSGUN_SERVICE 1

    The memory usage of the Debug target is: FLASH 227.4 KB, RAM 35.6 KB

    My exaple fits wit no problem to the PCA10040 with a nRF52832!

    Did you select the correct debugger serial umber to download? Is it a bare PCA10040 that is only connected on connector J2 to USB.

    Make sure that no other target board is connected to the PCA10040 through the "Debug Out" port. If so, you will download my project to the connected external target board.

    Happy coding

    Christian

  • Sorry Christian,

    I have been on road on business travel and could not look into this case until coming friday. If you want someone else to look into it, i can forward this to my colleague to help us out.

  • Hello

    It would be great if you can forward this.

    We are already in field tests and I can only use the slow BLE 4.0 standard settings. Next week there is a road show, and the fast BLE 4.2 connection would be great

Reply Children
  • i tried your project and changed the MTU size and data length size. I see the pendSV interrupt causing a hardfault most likely due to a stack pull that happens with a corrupted stack frame. 

    I am guessing that you do not have enough free RAM space to do these operations .

    Try to see if you have stack overflow by doing one of the two methods mentioned here.

    Increasing the stack size might not work either, as you might have run out of free space on your device.

Related