Hi,
I need to create a device that can support up to 10 concurrent connection with MITM protection, so I would like to implement bonding with a passkey.
I started my project with the example "ble_app_gls", afterwards added multi-peripheral functionality based on example "ble_app_multiperipheral". Concurrent connections work correct, but I have a few question about peer manager:
1. When will the link not be authenticated and the peer will be removed? (I don't know when this might happen)
case PM_EVT_CONN_SEC_SUCCEEDED:
{
pm_conn_sec_status_t conn_sec_status;
// Check if the link is authenticated (meaning at least MITM).
err_code = pm_conn_sec_status_get(p_evt->conn_handle, &conn_sec_status);
APP_ERROR_CHECK(err_code);
if (conn_sec_status.mitm_protected)
{
NRF_LOG_INFO("Link secured. Role: %d. conn_handle: %d, Procedure: %d",
ble_conn_state_role(p_evt->conn_handle),
p_evt->conn_handle,
p_evt->params.conn_sec_succeeded.procedure);
}
else
{
// The peer did not use MITM, disconnect.
NRF_LOG_INFO("Collector did not use MITM, disconnecting");
err_code = pm_peer_id_get(p_evt->conn_handle, &m_peer_to_be_deleted);
APP_ERROR_CHECK(err_code);
err_code = sd_ble_gap_disconnect(p_evt->conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
APP_ERROR_CHECK(err_code);
}
} break;
2. How should I add this security for multi-peripheral? Whether the following changes are enough?
a) replacement the variable "static pm_peer_id_t m_peer_to_be_deleted = PM_PEER_ID_INVALID" to an array "static pm_peer_id_t m_peer_to_be_deleted[NRF_SDH_BLE_PERIPHERAL_LINK_COUNT]"
b) removal "m_peer_to_be_deleted = PM_PEER_ID_INVALID" from BLE_GAP_EVT_CONNECTED
case BLE_GAP_EVT_CONNECTED:
{
NRF_LOG_INFO("Connection with device %d established.", ((p_ble_evt->evt.gap_evt.conn_handle)+1)); // the +1 so that we start counting from 1 not zero.
/*deleted*/
/*m_peer_to_be_deleted = PM_PEER_ID_INVALID;*/
// Assign connection handle to available instance of QWR module.
for (uint32_t i = 0; i < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT; i++)
{
if (m_qwr[i].conn_handle == BLE_CONN_HANDLE_INVALID)
{
err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr[i], p_ble_evt->evt.gap_evt.conn_handle);
APP_ERROR_CHECK(err_code);
break;
}
}
//By default advertising stops when BLE_GAP_EVT_CONNECTED is received , however , we need to manually switch it back on, untill all potential-
// central devices are connected.
if (periph_link_cnt != NRF_SDH_BLE_PERIPHERAL_LINK_COUNT)
{
// Continue advertising. More connections can be established because the maximum link count has not been reached.
advertising_start(false);
}
} break;
c) the following change in the handling of the event PM_EVT_CONN_SEC_SUCCEEDED
if (conn_sec_status.mitm_protected)
{
NRF_LOG_INFO("Link secured. Role: %d. conn_handle: %d, Procedure: %d",
ble_conn_state_role(p_evt->conn_handle),
p_evt->conn_handle,
p_evt->params.conn_sec_succeeded.procedure);
}
else
{
// The peer did not use MITM, disconnect.
NRF_LOG_INFO("Collector did not use MITM, disconnecting");
/*Before*/
/*err_code = pm_peer_id_get(p_evt->conn_handle, &m_peer_to_be_deleted);*/
/*After*/
/*err_code = pm_peer_id_get(p_evt->conn_handle, &m_peer_to_be_deleted[p_evt->conn_handle]);*/
APP_ERROR_CHECK(err_code);
err_code = sd_ble_gap_disconnect(p_evt->conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
APP_ERROR_CHECK(err_code);
}
d) the following change in the handling of the event BLE_GAP_EVT_DISCONNECTED
case BLE_GAP_EVT_DISCONNECTED:
{
NRF_LOG_INFO("Connection with device %d has been disconnected. Reason: 0x%X",
((p_ble_evt->evt.gap_evt.conn_handle)+1),// the +1 so that we start counting from 1 not zero.
p_ble_evt->evt.gap_evt.params.disconnected.reason);
//This is in case one of the centrals decided to disconnect, we restart advertising to indicate an available link
if (periph_link_cnt == (NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - 1))
{
// Advertising is not running when all connections are taken, and must therefore be started.
advertising_start(false);
}
// Check if the last connected peer had not used MITM, if so, delete its bond information.
/*Before*/
/*if (m_peer_to_be_deleted != PM_PEER_ID_INVALID)
{
err_code = pm_peer_delete(m_peer_to_be_deleted);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEBUG("Collector's bond deleted");
m_peer_to_be_deleted = PM_PEER_ID_INVALID;
}*/
/*After*/
for (uint32_t i = 0; i < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT; i++)
{
if ((i==p_ble_evt->evt.gap_evt.conn_handle) && (m_peer_to_be_deleted[i] != PM_PEER_ID_INVALID))
{
err_code = pm_peer_delete(m_peer_to_be_deleted[i]);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEBUG("Collector's bond deleted");
m_peer_to_be_deleted[i] = PM_PEER_ID_INVALID;
break;
}
}
} break;
Best regards,
KaEd1705