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

  • 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