nRF5 SDK is not maintained anymore
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Best way to detect when a client subscribes to the NUS

Hi,

So we have a project where we use the NUS, and we need to detect when a client subscribes. We eventually found a way, but it seems very obtuse and a bit black magic, so we wondered if this was the way things are "supposed" to work. Can you confirm?

First we register a handler on BLE events when we initialise the SD:

NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
Then in our handler we do this (actually a lot more but shortened for this post):
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    if ( p_ble_evt->header.evt_id == BLE_GATTS_EVT_WRITE && p_ble_evt->evt.gatts_evt.params.write.data[0] == 1 )
    {
         // do on subscribe stuff here
    }
}
(But surely there must be an easier way?)
thanks
  • Hi,

    The NUS service will actually raise an event when notifications are enabled/disabled by the client, but the ble_app_uart example does not subscribe for these events by default so it might be easy to overlook. You can "subscribe" for these events in the nus_data_handler():

    /**@brief Function for handling the data from the Nordic UART Service.
     *
     * @details This function will process the data received from the Nordic UART BLE Service and send
     *          it to the UART module.
     *
     * @param[in] p_evt       Nordic UART Service event.
     */
    /**@snippet [Handling the data received over BLE] */
    static void nus_data_handler(ble_nus_evt_t * p_evt)
    {
    
        
        switch (p_evt->type) 
        {
            case BLE_NUS_EVT_RX_DATA:
            {
        
                uint32_t err_code;
    
                NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
                NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
    
                for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
                {
                    do
                    {
                        err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
                        if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
                        {
                            NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
                            APP_ERROR_CHECK(err_code);
                        }
                    } while (err_code == NRF_ERROR_BUSY);
                }
                if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '\r')
                {
                    while (app_uart_put('\n') == NRF_ERROR_BUSY);
                }
            } break;
    
            case BLE_NUS_EVT_COMM_STARTED:
                NRF_LOG_INFO("Notifications enabled");
                break;
           
            case BLE_NUS_EVT_COMM_STOPPED:
                NRF_LOG_INFO("Notifications disabled");
                break;
    
            default:
                break;
        }
    
    }

    Best regards,

    Vidar

  • thanks, this works very well.

Related