base for ble unittests - BLE instance and mocked clasess (#14191)

* base for ble unittests - BLE instance and mocked clasess

* add default ble features to unittests

* add stubs

* move the files for includes to work

* default undefined ble roles to true

* add sample unittest

* accidental regex in licence removed

* template for ble unit tests

* rename to template

* add readme to unit test folder
pull/14211/head
Paul Szczepanek 2021-01-27 09:37:22 +00:00 committed by GitHub
parent 1b7b620528
commit 78b113b16c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1250 additions and 0 deletions

142
UNITTESTS/stubs/BLE.cpp Normal file
View File

@ -0,0 +1,142 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/
#include "ble/BLE.h"
#include "GattServerImpl_mock.h"
#include "GattClientImpl_mock.h"
#include "GapImpl_mock.h"
#include "SecurityManagerImpl_mock.h"
#include "ble/GattClient.h"
#include "ble/GattServer.h"
#include "ble/SecurityManager.h"
#include "ble/Gap.h"
#include "ble_mocks.h"
namespace ble {
static GapMock *gap_impl = nullptr;
static GattServerMock *gatt_server_impl = nullptr;
static GattClientMock *gatt_client_impl = nullptr;
static SecurityManagerMock *security_manager_impl = nullptr;
static Gap *gap = nullptr;
static GattServer *gatt_server = nullptr;
static GattClient *gatt_client = nullptr;
static SecurityManager *security_manager = nullptr;
GapMock& gap_mock() {
return *ble::gap_impl;
}
GattServerMock& gatt_server_mock() {
return *ble::gatt_server_impl;
}
GattClientMock& gatt_client_mock() {
return *ble::gatt_client_impl;
}
SecurityManagerMock& security_manager_mock() {
return *ble::security_manager_impl;
}
void reset_mocks() {
delete gap;
delete gap_impl;
delete gatt_server;
delete gatt_server_impl;
delete gatt_client;
delete gatt_client_impl;
delete security_manager;
delete security_manager_impl;
/* mocks */
gap_impl = new GapMock();
gatt_server_impl = new GattServerMock();
gatt_client_impl = new GattClientMock();
security_manager_impl = new SecurityManagerMock();
/* user APIS */
gap = new Gap(gap_impl);
gatt_server = new GattServer(gatt_server_impl);
gatt_client = new GattClient(gatt_client_impl);
security_manager = new SecurityManager(security_manager_impl);
}
class BLEInstanceBase {
};
BLE::BLE(ble::BLEInstanceBase &transport) : transport(transport)
{
reset_mocks();
}
BLE& BLE::Instance()
{
static ble::BLEInstanceBase transport;
static BLE instance(transport);
return instance;
}
ble::Gap &BLE::gap()
{
return *ble::gap;
}
ble::GattServer &BLE::gattServer()
{
return *ble::gatt_server;
}
ble::GattClient &BLE::gattClient()
{
return *ble::gatt_client;
}
ble::SecurityManager &BLE::securityManager()
{
return *ble::security_manager;
}
const ble::Gap &BLE::gap() const
{
auto &self = const_cast<BLE &>(*this);
return const_cast<const ble::Gap &>(self.gap());
}
const ble::GattServer &BLE::gattServer() const
{
auto &self = const_cast<BLE &>(*this);
return const_cast<const ble::GattServer &>(self.gattServer());
}
const ble::GattClient &BLE::gattClient() const
{
auto &self = const_cast<BLE &>(*this);
return const_cast<const ble::GattClient &>(self.gattClient());
}
const ble::SecurityManager &BLE::securityManager() const
{
auto &self = const_cast<BLE &>(*this);
return const_cast<const ble::SecurityManager &>(self.securityManager());
}
void BLE::processEvents()
{
}
}

View File

@ -0,0 +1,36 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 BLE_GAPMOCK_H
#define BLE_GAPMOCK_H
#include "gmock/gmock.h"
#include "source/generic/GapImpl.h"
class GapMock : public ble::impl::Gap {
public:
GapMock() {};
GapMock(const GapMock&) = delete;
GapMock& operator=(const GapMock&) = delete;
virtual ~GapMock() {};
MOCK_METHOD0(reset, ble_error_t());
};
#endif //BLE_GAPMOCK_H

View File

@ -0,0 +1,36 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 BLE_GATTCLIENTMOCK_H
#define BLE_GATTCLIENTMOCK_H
#include "gmock/gmock.h"
#include "source/generic/GattClientImpl.h"
class GattClientMock : public ble::impl::GattClient {
public:
GattClientMock() {};
GattClientMock(const GattClientMock&) = delete;
GattClientMock& operator=(const GattClientMock&) = delete;
virtual ~GattClientMock() {};
MOCK_METHOD0(reset, ble_error_t());
};
#endif //BLE_GATTCLIENTMOCK_H

View File

@ -0,0 +1,34 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 BLE_GATTSERVERMOCK_H
#define BLE_GATTSERVERMOCK_H
#include "gmock/gmock.h"
#include "source/GattServerImpl.h"
class GattServerMock : public ble::impl::GattServer {
public:
GattServerMock() {};
GattServerMock(const GattServerMock&) = delete;
GattServerMock& operator=(const GattServerMock&) = delete;
virtual ~GattServerMock() {};
MOCK_METHOD1(reset, ble_error_t(ble::GattServer*));
};
#endif //BLE_GATTSERVERMOCK_H

View File

@ -0,0 +1,36 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 SECURITYMANAGERMOCK_H
#define SECURITYMANAGERMOCK_H
#include "gmock/gmock.h"
#include "source/generic/SecurityManagerImpl.h"
class SecurityManagerMock : public ble::impl::SecurityManager {
public:
SecurityManagerMock() {};
SecurityManagerMock(const GattServerMock&) = delete;
SecurityManagerMock& operator=(const GattServerMock&) = delete;
virtual ~SecurityManagerMock() {};
MOCK_METHOD0(reset, ble_error_t());
};
#endif //SECURITYMANAGERMOCK_H

View File

@ -0,0 +1,42 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 BLE_MOCKS_H
#define BLE_MOCKS_H
#include "GattServerImpl_mock.h"
#include "GattClientImpl_mock.h"
#include "GapImpl_mock.h"
#include "SecurityManagerImpl_mock.h"
/***
* You must use reset_mocks() at the end of the test. To access mocks use:
* gap_mock(), gatt_server_mock(), gatt_client_mock(), security_manager_mock().
* All functions are in namespace ble.
*/
namespace ble {
void reset_mocks();
GapMock& gap_mock();
GattServerMock& gatt_server_mock();
GattClientMock& gatt_client_mock();
SecurityManagerMock& security_manager_mock();
}
#endif // BLE_MOCKS_H

View File

@ -0,0 +1,137 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 BLE_GATTSERVERSTUB_H
#define BLE_GATTSERVERSTUB_H
#include "ble/GattServer.h"
#include "FEATURE_BLE/source/generic/GattServerEvents.h"
#include "ble/Gap.h"
namespace ble {
namespace impl {
class GattServer {
public:
GattServer() {};
GattServer(const GattServer&) = delete;
GattServer& operator=(const GattServer&) = delete;
virtual ~GattServer() {};
using EventHandler = ble::GattServer::EventHandler;
using DataSentCallback_t = ble::GattServer::DataSentCallback_t ;
using DataSentCallbackChain_t = ble::GattServer::DataSentCallbackChain_t ;
using DataWrittenCallback_t = ble::GattServer::DataWrittenCallback_t ;
using DataWrittenCallbackChain_t = ble::GattServer::DataWrittenCallbackChain_t ;
using DataReadCallback_t = ble::GattServer::DataReadCallback_t;
using DataReadCallbackChain_t = ble::GattServer::DataReadCallbackChain_t;
using GattServerShutdownCallback_t = ble::GattServer::GattServerShutdownCallback_t;
using GattServerShutdownCallbackChain_t = ble::GattServer::GattServerShutdownCallbackChain_t;
using EventCallback_t = ble::GattServer::EventCallback_t;
virtual void setEventHandler(EventHandler *handler) { };
virtual ble_error_t reset(ble::GattServer* server) { return BLE_ERROR_NONE; };
virtual ble_error_t addService(GattService &service) { return BLE_ERROR_NONE; };
virtual ble_error_t read(
GattAttribute::Handle_t attributeHandle,
uint8_t buffer[],
uint16_t *lengthP
) { return BLE_ERROR_NONE; };
virtual ble_error_t read(
ble::connection_handle_t connectionHandle,
GattAttribute::Handle_t attributeHandle,
uint8_t *buffer,
uint16_t *lengthP
) { return BLE_ERROR_NONE; };
virtual ble_error_t write(
GattAttribute::Handle_t attributeHandle,
const uint8_t *value,
uint16_t size,
bool localOnly = false
) { return BLE_ERROR_NONE; };
virtual ble_error_t write(
ble::connection_handle_t connectionHandle,
GattAttribute::Handle_t attributeHandle,
const uint8_t *value,
uint16_t size,
bool localOnly = false
) { return BLE_ERROR_NONE; };
virtual ble_error_t areUpdatesEnabled(
const GattCharacteristic &characteristic,
bool *enabledP
) { return BLE_ERROR_NONE; };
virtual ble_error_t areUpdatesEnabled(
ble::connection_handle_t connectionHandle,
const GattCharacteristic &characteristic,
bool *enabledP
) { return BLE_ERROR_NONE; };
virtual ble::Gap::PreferredConnectionParams_t getPreferredConnectionParams() {
ble::Gap::PreferredConnectionParams_t params = {0}; return params;
};
virtual void setPreferredConnectionParams(const ble::Gap::PreferredConnectionParams_t &params) { };
virtual bool isOnDataReadAvailable() const { return true; };
virtual void onDataSent(const DataSentCallback_t &callback) { };
virtual DataSentCallbackChain_t &onDataSent() { static DataSentCallbackChain_t chain; return chain; };
virtual void onDataWritten(const DataWrittenCallback_t &callback) { };
virtual DataWrittenCallbackChain_t &onDataWritten() { static DataWrittenCallbackChain_t chain; return chain; };
virtual ble_error_t onDataRead(const DataReadCallback_t &callback) { return BLE_ERROR_NONE; };
virtual DataReadCallbackChain_t &onDataRead() { static DataReadCallbackChain_t chain; return chain; };
virtual void onShutdown(const GattServerShutdownCallback_t &callback) { };
virtual GattServerShutdownCallbackChain_t &onShutdown() { static GattServerShutdownCallbackChain_t chain; return chain; };
virtual void onUpdatesEnabled(EventCallback_t callback) { };
virtual void onUpdatesDisabled(EventCallback_t callback) { };
virtual void onConfirmationReceived(EventCallback_t callback) { };
virtual void handleDataWrittenEvent(const GattWriteCallbackParams *params) { };
virtual void handleDataReadEvent(const GattReadCallbackParams *params) { };
virtual void handleEvent(
GattServerEvents::gattEvent_e type,
ble::connection_handle_t connHandle,
GattAttribute::Handle_t attributeHandle
) { };
virtual void handleDataSentEvent(unsigned count) { };
};
}
}
#endif //BLE_GATTSERVERSTUB_H

View File

@ -0,0 +1,317 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 BLE_GAPSTUB_H
#define BLE_GAPSTUB_H
namespace ble {
namespace impl {
class Gap {
public:
Gap() {};
Gap(const Gap&) = delete;
Gap& operator=(const Gap&) = delete;
virtual ~Gap() {};
using EventHandler = ::ble::Gap::EventHandler;
using GapShutdownCallback_t = ::ble::Gap::GapShutdownCallback_t;
using GapShutdownCallbackChain_t = ::ble::Gap::GapShutdownCallbackChain_t ;
using PreferredConnectionParams_t = ::ble::Gap::PreferredConnectionParams_t ;
#if BLE_FEATURE_PRIVACY
#if BLE_ROLE_BROADCASTER
static const peripheral_privacy_configuration_t default_peripheral_privacy_configuration;
#endif // BLE_ROLE_BROADCASTER
#if BLE_ROLE_OBSERVER
/**
* Default peripheral privacy configuration.
*/
static const central_privacy_configuration_t default_central_privacy_configuration;
#endif // BLE_ROLE_OBSERVER
#endif // BLE_FEATURE_PRIVACY
public:
virtual void setEventHandler(EventHandler *handler) { };
virtual bool isFeatureSupported(controller_supported_features_t feature) { return true; };
/* advertising */
#if BLE_ROLE_BROADCASTER
virtual uint8_t getMaxAdvertisingSetNumber() { return 1; };
virtual uint16_t getMaxAdvertisingDataLength() { return 23; };
virtual uint16_t getMaxConnectableAdvertisingDataLength() { return 21; };
virtual uint16_t getMaxActiveSetAdvertisingDataLength() { return 21; };
#if BLE_FEATURE_EXTENDED_ADVERTISING
virtual ble_error_t createAdvertisingSet(
advertising_handle_t *handle,
const AdvertisingParameters &parameters
) { return BLE_ERROR_NONE; };
virtual ble_error_t destroyAdvertisingSet(advertising_handle_t handle) { return BLE_ERROR_NONE; };
#endif // BLE_FEATURE_EXTENDED_ADVERTISING
virtual ble_error_t setAdvertisingParameters(
advertising_handle_t handle,
const AdvertisingParameters &params
) { return BLE_ERROR_NONE; };
virtual ble_error_t setAdvertisingPayload(
advertising_handle_t handle,
mbed::Span<const uint8_t> payload
) { return BLE_ERROR_NONE; };
virtual ble_error_t setAdvertisingScanResponse(
advertising_handle_t handle,
mbed::Span<const uint8_t> response
) { return BLE_ERROR_NONE; };
virtual ble_error_t startAdvertising(
advertising_handle_t handle,
adv_duration_t maxDuration = adv_duration_t::forever(),
uint8_t maxEvents = 0
) { return BLE_ERROR_NONE; };
virtual ble_error_t stopAdvertising(advertising_handle_t handle) { return BLE_ERROR_NONE; };
virtual bool isAdvertisingActive(advertising_handle_t handle) { return true; };
#endif // BLE_ROLE_BROADCASTER
#if BLE_ROLE_BROADCASTER
#if BLE_FEATURE_PERIODIC_ADVERTISING
virtual ble_error_t setPeriodicAdvertisingParameters(
advertising_handle_t handle,
periodic_interval_t periodicAdvertisingIntervalMin,
periodic_interval_t periodicAdvertisingIntervalMax,
bool advertiseTxPower = true
) { return BLE_ERROR_NONE; };
virtual ble_error_t setPeriodicAdvertisingPayload(
advertising_handle_t handle,
mbed::Span<const uint8_t> payload
) { return BLE_ERROR_NONE; };
virtual ble_error_t startPeriodicAdvertising(advertising_handle_t handle) { return BLE_ERROR_NONE; };
virtual ble_error_t stopPeriodicAdvertising(advertising_handle_t handle) { return BLE_ERROR_NONE; };
virtual bool isPeriodicAdvertisingActive(advertising_handle_t handle) { return true; };
#endif // BLE_ROLE_BROADCASTER
#endif // BLE_FEATURE_PERIODIC_ADVERTISING
/* scanning */
#if BLE_ROLE_OBSERVER
virtual ble_error_t setScanParameters(const ScanParameters &params) { return BLE_ERROR_NONE; };
virtual ble_error_t startScan(
scan_duration_t duration = scan_duration_t::forever(),
duplicates_filter_t filtering = duplicates_filter_t::DISABLE,
scan_period_t period = scan_period_t(0)
) { return BLE_ERROR_NONE; };
virtual ble_error_t initiate_scan() { return BLE_ERROR_NONE; };
virtual ble_error_t stopScan() { return BLE_ERROR_NONE; };
#endif // BLE_ROLE_OBSERVER
#if BLE_ROLE_OBSERVER
#if BLE_FEATURE_PERIODIC_ADVERTISING
virtual ble_error_t createSync(
peer_address_type_t peerAddressType,
const address_t &peerAddress,
uint8_t sid,
slave_latency_t maxPacketSkip,
sync_timeout_t timeout
) { return BLE_ERROR_NONE; };
virtual ble_error_t createSync(
slave_latency_t maxPacketSkip,
sync_timeout_t timeout
) { return BLE_ERROR_NONE; };
virtual ble_error_t cancelCreateSync() { return BLE_ERROR_NONE; };
virtual ble_error_t terminateSync(periodic_sync_handle_t handle) { return BLE_ERROR_NONE; };
virtual ble_error_t addDeviceToPeriodicAdvertiserList(
peer_address_type_t peerAddressType,
const address_t &peerAddress,
advertising_sid_t sid
) { return BLE_ERROR_NONE; };
virtual ble_error_t removeDeviceFromPeriodicAdvertiserList(
peer_address_type_t peerAddressType,
const address_t &peerAddress,
advertising_sid_t sid
) { return BLE_ERROR_NONE; };
virtual ble_error_t clearPeriodicAdvertiserList() { return BLE_ERROR_NONE; };
uint8_t getMaxPeriodicAdvertiserListSize() { return 1; };
#endif // BLE_ROLE_OBSERVER
#endif // BLE_FEATURE_PERIODIC_ADVERTISING
#if BLE_ROLE_CENTRAL
virtual ble_error_t connect(
peer_address_type_t peerAddressType,
const address_t &peerAddress,
const ConnectionParameters &connectionParams
) { return BLE_ERROR_NONE; };
virtual ble_error_t cancelConnect() { return BLE_ERROR_NONE; };
#endif // BLE_ROLE_CENTRAL
#if BLE_FEATURE_CONNECTABLE
virtual ble_error_t updateConnectionParameters(
connection_handle_t connectionHandle,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t supervision_timeout,
conn_event_length_t minConnectionEventLength = conn_event_length_t(0),
conn_event_length_t maxConnectionEventLength = conn_event_length_t(0)
) { return BLE_ERROR_NONE; };
virtual ble_error_t manageConnectionParametersUpdateRequest(
bool userManageConnectionUpdateRequest
) { return BLE_ERROR_NONE; };
virtual ble_error_t acceptConnectionParametersUpdate(
connection_handle_t connectionHandle,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t supervision_timeout,
conn_event_length_t minConnectionEventLength = conn_event_length_t(0),
conn_event_length_t maxConnectionEventLength = conn_event_length_t(0)
) { return BLE_ERROR_NONE; };
virtual ble_error_t rejectConnectionParametersUpdate(
connection_handle_t connectionHandle
) { return BLE_ERROR_NONE; };
virtual ble_error_t disconnect(
connection_handle_t connectionHandle,
local_disconnection_reason_t reason
) { return BLE_ERROR_NONE; };
#endif // BLE_FEATURE_CONNECTABLE
#if BLE_FEATURE_PHY_MANAGEMENT
virtual ble_error_t readPhy(connection_handle_t connection) { return BLE_ERROR_NONE; };
virtual ble_error_t setPreferredPhys(
const phy_set_t *txPhys,
const phy_set_t *rxPhys
) { return BLE_ERROR_NONE; };
virtual ble_error_t setPhy(
connection_handle_t connection,
const phy_set_t *txPhys,
const phy_set_t *rxPhys,
coded_symbol_per_bit_t codedSymbol
) { return BLE_ERROR_NONE; };
#endif // BLE_FEATURE_PHY_MANAGEMENT
#if BLE_FEATURE_PRIVACY
virtual ble_error_t enablePrivacy(bool enable) { return BLE_ERROR_NONE; };
#if BLE_ROLE_BROADCASTER
virtual ble_error_t setPeripheralPrivacyConfiguration(
const peripheral_privacy_configuration_t *configuration
) { return BLE_ERROR_NONE; };
virtual ble_error_t getPeripheralPrivacyConfiguration(
peripheral_privacy_configuration_t *configuration
) { return BLE_ERROR_NONE; };
#endif // BLE_ROLE_BROADCASTER
#if BLE_ROLE_OBSERVER
virtual ble_error_t setCentralPrivacyConfiguration(
const central_privacy_configuration_t *configuration
) { return BLE_ERROR_NONE; };
virtual ble_error_t getCentralPrivacyConfiguration(
central_privacy_configuration_t *configuration
) { return BLE_ERROR_NONE; };
#endif // BLE_ROLE_OBSERVER
#endif // BLE_FEATURE_PRIVACY
#if BLE_FEATURE_WHITELIST
virtual uint8_t getMaxWhitelistSize() const { return 1; };
virtual ble_error_t getWhitelist(whitelist_t &whitelist) const { return BLE_ERROR_NONE; };
virtual ble_error_t setWhitelist(const whitelist_t &whitelist) { return BLE_ERROR_NONE; };
#endif // BLE_FEATURE_WHITELIST
virtual ble_error_t getAddress(
own_address_type_t &typeP,
address_t &address
) { return BLE_ERROR_NONE; };
static ble_error_t getRandomAddressType(
ble::address_t address,
ble::random_address_type_t *addressType
) { return BLE_ERROR_NONE;};
virtual ble_error_t reset() { return BLE_ERROR_NONE; };
virtual void onShutdown(const GapShutdownCallback_t &callback) { };
virtual GapShutdownCallbackChain_t &onShutdown() { static GapShutdownCallbackChain_t chain; return chain; };
/*
* API reserved for the controller driver to set the random static address.
* Setting a new random static address while the controller is operating is
* forbidden by the Bluetooth specification.
*/
virtual ble_error_t setRandomStaticAddress(const ble::address_t &address) { return BLE_ERROR_NONE; };
virtual ble::address_t getRandomStaticAddress() { return ble::address_t(); };
};
}
}
#endif //BLE_GAPSTUB_H

View File

@ -0,0 +1,134 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 BLE_GATTCLIENTSTUB_H
#define BLE_GATTCLIENTSTUB_H
#include "events/EventQueue.h"
#include "events/mbed_events.h"
namespace ble {
namespace impl {
class GattClient {
public:
using EventHandler = ble::GattClient::EventHandler;
using WriteOp_t = ble::GattClient::WriteOp_t;
using HVXCallback_t = ble::GattClient::HVXCallback_t ;
using GattClientShutdownCallback_t = ble::GattClient::GattClientShutdownCallback_t ;
using GattClientShutdownCallbackChain_t = ble::GattClient::GattClientShutdownCallbackChain_t ;
using HVXCallbackChain_t = ble::GattClient::HVXCallbackChain_t ;
using ReadCallbackChain_t = ble::GattClient::ReadCallbackChain_t ;
using WriteCallbackChain_t = ble::GattClient::WriteCallbackChain_t ;
GattClient() {};
GattClient(const GattClient&) = delete;
GattClient& operator=(const GattClient&) = delete;
virtual ~GattClient() {};
virtual void setEventHandler(EventHandler *handler) { };
virtual ble_error_t launchServiceDiscovery(
ble::connection_handle_t connectionHandle,
ServiceDiscovery::ServiceCallback_t sc = nullptr,
ServiceDiscovery::CharacteristicCallback_t cc = nullptr,
const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)
) { return BLE_ERROR_NONE; };
virtual ble_error_t discoverServices(
ble::connection_handle_t connectionHandle,
ServiceDiscovery::ServiceCallback_t callback,
const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)
) { return BLE_ERROR_NONE; };
virtual ble_error_t discoverServices(
ble::connection_handle_t connectionHandle,
ServiceDiscovery::ServiceCallback_t callback,
GattAttribute::Handle_t startHandle,
GattAttribute::Handle_t endHandle
) { return BLE_ERROR_NONE; };
virtual bool isServiceDiscoveryActive(void) const { return true; };
virtual void terminateServiceDiscovery(void) { };
virtual ble_error_t read(
ble::connection_handle_t connHandle,
GattAttribute::Handle_t attributeHandle,
uint16_t offset
) const { return BLE_ERROR_NONE; };
virtual ble_error_t write(
GattClient::WriteOp_t cmd,
ble::connection_handle_t connHandle,
GattAttribute::Handle_t attributeHandle,
size_t length,
const uint8_t *value
) const { return BLE_ERROR_NONE; };
/* Event callback handlers. */
virtual void onDataRead(ReadCallback_t callback) { };
virtual ReadCallbackChain_t &onDataRead() { static ReadCallbackChain_t chain; return chain; };
virtual void onDataWritten(WriteCallback_t callback) { };
virtual WriteCallbackChain_t &onDataWritten() { static WriteCallbackChain_t chain; return chain; };
virtual void onServiceDiscoveryTermination(
ServiceDiscovery::TerminationCallback_t callback
) { };
virtual ble_error_t discoverCharacteristicDescriptors(
const DiscoveredCharacteristic &characteristic,
const CharacteristicDescriptorDiscovery::DiscoveryCallback_t &discoveryCallback,
const CharacteristicDescriptorDiscovery::TerminationCallback_t &terminationCallback
) { return BLE_ERROR_NONE; };
virtual bool isCharacteristicDescriptorDiscoveryActive(
const DiscoveredCharacteristic &characteristic
) const { return true; };
virtual void terminateCharacteristicDescriptorDiscovery(
const DiscoveredCharacteristic &characteristic
) { };
virtual ble_error_t negotiateAttMtu(ble::connection_handle_t connection) { return BLE_ERROR_NONE; };
virtual void onHVX(HVXCallback_t callback) { };
virtual void onShutdown(const GattClientShutdownCallback_t &callback) { };
virtual GattClientShutdownCallbackChain_t &onShutdown() { static GattClientShutdownCallbackChain_t chain; return chain; };
virtual HVXCallbackChain_t &onHVX() { static HVXCallbackChain_t chain; return chain; };
virtual ble_error_t reset(void) { return BLE_ERROR_NONE; };
virtual void processReadResponse(const GattReadCallbackParams *params) { };
virtual void processWriteResponse(const GattWriteCallbackParams *params) { };
virtual void processHVXEvent(const GattHVXCallbackParams *params) { };
};
}
}
#endif //BLE_GATTCLIENTSTUB_H

