Nordic BLE: Implement PHY APIs for NRF52.

pull/7899/head
Vincent Coubard 2018-06-29 16:11:51 +01:00
parent 47ea39982f
commit 954f004d16
3 changed files with 205 additions and 11 deletions

View File

@ -335,16 +335,18 @@ void btle_handler(const ble_evt_t *p_ble_evt)
#ifndef S140
// Handle PHY upgrade request
case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
{
ble_gap_phys_t const phys =
{
/* rx_phys */ BLE_GAP_PHY_AUTO,
/* tx_phys */ BLE_GAP_PHY_AUTO,
};
ASSERT_STATUS_RET_VOID( sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys) );
gap.on_phy_update_request(
p_ble_evt->evt.gap_evt.conn_handle,
p_ble_evt->evt.gap_evt.params.phy_update_request
);
break;
}
#endif
case BLE_GAP_EVT_PHY_UPDATE:
gap.on_phy_update(
p_ble_evt->evt.gap_evt.conn_handle,
p_ble_evt->evt.gap_evt.params.phy_update
);
break;
// Handle Data length negotiation request
case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:

View File

@ -115,6 +115,33 @@ peer_address_type_t convert_identity_address(advertising_peer_address_type_t add
}
}
// FIXME: update when SD 5 (not alpha!) or more is used for 52840.
#ifndef BLE_GAP_PHY_AUTO
#define BLE_GAP_PHY_AUTO 0
#endif
uint8_t to_nordic_phy_set(const ble::phys_t* phys) {
if (!phys) {
return BLE_GAP_PHY_AUTO;
}
uint8_t nordic_phys = 0;
if (phys->le_1m) {
nordic_phys |= BLE_GAP_PHY_1MBPS;
}
if (phys->le_2m) {
nordic_phys |= BLE_GAP_PHY_2MBPS;
}
if (phys->le_coded) {
nordic_phys |= BLE_GAP_PHY_CODED;
}
return nordic_phys;
}
} // namespace
void radioNotificationStaticCallback(bool param) {
@ -134,6 +161,8 @@ nRF5xGap::nRF5xGap() : Gap(),
_peripheral_privacy_configuration(default_peripheral_privacy_configuration),
_central_privacy_configuration(default_central_privacy_configuration),
_non_private_address_type(LegacyAddressType::RANDOM_STATIC),
_prefered_tx_phys(BLE_GAP_PHY_AUTO),
_prefered_rx_phys(BLE_GAP_PHY_AUTO),
_connections_role()
{
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
@ -654,6 +683,87 @@ ble_error_t nRF5xGap::connect(
}
}
ble_error_t nRF5xGap::readPhy(Handle_t connection) {
/*
* This function is not implemented as it is not possible with current
* nordic API to know which phy was used to establish the connection.
*
* TODO: Update when Nordic provides the API to do the job.
*/
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t nRF5xGap::setPreferedPhys(
const Phys_t* txPhys,
const Phys_t* rxPhys
) {
uint8_t prefered_tx_phys = to_nordic_phy_set(txPhys);
uint8_t prefered_rx_phys = to_nordic_phy_set(rxPhys);
#ifdef S140
ble_opt_t opt = { 0 };
opt.gap_opt.preferred_phys.tx_phys = prefered_tx_phys;
opt.gap_opt.preferred_phys.rx_phys = prefered_rx_phys;
uint32_t err = sd_ble_opt_set(BLE_GAP_OPT_PREFERRED_PHYS_SET, &opt);
switch (err) {
case NRF_SUCCESS:
break;
case NRF_ERROR_INVALID_ADDR:
case BLE_ERROR_INVALID_CONN_HANDLE:
case NRF_ERROR_INVALID_PARAM:
return BLE_ERROR_INVALID_PARAM;
case NRF_ERROR_INVALID_STATE:
return BLE_ERROR_INVALID_STATE;
case NRF_ERROR_BUSY:
return BLE_STACK_BUSY;
default:
return BLE_ERROR_UNSPECIFIED;
}
#endif
_prefered_tx_phys = prefered_tx_phys;
_prefered_rx_phys = prefered_rx_phys;
return BLE_ERROR_NONE;
}
ble_error_t nRF5xGap::setPhy(
Handle_t connection,
const Phys_t* txPhys,
const Phys_t* rxPhys,
CodedSymbolPerBit_t codedSymbol
) {
#ifdef S140
return BLE_ERROR_NOT_IMPLEMENTED;
#else
// TODO handle coded symbol once supported by the softdevice.
ble_gap_phys_t gap_phys = {
to_nordic_phy_set(txPhys),
to_nordic_phy_set(rxPhys)
};
uint32_t err = sd_ble_gap_phy_update(connection, &gap_phys);
switch (err) {
case NRF_SUCCESS:
return BLE_ERROR_NONE;
case NRF_ERROR_INVALID_ADDR:
case BLE_ERROR_INVALID_CONN_HANDLE:
case NRF_ERROR_INVALID_PARAM:
return BLE_ERROR_INVALID_PARAM;
case NRF_ERROR_INVALID_STATE:
return BLE_ERROR_INVALID_STATE;
case NRF_ERROR_BUSY:
return BLE_STACK_BUSY;
default:
return BLE_ERROR_UNSPECIFIED;
}
#endif
}
ble_error_t nRF5xGap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason)
{
uint8_t code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
@ -1507,6 +1617,67 @@ void nRF5xGap::release_all_connections_role() {
_connections_role[i].is_allocated = false;
}
}
void nRF5xGap::on_phy_update(
Handle_t connection,
const ble_gap_evt_phy_update_t& evt
) {
if (!_eventHandler) {
return;
}
ble_error_t status;
switch (evt.status) {
case BLE_HCI_STATUS_CODE_SUCCESS:
status = BLE_ERROR_NONE;
break;
case BLE_HCI_UNSUPPORTED_REMOTE_FEATURE:
status = BLE_ERROR_OPERATION_NOT_PERMITTED;
break;
case BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION:
case BLE_HCI_DIFFERENT_TRANSACTION_COLLISION:
status = BLE_ERROR_INVALID_STATE;
break;
case BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS:
status = BLE_ERROR_INVALID_PARAM;
break;
default:
status = BLE_ERROR_UNSPECIFIED;
break;
}
_eventHandler->onPhyUpdateComplete(
status,
connection,
Phy_t::LE_1M,
Phy_t::LE_1M
);
}
#ifndef S140
void nRF5xGap::on_phy_update_request(
Handle_t connection,
const ble_gap_evt_phy_update_request_t& evt
) {
ble_gap_phys_t phys = {
_prefered_tx_phys & evt.peer_preferred_phys.tx_phys,
_prefered_rx_phys & evt.peer_preferred_phys.rx_phys
};
if (!phys.tx_phys) {
phys.tx_phys = BLE_GAP_PHY_AUTO;
}
if (!phys.rx_phys) {
phys.rx_phys = BLE_GAP_PHY_AUTO;
}
sd_ble_gap_phy_update(connection, &phys);
}
#endif

View File

@ -30,10 +30,10 @@
#endif
#ifndef YOTTA_CFG_IRK_TABLE_MAX_SIZE
#if (NRF_SD_BLE_API_VERSION >= 3)
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT
#else
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
#endif
#endif
#elif YOTTA_CFG_IRK_TABLE_MAX_SIZE > BLE_GAP_WHITELIST_IRK_MAX_COUNT
#undef YOTTA_CFG_IRK_TABLE_MAX_SIZE
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
@ -77,7 +77,7 @@ public:
// The Mbed infrastructure expects 100ms+ - so for now return that
// return getMinAdvertisingInterval();
// FIXME infrastructure
return GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON;
return GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON;
#else
return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_NONCON_INTERVAL_MIN);
#endif
@ -89,6 +89,19 @@ public:
virtual ble_error_t connect(const Address_t, ble::peer_address_type_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams);
virtual ble_error_t connect(const Address_t, BLEProtocol::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams);
ble_error_t connect(const Address_t, BLEProtocol::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams, bool identity);
virtual ble_error_t readPhy(Handle_t connection);
virtual ble_error_t setPreferedPhys(
const Phys_t* txPhys,
const Phys_t* rxPhys
);
virtual ble_error_t setPhy(
Handle_t connection,
const Phys_t* txPhys,
const Phys_t* rxPhys,
CodedSymbolPerBit_t codedSymbol
);
virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason);
virtual ble_error_t disconnect(DisconnectionReason_t reason);
@ -287,6 +300,12 @@ private:
void release_connection_role(ble::connection_handle_t);
void release_all_connections_role();
void on_phy_update(Handle_t connection, const ble_gap_evt_phy_update_t& evt);
// FIXME: remove guard when S140 updated
#ifndef S140
void on_phy_update_request(Handle_t connection, const ble_gap_evt_phy_update_request_t& evt);
#endif
uint16_t m_connectionHandle;
ConnectionEventMonitor::EventHandler* _connection_event_handler;
@ -295,6 +314,8 @@ private:
CentralPrivacyConfiguration_t _central_privacy_configuration;
AddressType_t _non_private_address_type;
Address_t _non_private_address;
uint8_t _prefered_tx_phys;
uint8_t _prefered_rx_phys;
struct connection_role_t {
connection_role_t() :