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

problem: NUS client multilink SDK 14.2.0 handles assignment fails

Hello,

I am implementing an application, where I want to connect three NUS peripherals to one NUS client. As a beginning point, I started with the supplied examples from SDK 14.2.0 (ble_app_uart and ble_app_uart_c). For the multilink feature, I adapted ble_app_multilink_central and advice from this topic.

I have taken BLE_NUS_C_ARRAY_DEF(m_ble_nus_c, SENSOR_BLE_LINK_COUNT) define from SDK 15, for having an array holding all of my NUS client structs. Different from the ble_app_multilink example, I used this advice for not having mutliple discovery events.

#define NRF_SDH_BLE_CENTRAL_LINK_COUNT  3
#define SENSOR_BLE_LINK_COUNT           NRF_SDH_BLE_CENTRAL_LINK_COUNT

/** @brief Macro for defining multiple ble_nus_c instances. Taken from SDK 15.0.0.
 *
 * @param   _name   Name of the array of instances.
 * @param   _cnt    Number of instances to define.
 * @hideinitializer
 */
#define BLE_NUS_C_ARRAY_DEF(_name, _cnt)                 \
static ble_nus_c_t _name[_cnt];                          \
NRF_SDH_BLE_OBSERVERS(_name ## _obs,                     \
                      BLE_NUS_C_BLE_OBSERVER_PRIO,       \
                      ble_nus_c_on_ble_evt, &_name, _cnt)

BLE_NUS_C_ARRAY_DEF(m_ble_nus_c, SENSOR_BLE_LINK_COUNT);                    /**< BLE NUS service client instance. */
NRF_BLE_GATT_DEF(m_gatt);                                                   /**< GATT module instance. */
//BLE_DB_DISCOVERY_ARRAY_DEF(m_db_disc, SENSOR_BLE_LINK_COUNT);             /**< Database discovery module instances. */
BLE_DB_DISCOVERY_DEF(m_db_disc);

static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
{
    NRF_LOG_INFO("call to ble_nus_c_on_db_disc_evt for instance %d and link 0x%x (event type 0x%x)!",
                  p_evt->conn_handle,
                  p_evt->conn_handle,
                  p_evt->evt_type);

    ble_nus_c_on_db_disc_evt(&m_ble_nus_c[p_evt->conn_handle], p_evt);
}

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    ret_code_t            err_code;
    ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_ADV_REPORT:
            on_adv_report(p_ble_evt);
            break;
        case BLE_GAP_EVT_CONNECTED:
        {
            is_scanning = false;
            uint16_t conn_handle;

            NRF_LOG_INFO("Connection 0x%x established, starting DB discovery.", p_gap_evt->conn_handle);

            APP_ERROR_CHECK_BOOL(p_gap_evt->conn_handle < SENSOR_BLE_LINK_COUNT);

            err_code = ble_nus_c_handles_assign(&m_ble_nus_c[p_gap_evt->conn_handle], p_gap_evt->conn_handle, NULL);
            APP_ERROR_CHECK(err_code);

            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);

            err_code = ble_db_discovery_start(&m_db_disc, p_gap_evt->conn_handle);
            if (err_code != NRF_ERROR_BUSY)
            {
                APP_ERROR_CHECK(err_code);
            }

            if (ble_conn_state_n_centrals() == SENSOR_BLE_LINK_COUNT)
            {
                NRF_LOG_INFO("SENSOR_BLE_LINK_COUNT = %d reached", SENSOR_BLE_LINK_COUNT);
            }
            else
            {
                // Resume scanning.
                scan_start();
            }
            break;
        }
        // Upon disconnection start scanning again.
        case BLE_GAP_EVT_DISCONNECTED:
        {
            NRF_LOG_INFO("Disconnect on handle %d (reason: 0x%x).",
                            p_gap_evt->conn_handle,
                            p_gap_evt->params.disconnected.reason);

            if (ble_conn_state_n_centrals() < SENSOR_BLE_LINK_COUNT)
            {
                // restart scanning
                scan_start();
            }
        } break;
    }
}

All peripherals are connecting without a problem, but when it comes to discovery of the service and the assignment of the handles associated with it, I am having problems. Independent on the order of connection of my devices (which shows, that the error must be in my code in the central device), the assignment of handles for the conn_handle = 0x1 is always failing.

static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt)
{
    ret_code_t err_code;

    switch (p_ble_nus_evt->evt_type)
    {
        case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
            NRF_LOG_INFO("Discovery on handle %d complete.", p_ble_nus_evt->conn_handle);

            err_code = ble_nus_c_handles_assign(&p_ble_nus_c[p_ble_nus_evt->conn_handle], p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
            APP_ERROR_CHECK(err_code);

            NRF_LOG_INFO("m_ble_nus_c[0x%x]: conn_handle = 0x%x, rx = 0x%x, tx = 0x%x, cccd = 0x%x",
                                p_ble_nus_evt->conn_handle,
                                m_ble_nus_c[p_ble_nus_evt->conn_handle].conn_handle,
                                m_ble_nus_c[p_ble_nus_evt->conn_handle].handles.nus_rx_handle,
                                m_ble_nus_c[p_ble_nus_evt->conn_handle].handles.nus_tx_handle,
                                m_ble_nus_c[p_ble_nus_evt->conn_handle].handles.nus_tx_cccd_handle);

            err_code = ble_nus_c_tx_notif_enable(&p_ble_nus_c[p_ble_nus_evt->conn_handle]);
            if (err_code != NRF_ERROR_BUSY)
             {
                 APP_ERROR_CHECK(err_code);
             }
            NRF_LOG_INFO("Connected to device with Nordic UART Service on handle %d.", p_ble_nus_evt->conn_handle);

            break;

        case BLE_NUS_C_EVT_NUS_TX_EVT:
            /*[...]*/
            break;
        case BLE_NUS_C_EVT_DISCONNECTED:
            NRF_LOG_INFO("NUS peripheral on handle 0x%x disconnected.", p_ble_nus_evt->conn_handle);
            break;
    }
}

Printing out the handles in ble_nus_c_evt_handler() on BLE_NUS_C_EVT_DISCOVERY_COMPLETE after ble_nus_c_handles_assign() (not shown in code) given by p_ble_nus_evt->handles.nus_rx_handlep_ble_nus_evt->handles.nus_tx_handle and p_ble_nus_evt->handles.nus_tx_cccd_handle will show the correct values, so the discovery seems to work:

 <info> app: p_ble_nus_c[0x0]: conn_handle = 0x0, rx = 0xD, tx = 0xF, cccd = 0x10 

But printing the values for m_ble_nus_c[p_ble_nus_evt->conn_handle].handles. is giving the following only for handle 0x1:

 <info> app: m_ble_nus_c[0x1]: conn_handle = 0x1, rx = 0x0, tx = 0x0, cccd = 0x0 

Any idea what I am missing or any clue what could be causing this behaviour?

Thanks and regards,

Björn

 

Related