BLE: Rework Gap event handler.

Every user facing event handler accept a single parameter type; event that contains all the event fields.
That strategy allows us to extend the type later if required while we do not disrupt existing code.
pull/8738/head
Vincent Coubard 2018-11-13 10:37:44 +00:00
parent 6a63948a7d
commit f136b0cb00
2 changed files with 495 additions and 80 deletions

View File

@ -1148,50 +1148,104 @@ public:
* Definition of the general handler of Gap related events.
*/
struct EventHandler {
/**
* FIXME
* @param advHandle
* @param peerAddressType
* @param peerAddress
*/
virtual void onScanRequest(
AdvHandle_t advHandle,
PeerAddressType_t peerAddressType,
const BLEProtocol::AddressBytes_t &peerAddress
) {
(void) advHandle;
(void) peerAddressType;
(void) peerAddress;
}
/**
* FIXME
* @param advHandle
* @param connection
* @param completed_events
* @param connected
*/
virtual void onAdvertisingEnd(
AdvHandle_t advHandle,
Handle_t connection,
uint8_t completed_events,
bool connected
) {
(void) advHandle;
(void) connection;
(void) completed_events;
(void) connected;
}
struct AdvertisingReportEvent {
AdvertisingReportEvent(
const AdvertisingEventType_t &type,
const PeerAddressType_t &peerAddressType,
const ble::address_t &peerAddress,
const Phy_t &primaryPhy,
const Phy_t &secondaryPhy,
ble::advertising_sid_t SID,
ble::advertising_power_t txPower,
ble::rssi_t rssi,
int16_t periodicInterval,
const PeerAddressType_t &directAddressType,
const ble::address_t &directAddress,
const mbed::Span<const uint8_t> &advertisingData
) :
type(type),
peerAddressType(peerAddressType),
peerAddress(peerAddress),
primaryPhy(primaryPhy),
secondaryPhy(secondaryPhy),
SID(SID),
txPower(txPower),
rssi(rssi),
periodicInterval(periodicInterval),
directAddressType(directAddressType),
directAddress(directAddress),
advertisingData(advertisingData) { }
struct AdvertisingReportEvent_t {
const AdvertisingEventType_t &getType() const
{
return type;
}
const PeerAddressType_t &getPeerAddressType() const
{
return peerAddressType;
}
const ble::address_t &getPeerAddress() const
{
return peerAddress;
}
const Phy_t &getPrimaryPhy() const
{
return primaryPhy;
}
const Phy_t &getSecondaryPhy() const
{
return secondaryPhy;
}
ble::advertising_sid_t getSID() const
{
return SID;
}
ble::advertising_power_t getTxPower() const
{
return txPower;
}
ble::rssi_t getRssi() const
{
return rssi;
}
int16_t getPeriodicInterval() const
{
return periodicInterval;
}
const PeerAddressType_t &getDirectAddressType() const
{
return directAddressType;
}
const ble::address_t &getDirectAddress() const
{
return directAddress;
}
const mbed::Span<const uint8_t> &getAdvertisingData() const
{
return advertisingData;
}
private:
AdvertisingEventType_t type;
PeerAddressType_t peerAddressType;
ble::address_t const &peerAddress;
const ble::address_t &peerAddress;
Phy_t primaryPhy;
Phy_t secondaryPhy;
uint8_t SID;
int8_t txPower;
int8_t rssi;
ble::advertising_sid_t SID;
ble::advertising_power_t txPower;
ble::rssi_t rssi;
int16_t periodicInterval;
PeerAddressType_t directAddressType;
const ble::address_t &directAddress;
@ -1200,26 +1254,93 @@ public:
/**
* FIXME
* @param type
* @param peerAddressType
* @param peerAddress
* @param primaryPhy
* @param secondaryPhy
* @param SID
* @param txPower
* @param rssi
* @param periodicInterval
* @param directAddressType
* @param directAddress
* @param advertisingData
*/
void onAdvertisingReport(
const AdvertisingReportEvent_t &event
) {
virtual void onAdvertisingReport(const AdvertisingReportEvent &event) {
(void) event;
}
struct ConnectionCompleteEvent_t {
struct ConnectionCompleteEvent {
ConnectionCompleteEvent(
bool success,
Handle_t connectionHandle,
Role_t ownRole,
const PeerAddressType_t &peerAddressType,
const ble::address_t &peerAddress,
const ble::address_t &localResolvablePrivateAddress,
const ble::address_t &peerResolvablePrivateAddress,
uint16_t connectionInterval_us,
uint16_t connectionLatency,
uint16_t supervisionTimeout_ms,
uint16_t masterClockAccuracy_ppm
) :
success(success),
connectionHandle(connectionHandle),
ownRole(ownRole),
peerAddressType(peerAddressType),
peerAddress(peerAddress),
localResolvablePrivateAddress(localResolvablePrivateAddress),
peerResolvablePrivateAddress(peerResolvablePrivateAddress),
connectionInterval_us(connectionInterval_us),
connectionLatency(connectionLatency),
supervisionTimeout_ms(supervisionTimeout_ms),
masterClockAccuracy_ppm(masterClockAccuracy_ppm) { }
bool isSuccess() const
{
return success;
}
Handle_t getConnectionHandle() const
{
return connectionHandle;
}
Role_t getOwnRole() const
{
return ownRole;
}
const PeerAddressType_t &getPeerAddressType() const
{
return peerAddressType;
}
const ble::address_t &getPeerAddress() const
{
return peerAddress;
}
const ble::address_t &getLocalResolvablePrivateAddress() const
{
return localResolvablePrivateAddress;
}
const ble::address_t &getPeerResolvablePrivateAddress() const
{
return peerResolvablePrivateAddress;
}
uint16_t getConnectionInterval_us() const
{
return connectionInterval_us;
}
uint16_t getConnectionLatency() const
{
return connectionLatency;
}
uint16_t getSupervisionTimeout_ms() const
{
return supervisionTimeout_ms;
}
uint16_t getMasterClockAccuracy_ppm() const
{
return masterClockAccuracy_ppm;
}
private:
bool success;
Handle_t connectionHandle;
Role_t ownRole;
@ -1234,11 +1355,255 @@ public:
};
void onConnectionComplete(
const ConnectionCompleteEvent_t &event
const ConnectionCompleteEvent &event
) {
(void)event;
}
struct PeriodicAdvertisingSyncEstablishedEvent {
PeriodicAdvertisingSyncEstablishedEvent(
ble_error_t status,
ble::periodic_sync_handle_t syncHandle,
ble::advertising_sid_t sid,
const PeerAddressType_t &peerAddressType,
const ble::address_t &peerAddress,
const Phy_t &peerPhy,
uint16_t advertisingInterval,
const ble::clock_accuracy_t &peerClockAccuracy
) :
status(status),
syncHandle(syncHandle),
sid(sid),
peerAddressType(peerAddressType),
peerAddress(peerAddress),
peerPhy(peerPhy),
advertisingInterval(advertisingInterval),
peerClockAccuracy(peerClockAccuracy) { }
ble_error_t getStatus() const
{
return status;
}
ble::periodic_sync_handle_t getSyncHandle() const
{
return syncHandle;
}
ble::advertising_sid_t getSid() const
{
return sid;
}
const PeerAddressType_t &getPeerAddressType() const
{
return peerAddressType;
}
const ble::address_t &getPeerAddress() const
{
return peerAddress;
}
const Phy_t &getPeerPhy() const
{
return peerPhy;
}
uint16_t getAdvertisingInterval() const
{
return advertisingInterval;
}
const ble::clock_accuracy_t &getPeerClockAccuracy() const
{
return peerClockAccuracy;
}
private:
ble_error_t status;
ble::periodic_sync_handle_t syncHandle;
ble::advertising_sid_t sid;
PeerAddressType_t peerAddressType;
const ble::address_t& peerAddress;
Phy_t peerPhy;
uint16_t advertisingInterval;
ble::clock_accuracy_t peerClockAccuracy;
};
virtual void onPeriodicAdvertisingSyncEstablished(
const PeriodicAdvertisingSyncEstablishedEvent &event
)
{
(void) event;
}
struct PeriodicAdvertisingReportEvent {
PeriodicAdvertisingReportEvent(
ble::periodic_sync_handle_t syncHandle,
ble::advertising_power_t txPower,
ble::rssi_t rssi,
const ble::advertising_data_status_t &dataStatus,
const mbed::Span<const uint8_t> &payload
) :
syncHandle(syncHandle),
txPower(txPower),
rssi(rssi),
dataStatus(dataStatus),
payload(payload) { }
ble::periodic_sync_handle_t getSyncHandle() const
{
return syncHandle;
}
ble::advertising_power_t getTxPower() const
{
return txPower;
}
ble::rssi_t getRssi() const
{
return rssi;
}
const ble::advertising_data_status_t &getDataStatus() const
{
return dataStatus;
}
const mbed::Span<const uint8_t> &getPayload() const
{
return payload;
}
private:
ble::periodic_sync_handle_t syncHandle;
ble::advertising_power_t txPower;
ble::rssi_t rssi;
ble::advertising_data_status_t dataStatus;
mbed::Span<const uint8_t> payload;
};
virtual void onPeriodicAdvertisingReportEvent(
const PeriodicAdvertisingReportEvent & event
)
{
(void) event;
}
struct PeriodicAdvertisingSyncLoss {
PeriodicAdvertisingSyncLoss(ble::periodic_sync_handle_t syncHandle) :
syncHandle(syncHandle) { }
ble::periodic_sync_handle_t getSyncHandle() const
{
return syncHandle;
}
private:
ble::periodic_sync_handle_t syncHandle;
};
virtual void onPeriodicAdvertisingSyncLoss(
const PeriodicAdvertisingSyncLoss &event
)
{
(void) event;
}
struct ScanTimeoutEvent { };
virtual void onScanTimeout(const ScanTimeoutEvent &) { }
struct AdvertisingEndEvent_t {
AdvertisingEndEvent_t(
AdvHandle_t advHandle,
Handle_t connection,
uint8_t completed_events,
bool connected
) :
advHandle(advHandle),
connection(connection),
completed_events(completed_events),
connected(connected) { }
AdvHandle_t getAdvHandle() const
{
return advHandle;
}
Handle_t getConnection() const
{
return connection;
}
uint8_t getCompleted_events() const
{
return completed_events;
}
bool isConnected() const
{
return connected;
}
private:
AdvHandle_t advHandle;
Handle_t connection;
uint8_t completed_events;
bool connected;
};
/**
* FIXME
*/
virtual void onAdvertisingEnd(const AdvertisingEndEvent_t& event) {
(void) event;
}
/**
* FIXME
*/
struct ScanRequestEvent_t {
ScanRequestEvent_t(
AdvHandle_t advHandle,
const PeerAddressType_t &peerAddressType,
const ble::address_t &peerAddress
) :
advHandle(advHandle),
peerAddressType(peerAddressType),
peerAddress(peerAddress) { }
AdvHandle_t getAdvHandle() const
{
return advHandle;
}
const PeerAddressType_t &getPeerAddressType() const
{
return peerAddressType;
}
const ble::address_t &getPeerAddress() const
{
return peerAddress;
}
private:
AdvHandle_t advHandle;
PeerAddressType_t peerAddressType;
const ble::address_t &peerAddress;
};
/**
* FIXME
*/
virtual void onScanRequest(const ScanRequestEvent_t& event) {
(void) event;
}
/**
* Function invoked when the current transmitter and receiver PHY have
* been read for a given connection.

View File

@ -1218,7 +1218,11 @@ void GenericGap::processDisconnectionEvent(
void GenericGap::on_scan_timeout()
{
_event_queue.post(mbed::callback(this, &GenericGap::process_scan_timeout));
if (!_eventHandler) {
return;
}
_eventHandler->onScanTimeout(::Gap::EventHandler::ScanTimeoutEvent());
}
void GenericGap::process_scan_timeout()
@ -1864,6 +1868,7 @@ ble_error_t GenericGap::setAdvertisingData(
&pal::Gap::set_extended_scan_response_data :
&pal::Gap::set_extended_advertising_data;
// FIXME: Handle the case where the payload size is 0
for (size_t i = 0, end = payload.size(); i < end; i += MAX_HCI_DATA_LENGTH) {
// select the operation based on the index
op_t op(op_t::INTERMEDIATE_FRAGMENT);
@ -2181,8 +2186,12 @@ void GenericGap::on_enhanced_connection_complete(
uint16_t supervision_timeout,
pal::clock_accuracy_t master_clock_accuracy
) {
if (_eventHandler) {
Gap::EventHandler::ConnectionCompleteEvent_t event = {
if (!_eventHandler) {
return;
}
_eventHandler->onConnectionComplete(
Gap::EventHandler::ConnectionCompleteEvent(
(status==pal::hci_error_code_t::SUCCESS),
(ble::connection_handle_t)connection_handle,
(Gap::Role_t)own_role.value(),
@ -2194,10 +2203,8 @@ void GenericGap::on_enhanced_connection_complete(
connection_latency,
supervision_timeout * 10,
master_clock_accuracy.get_ppm()
};
_eventHandler->onConnectionComplete(event);
}
)
);
}
void GenericGap::on_extended_advertising_report(
@ -2216,13 +2223,17 @@ void GenericGap::on_extended_advertising_report(
const uint8_t *data
)
{
if (_eventHandler) {
Gap::EventHandler::AdvertisingReportEvent_t event = {
if (!_eventHandler) {
return;
}
_eventHandler->onAdvertisingReport(
::Gap::EventHandler::AdvertisingReportEvent(
event_type,
(PeerAddressType_t::type)(address_type? address_type->value() : connection_peer_address_type_t::PUBLIC_ADDRESS),
(PeerAddressType_t::type)(address_type ? address_type->value() : PeerAddressType_t::ANONYMOUS),
(BLEProtocol::AddressBytes_t&)address,
primary_phy,
secondary_phy? *secondary_phy : phy_t::LE_1M,
secondary_phy? *secondary_phy : phy_t::NONE,
advertising_sid,
tx_power,
rssi,
@ -2230,10 +2241,8 @@ void GenericGap::on_extended_advertising_report(
(PeerAddressType_t::type)direct_address_type.value(),
(BLEProtocol::AddressBytes_t&)direct_address,
mbed::make_Span(data, data_length)
};
_eventHandler->onAdvertisingReport(event);
}
)
);
}
void GenericGap::on_periodic_advertising_sync_established(
@ -2247,6 +2256,22 @@ void GenericGap::on_periodic_advertising_sync_established(
pal::clock_accuracy_t clock_accuracy
)
{
if (!_eventHandler) {
return;
}
_eventHandler->onPeriodicAdvertisingSyncEstablished(
::Gap::EventHandler::PeriodicAdvertisingSyncEstablishedEvent(
(error == pal::hci_error_code_t::SUCCESS) ? BLE_ERROR_NONE : BLE_ERROR_INTERNAL_STACK_FAILURE,
sync_handle,
advertising_sid,
static_cast<PeerAddressType_t::type>(advertiser_address_type.value()),
advertiser_address,
advertiser_phy,
periodic_advertising_interval,
clock_accuracy
)
);
}
@ -2259,12 +2284,30 @@ void GenericGap::on_periodic_advertising_report(
const uint8_t *data
)
{
if (!_eventHandler) {
return;
}
_eventHandler->onPeriodicAdvertisingReportEvent(
::Gap::EventHandler::PeriodicAdvertisingReportEvent(
sync_handle,
tx_power,
rssi,
data_status,
mbed::make_const_Span(data, data_length)
)
);
}
void GenericGap::on_periodic_advertising_sync_loss(pal::sync_handle_t sync_handle)
{
if (!_eventHandler) {
return;
}
_eventHandler->onPeriodicAdvertisingSyncLoss(
::Gap::EventHandler::PeriodicAdvertisingSyncLoss(sync_handle)
);
}
void GenericGap::on_advertising_set_terminated(
@ -2276,14 +2319,18 @@ void GenericGap::on_advertising_set_terminated(
{
_active_sets.clear(advertising_handle);
if (_eventHandler) {
_eventHandler->onAdvertisingEnd(
if (!_eventHandler) {
return;
}
_eventHandler->onAdvertisingEnd(
::Gap::EventHandler::AdvertisingEndEvent_t(
advertising_handle,
connection_handle,
number_of_completed_extended_advertising_events,
status == pal::hci_error_code_t::SUCCESS
);
}
)
);
}
void GenericGap::on_scan_request_received(
@ -2292,14 +2339,17 @@ void GenericGap::on_scan_request_received(
const ble::address_t &address
)
{
if (_eventHandler) {
_eventHandler->onScanRequest(
advertising_handle,
(ble::peer_address_type_t::type)scanner_address_type.value(),
(const BLEProtocol::AddressBytes_t&)address
);
if (!_eventHandler) {
return;
}
_eventHandler->onScanRequest(
::Gap::EventHandler::ScanRequestEvent_t(
advertising_handle,
(ble::peer_address_type_t::type) scanner_address_type.value(),
address
)
);
}
ble_error_t GenericGap::setScanParameters(const GapScanParameters &params)