Hi Nordic Team!
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
