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

Bluetooth connection issues - between two nRFs

Hey,

I encountered a very strange problem while I was trying to connect from nRF52832 (as a central device) to my nRF52805 as a peripheral. If I am trying to connect to the nRF52805 from any other device (tried with more than 10 different smartphones), it connects properly.

For some reason when I try to establish a connection with my nRF52832 (central device) by calling the function:
sd_ble_gap_connect to the nRF52805 address, It starts to establish a connection and I get one interrupt from the function ble_evt_handler with BLE_GAP_EVT_CONNECTED,

BUT then when I call the ble_db_discovery_start (and I see that I get SUCCESS error code), I don't get an interrupt from the function ble_nus_c_evt_handler and the connection procedure is stuck...

I know I should get an interrupt from this function with BLE_NUS_C_EVT_DISCOVERY_COMPLETE and it should recognizes my NUS (service 01), but for some reason its not happening.
(We successfully worked in the same setup in the past, with other product we developed) |
We suspect it could be somehow related to HW / noise issues in the channel, but as mentioned before, the initial connectivity is passed, and the process gets stuck only in a later stage (as part of the handshaking, as mentioned above)

Any ideas what can cause this problem?Post

Thanks in advance!

Parents
  • Hey, for both versions I use SDK v5 

    For the nRF52832 (central) I use SDK v14.2 and SoftDevice version S132 v5.0
    For the nRF52810 (peripheral) I use SDK v15.3 and SoftDevice version S112 v5.1.0
    I don't have a sniffer log.
    This is the code for the discovery:
    First I call this function with the correct peer address:
    err_code = sd_ble_gap_connect(peer_addr, &m_scan_params, &m_connection_param, APP_BLE_CONN_CFG_TAG);
    This is the function that receives the event after I call the function above (with BLE_GAP_EVT_CONNECTED parameter):
    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    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; // BLE_GAP_EVT_ADV_REPORT

            case BLE_GAP_EVT_CONNECTED:
                NRF_LOG_INFO("Connected to target");
                err_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_ble_evt->evt.gap_evt.conn_handle, NULL);
                APP_ERROR_CHECK(err_code);

                // start discovery of services. The NUS Client waits for a discovery result
                err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
    NRF_LOG_DEBUG("err_code = %d", err_code);
                APP_ERROR_CHECK(err_code);
                break;

    case BLE_GAP_EVT_DISCONNECTED:
    NRF_LOG_INFO("Disconnected from target");
    NRF_LOG_FLUSH();
    is_disconnected_from_target = true;
    break;


            case BLE_GAP_EVT_TIMEOUT:
                if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN)
                {
                    NRF_LOG_INFO("Scan timed out.");
                    scan_start();
                }
                else if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
                {
                    NRF_LOG_INFO("Connection Request timed out.");
                }
                break;

            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                // Pairing not supported
                err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
                APP_ERROR_CHECK(err_code);
                break;

            case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
                // Accepting parameters requested by peer.
                err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                                        &p_gap_evt->params.conn_param_update_request.conn_params);
                APP_ERROR_CHECK(err_code);
                break;

            case BLE_GATTC_EVT_TIMEOUT:
                // Disconnect on GATT Client timeout event.
                NRF_LOG_DEBUG("GATT Client Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;

            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                NRF_LOG_DEBUG("GATT Server Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;

            default:
                break;
        }
    }
    This is the discovery function:
    uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle)
    {
        VERIFY_PARAM_NOT_NULL(p_db_discovery);
        VERIFY_MODULE_INITIALIZED();

        if (m_num_of_handlers_reg == 0)
        {
            // No user modules were registered. There are no services to discover.
            return NRF_ERROR_INVALID_STATE;
        }

        if (p_db_discovery->discovery_in_progress)
        {
            return NRF_ERROR_BUSY;
        }

        return discovery_start(p_db_discovery, conn_handle);
    }
    This is the discovery start function:

    static uint32_t discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle)
    {
        uint32_t err_code;
        ble_gatt_db_srv_t * p_srv_being_discovered;

        memset(p_db_discovery, 0x00, sizeof(ble_db_discovery_t));

        p_db_discovery->conn_handle = conn_handle;

        m_pending_usr_evt_index   = 0;

        p_db_discovery->discoveries_count = 0;
        p_db_discovery->curr_srv_ind      = 0;
        p_db_discovery->curr_char_ind     = 0;

        p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
        p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind];

        NRF_LOG_DEBUG("Starting discovery of service with UUID 0x%x on connection handle 0x%x.",
                      p_srv_being_discovered->srv_uuid.uuid, conn_handle);

        err_code = sd_ble_gattc_primary_services_discover(conn_handle,
                                                          SRV_DISC_START_HANDLE,
                                                          &(p_srv_being_discovered->srv_uuid));
        if (err_code != NRF_ERROR_BUSY)
        {
    NRF_LOG_DEBUG("err_code != NRF_ERROR_BUSY = %d", err_code);
            VERIFY_SUCCESS(err_code);
            p_db_discovery->discovery_in_progress = true;
            p_db_discovery->discovery_pending     = false;
        }
        else
        {
    NRF_LOG_DEBUG("err_code == NRF_ERROR_BUSY");
            p_db_discovery->discovery_in_progress = true;
            p_db_discovery->discovery_pending     = true;
        }

        return NRF_SUCCESS;
    }
    This is the function that I want to be called, but I never reach it:
    /**@brief Callback handling NUS Client events.
     *
     * @details This function is called to notify the application of NUS client events.
     *
     * @param[in]   p_ble_nus_c   NUS Client Handle. This identifies the NUS client
     * @param[in]   p_ble_nus_evt Pointer to the NUS Client event.
     */

    /**@snippet [Handling events from the ble_nus_c module] */
    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 complete.");
    NRF_LOG_FLUSH();
                err_code = ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
                APP_ERROR_CHECK(err_code);

    // Send data back to peripheral.
            //do
            //{
              //  ret_val =
    //ble_nus_c_string_send(&m_ble_nus_c, (uint8_t*)"7", 1);
            //    if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
            //    {
            //        NRF_LOG_ERROR("Failed sending NUS message. Error 0x%x. ", ret_val);
            //        APP_ERROR_CHECK(ret_val);
            //    }
            //} while (ret_val == NRF_ERROR_BUSY);

                err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
                APP_ERROR_CHECK(err_code);
                NRF_LOG_INFO("Connected to device with Nordic UART Service.");
    printf("Connected");
                break;

            case BLE_NUS_C_EVT_NUS_TX_EVT:
                ble_nus_chars_received_uart_print(p_ble_nus_evt->p_data, p_ble_nus_evt->data_len);
                break;

            case BLE_NUS_C_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected.");
    NRF_LOG_FLUSH();
    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_RESET);
                //scan_start();
                break;
        }
    }
    /**@snippet [Handling events from the ble_nus_c module] */
    Thanks
  • What is happening in the check if NUS is discovered?
    Have you done any changes to the uuid ? 

    Maybe set a breakpoint in void ble_nus_c_on_db_disc_evt to see what appens in the event.

    Regards,
    Jonathan

Reply Children
No Data
Related