View File

@ -0,0 +1,186 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 SECURITYMANAGERSTUB_H
#define SECURITYMANAGERSTUB_H
namespace ble {
namespace impl {
class SecurityManager {
public:
SecurityManager() {};
SecurityManager(const SecurityManager&) = delete;
SecurityManager& operator=(const SecurityManager&) = delete;
virtual ~SecurityManager() {};
using SecurityIOCapabilities_t = ble::SecurityManager::SecurityIOCapabilities_t;
using SecurityMode_t = ble::SecurityManager::SecurityMode_t;
using SecurityManagerShutdownCallback_t = ble::SecurityManager::SecurityManagerShutdownCallback_t;
using SecurityManagerShutdownCallbackChain_t = ble::SecurityManager::SecurityManagerShutdownCallbackChain_t;
using EventHandler = ble::SecurityManager::EventHandler;
using Passkey_t = ble::SecurityManager::Passkey_t ;
static auto constexpr IO_CAPS_NONE = ble::SecurityManager::IO_CAPS_NONE;
virtual ble_error_t init(
bool enableBonding = true,
bool requireMITM = true,
SecurityIOCapabilities_t iocaps = IO_CAPS_NONE,
const Passkey_t passkey = nullptr,
bool signing = true,
const char *dbFilepath = nullptr
) { return BLE_ERROR_NONE; };
virtual ble_error_t setDatabaseFilepath(const char *dbFilepath = nullptr) { return BLE_ERROR_NONE; };
virtual ble_error_t reset() { return BLE_ERROR_NONE; };
virtual ble_error_t preserveBondingStateOnReset(bool enable) { return BLE_ERROR_NONE; };
////////////////////////////////////////////////////////////////////////////
// List management
//
virtual ble_error_t purgeAllBondingState() { return BLE_ERROR_NONE; };
virtual ble_error_t generateWhitelistFromBondTable(::ble::whitelist_t *whitelist) const { return BLE_ERROR_NONE; };
////////////////////////////////////////////////////////////////////////////
// Pairing
//
#if BLE_ROLE_CENTRAL
virtual ble_error_t requestPairing(ble::connection_handle_t connectionHandle) { return BLE_ERROR_NONE; };
#endif // BLE_ROLE_CENTRAL
#if BLE_ROLE_PERIPHERAL
virtual ble_error_t acceptPairingRequest(ble::connection_handle_t connectionHandle) { return BLE_ERROR_NONE; };
#endif // BLE_ROLE_PERIPHERAL
virtual ble_error_t cancelPairingRequest(ble::connection_handle_t connectionHandle) { return BLE_ERROR_NONE; };
virtual ble_error_t setPairingRequestAuthorisation(bool required = true) { return BLE_ERROR_NONE; };
virtual ble_error_t getPeerIdentity(ble::connection_handle_t connectionHandle) { return BLE_ERROR_NONE; };
////////////////////////////////////////////////////////////////////////////
// Feature support
//
#if BLE_FEATURE_SECURE_CONNECTIONS
virtual ble_error_t allowLegacyPairing(bool allow = true) { return BLE_ERROR_NONE; };
virtual ble_error_t getSecureConnectionsSupport(bool *enabled) { return BLE_ERROR_NONE; };
#endif // BLE_FEATURE_SECURE_CONNECTIONS
////////////////////////////////////////////////////////////////////////////
// Security settings
//
virtual ble_error_t setIoCapability(SecurityIOCapabilities_t iocaps) { return BLE_ERROR_NONE; };
virtual ble_error_t setDisplayPasskey(const Passkey_t passkey) { return BLE_ERROR_NONE; };
virtual ble_error_t setLinkSecurity(ble::connection_handle_t connectionHandle, SecurityMode_t securityMode) { return BLE_ERROR_NONE; };
virtual ble_error_t setKeypressNotification(bool enabled = true) { return BLE_ERROR_NONE; };
#if BLE_FEATURE_SIGNING
virtual ble_error_t enableSigning(ble::connection_handle_t connectionHandle, bool enabled = true) { return BLE_ERROR_NONE; };
#endif // BLE_FEATURE_SIGNING
virtual ble_error_t setHintFutureRoleReversal(bool enable = true) { return BLE_ERROR_NONE; };
////////////////////////////////////////////////////////////////////////////
// Encryption
//
virtual ble_error_t getLinkEncryption(ble::connection_handle_t connectionHandle, ble::link_encryption_t *encryption) { return BLE_ERROR_NONE; };
virtual ble_error_t setLinkEncryption(ble::connection_handle_t connectionHandle, ble::link_encryption_t encryption) { return BLE_ERROR_NONE; };
virtual ble_error_t setEncryptionKeyRequirements(uint8_t minimumByteSize, uint8_t maximumByteSize) { return BLE_ERROR_NONE; };
virtual ble_error_t getEncryptionKeySize(
connection_handle_t connectionHandle,
uint8_t *size
) { return BLE_ERROR_NONE; };
////////////////////////////////////////////////////////////////////////////
// Authentication
//
virtual ble_error_t requestAuthentication(ble::connection_handle_t connectionHandle) { return BLE_ERROR_NONE; };
////////////////////////////////////////////////////////////////////////////
// MITM
//
virtual ble_error_t generateOOB(const ble::address_t *address) { return BLE_ERROR_NONE; };
virtual ble_error_t setOOBDataUsage(ble::connection_handle_t connectionHandle, bool useOOB, bool OOBProvidesMITM = true) { return BLE_ERROR_NONE; };
virtual ble_error_t passkeyEntered(ble::connection_handle_t connectionHandle, Passkey_t passkey) { return BLE_ERROR_NONE; };
virtual ble_error_t legacyPairingOobReceived(const ble::address_t *address, const ble::oob_tk_t *tk) { return BLE_ERROR_NONE; };
#if BLE_FEATURE_SECURE_CONNECTIONS
virtual ble_error_t confirmationEntered(ble::connection_handle_t connectionHandle, bool confirmation) { return BLE_ERROR_NONE; };
virtual ble_error_t sendKeypressNotification(ble::connection_handle_t connectionHandle, ble::Keypress_t keypress) { return BLE_ERROR_NONE; };
virtual ble_error_t oobReceived(
const ble::address_t *address,
const ble::oob_lesc_value_t *random,
const ble::oob_confirm_t *confirm
) { return BLE_ERROR_NONE; };
#endif // BLE_FEATURE_SECURE_CONNECTIONS
////////////////////////////////////////////////////////////////////////////
// Keys
//
#if BLE_FEATURE_SIGNING
virtual ble_error_t getSigningKey(ble::connection_handle_t connectionHandle, bool authenticated) { return BLE_ERROR_NONE; };
#endif // BLE_FEATURE_SIGNING
////////////////////////////////////////////////////////////////////////////
// Privacy
//
#if BLE_FEATURE_PRIVACY
virtual ble_error_t setPrivateAddressTimeout(
uint16_t timeout_in_seconds
) { return BLE_ERROR_NONE; };
#endif // BLE_FEATURE_PRIVACY
/* Event callback handlers. */
public:
virtual void onShutdown(const SecurityManagerShutdownCallback_t &callback) { };
template<typename T>
void onShutdown(T *objPtr, void (T::*memberPtr)(const SecurityManager *)) { };
virtual SecurityManagerShutdownCallbackChain_t &onShutdown() { static SecurityManagerShutdownCallbackChain_t chain; return chain; };
virtual void setSecurityManagerEventHandler(EventHandler *handler) { };
};
}
}
#endif //SECURITYMANAGERSTUB_H

