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

Cannot detect advertising timeout event (BLE_GAP_EVT_TIMEOUT, BLE_ADV_EVT_IDLE, etc)

Hi, I am developing an application using the nRF52DK and SDK V15.2.0. My application is built off of the uart example. I want my device to read some data from a sensor, advertise for 5 seconds, then either send the data if a connection is made or store the data and re-advertise in 30 seconds in the event of an advertising timeout. If the connection is made and data is sent, I also want the nRF52 DK to repeat this protocol every 30 seconds. I.E. read data, advertise, sleep for 30 seconds, repeat.

If a connection is made every time, the protocol works great - the DK sends the data, goes to sleep for 30 seconds, then reads more data and advertises itself again. However, it does not work if no connection is made and the nRF52DK times out while advertising. I have removed every instance/call to power management/sleep mode functions, to eliminate this variable from the issue. I have a switch cases in the "on_adv_evt()" function to recognize the BLE_ADV_EVT_IDLE case. I have switch cases in "ble_evt_handler()" for BLE_GATTC_EVT_TIMEOUT,  BLE_GATTS_EVT_TIMEOUT, and BLE_GAP_EVT_TIMEOUT. Here are some of my connection parameters and switch cases:

/* CONNECTION PARAMS */

define APP_ADV_INTERVAL                 325  // units of 0.625 ms                                   

#define APP_ADV_DURATION                500  // units of 10 ms                                      

#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)             
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(200, UNIT_1_25_MS)            
#define SLAVE_LATENCY                   0                                          
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(5000, UNIT_10_MS)             
#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(500)                      
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                     
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                         

/* on_adv_evt() function */

static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_FAST:
            NRF_LOG_INFO("FAST ADVERTISING STARTED");
            break;
        case BLE_ADV_EVT_IDLE:
            NRF_LOG_INFO("on_adv_evt IDLE EVENT");
            // Restart timer 
            init_and_start_app_timer();
            break;
        default:
            break;
    }
}

/* ble_evt_handler() function */

// Only the relevant timeout-related switch cases are included,
// the other standard connection/disconnected/etc are not included
// here for brevity

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    uint32_t err_code;

    NRF_LOG_INFO("INSIDE BLE EVT HANDLER\n");
    NRF_LOG_INFO("evt id: %u\n", p_ble_evt->header.evt_id);

    switch (p_ble_evt->header.evt_id)
    {    
        case BLE_GATTC_EVT_TIMEOUT:
            NRF_LOG_INFO("TIMEOUT GATTC EVT\n");
            // Disconnect on GATT Client timeout event.
            err_code = 
                sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                      BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            // restart timer
            init_and_start_app_timer();
            break;
        case BLE_GATTS_EVT_TIMEOUT:
            NRF_LOG_INFO("TIMEOUT GATTS EVT\n");
            // Disconnect on GATT Server timeout event.
            err_code = 
                sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                      BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            APP_ERROR_CHECK(err_code);
            // restart timer
            init_and_start_app_timer();
            break;
        case BLE_GAP_EVT_TIMEOUT:
            NRF_LOG_INFO("TIMEOUT GAP EVT\n");
            // Restart timer 
            init_and_start_app_timer();
            break;
        default:
            // No implementation needed.
            break;
    }
}
    
    

I know that my "init_and_start_app_timer()" function works, because it works when a connection is made every time (waits for 30 seconds using app timer, then starts advertising again). I put print statements in each case where the advertising could be recognized, but nothing ever prints. I also run the debugger and put breakpoints at each of the relevant switch cases, but the breakpoints are never reached. This tells me these events are not being triggered, or for some reason my application is not receiving the events. 

I am also using peer manager, do I need to check for some event here? I would not think so, because there would be no peer to manage if a connection is not made. My application does not throw any errors when I let the DK advertise but do not make a connection, it just runs perpetually doing seemingly nothing. 

Any advice or insights to help me recognize when advertising timeout occurs would be incredibly helpful! Thanks so much.

Parents Reply Children
Related