When notification with big data, only maximum 4 notification is sent.

Dear Nordic support team,
I meet a situation: I have big data array need to transfer("arrayTransfer" with 3072 bytes)
to smart phone by notification method. Using timer 10s to send 3072 byte to smart phone.

I want to send 128 bytes data for one notification.

So I have to separate "arrayTransfer" to small array (128 bytes each notification).

It mean with 3072 byte we need send 24 notifies to smart phone.

I see that on our App only receive 4 notifies instead 24.

If I change separate "arrayTransfer" to small array (32 bytes each notification).

It mean with 3072 byte we need send 96 notifies to smart phone.

But we also only receive 4 notifies instead 96.

=> Why we only send maximum 4 time notification?

     I try with change number of notification byte: 128byte/32bytes/8bytes/... The same result, we on ly maximum 4 notifications is sent to smartphone.

=> How to change the maximum notification send? Can you see and help me review the "dataTransferHandler" function below.

thanks and best regards,

   



Here is my function code in the "main.c"

uint8_t arrayTransfer[3072]; 

void initArray(void)
{
 uint8_t i, j;
    for(i =0; i<24; i++)
    {
        for(j = 0; j< 128; j++)
        {
            arrayTransfer[i*loop2 + j] = j;
        }
    }
 
}
static void dataTransferHandler(void * p_context)
{

    UNUSED_PARAMETER(p_context);
    uint8_t dataTransfer[128];
    uint8_t dataLengthTransfer = sizeof(dataTransfer), i, j;
    ret_code_t err_code;
    

    for(i = 0; i< 24; i++)
    {
        for(j = 0; j<128; j++)
        {
            dataTransfer[j] = arrayTransfer[i*128+j+i];
        }
        err_code = ble_TWIs_temperature_update(&m_TWIs, dataTransfer, BLE_CONN_HANDLE_ALL, dataLengthTransfer);
    }


    if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) &&
        (err_code != NRF_ERROR_RESOURCES) && (err_code != NRF_ERROR_BUSY) &&
        (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING))
    {
        APP_ERROR_HANDLER(err_code);
    }
}



int main(void)
{
    bool erase_bonds;
    ret_code_t err_code;
    // Initialize.
    log_init();
    timers_init();
    initArray();
    ......
}


  • Hi,

    How does the function ble_TWIs_temperature_update() look like?

    Can you print what the function is returning?

  • hello Sigurd,

    Bellow is the ble_TWIs_temperature_update()

    ret_code_t ble_TWIs_temperature_update(ble_TWIs_t * p_TWIs, uint8_t     *pData, uint16_t    conn_handle, uint16_t datalength)
    {
        if (p_TWIs == NULL)
        {
            return NRF_ERROR_NULL;
        }
    
        ret_code_t         err_code = NRF_SUCCESS;
        ble_gatts_value_t  gatts_value;
    
        //if (currentVal != lastVal)
        {
            // Initialize value struct.
            memset(&gatts_value, 0, sizeof(gatts_value));
    
            gatts_value.len     = datalength * sizeof(uint8_t);
            gatts_value.offset  = 0;
            gatts_value.p_value = pData;
    
            // Send value if connected and notifying.
            if (p_TWIs->is_notification_supported)
            {
                ble_gatts_hvx_params_t hvx_params;
    
                memset(&hvx_params, 0, sizeof(hvx_params));
    
                hvx_params.handle = p_TWIs->TWI2C_level_handles.value_handle;
                hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
                hvx_params.offset = gatts_value.offset;
                hvx_params.p_len  = &datalength;
                hvx_params.p_data = gatts_value.p_value;
    
                if (conn_handle == BLE_CONN_HANDLE_ALL)
                {
                    NRF_LOG_DEBUG("conn_handle == BLE_CONN_HANDLE_ALL")
                    ble_conn_state_conn_handle_list_t conn_handles = ble_conn_state_conn_handles();
                    // Try sending notifications to all valid connection handles.
                    for (uint32_t i = 0; i < conn_handles.len; i++)
                    {
                        if (ble_conn_state_status(conn_handles.conn_handles[i]) == BLE_CONN_STATUS_CONNECTED)
                        {
                            if (err_code == NRF_SUCCESS)
                            {
                                err_code = temperature_notification_send(&hvx_params,
                                                                     conn_handles.conn_handles[i]);
                                 NRF_LOG_DEBUG("Try sending notifications to all valid connection handles")
                            }
                            else
                            {
                                // Preserve the first non-zero error code
                                UNUSED_RETURN_VALUE(temperature_notification_send(&hvx_params, conn_handles.conn_handles[i]));
                            }
                        }
                    }
                }
                else
                {
                    NRF_LOG_DEBUG("conn_handle != BLE_CONN_HANDLE_ALL")
                    err_code = temperature_notification_send(&hvx_params, conn_handle);
                }
            }
            else
            {
                err_code = NRF_ERROR_INVALID_STATE;
            }
        }
        return err_code;
    }

  • You might be filling up the SoftDevice buffer to fast. After 4 notifications queued/buffered, you are likely getting NRF_ERROR_RESOURCES returned. You could try to set NRF_SDH_BLE_GAP_EVENT_LENGTH in sdk_config.h to a higher value, e.g. 320. After this change, you likely need to allocate more RAM to the SoftDevice.

  • hi,

    I get log error code return in dataTransferHandler() function, and see that it return  0(NRF_SUCCESS) total 4 times, and 20 times remain return 19(NRF_ERROR_RESOURCES), NRF_ERROR_RESOURCES mean Not enough resources like that below:

    #define NRF_SUCCESS        (NRF_ERROR_BASE_NUM + 0)  ///< Successful command

    #define NRF_ERROR_RESOURCES              (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation

    So i think this is the main reason it only send 4 notifications to smart phone app..

    => Do you have sugestion for me?

    Below is my RAM and Flash configure:

    linker_section_placement_macros="FLASH_PH_START=0x0;FLASH_PH_SIZE=0x30000;RAM_PH_START=0x20000000;RAM_PH_SIZE=0x6000;FLASH_START=0x19000;FLASH_SIZE=0x17000;RAM_START=0x20002000;RAM_SIZE=0x6000"
    linker_section_placements_segments="FLASH RX 0x0 0x30000;RAM1 RWX 0x20000000 0x6000"

    dataTransferHandler() function:

    static void dataTransferHandler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
        
        uint8_t dataLengthTransfer = 128;
        ret_code_t err_code;
        uint16_t i = 0, j;
    
        for(i = 0; i< 24; i++)
         {
            for(j = 0; j<128; j++)
    
            {
                dataTransfer[j] = arrayTransfer[i*128+j+i];
            }
            err_code = ble_TWIs_temperature_update(&m_TWIs, dataTransfer, BLE_CONN_HANDLE_ALL, dataLengthTransfer);
            NRF_LOG_INFO("err_code: %d.", err_code); //get erro code to check
            
            if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) &&
                (err_code != NRF_ERROR_RESOURCES) && (err_code != NRF_ERROR_BUSY) &&
                (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING))
            {
                APP_ERROR_HANDLER(err_code);
            }
        }
    }

  • Hi,

    Quangca said:
    Do you have sugestion for me?

    Yes, as mentioned:

    Sigurd said:
    You could try to set NRF_SDH_BLE_GAP_EVENT_LENGTH in sdk_config.h to a higher value, e.g. 320.
Related