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

Adding peer manager to multiperipheral example and getting FATAL ERROR

Hi Nordic Team! Blush

I have bought nRF52 DK and my aim is to create BLE application for a peripheral that it would be possible to connect multiple centrals (for example android smartphones) to it. I use SEGGER Embedded Studio for ARM V3.34b 64bit to flash my device with SoftDevice s132_nrf52_6.0.0 and with multiperipheral example from nRF5_SDK_15.0.0_a53641a.

The example has got very limited functionality but I believe this will be my base application to work with. I want to extend and develop it. The first thing I want do add is the pairing and bonding (so using persistent memory).

I followed the guide:

https://devzone.nordicsemi.com/tutorials/b/software-development-kit/posts/migrating-to-peer-manager

and added to nRF_BLE group the following:

  • [sdk]/components/ble/peer_manager/ (all source files)
  • [sdk]/components/ble/common/ble_conn_state.c (it was already there)

Added to nRF_Libraries group the following:

  • [sdk]/components/libraries/fds/fds.c
  • [sdk]/components/libraries/fstorage/fstorage.c (nrf_fstorage.c was in the folder, not fstorage.c)
  • [sdk]/components/libraries/util/sdk_mapped_flags.c
  • [sdk]/components/libraries/fstorage/nrf_fstorage_sd.c

I hadn’t to add the directories:

  • [sdk]/components/ble/peer_manager/
  • [sdk]/components/libraries/fds
  • [sdk]/components/libraries/fstorage
  • [sdk]/components/libraries/experimental_section_vars

because they were already there.

Added:

#include "nrf_fstorage.h"
#include "fds.h"
#include "peer_manager.h"

to main.c file.

 

Then I “borrowed” some functions from Heart Rate Service Sample Application from the same SDK:

 

#define SEC_PARAM_BOND                      1                                       /**< Perform bonding. */
#define SEC_PARAM_MITM                      0                                       /**< Man In The Middle protection not required. */
#define SEC_PARAM_LESC                      0                                       /**< LE Secure Connections not enabled. */
#define SEC_PARAM_KEYPRESS                  0                                       /**< Keypress notifications not enabled. */
#define SEC_PARAM_IO_CAPABILITIES           BLE_GAP_IO_CAPS_NONE                    /**< No I/O capabilities. */
#define SEC_PARAM_OOB                       0                                       /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE              7                                       /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE              16                                      /**< Maximum encryption key size. */

 

 

static void fds_evt_handler(fds_evt_t const * const p_evt)
{
    if (p_evt->id == FDS_EVT_GC)
    {
        NRF_LOG_DEBUG("GC completed\n");
    }
}

 

static void pm_evt_handler(pm_evt_t const * p_evt)
{
    ret_code_t err_code;

    switch (p_evt->evt_id)
    {
        case PM_EVT_BONDED_PEER_CONNECTED:
        {
            NRF_LOG_INFO("Connected to a previously bonded device.");
        } break;

        case PM_EVT_CONN_SEC_SUCCEEDED:
        {
            NRF_LOG_INFO("Connection secured: role: %d, conn_handle: 0x%x, procedure: %d.",
                         ble_conn_state_role(p_evt->conn_handle),
                         p_evt->conn_handle,
                         p_evt->params.conn_sec_succeeded.procedure);
        } break;

        case PM_EVT_CONN_SEC_FAILED:
        {
            /* Often, when securing fails, it shouldn't be restarted, for security reasons.
             * Other times, it can be restarted directly.
             * Sometimes it can be restarted, but only after changing some Security Parameters.
             * Sometimes, it cannot be restarted until the link is disconnected and reconnected.
             * Sometimes it is impossible, to secure the link, or the peer device does not support it.
             * How to handle this error is highly application dependent. */
        } 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 = false};
            pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
        } break;

        case PM_EVT_STORAGE_FULL:
        {
            // Run garbage collection on the flash.
            err_code = fds_gc();
            if (err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
            {
                // Retry.
            }
            else
            {
                APP_ERROR_CHECK(err_code);
            }
        } break;

        case PM_EVT_PEERS_DELETE_SUCCEEDED:
        {
            NRF_LOG_DEBUG("PM_EVT_PEERS_DELETE_SUCCEEDED");
            advertising_start(); // was advertising_start(false) before
        } break;

        case PM_EVT_PEER_DATA_UPDATE_FAILED:
        {
            // Assert.
            APP_ERROR_CHECK(p_evt->params.peer_data_update_failed.error);
        } break;

        case PM_EVT_PEER_DELETE_FAILED:
        {
            // Assert.
            APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error);
        } break;

        case PM_EVT_PEERS_DELETE_FAILED:
        {
            // Assert.
            APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error);
        } break;

        case PM_EVT_ERROR_UNEXPECTED:
        {
            // Assert.
            APP_ERROR_CHECK(p_evt->params.error_unexpected.error);
        } break;

        case PM_EVT_CONN_SEC_START:
        case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
        case PM_EVT_PEER_DELETE_SUCCEEDED:
        case PM_EVT_LOCAL_DB_CACHE_APPLIED:
        case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
            // This can happen when the local DB has changed.
        case PM_EVT_SERVICE_CHANGED_IND_SENT:
        case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
        default:
            break;
    }
}

 

 