View File

@ -19,6 +19,49 @@
#ifndef MBED_BLE_ROLES_H__
#define MBED_BLE_ROLES_H__
#if !defined(BLE_ROLE_OBSERVER)
#define BLE_ROLE_OBSERVER 1
#endif
#if !defined(BLE_ROLE_BROADCASTER)
#define BLE_ROLE_BROADCASTER 1
#endif
#if !defined(BLE_ROLE_CENTRAL)
#define BLE_ROLE_CENTRAL 1
#endif
#if !defined(BLE_ROLE_PERIPHERAL)
#define BLE_ROLE_PERIPHERAL 1
#endif
#if !defined(BLE_FEATURE_GATT_CLIENT)
#define BLE_FEATURE_GATT_CLIENT 1
#endif
#if !defined(BLE_FEATURE_GATT_SERVER)
#define BLE_FEATURE_GATT_SERVER 1
#endif
#if !defined(BLE_FEATURE_SECURITY)
#define BLE_FEATURE_SECURITY 1
#endif
#if !defined(BLE_FEATURE_SECURE_CONNECTIONS)
#define BLE_FEATURE_SECURE_CONNECTIONS 1
#endif
#if !defined(BLE_FEATURE_SIGNING)
#define BLE_FEATURE_SIGNING 1
#endif
#if !defined(BLE_FEATURE_WHITELIST)
#define BLE_FEATURE_WHITELIST 1
#endif
#if !defined(BLE_FEATURE_PRIVACY)
#define BLE_FEATURE_PRIVACY 1
#endif
#if !defined(BLE_FEATURE_PHY_MANAGEMENT)
#define BLE_FEATURE_PHY_MANAGEMENT 1
#endif
#if !defined(BLE_FEATURE_EXTENDED_ADVERTISING)
#define BLE_FEATURE_EXTENDED_ADVERTISING 1
#endif
#if !defined(BLE_FEATURE_PERIODIC_ADVERTISING)
#define BLE_FEATURE_PERIODIC_ADVERTISING 1
#endif
#if !(BLE_ROLE_OBSERVER) && !(BLE_ROLE_BROADCASTER)
#error "BLE requires at least one role 'BROADCASTER' or 'OBSERVER' to be enabled"
#endif

