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

ble_nus_data_send() usage (again)

I want to quickly send up to 100KB of data to a connected smartphone and then disconnect to save battery.

I have most of this working using the NUS service but today I noticed ble_nus_data_send() takes a pointer (uint16_t  * p_length) as a parameter, this is the number of bytes to send and also the number of bytes sent. The example doesn't check this value at all.

Should I check *p_length immediately after calling the ble_nus_data_send() function? It's not obvious if *p_length is updated asynchronously or not. 

the ble_nus_data_send() calls down to sd_ble_gatts_hvx but there is no source available to look at.

At the moment my main loop looks like this (simplified)

    for (;;)
    {
        if (can_send)
        {
            int expected = length;
            err_code = ble_nus_data_send(&m_nus, data_p, &length, conn_handle);
            APP_ERROR_CHECK(err_code);
            if (expected != lenght)
            {
                //log error and explode
            }
            can_send = false;
        }
        idle_state_handle();
    }


in NUS event handler

if (p_evt->type == BLE_NUS_EVT_TX_RDY)
{
    can_send = true; 
}


I send BLE_NUS_MAX_DATA_LEN bytes per call.

If *p_length is less than requested then what should I do? 

To give an example, If I call ble_nus_data_send() with *p_length = 240 and after the call I see *p_length == 100, should I wait to get BLE_NUS_EVT_TX_RDY  and then send the remaining 140 bytes again?

Is there a substantially faster way to send the data instead of using the NUS service? 

My connection parameters are 

#define MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_1_25_MS) //The central decides anyway
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(30, UNIT_1_25_MS) // These comply with apple guidelines 
#define SLAVE_LATENCY 30  
#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)

Any help is appreciated,

-Jason

Related