diff --git a/features/FEATURE_BLE/ble/Gap.h b/features/FEATURE_BLE/ble/Gap.h index 13c5daf30c..9ba0525cf0 100644 --- a/features/FEATURE_BLE/ble/Gap.h +++ b/features/FEATURE_BLE/ble/Gap.h @@ -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 &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 &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 &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 &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 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. diff --git a/features/FEATURE_BLE/source/generic/GenericGap.cpp b/features/FEATURE_BLE/source/generic/GenericGap.cpp index 40b194ad6f..1e47cad045 100644 --- a/features/FEATURE_BLE/source/generic/GenericGap.cpp +++ b/features/FEATURE_BLE/source/generic/GenericGap.cpp @@ -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(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 ¶ms)