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

Repeated pairing of ANCs service fails to pop up "allow device to display your iPhone notifications?"

dear all:
    I use the latest sdk17 to test the ANCs sample on the 52840 DK。 The address of the example is: SDK_Path\examples\ble_peripheral\ble_app_ancs_c。after the IOS mobile terminal actively unbinds the device, it is unable to pair repeatedly.
   
    In pm_ evt_handler function can be paired repeatedly after adding relevant code,But it can't pop up "allow device to display your iPhone notifications?"。
/**@brief Function for handling Peer Manager events.
 *
 * @param[in] p_evt  Peer Manager event.
 */
static void pm_evt_handler(pm_evt_t const * p_evt)
{
    ret_code_t ret;

    pm_handler_on_pm_evt(p_evt);
    pm_handler_flash_clean(p_evt);

    switch (p_evt->evt_id)
    {
        case PM_EVT_BONDED_PEER_CONNECTED:
        {
            if (p_evt->peer_id != PM_PEER_ID_INVALID)
            {
                uint32_t data_len = sizeof(m_peer_srv_buf);
                ret = pm_peer_data_remote_db_load(p_evt->peer_id, m_peer_srv_buf, &data_len);
                if (ret == NRF_ERROR_NOT_FOUND)
                {
                    NRF_LOG_DEBUG("Could not find the remote database in flash.");
                    ret = nrf_ble_gatts_c_handles_assign(&m_gatts_c, p_evt->conn_handle, NULL);
                    APP_ERROR_CHECK(ret);

                    // Discover peer's services.
                    m_ancs_discovered  = false;
                    m_gatts_discovered = false;
                    memset(&m_db_disc, 0x00, sizeof(m_db_disc));
                    ret = ble_db_discovery_start(&m_db_disc, p_evt->conn_handle);
                    APP_ERROR_CHECK(ret);
                }
                else
                {
                    // Check if the load was successful.
                    ASSERT(data_len == sizeof(m_peer_srv_buf));
                    APP_ERROR_CHECK(ret);
                    NRF_LOG_INFO("Remote Database loaded from flash.");

                    // Assign the loaded handles to the GATT Service client module.
                    ble_gatt_db_char_t srv_changed_handles = m_peer_srv_buf[0].charateristics[0];
                    ret = nrf_ble_gatts_c_handles_assign(&m_gatts_c,
                                                         p_evt->conn_handle,
                                                         &srv_changed_handles);
                    APP_ERROR_CHECK(ret);

                    // Enable indications.
                    ret = nrf_ble_gatts_c_enable_indication(&m_gatts_c, true);
                    APP_ERROR_CHECK(ret);

                    //Load the relevant handles into a ble_ancs_c_service_t struct that can be
                    // assigned to the ANCS module.
                    ble_ancs_c_service_t ancs_handles;
                    ble_gatt_db_char_t * p_char           = m_peer_srv_buf[1].charateristics;
                    ancs_handles.control_point_char       = p_char[0].characteristic;
                    ancs_handles.notif_source_char        = p_char[1].characteristic;
                    ancs_handles.notif_source_cccd.handle = p_char[1].cccd_handle;
                    ancs_handles.data_source_char         = p_char[2].characteristic;
                    ancs_handles.data_source_cccd.handle  = p_char[2].cccd_handle;

                    ret = nrf_ble_ancs_c_handles_assign(&m_ancs_c, p_evt->conn_handle,
                                                        &ancs_handles);
                    APP_ERROR_CHECK(ret);
                }
            }
        } break;

        case PM_EVT_CONN_SEC_SUCCEEDED:
        {
            // Check it the Service Changed characteristic handle exists in our client instance.
            // If it is invalid, we know service discovery is needed.
            // (No database was loaded during @ref PM_EVT_BONDED_PEER_CONNECTED)
            if (m_gatts_c.srv_changed_char.characteristic.handle_value == BLE_GATT_HANDLE_INVALID)
            {
                ret = nrf_ble_gatts_c_handles_assign(&m_gatts_c, p_evt->conn_handle, NULL);
                APP_ERROR_CHECK(ret);

                // Discover peer's services.
                m_ancs_discovered  = false;
                m_gatts_discovered = false;
                memset(&m_db_disc, 0x00, sizeof(m_db_disc));
                ret = ble_db_discovery_start(&m_db_disc, p_evt->conn_handle);
                APP_ERROR_CHECK(ret);
            }

        } break;

        case PM_EVT_PEERS_DELETE_SUCCEEDED:
        {
            advertising_start(false);
        } break;

        case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
        {
            // Note: You should check on what kind of white list policy your application should use.
            if (     p_evt->params.peer_data_update_succeeded.flash_changed
                 && (p_evt->params.peer_data_update_succeeded.data_id == PM_PEER_DATA_ID_BONDING))
            {
                NRF_LOG_DEBUG("New Bond, add the peer to the whitelist if possible");
                NRF_LOG_DEBUG("\tm_whitelist_peer_cnt %d, MAX_PEERS_WLIST %d",
                               m_whitelist_peer_cnt + 1,
                               BLE_GAP_WHITELIST_ADDR_MAX_COUNT);

                if (m_whitelist_peer_cnt < BLE_GAP_WHITELIST_ADDR_MAX_COUNT)
                {
                    bool already_added = false;
                    for (uint8_t i = 0; i < m_whitelist_peer_cnt; i++) {
                        if (m_whitelist_peers[i] == p_evt->peer_id) {
                            already_added = true;
                            break;
                        }
                    }

                    if (!already_added) 
                    {
                        // Bonded to a new peer, add it to the whitelist.
                        m_whitelist_peers[m_whitelist_peer_cnt++] = p_evt->peer_id;
                    }

                    // The whitelist has been modified, update it in the Peer Manager.
                    ret = pm_device_identities_list_set(m_whitelist_peers, m_whitelist_peer_cnt);
                    if (ret != NRF_ERROR_NOT_SUPPORTED)
                    {
                        APP_ERROR_CHECK(ret);
                    }

                    ret = pm_whitelist_set(m_whitelist_peers, m_whitelist_peer_cnt);
                    APP_ERROR_CHECK(ret);
                }
            }
        } break;
        
        case PM_EVT_CONN_SEC_CONFIG_REQ: {
            // Reject pairing request from an already bonded peer.
            pm_conn_sec_config_t conn_sec_config = {.allow_repairing = true};
            pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
        }
        break;

        default:
            break;
    }
}
How can I realize the prompt pop-up of IOS mobile phone after each repeated pairing.
  • Hi,

    You can fix this by always doing service discovery while connecting again to an allready bonded pair. A simple way to do it is demonstrated by this diff (which includes your changes to the example as well):

    diff --git a/examples/ble_peripheral/ble_app_ancs_c/main.c b/examples/ble_peripheral/ble_app_ancs_c/main.c
    index 65d5a39..d14535e 100644
    --- a/examples/ble_peripheral/ble_app_ancs_c/main.c
    +++ b/examples/ble_peripheral/ble_app_ancs_c/main.c
    @@ -168,6 +168,7 @@ static uint8_t m_attr_date[ATTR_DATA_SIZE];                                   /*
     static uint8_t m_attr_posaction[ATTR_DATA_SIZE];                              /**< Buffer to store attribute data. */
     static uint8_t m_attr_negaction[ATTR_DATA_SIZE];                              /**< Buffer to store attribute data. */
     static uint8_t m_attr_disp_name[ATTR_DATA_SIZE];                              /**< Buffer to store attribute data. */
    +static bool m_force_service_discovery = false;
     
     /**@brief String literals for the iOS notification categories. used then printing to UART. */
     static char const * lit_catid[BLE_ANCS_NB_OF_CATEGORY_ID] =
    @@ -363,8 +364,10 @@ static void pm_evt_handler(pm_evt_t const * p_evt)
                 // Check it the Service Changed characteristic handle exists in our client instance.
                 // If it is invalid, we know service discovery is needed.
                 // (No database was loaded during @ref PM_EVT_BONDED_PEER_CONNECTED)
    -            if (m_gatts_c.srv_changed_char.characteristic.handle_value == BLE_GATT_HANDLE_INVALID)
    +            if (m_gatts_c.srv_changed_char.characteristic.handle_value == BLE_GATT_HANDLE_INVALID ||
    +                m_force_service_discovery)
                 {
    +                m_force_service_discovery = false;
                     ret = nrf_ble_gatts_c_handles_assign(&m_gatts_c, p_evt->conn_handle, NULL);
                     APP_ERROR_CHECK(ret);
     
    @@ -396,8 +399,19 @@ static void pm_evt_handler(pm_evt_t const * p_evt)
     
                     if (m_whitelist_peer_cnt < BLE_GAP_WHITELIST_ADDR_MAX_COUNT)
                     {
    +                    bool already_added = false;
    +                    for (uint8_t i = 0; i < m_whitelist_peer_cnt; i++) {
    +                        if (m_whitelist_peers[i] == p_evt->peer_id) {
    +                            already_added = true;
    +                            break;
    +                        }
    +                    }
    +
    +                    if (!already_added) 
    +                    {
                         // Bonded to a new peer, add it to the whitelist.
                         m_whitelist_peers[m_whitelist_peer_cnt++] = p_evt->peer_id;
    +                    }
     
                         // The whitelist has been modified, update it in the Peer Manager.
                         ret = pm_device_identities_list_set(m_whitelist_peers, m_whitelist_peer_cnt);
    @@ -412,6 +426,14 @@ static void pm_evt_handler(pm_evt_t const * p_evt)
                 }
             } break;
     
    +        case PM_EVT_CONN_SEC_CONFIG_REQ: {
    +            // Reject pairing request from an already bonded peer.
    +            pm_conn_sec_config_t conn_sec_config = {.allow_repairing = true};
    +            pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
    +            m_force_service_discovery = true;
    +        }
    +        break;
    +
             default:
                 break;
         }
    

  • Thank you for solving the problem perfectly according to your method.
Related