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

Prevent SD from Automatically Advertising after Disconnection

I have an NRF51 board running as a GATT server. Using an iOS application (LightBlue) I connect to the NRF51. If I quit the iOS application then I get a disconnect event and the NRF51 starts to automatically begin advertising again. I do not want the NRF51 to begin advertising again after a disconnection--I intend to put my system to sleep after displaying a little shutdown LED animation. I don't want someone connecting while I am doing this shutdown.

I think I have a workaround where I call sd_ble_gap_adv_stop() in my advertising event handler if the system is shutting down, but is there a way to prevent it from trying to automatically advertising after being disconnected?

  • Hi

    • If you are using e.g. ble_app_hrs (heart rate example) then you will get a callback in your nRF51 application when you disconnect.

    • This callback will enter the ble_evt_dispatch function in the main.c file. The dispatcher will direct the BLE calls to different modules, including the advertising module, with call to ble_advertising_on_ble_evt function in the advertising module.

    • In the ble_advertising_on_ble_evt function, there is a switch statement BLE_GAP_EVT_DISCONNECTED, which is entered upon disconnect.

    • Instead of starting starting advertising in BLE_ADV_MODE_DIRECTED, as done in the ble_app_hrs example, just set the advertising module into the idle state with the following code:

        case BLE_GAP_EVT_DISCONNECTED:
        {
        		uint32_t err_code;
        		m_whitelist_temporarily_disabled = false;
      
        		if (p_ble_evt->evt.gap_evt.conn_handle == current_slave_link_conn_handle)
        		{
        			 m_adv_evt = BLE_ADV_EVT_IDLE;
        			 m_evt_handler(m_adv_evt);
        		}
        		break;
        }
      

    Then the advertising module will call the registered callback handler in main.c (which was registered in call to advertising_init() in the main function). The callback handler (on_adv_evt) calls sleep_mode_enter() which makes the chip enter System Off mode and shuts down all LED activity on the development board.

  • Thanks for the reply. Couple questions:

    1. m_adv_evt and m_whitelist_temporarily_disabled are statically defined in ble_advertising.h. How can I use them in main.c without hacking ble_advertising.c where they are declared static?
    2. Which function is restarting the advertisement on a disconnection event? Is this being internally done by the softdevice?

    My problem with the solution is that I have a short LED animation I need to perform before the system shuts down. I do not want the system to be advertising while it is shutting down. My workaround works, but there is a (very) short period of time that advertising is active before the advertising event handler is called and I shut off the advertising.

  • I think you must "hack" the ble_advertising.c in order to not restart the advertising on disconnect. The function above is the one starting the advertising with call to

    ble_advertising_start(BLE_ADV_MODE_DIRECTED);
    

    this call you can see in the original ble_app_hrs example. I have replaced it with the code above. The code above calls the registered event handler in main.c, i.e. the on_adv_evt in main.c. It is actually in on_adv_evt that the chip is put to System Off mode with call to sleep_mode_enter(). Before calling sleep_mode_enter(), you can perform your LED operation.

    If you change the ble_advertising.c file, it is a good practice to place it in your project folder, in order to have the library files unmodified.

  • I was under the mistaken impression that your code was destined for the ble event handler for the disconnection event. Placing in ble_advertising.c makes makes your code make sense now--and even better, it works as advertised (pardon the semi-intentional pun).

    Thanks for the help.

    -F

Related