connection monitor

pull/6188/head
paul-szczepanek-arm 2018-02-19 15:32:07 +00:00
parent 2f1e211da1
commit d9156a28e2
7 changed files with 198 additions and 54 deletions

View File

@ -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 <algorithm>
#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 */

View File

@ -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

View File

@ -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;
};
}

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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 */
}