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

NUS Multiperipheral error after pm_conn_secure

Hi, I'm working with nRF52832 DK,  SDK 15 on Windows with Keil5. I create Multiperiherial Nus with peer manager and fstorage and it works, but after some connetions I get an error in pm_conn_secure() error code 86.I dont know how many connections are needed for this error, maybe about 30. If i erase crystal in keil and programm nRF again i see that all working fine again and after some connections/disconnections error appears again.

Parents
  • Hi.

    Could you try to see which NRF_ERROR pm_conn_secure() returns? It is much easier to know whats faulty then. There is documentation on how to debug on Keil's website here.

    Best regards,

    Andreas

  • I see that link_secure() return NRF_ERROR_STORAGE_FULL 

  • Hi.

    This happend because smd_link_secure(); returned NRF_ERROR_STORAGE_FULL.

    /**@brief Function for initiating security on the link, with the specified parameters.
     *
     * @note If the connection is a peripheral connection, this will send a security request to the
     *       master, but the master is not obligated to initiate pairing or encryption in response.
     * @note If the connection is a central connection and a key is available, the parameters will be
     *       used to determine whether to re-pair or to encrypt using the existing key. If no key is
     *       available, pairing will be started.
     *
     * @param[in]  conn_handle      Handle of the connection to initiate pairing on.
     * @param[in]  p_sec_params     The security parameters to use for this link. As a central, this can
     *                              be NULL to reject a slave security request.
     * @param[in]  force_repairing  Whether to force a pairing procedure to happen regardless of whether
     *                              an encryption key already exists. This argument is only relevant for
     *                              the central role. Recommended value: false
     *
     * @retval NRF_SUCCESS                    Success.
     * @retval NRF_ERROR_NULL                 p_sec_params was NULL (peripheral only).
     * @retval NRF_ERROR_INVALID_STATE        A security procedure is already in progress on the link,
     *                                        or the link is disconnecting.
     * @retval NRF_ERROR_INVALID_PARAM        Invalid combination of parameters (not including conn_handle).
     * @retval NRF_ERROR_INVALID_DATA         Peer is bonded, but no LTK was found, and repairing was
     *                                        not requested.
     * @retval NRF_ERROR_BUSY                 Unable to initiate procedure at this time.
     * @retval NRF_ERROR_TIMEOUT              There has been an SMP timeout, so no more SMP operations
     *                                        can be performed on this link.
     * @retval BLE_ERROR_INVALID_CONN_HANDLE  Invalid connection handle.
     * @retval NRF_ERROR_STORAGE_FULL         No more room in flash. Fix and reattempt after the next
     *                                        FDS garbage collection procedure.
     * @retval NRF_ERROR_INTERNAL             No more available peer IDs.
     */
    ret_code_t smd_link_secure(uint16_t               conn_handle,
                               ble_gap_sec_params_t * p_sec_params,
                               bool                   force_repairing);
    

    The error is returned because the is not enough room in your flash memory. You have to retry after the next FDS garbage collection procedure.

    Best regards,

    Andreas

  • i use  pm_peer_delete(p_gap_evt->conn_handle) in BLE_GAP_EVT_DISCONNECTED, and I thought it would remove all connection data. Now i add  

    //Run garbage collection on the flash

     // Upon disconnection, reset the connection handle of the peer which disconnected, update
            // the LEDs status and start scanning again.
            case BLE_GAP_EVT_DISCONNECTED:
            {
    					
    			err_code = pm_peer_delete(p_gap_evt->conn_handle);
    			APP_ERROR_CHECK(err_code);
    
                NRF_LOG_INFO("Central link 0x%x disconnected (reason: 0x%x)",
                             p_gap_evt->conn_handle,
                             p_gap_evt->params.disconnected.reason);
    					
    			// Run garbage collection on the flash.
    				do
    					{
    						err_code = fds_gc();
    					}while(err_code != 0);
    				APP_ERROR_CHECK(err_code);
    				
                if (ble_conn_state_central_conn_count() == 0)
                {
                    err_code = app_button_disable();
                    APP_ERROR_CHECK(err_code);
    
                    // Turn off connection indication LED
                    bsp_board_led_off(CENTRAL_CONNECTED_LED);
                }
    											
                // Start scanning
                scan_start();
    
                // Turn on LED for indicating scanning
                bsp_board_led_on(CENTRAL_SCANNING_LED);
    
            } break;

    and its working. This is the right solution ?

Reply
  • i use  pm_peer_delete(p_gap_evt->conn_handle) in BLE_GAP_EVT_DISCONNECTED, and I thought it would remove all connection data. Now i add  

    //Run garbage collection on the flash

     // Upon disconnection, reset the connection handle of the peer which disconnected, update
            // the LEDs status and start scanning again.
            case BLE_GAP_EVT_DISCONNECTED:
            {
    					
    			err_code = pm_peer_delete(p_gap_evt->conn_handle);
    			APP_ERROR_CHECK(err_code);
    
                NRF_LOG_INFO("Central link 0x%x disconnected (reason: 0x%x)",
                             p_gap_evt->conn_handle,
                             p_gap_evt->params.disconnected.reason);
    					
    			// Run garbage collection on the flash.
    				do
    					{
    						err_code = fds_gc();
    					}while(err_code != 0);
    				APP_ERROR_CHECK(err_code);
    				
                if (ble_conn_state_central_conn_count() == 0)
                {
                    err_code = app_button_disable();
                    APP_ERROR_CHECK(err_code);
    
                    // Turn off connection indication LED
                    bsp_board_led_off(CENTRAL_CONNECTED_LED);
                }
    											
                // Start scanning
                scan_start();
    
                // Turn on LED for indicating scanning
                bsp_board_led_on(CENTRAL_SCANNING_LED);
    
            } break;

    and its working. This is the right solution ?

Children
  • Hi.

    I would use an app timer in the section  // Run garbage collection on the flash. where you call fds_gc();

    /**@brief   Function for running garbage collection.
     *
     * Garbage collection reclaims the flash space that is occupied by records that have been deleted,
     * or that failed to be completely written due to, for example, a power loss.
     *
     * This function is asynchronous. Completion is reported through an event that is sent to the
     * registered event handler function.
     *
     * @retval  FDS_SUCCESS                 If the operation was queued successfully.
     * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
     * @retval  FDS_ERR_NO_SPACE_IN_QUEUES  If the operation queue is full.
     */
    ret_code_t fds_gc(void);

    If you at some point in time get the error FDS_ERR_NO_SPACE_IN_QUEUES, you might end up in an infinite loop since there is no time to process the queue.

    Best regards,

    Andreas

Related