From d9156a28e26a0ac66593d607a28e4328d51ccbe8 Mon Sep 17 00:00:00 2001 From: paul-szczepanek-arm <33840200+paul-szczepanek-arm@users.noreply.github.com> Date: Mon, 19 Feb 2018 15:32:07 +0000 Subject: [PATCH] connection monitor --- .../FEATURE_BLE/ble/ConnectionEventMonitor.h | 62 +++++++++++++++++++ features/FEATURE_BLE/ble/Gap.h | 12 +++- features/FEATURE_BLE/ble/generic/GenericGap.h | 30 ++++++++- .../ble/generic/GenericSecurityManager.h | 39 +++++++----- .../FEATURE_BLE/source/generic/GenericGap.cpp | 57 ++++++++++++++++- .../source/generic/GenericSecurityManager.cpp | 49 ++++++--------- .../TARGET_CORDIO/CordioSecurityManager.h | 3 +- 7 files changed, 198 insertions(+), 54 deletions(-) create mode 100644 features/FEATURE_BLE/ble/ConnectionEventMonitor.h diff --git a/features/FEATURE_BLE/ble/ConnectionEventMonitor.h b/features/FEATURE_BLE/ble/ConnectionEventMonitor.h new file mode 100644 index 0000000000..e9be7447ca --- /dev/null +++ b/features/FEATURE_BLE/ble/ConnectionEventMonitor.h @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017-2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_BLE_CONNECTION_EVENT_MONITOR +#define MBED_BLE_CONNECTION_EVENT_MONITOR + +#include + +#include "ble/BLE.h" +#include "ble/BLEProtocol.h" +#include "ble/Gap.h" +#include "ble/pal/PalGap.h" +#include "ble/pal/GapEvents.h" +#include "ble/pal/GapTypes.h" +#include "ble/BLETypes.h" +#include "ble/pal/GenericAccessService.h" +#include "ble/pal/EventQueue.h" + +namespace ble { + +class ConnectionEventHandler { + virtual void on_connected( + connection_handle_t connection, + Gap::Role_t role, + BLEProtocol::AddressType_t peer_address_type, + const BLEProtocol::AddressBytes_t peer_address, + BLEProtocol::AddressType_t local_address_type, + const BLEProtocol::AddressBytes_t local_address, + const Gap::ConnectionParams_t *connection_params + ) = 0; + + void on_disconnected( + connection_handle_t connection, + Gap::DisconnectionReason_t reason + ) = 0; +}; + +class ConnectionEventMonitor { + /** + * Register a handler for connection events to be used internally and serviced first. + * + * @param[in] connection_event_handler Event handler being registered. + */ + void set_connection_event_handler(ConnectionEventHandler *connection_event_handler) = 0; +} + +} + +#endif /* MBED_BLE_CONNECTION_EVENT_MONITOR */ diff --git a/features/FEATURE_BLE/ble/Gap.h b/features/FEATURE_BLE/ble/Gap.h index f9b5bdbe34..038ec74727 100644 --- a/features/FEATURE_BLE/ble/Gap.h +++ b/features/FEATURE_BLE/ble/Gap.h @@ -2281,7 +2281,7 @@ public: * @param[in] ownAddr Address this device uses for this connection. * @param[in] connectionParams Parameters of the connection. */ - void processConnectionEvent( + virtual void processConnectionEvent( Handle_t handle, Role_t role, BLEProtocol::AddressType_t peerAddrType, @@ -2304,6 +2304,7 @@ public: ownAddr, connectionParams ); + connectionCallChain.call(&callbackParams); } @@ -2316,7 +2317,7 @@ public: * @param[in] handle Handle of the terminated connection. * @param[in] reason Reason of the disconnection. */ - void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) + virtual void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) { /* Update Gap state */ --connectionCount; @@ -2447,6 +2448,13 @@ protected: */ DisconnectionEventCallbackChain_t disconnectionCallChain; + /** + * Register a callback handling connection events to be used internally and serviced first. + * + * @param[in] callback Event handler being registered. + */ + virtual void onConnectionPrivate(ConnectionEventCallback_t callback) { } + private: /** * Callchain containing all registered callback handlers for shutdown diff --git a/features/FEATURE_BLE/ble/generic/GenericGap.h b/features/FEATURE_BLE/ble/generic/GenericGap.h index 84864e0951..7d66c95e38 100644 --- a/features/FEATURE_BLE/ble/generic/GenericGap.h +++ b/features/FEATURE_BLE/ble/generic/GenericGap.h @@ -28,12 +28,12 @@ #include "ble/BLETypes.h" #include "ble/pal/GenericAccessService.h" #include "ble/pal/EventQueue.h" +#include "ble/ConnectionEventMonitor.h" #include "drivers/Timeout.h" namespace ble { namespace generic { - /** * Generic implementation of the Gap class. * It requires a pal::Gap and a pal::GenericAccessService injected at @@ -41,7 +41,8 @@ namespace generic { * * @attention: Not part of the public interface of BLE API. */ -class GenericGap : public ::Gap { +class GenericGap : public ::Gap, + public ConnectionEventMonitor { public: /** @@ -250,6 +251,27 @@ public: */ virtual ble_error_t reset(void); + /** + * @copydoc ::Gap::processConnectionEvent + */ + virtual void processConnectionEvent( + Handle_t handle, + Role_t role, + BLEProtocol::AddressType_t peerAddrType, + const BLEProtocol::AddressBytes_t peerAddr, + BLEProtocol::AddressType_t ownAddrType, + const BLEProtocol::AddressBytes_t ownAddr, + const ConnectionParams_t *connectionParams + ); + + /** + * @copydoc ::Gap::processDisconnectionEvent + */ + virtual void processDisconnectionEvent( + Handle_t handle, + DisconnectionReason_t reason + ); + private: void on_scan_timeout(); @@ -279,6 +301,9 @@ private: bool initialize_whitelist() const; + /** implements ConnectionEventMonitor */ + void set_connection_event_handler(ConnectionEventHandler *_connection_event_handler); + pal::EventQueue& _event_queue; pal::Gap &_pal_gap; pal::GenericAccessService &_gap_service; @@ -290,6 +315,7 @@ private: mutable Whitelist_t _whitelist; mbed::Timeout _advertising_timeout; mbed::Timeout _scan_timeout; + ConnectionEventHandler *_connection_event_handler; }; } diff --git a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h index b48ded0d76..0a8b73dad2 100644 --- a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h +++ b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h @@ -22,6 +22,7 @@ #include "ble/generic/GenericSecurityDb.h" #include "Callback.h" #include "ble/Gap.h" +#include "ble/generic/GenericGap.h" #include "ble/pal/PalSecurityManager.h" namespace ble { @@ -37,7 +38,8 @@ typedef SecurityManager::SecurityIOCapabilities_t SecurityIOCapabilities_t; class GenericSecurityManagerEventHandler; class GenericSecurityManager : public SecurityManager, - public pal::SecurityManagerEventHandler { + public pal::SecurityManagerEventHandler, + public ConnectionEventHandler { public: /* implements SecurityManager */ @@ -232,7 +234,7 @@ public: GenericSecurityManager( ble::pal::SecurityManager &palImpl, GenericSecurityDb &dbImpl, - Gap &gapImpl + GenericGap &gapImpl ) : _pal(palImpl), _db(dbImpl), _gap(gapImpl), @@ -374,17 +376,6 @@ private: bool enable = true ); - /** - * Inform the security manager that a device has been disconnected and its - * entry can be put in NVM storage. Called by GAP. - * - * @param[in] connectionHandle Handle to identify the connection. - * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. - */ - void on_disconnected( - connection_handle_t connection - ); - /** * Inform the Security manager of a new connection. This will create * or retrieve an existing security manager entry for the connected device. @@ -398,10 +389,24 @@ private: */ void on_connected( connection_handle_t connection, - bool is_master, + Gap::Role_t role, BLEProtocol::AddressType_t peer_address_type, - const address_t &peer_address, - const address_t &local_address + const BLEProtocol::AddressBytes_t peer_address, + BLEProtocol::AddressType_t local_address_type, + const BLEProtocol::AddressBytes_t local_address, + const Gap::ConnectionParams_t *connection_params + ); + + /** + * Inform the security manager that a device has been disconnected and its + * entry can be put in NVM storage. Called by GAP. + * + * @param[in] connectionHandle Handle to identify the connection. + * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. + */ + void on_disconnected( + connection_handle_t connection, + Gap::DisconnectionReason_t reason ); /** @@ -425,7 +430,7 @@ private: private: ble::pal::SecurityManager &_pal; GenericSecurityDb &_db; - Gap &_gap; + GenericGap &_gap; AuthenticationMask _default_authentication; KeyDistribution _default_key_distribution; diff --git a/features/FEATURE_BLE/source/generic/GenericGap.cpp b/features/FEATURE_BLE/source/generic/GenericGap.cpp index 8b2ec7a4d2..9280b805f5 100644 --- a/features/FEATURE_BLE/source/generic/GenericGap.cpp +++ b/features/FEATURE_BLE/source/generic/GenericGap.cpp @@ -382,7 +382,8 @@ GenericGap::GenericGap( _advertising_filter_policy(pal::advertising_filter_policy_t::NO_FILTER), _whitelist(), _advertising_timeout(), - _scan_timeout() + _scan_timeout(), + _connection_event_handler(NULL) { _pal_gap.when_gap_event_received( mbed::callback(this, &GenericGap::on_gap_event_received) @@ -896,6 +897,55 @@ ble_error_t GenericGap::reset(void) return BLE_ERROR_NONE; } +void GenericGap::processConnectionEvent( + Handle_t handle, + Role_t role, + BLEProtocol::AddressType_t peerAddrType, + const BLEProtocol::AddressBytes_t peerAddr, + BLEProtocol::AddressType_t ownAddrType, + const BLEProtocol::AddressBytes_t ownAddr, + const ConnectionParams_t *connectionParams +) { + if (_connection_event_handler) { + _connection_event_handler->on_connected( + handle, + role, + peerAddrType, + peerAddr, + ownAddrType, + ownAddr, + connectionParams + ); + } + + ::Gap::processConnectionEvent( + handle, + role, + peerAddrType, + peerAddr, + ownAddrType, + ownAddr, + connectionParams + ); +} + +void GenericGap::processDisconnectionEvent( + Handle_t handle, + DisconnectionReason_t reason +) { + if (_connection_event_handler) { + _connection_event_handler->on_disconnected( + handle, + reason + ); + } + + ::Gap::processDisconnectionEvent( + handle, + reason + ); +} + void GenericGap::on_scan_timeout() { _event_queue.post(mbed::callback(this, &GenericGap::process_scan_timeout)); @@ -1087,5 +1137,10 @@ bool GenericGap::initialize_whitelist() const return true; } +void GenericGap::set_connection_event_handler(ConnectionEventHandler *connection_event_handler) +{ + _connection_event_handler = connection_event_handler; +} + } // namespace generic } // namespace ble diff --git a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp index 42c957fd19..c795b77ade 100644 --- a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp +++ b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp @@ -55,8 +55,7 @@ ble_error_t GenericSecurityManager::init( init_signing(); } - _gap.onConnection(this, &GenericSecurityManager::connection_callback); - _gap.onDisconnection(this, &GenericSecurityManager::disconnection_callback); + _gap.set_connection_event_handler(this); _pal.generate_public_key(); @@ -727,27 +726,20 @@ void GenericSecurityManager::set_mitm_performed(connection_handle_t connection, } } -void GenericSecurityManager::on_disconnected(connection_handle_t connection) { - SecurityEntry_t *entry = _db.get_entry(connection); - if (!entry) { - return; - } - entry->connected = false; - _db.sync(); -} - void GenericSecurityManager::on_connected( connection_handle_t connection, - bool is_master, + Gap::Role_t role, BLEProtocol::AddressType_t peer_address_type, - const address_t &peer_address, - const address_t &local_address + const BLEProtocol::AddressBytes_t peer_address, + BLEProtocol::AddressType_t local_address_type, + const BLEProtocol::AddressBytes_t local_address, + const Gap::ConnectionParams_t *connection_params ) { SecurityEntry_t *entry = _db.connect_entry( connection, peer_address_type, - peer_address, - local_address + address_t(peer_address), + address_t(local_address) ); if (!entry) { @@ -756,26 +748,21 @@ void GenericSecurityManager::on_connected( entry->reset(); - entry->is_master = is_master; + entry->is_master = (role == Gap::CENTRAL); entry->handle = connection; entry->connected = true; } -void GenericSecurityManager::connection_callback( - const Gap::ConnectionCallbackParams_t* params +void GenericSecurityManager::on_disconnected( + connection_handle_t connection, + Gap::DisconnectionReason_t reason ) { - on_connected( - params->handle, - (params->role == Gap::CENTRAL), - params->peerAddrType, - address_t(params->peerAddr), - address_t(params->ownAddr) - ); -} -void GenericSecurityManager::disconnection_callback( - const Gap::DisconnectionCallbackParams_t* params -) { - on_disconnected(params->handle); + SecurityEntry_t *entry = _db.get_entry(connection); + if (!entry) { + return; + } + entry->connected = false; + _db.sync(); } /* Implements ble::pal::SecurityManagerEventHandler */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/CordioSecurityManager.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/CordioSecurityManager.h index f44533e2b1..4e0e51217f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/CordioSecurityManager.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/CordioSecurityManager.h @@ -21,6 +21,7 @@ #include "ble/generic/GenericSecurityManager.h" #include "ble/generic/GenericSecurityDb.h" +#include "ble/generic/GenericGap.h" #include "ble/pal/PalSecurityManager.h" #include "CordioPalSecurityManager.h" #include "CordioGap.h" @@ -45,7 +46,7 @@ public: SecurityManager( pal::SecurityManager &palImpl, generic::GenericSecurityDb &dbImpl, - Gap &gapImpl + generic::GenericGap &gapImpl ) : generic::GenericSecurityManager(palImpl, dbImpl, gapImpl) { /* empty */ }