static void peer_manager_init(void)
{
    ble_gap_sec_params_t sec_param;
    ret_code_t           err_code;

    err_code = pm_init();
    APP_ERROR_CHECK(err_code);

    memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));

    // Security parameters to be used for all security procedures.
    sec_param.bond           = SEC_PARAM_BOND;
    sec_param.mitm           = SEC_PARAM_MITM;
    sec_param.io_caps        = SEC_PARAM_IO_CAPABILITIES;
    sec_param.oob            = SEC_PARAM_OOB;
    sec_param.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
    sec_param.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
    sec_param.kdist_own.enc  = 1;
    sec_param.kdist_own.id   = 1;
    sec_param.kdist_peer.enc = 1;
    sec_param.kdist_peer.id  = 1;

    err_code = pm_sec_params_set(&sec_param);
    APP_ERROR_CHECK(err_code);

    err_code = pm_register(pm_evt_handler);
    APP_ERROR_CHECK(err_code);

    err_code = fds_register(fds_evt_handler);
    APP_ERROR_CHECK(err_code);
}

 

 and added the call:

    peer_manager_init();
  inside main() function.

Then I got into sdk_config.h file and changed some defines:

#define PEER_MANAGER_ENABLED 0 to #define PEER_MANAGER_ENABLED 1

#define FDS_ENABLED 0 to #define FDS_ENABLED 1

#define NRF_FSTORAGE_ENABLED 0 to #define NRF_FSTORAGE_ENABLED 1

 

 and changed 

static void advertising_start(void) to void advertising_start(void)

in main.c file (there was an error during compilation without this change).

 

According to: https://devzone.nordicsemi.com/b/blog/posts/segger-embedded-studio-a-cross-platform-ide

 I have checked the flash_placement.xml but the below lines already were there:

FLASH:  ...

  <ProgramSection alignment="4" keep="Yes" load="Yes" name=".fs_data"  inputsections="*(.fs_data*)" runin=".fs_data_run"/> 

...

RAM:   ...

<ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />

...

 I have imported thumb_crt0.s (to have own copy in project folder, not use the shared one from SDK) and added: 

# ADD HERE ... 
ldr r0, =__fs_data_load_start__
ldr r1, =__fs_data_start__
ldr r2, =__fs_data_end__
bl memory_copy
# TO HERE ...

 

 

 The program compiles and flashed without any error. I am able to connect more than one smartphone to it, so multiconnection works. When I hit "bond" on nRF Connect mobile app I get DC and message on puTTY terminal saying:

<error> app: Fatal error
<warning> app: System reset

 My question is: what have I done wrong or what changes have to be done additionally? I don't know whether the problem is with the peer manager or the flash data storage.

 thanks,
Pawel

Parents
  • Hi Pawel,

    Have you had any progress on this?

     I have added MultiPeripheral example with peer manager added which seem to work.ble_app_multiperipheral - Copy.zip

  • Hi Martin,

    Yes, in the last days I have added peer manager and it seems working. I used the method I described. I just don't know where I made a mistake or something. Also I have implemented passkey entry.

    Thank you for your file, now I can use it in future for reference but there is something strange about it. There is no 'ses' folder which I can check and compile so I just moved hex file directly to JLINK, it flashes and "multiperipheral example started" shows in terminal, chip shows in the mobile app as nordic_blinky, I am able to connect but unable to pair. I press bond but app shows "pairing rejected...". Should I worry about this?

  • Hi Pawel,

    I am glad that you got it to work.

     

     The reason there is no 'ses' folder is because I used Keil and delete the other folders to make the .zip file smaller. (You could use main.c/sdk_config.h as reference if you need to)

    - You shouldn't worry about that.

    Because it sounds that you have flashed another .hex file than what is in the .zip file. (it should show up as "multi_peer" in the app)

    If you want to try it, Remember to erase whats on the chip ("nrfjprog -e") before you try to flash the .hex file in [\ble_app_multiperipheral - Copy\pca10040\s132\arm5_no_packs\_build] folder + the softdevice.

     

  • erase: 

    SD:

    hex:

    When I flash this (it WAS inside the .zip you have provided, Martin):

    it advertises as nordic_blinky, shows up in terminal and behaves just like I described 2 hours ago (no bonding)

    When I flash this hex ble_app_multiperipheral - Copy\pca10040\s132\arm5_no_packs\_build (after erasing and flashing SoftDevice):

    it doesn't advertise (even the LED for advertising is off), doesn't show in nrfConnect app, no output to puTTY.

  • Hi Pawel,

    The files you find in the "hex" folder is already precompiled .hex files from the unmodified SDK example (in this case the 'ble_app_multiperipheral' application). So when you are flashing one of the .hex files found there, you are just really running the unmodified "ble_app_multiperipheral" example. If you look into each example in the SDK you can see this folder. 

     

    To test the modified application Try this:

    1. Erase whats on the chip. 

    2. Flash the SD [nRF5_SDK_15.0.0_a53641a\nRF5_SDK_15.0.0_a53641a\components\softdevice\s132\hex]

    3. Flash the Application [nRF5_SDK_15.0.0_CUSTOM\examples\ble_peripheral\experimental\ble_app_multiperipheral - Copy\pca10040\s132\arm5_no_packs\_build]

     

  • Well now I am seeing multi_peer and it pairs but why does it matter that now I have:

    *used the SoftDevice of the same name and same version but from different folder

    *flashed the program from nRFgo studio programming tab instead of drag and dropping to JLINK folder?

    anyway thanks Martin

Reply Children
No Data
Related