BLE: Add API to manage GAP connection parameter updates.

pull/8738/head
Vincent Coubard 2018-11-16 16:34:57 +00:00
parent b6a0c8aea5
commit 869bb308c5
7 changed files with 383 additions and 4 deletions

View File

@ -324,9 +324,17 @@ public:
*
* @param event Connection event @see ConnectionCompleteEvent_t for details.
*/
void onConnectionComplete(const ble::ConnectionCompleteEvent &event) { }
virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) { }
void onDisconnection(const ble::DisconnectionEvent &event) { }
virtual void onUpdateConnectionParametersRequest(
const ble::UpdateConnectionParametersRequestEvent &event
) { }
virtual void onConnectionParametersUpdateComplete(
const ble::ConnectionParametersUpdateCompleteEvent &event
) { }
virtual void onDisconnection(const ble::DisconnectionEvent &event) { }
/**
* Function invoked when the current transmitter and receiver PHY have
@ -710,6 +718,34 @@ public:
*/
virtual ble_error_t cancelConnect();
virtual ble_error_t updateConnectionParameters(
ble::connection_handle_t connectionHandle,
ble::conn_interval_t minConnectionInterval,
ble::conn_interval_t maxConnectionInterval,
ble::slave_latency_t slaveLatency,
ble::supervision_timeout_t supervision_timeout,
ble::conn_event_length_t minConnectionEventLength = ble::conn_event_length_t(0),
ble::conn_event_length_t maxConnectionEventLength = ble::conn_event_length_t(0)
);
virtual ble_error_t manageConnectionParametersUpdateRequest(
bool userManageConnectionUpdateRequest
);
virtual ble_error_t acceptConnectionParametersUpdate(
ble::connection_handle_t connectionHandle,
ble::conn_interval_t minConnectionInterval,
ble::conn_interval_t maxConnectionInterval,
ble::slave_latency_t slaveLatency,
ble::supervision_timeout_t supervision_timeout,
ble::conn_event_length_t minConnectionEventLength = ble::conn_event_length_t(0),
ble::conn_event_length_t maxConnectionEventLength = ble::conn_event_length_t(0)
);
virtual ble_error_t rejectConnectionParametersUpdate(
ble::connection_handle_t connectionHandle
);
/**
* Initiate a disconnection procedure.
*

View File

@ -552,7 +552,6 @@ private:
const address_t &peerAddress;
};
struct DisconnectionEvent {
DisconnectionEvent(
connection_handle_t connectionHandle,
@ -574,6 +573,104 @@ private:
ble::disconnection_reason_t reason;
};
struct UpdateConnectionParametersRequestEvent {
UpdateConnectionParametersRequestEvent(
connection_handle_t connectionHandle,
const conn_interval_t &minConnectionInterval,
const conn_interval_t &maxConnectionInterval,
const slave_latency_t &slaveLatency,
const supervision_timeout_t &supervision_timeout
) :
connectionHandle(connectionHandle),
minConnectionInterval(minConnectionInterval),
maxConnectionInterval(maxConnectionInterval),
slaveLatency(slaveLatency),
supervisionTimeout(supervision_timeout)
{ }
connection_handle_t getConnectionHandle() const
{
return connectionHandle;
}
const conn_interval_t &getMinConnectionInterval() const
{
return minConnectionInterval;
}
const conn_interval_t &getMaxConnectionInterval() const
{
return maxConnectionInterval;
}
const slave_latency_t &getSlaveLatency() const
{
return slaveLatency;
}
const supervision_timeout_t &getSupervisionTimeout() const
{
return supervisionTimeout;
}
private:
ble::connection_handle_t connectionHandle;
ble::conn_interval_t minConnectionInterval;
ble::conn_interval_t maxConnectionInterval;
ble::slave_latency_t slaveLatency;
ble::supervision_timeout_t supervisionTimeout;
};
struct ConnectionParametersUpdateCompleteEvent {
ConnectionParametersUpdateCompleteEvent(
ble_error_t status,
connection_handle_t connectionHandle,
const conn_interval_t &connectionInterval,
const slave_latency_t &slaveLatency,
const supervision_timeout_t &supervisionTimeout
) :
status(status),
connectionHandle(connectionHandle),
connectionInterval(connectionInterval),
slaveLatency(slaveLatency),
supervisionTimeout(supervisionTimeout)
{ }
ble_error_t getStatus() const
{
return status;
}
connection_handle_t getConnectionHandle() const
{
return connectionHandle;
}
const conn_interval_t &getConnectionInterval() const
{
return connectionInterval;
}
const slave_latency_t &getSlaveLatency() const
{
return slaveLatency;
}
const supervision_timeout_t &getSupervisionTimeout() const
{
return supervisionTimeout;
}
private:
ble_error_t status;
ble::connection_handle_t connectionHandle;
ble::conn_interval_t connectionInterval;
ble::slave_latency_t slaveLatency;
ble::supervision_timeout_t supervisionTimeout;
};
} // namespace ble
#endif //BLE_GAP_EVENTS_H

View File

@ -304,6 +304,34 @@ public:
*/
virtual ble_error_t cancelConnect();
virtual ble_error_t manageConnectionParametersUpdateRequest(
bool userManageConnectionUpdateRequest
);
virtual ble_error_t updateConnectionParameters(
ble::connection_handle_t connectionHandle,
ble::conn_interval_t minConnectionInterval,
ble::conn_interval_t maxConnectionInterval,
ble::slave_latency_t slaveLatency,
ble::supervision_timeout_t supervisionTimeout,
ble::conn_event_length_t minConnectionEventLength,
ble::conn_event_length_t maxConnectionEventLength
);
virtual ble_error_t acceptConnectionParametersUpdate(
ble::connection_handle_t connectionHandle,
ble::conn_interval_t minConnectionInterval,
ble::conn_interval_t maxConnectionInterval,
ble::slave_latency_t slaveLatency,
ble::supervision_timeout_t supervisionTimeout,
ble::conn_event_length_t minConnectionEventLength,
ble::conn_event_length_t maxConnectionEventLength
);
virtual ble_error_t rejectConnectionParametersUpdate(
ble::connection_handle_t connectionHandle
);
/**
* @see Gap::readPhy
*/
@ -659,6 +687,22 @@ private:
const ble::address_t &address
);
virtual void on_connection_update_complete(
pal::hci_error_code_t status,
connection_handle_t connection_handle,
uint16_t connection_interval,
uint16_t connection_latency,
uint16_t supervision_timeout
);
virtual void on_remote_connection_parameter(
connection_handle_t connection_handle,
uint16_t connection_interval_min,
uint16_t connection_interval_max,
uint16_t connection_latency,
uint16_t supervision_timeout
);
private:
pal::EventQueue& _event_queue;
pal::Gap &_pal_gap;
@ -722,6 +766,7 @@ private:
// deprecation flags
mutable bool _deprecated_scan_api_used : 1;
mutable bool _non_deprecated_scan_api_used : 1;
bool _user_manage_connection_parameter_requests : 1;
private:
ble_error_t setExtendedAdvertisingParameters(

View File

@ -219,6 +219,22 @@ struct Gap {
connection_peer_address_type_t scanner_address_type,
const address_t &address
) = 0;
virtual void on_connection_update_complete(
hci_error_code_t status,
connection_handle_t connection_handle,
uint16_t connection_interval,
uint16_t connection_latency,
uint16_t supervision_timeout
) = 0;
virtual void on_remote_connection_parameter(
connection_handle_t connection_handle,
uint16_t connection_interval_min,
uint16_t connection_interval_max,
uint16_t connection_latency,
uint16_t supervision_timeout
) = 0;
};
/**

View File

@ -271,6 +271,42 @@ ble_error_t Gap::cancelConnect() {
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::updateConnectionParameters(
ble::connection_handle_t connectionHandle,
ble::conn_interval_t minConnectionInterval,
ble::conn_interval_t maxConnectionInterval,
ble::slave_latency_t slaveLatency,
ble::supervision_timeout_t supervision_timeout,
ble::conn_event_length_t minConnectionEventLength,
ble::conn_event_length_t maxConnectionEventLength
) {
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::manageConnectionParametersUpdateRequest(
bool userManageConnectionUpdateRequest
) {
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::acceptConnectionParametersUpdate(
ble::connection_handle_t connectionHandle,
ble::conn_interval_t minConnectionInterval,
ble::conn_interval_t maxConnectionInterval,
ble::slave_latency_t slaveLatency,
ble::supervision_timeout_t supervision_timeout,
ble::conn_event_length_t minConnectionEventLength,
ble::conn_event_length_t maxConnectionEventLength
) {
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::rejectConnectionParametersUpdate(
ble::connection_handle_t connectionHandle
) {
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::disconnect(
ble::connection_handle_t connectionHandle,
ble::local_disconnection_reason_t reason

View File

@ -419,7 +419,8 @@ GenericGap::GenericGap(
_random_address_rotating(false),
_advertising_timeout(),
_scan_timeout(),
_connection_event_handler(NULL)
_connection_event_handler(NULL),
_user_manage_connection_parameter_requests(false)
{
_pal_gap.initialize();
@ -646,6 +647,67 @@ ble_error_t GenericGap::connect(
);
}
ble_error_t GenericGap::manageConnectionParametersUpdateRequest(bool flag) {
_user_manage_connection_parameter_requests = flag;
}
ble_error_t GenericGap::updateConnectionParameters(
connection_handle_t connectionHandle,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t supervisionTimeout,
conn_event_length_t minConnectionEventLength,
conn_event_length_t maxConnectionEventLength
) {
if (supervisionTimeout <= (1 + slaveLatency.value()) * maxConnectionInterval * 2) {
return BLE_ERROR_INVALID_PARAM;
}
return _pal_gap.connection_parameters_update(
connectionHandle,
minConnectionInterval.value(),
maxConnectionInterval.value(),
slaveLatency.value(),
supervisionTimeout.value(),
minConnectionEventLength.value(),
maxConnectionEventLength.value()
);
}
ble_error_t GenericGap::acceptConnectionParametersUpdate(
connection_handle_t connectionHandle,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t supervisionTimeout,
conn_event_length_t minConnectionEventLength,
conn_event_length_t maxConnectionEventLength
) {
if (supervisionTimeout <= (1 + slaveLatency.value()) * maxConnectionInterval * 2) {
return BLE_ERROR_INVALID_PARAM;
}
return _pal_gap.accept_connection_parameter_request(
connectionHandle,
minConnectionInterval.value(),
maxConnectionInterval.value(),
slaveLatency.value(),
supervisionTimeout.value(),
minConnectionEventLength.value(),
maxConnectionEventLength.value()
);
}
ble_error_t GenericGap::rejectConnectionParametersUpdate(
ble::connection_handle_t connectionHandle
) {
return _pal_gap.reject_connection_parameter_request(
connectionHandle,
pal::hci_error_code_t::UNACCEPTABLE_CONNECTION_PARAMETERS
);
}
ble_error_t GenericGap::cancelConnect()
{
return _pal_gap.cancel_connection_creation();
@ -2374,6 +2436,63 @@ void GenericGap::on_scan_request_received(
);
}
void GenericGap::on_connection_update_complete(
pal::hci_error_code_t status,
connection_handle_t connection_handle,
uint16_t connection_interval,
uint16_t connection_latency,
uint16_t supervision_timeout
) {
if (!_eventHandler) {
return;
}
_eventHandler->onConnectionParametersUpdateComplete(
ConnectionParametersUpdateCompleteEvent(
status == pal::hci_error_code_t::SUCCESS ? BLE_ERROR_NONE : BLE_ERROR_UNSPECIFIED,
connection_handle,
conn_interval_t(connection_interval),
slave_latency_t(connection_latency),
supervision_timeout_t(supervision_timeout)
)
);
}
void GenericGap::on_remote_connection_parameter(
connection_handle_t connection_handle,
uint16_t connection_interval_min,
uint16_t connection_interval_max,
uint16_t connection_latency,
uint16_t supervision_timeout
) {
if (_user_manage_connection_parameter_requests) {
// ignore for now as it is
_pal_gap.accept_connection_parameter_request(
connection_handle,
connection_interval_min,
connection_interval_max,
connection_latency,
supervision_timeout,
/* connection event length min */ 0,
/* connection event length max */ 0
);
} else {
if (!_eventHandler) {
return;
}
_eventHandler->onUpdateConnectionParametersRequest(
UpdateConnectionParametersRequestEvent(
connection_handle,
conn_interval_t(connection_interval_min),
conn_interval_t(connection_interval_max),
connection_latency,
supervision_timeout_t(supervision_timeout)
)
);
}
}
ble_error_t GenericGap::setScanParameters(const ScanParameters &params)
{
useVersionTwoAPI();

View File

@ -560,6 +560,36 @@ void Gap::gap_handler(const wsfMsgHdr_t* msg) {
evt->pData
);
} break;
case DM_CONN_UPDATE_IND: {
if (!handler) {
break;
}
const hciLeConnUpdateCmplEvt_t* evt = (const hciLeConnUpdateCmplEvt_t*) msg;
handler->on_connection_update_complete(
(hci_error_code_t::type) evt->status,
evt->hdr.param,
evt->connInterval,
evt->connLatency,
evt->supTimeout
);
} break;
case DM_REM_CONN_PARAM_REQ_IND: {
if (!handler) {
break;
}
const hciLeRemConnParamReqEvt_t* evt = (const hciLeRemConnParamReqEvt_t*) msg;
handler->on_remote_connection_parameter(
evt->hdr.param,
evt->intervalMin,
evt->intervalMax,
evt->latency,
evt->timeout
);
} break;
}
// all handlers are stored in a static array