View File

@ -0,0 +1,8 @@
# BLE unit testing
The [ble_template](./ble_template) contains a template you can use as a starting point for writing unit tests
for you application or library that uses the BLE API.
Copy the template into another directory (must be under UNITTESTS) and add your tests to the cpp file.
Please refer to [Mbed OS BLE introduction](https://os.mbed.com/docs/latest/apis/ble.html) for details.

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2020, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/
#include "gtest/gtest.h"
#include "ble/BLE.h"
#include "ble/Gap.h"
#include "ble/GattServer.h"
#include "ble/GattClient.h"
#include "ble/SecurityManager.h"
#include "ble_mocks.h"
/* This test does not test anything, you may use it as a template for your unit tests.
* It shows all the elements you need to use mocks for all the ble APIS. */
class TestBLE : public testing::Test {
protected:
void SetUp()
{
ble = &BLE::Instance();
}
void TearDown()
{
}
BLE* ble;
};
TEST_F(TestBLE, reset)
{
/* these are the user facing APIs */
Gap &gap = ble->gap();
GattClient &client = ble->gattClient();
GattServer &server = ble->gattServer();
SecurityManager &sm = ble->securityManager();
/* they in turn call the implementations which are mocked and can have expectations set on them */
EXPECT_CALL(ble::gap_mock(), reset());
EXPECT_CALL(ble::gatt_client_mock(), reset());
EXPECT_CALL(ble::gatt_server_mock(), reset(&server)); /* this reset contains pointer to user API */
EXPECT_CALL(ble::security_manager_mock(), reset());
/* calls are made on real APIs but will fulfill expectations on the mocks as that's what they call in the end */
gap.reset();
client.reset();
server.reset();
sm.reset();
/* remember you must call this at the end of the test if you have any expectations set */
ble::reset_mocks();
}

View File

@ -0,0 +1,32 @@
####################
# UNIT TESTS
####################
# Add test specific include paths
set(unittest-includes ${unittest-includes}
../connectivity/FEATURE_BLE/include/ble
../connectivity/FEATURE_BLE/include
../connectivity
)
# Source files
set(unittest-sources
../connectivity/FEATURE_BLE/source/gap/AdvertisingDataBuilder.cpp
../connectivity/FEATURE_BLE/source/gap/AdvertisingParameters.cpp
../connectivity/FEATURE_BLE/source/gap/ConnectionParameters.cpp
../connectivity/FEATURE_BLE/source/gatt/DiscoveredCharacteristic.cpp
../connectivity/FEATURE_BLE/source/Gap.cpp
../connectivity/FEATURE_BLE/source/GattClient.cpp
../connectivity/FEATURE_BLE/source/GattServer.cpp
../connectivity/FEATURE_BLE/source/SecurityManager.cpp
)
# Test files
set(unittest-test-sources
${CMAKE_CURRENT_LIST_DIR}/ble.cpp
stubs/BLE.cpp
)
set(unittest-test-flags
-DMBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE=115200
)