Modify shutdown due to BLE API change

The module is updated to comply with the changes to BLE API regarding correct
shutdown functionality. The following changes are introduced to ble-nrf51822:

* Calls to the old static function shutdown in Gap, GattClient, GattServer and
SecurityManager are removed.
* The cleanup function in Gap, GattClient, GattServer and SecurityManager is
renamed to `reset()` and made public.
* The static references inside nRF5xGap, nRF5xGattClient, nRF5xGattServer and
nRF5xSecurityManager to objects of their own class are moved to nRF5xn.
* The static getInstance accessors in nRF5xGap, nRF5xGattClient,
nRF5xGattServer and nRF5xSecurityManager are removed and their functionality is
moved to the implemented virtual accessors in nRF5xn i.e. getGap(),
getGattClient, etc.
* A static function Instance is added to nRF5xn class to make the transport
object accessible across the module.
This commit is contained in:
Andres Amaya Garcia 2015-12-14 15:15:35 +00:00
parent 0429643609
commit 0bcc2e96c9
14 changed files with 257 additions and 129 deletions

View file

@ -27,9 +27,7 @@
#include "custom/custom_helper.h"
#include "ble/GapEvents.h"
#include "nRF5xGap.h"
#include "nRF5xGattServer.h"
#include "nRF5xSecurityManager.h"
#include "nRF5xn.h"
extern "C" {
#include "pstorage.h"
@ -138,6 +136,11 @@ static void btle_handler(ble_evt_t *p_ble_evt)
bleGattcEventHandler(p_ble_evt);
#endif
nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
nRF5xGap &gap = (nRF5xGap &) ble.getGap();
nRF5xGattServer &gattServer = (nRF5xGattServer &) ble.getGattServer();
nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
/* Custom event handler */
switch (p_ble_evt->header.evt_id) {
case BLE_GAP_EVT_CONNECTED: {
@ -148,11 +151,11 @@ static void btle_handler(ble_evt_t *p_ble_evt)
#else
Gap::Role_t role = static_cast<Gap::Role_t>(p_ble_evt->evt.gap_evt.params.connected.role);
#endif
nRF5xGap::getInstance().setConnectionHandle(handle);
gap.setConnectionHandle(handle);
const Gap::ConnectionParams_t *params = reinterpret_cast<Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params));
const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr;
const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr;
nRF5xGap::getInstance().processConnectionEvent(handle,
gap.processConnectionEvent(handle,
role,
static_cast<Gap::AddressType_t>(peer->addr_type), peer->addr,
static_cast<Gap::AddressType_t>(own->addr_type), own->addr,
@ -164,7 +167,7 @@ static void btle_handler(ble_evt_t *p_ble_evt)
Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
// Since we are not in a connection and have not started advertising,
// store bonds
nRF5xGap::getInstance().setConnectionHandle (BLE_CONN_HANDLE_INVALID);
gap.setConnectionHandle (BLE_CONN_HANDLE_INVALID);
Gap::DisconnectionReason_t reason;
switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) {
@ -183,16 +186,16 @@ static void btle_handler(ble_evt_t *p_ble_evt)
reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason);
break;
}
nRF5xGap::getInstance().processDisconnectionEvent(handle, reason);
gap.processDisconnectionEvent(handle, reason);
break;
}
case BLE_GAP_EVT_PASSKEY_DISPLAY:
nRF5xSecurityManager::getInstance().processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
securityManager.processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
break;
case BLE_GAP_EVT_TIMEOUT:
nRF5xGap::getInstance().processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
gap.processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
break;
case BLE_GATTC_EVT_TIMEOUT:
@ -204,12 +207,12 @@ static void btle_handler(ble_evt_t *p_ble_evt)
case BLE_GAP_EVT_ADV_REPORT: {
const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report;
nRF5xGap::getInstance().processAdvertisementReport(advReport->peer_addr.addr,
advReport->rssi,
advReport->scan_rsp,
static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type),
advReport->dlen,
advReport->data);
gap.processAdvertisementReport(advReport->peer_addr.addr,
advReport->rssi,
advReport->scan_rsp,
static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type),
advReport->dlen,
advReport->data);
break;
}
@ -217,7 +220,7 @@ static void btle_handler(ble_evt_t *p_ble_evt)
break;
}
nRF5xGattServer::getInstance().hwCallback(p_ble_evt);
gattServer.hwCallback(p_ble_evt);
}
/*! @brief Callback when an error occurs inside the SoftDevice */

View file

@ -14,13 +14,15 @@
* limitations under the License.
*/
#include "nRF5xServiceDiscovery.h"
#include "nRF5xGattClient.h"
#include "nRF5xn.h"
#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
{
nRF5xServiceDiscovery &sdSingleton = nRF5xGattClient::getInstance().discovery;
nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
nRF5xGap &gap = (nRF5xGap &) ble.getGap();
nRF5xGattClient &gattClient = (nRF5xGattClient &) ble.getGattClient();
nRF5xServiceDiscovery &sdSingleton = gattClient.discovery;
switch (p_ble_evt->header.evt_id) {
case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
@ -63,7 +65,7 @@ void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
.len = p_ble_evt->evt.gattc_evt.params.read_rsp.len,
.data = p_ble_evt->evt.gattc_evt.params.read_rsp.data,
};
nRF5xGattClient::getInstance().processReadResponse(&response);
gattClient.processReadResponse(&response);
}
break;
@ -76,7 +78,7 @@ void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
.len = p_ble_evt->evt.gattc_evt.params.write_rsp.len,
.data = p_ble_evt->evt.gattc_evt.params.write_rsp.data,
};
nRF5xGattClient::getInstance().processWriteResponse(&response);
gattClient.processWriteResponse(&response);
}
break;
@ -88,7 +90,7 @@ void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
params.len = p_ble_evt->evt.gattc_evt.params.hvx.len;
params.data = p_ble_evt->evt.gattc_evt.params.hvx.data;
nRF5xGattClient::getInstance().processHVXEvent(&params);
gattClient.processHVXEvent(&params);
}
break;
}

View file

@ -16,8 +16,7 @@
#include "btle.h"
#include "nRF5xGap.h"
#include "nRF5xSecurityManager.h"
#include "nRF5xn.h"
extern "C" {
#include "pstorage.h"
@ -204,17 +203,20 @@ btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMo
ret_code_t
dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result)
{
nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
switch (p_event->event_id) {
case DM_EVT_SECURITY_SETUP: /* started */ {
const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params;
nRF5xSecurityManager::getInstance().processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
securityManager.processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
peerParams->bond,
peerParams->mitm,
(SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
break;
}
case DM_EVT_SECURITY_SETUP_COMPLETE:
nRF5xSecurityManager::getInstance().
securityManager.
processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle,
(SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status));
break;
@ -248,11 +250,11 @@ dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t ev
break;
}
nRF5xSecurityManager::getInstance().processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
securityManager.processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
break;
}
case DM_EVT_DEVICE_CONTEXT_STORED:
nRF5xSecurityManager::getInstance().processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
securityManager.processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
break;
default:
break;

View file

@ -14,23 +14,17 @@
* limitations under the License.
*/
#include "nRF5xGap.h"
#include "nRF5xn.h"
#include "mbed.h"
#include "ble/BLE.h"
#include "common/common.h"
#include "ble_advdata.h"
#include "ble_hci.h"
nRF5xGap &nRF5xGap::getInstance() {
static nRF5xGap m_instance;
if (gapInstance == NULL) {
gapInstance = &m_instance;
}
return m_instance;
}
void radioNotificationStaticCallback(bool param) {
nRF5xGap::getInstance().processRadioNotificationEvent(param);
nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
gap.processRadioNotificationEvent(param);
}
/**************************************************************************/
@ -349,10 +343,10 @@ ble_error_t nRF5xGap::updateConnectionParams(Handle_t handle, const ConnectionPa
Everything executed properly
*/
/**************************************************************************/
ble_error_t nRF5xGap::cleanup(void)
ble_error_t nRF5xGap::reset(void)
{
/* Clear all state that is from the parent, including private members */
if (Gap::cleanup() != BLE_ERROR_NONE) {
if (Gap::reset() != BLE_ERROR_NONE) {
return BLE_ERROR_INVALID_STATE;
}

View file

@ -44,8 +44,6 @@ void radioNotificationStaticCallback(bool param);
class nRF5xGap : public Gap
{
public:
static nRF5xGap &getInstance();
/* Functions that must be implemented from Gap */
virtual ble_error_t setAddress(AddressType_t type, const Address_t address);
virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address);
@ -76,6 +74,8 @@ public:
virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params);
virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params);
virtual ble_error_t reset(void);
virtual ble_error_t initRadioNotification(void) {
if (ble_radio_notification_init(NRF_APP_PRIORITY_HIGH, NRF_RADIO_NOTIFICATION_DISTANCE_800US, radioNotificationStaticCallback) == NRF_SUCCESS) {
return BLE_ERROR_NONE;
@ -112,9 +112,6 @@ public:
}
#endif
protected:
virtual ble_error_t cleanup(void);
private:
bool radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */
Timeout radioNotificationTimeout;
@ -199,6 +196,12 @@ private:
private:
uint16_t m_connectionHandle;
/*
* Allow instantiation from nRF5xn when required.
*/
friend class nRF5xn;
nRF5xGap() {
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
}

View file

@ -16,14 +16,6 @@
#include "nRF5xGattClient.h"
nRF5xGattClient &
nRF5xGattClient::getInstance(void) {
if (gattClientInstance == NULL) {
gattClientInstance = new nRF5xGattClient();
}
return (nRF5xGattClient &) *gattClientInstance;
}
#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
ble_error_t
nRF5xGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle,

View file

@ -23,8 +23,6 @@
class nRF5xGattClient : public GattClient
{
public:
static nRF5xGattClient &getInstance();
/**
* When using S110, all Gatt client features will return
* BLE_ERROR_NOT_IMPLEMENTED
@ -147,26 +145,30 @@ public:
}
}
protected:
/**
* @brief Clear nRF5xGattClient's state.
*
* @return
* BLE_ERROR_NONE if successful.
*/
virtual ble_error_t cleanup(void) {
virtual ble_error_t reset(void) {
/* Clear all state that is from the parent, including private members */
if (GattClient::cleanup() != BLE_ERROR_NONE) {
if (GattClient::reset() != BLE_ERROR_NONE) {
return BLE_ERROR_INVALID_STATE;
}
/* Clear derived class members */
discovery.cleanup();
discovery.reset();
return BLE_ERROR_NONE;
}
public:
/*
* Allow instantiation from nRF5xn when required.
*/
friend class nRF5xn;
nRF5xGattClient() : discovery(this) {
/* empty */
}

View file

@ -20,14 +20,7 @@
#include "common/common.h"
#include "btle/custom/custom_helper.h"
#include "nRF5xGap.h"
nRF5xGattServer &nRF5xGattServer::getInstance(void) {
if (gattServerInstance == NULL) {
gattServerInstance = new nRF5xGattServer();
}
return (nRF5xGattServer &) *gattServerInstance;
}
#include "nRF5xn.h"
/**************************************************************************/
/*!
@ -243,7 +236,8 @@ ble_error_t nRF5xGattServer::write(Gap::Handle_t connectionHandle, GattAttribute
hvx_params.p_len = &len;
if (connectionHandle == BLE_CONN_HANDLE_INVALID) { /* use the default connection handle if the caller hasn't specified a valid connectionHandle. */
connectionHandle = nRF5xGap::getInstance().getConnectionHandle();
nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
connectionHandle = gap.getConnectionHandle();
}
error_t error = (error_t) sd_ble_gatts_hvx(connectionHandle, &hvx_params);
if (error != ERROR_NONE) {
@ -282,7 +276,8 @@ ble_error_t nRF5xGattServer::write(Gap::Handle_t connectionHandle, GattAttribute
ble_error_t nRF5xGattServer::areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP)
{
/* Forward the call with the default connection handle. */
return areUpdatesEnabled(nRF5xGap::getInstance().getConnectionHandle(), characteristic, enabledP);
nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
return areUpdatesEnabled(gap.getConnectionHandle(), characteristic, enabledP);
}
ble_error_t nRF5xGattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP)
@ -322,10 +317,10 @@ ble_error_t nRF5xGattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, c
Everything executed properly
*/
/**************************************************************************/
ble_error_t nRF5xGattServer::cleanup(void)
ble_error_t nRF5xGattServer::reset(void)
{
/* Clear all state that is from the parent, including private members */
if (GattServer::cleanup() != BLE_ERROR_NONE) {
if (GattServer::reset() != BLE_ERROR_NONE) {
return BLE_ERROR_INVALID_STATE;
}

View file

@ -27,8 +27,6 @@
class nRF5xGattServer : public GattServer
{
public:
static nRF5xGattServer &getInstance();
/* Functions that must be implemented from GattServer */
virtual ble_error_t addService(GattService &);
virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
@ -37,13 +35,12 @@ public:
virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
virtual ble_error_t areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP);
virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP);
virtual ble_error_t reset(void);
/* nRF51 Functions */
void eventCallback(void);
void hwCallback(ble_evt_t *p_ble_evt);
protected:
virtual ble_error_t cleanup(void);
private:
const static unsigned BLE_TOTAL_CHARACTERISTICS = 20;
@ -89,6 +86,11 @@ private:
uint8_t descriptorCount;
uint16_t nrfDescriptorHandles[BLE_TOTAL_DESCRIPTORS];
/*
* Allow instantiation from nRF5xn when required.
*/
friend class nRF5xn;
nRF5xGattServer() : GattServer(), p_characteristics(), nrfCharacteristicHandles(), p_descriptors(), descriptorCount(0), nrfDescriptorHandles() {
/* empty */
}

View file

@ -1,24 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 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.
*/
#include "nRF5xSecurityManager.h"
nRF5xSecurityManager &nRF5xSecurityManager::getInstance(void) {
if (securityManagerInstance == NULL) {
securityManagerInstance = new nRF5xSecurityManager();
}
return (nRF5xSecurityManager &) *securityManagerInstance;
}

View file

@ -25,8 +25,6 @@
class nRF5xSecurityManager : public SecurityManager
{
public:
static nRF5xSecurityManager &getInstance();
/* Functions that must be implemented from SecurityManager */
virtual ble_error_t init(bool enableBonding,
bool requireMITM,
@ -53,9 +51,9 @@ public:
* @return
* BLE_ERROR_NONE if successful.
*/
virtual ble_error_t cleanup(void)
virtual ble_error_t reset(void)
{
if (SecurityManager::cleanup() != BLE_ERROR_NONE) {
if (SecurityManager::reset() != BLE_ERROR_NONE) {
return BLE_ERROR_INVALID_STATE;
}
@ -63,6 +61,11 @@ public:
}
public:
/*
* Allow instantiation from nRF5xn when required.
*/
friend class nRF5xn;
nRF5xSecurityManager() {
/* empty */
}

View file

@ -105,9 +105,9 @@ public:
* @return
* BLE_ERROR_NONE if successful.
*/
virtual ble_error_t cleanup(void) {
virtual ble_error_t reset(void) {
/* Clear all state that is from the parent, including private members */
if (ServiceDiscovery::cleanup() != BLE_ERROR_NONE) {
if (ServiceDiscovery::reset() != BLE_ERROR_NONE) {
return BLE_ERROR_INVALID_STATE;
}

View file

@ -31,6 +31,12 @@ extern "C" {
*/
static nRF5xn deviceInstance;
/**
* The singleton for nRF5xGap. This has been kept static because it is
* always needed for any application that uses BLE.
*/
nRF5xGap nRF5xn::_gapInstance;
/**
* BLE-API requires an implementation of the following function in order to
* obtain its transport handle.
@ -38,10 +44,21 @@ static nRF5xn deviceInstance;
BLEInstanceBase *
createBLEInstance(void)
{
return (&deviceInstance);
return &nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
}
nRF5xn::nRF5xn(void) : initialized(false), instanceID(BLE::DEFAULT_INSTANCE)
nRF5xn& nRF5xn::Instance(BLE::InstanceID_t instanceId)
{
return deviceInstance;
}
nRF5xn::nRF5xn(void) :
initialized(false),
instanceID(BLE::DEFAULT_INSTANCE),
gapInstance(NULL),
gattServerInstance(NULL),
gattClientInstance(NULL),
securityManagerInstance(NULL)
{
}
@ -123,22 +140,38 @@ ble_error_t nRF5xn::shutdown(void)
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
}
/* Shutdown the SoftDevice */
/*
* Shutdown the SoftDevice first. This is because we need to disable all
* interrupts. Otherwise if we clear the BLE API and glue code first there
* will be many NULL references and no config information which could lead
* to errors if the shutdown process is interrupted.
*/
if(softdevice_handler_sd_disable() != NRF_SUCCESS) {
return BLE_STACK_BUSY;
}
/* Shutdown the BLE API and nRF51 glue code */
if (gattServerInstance != NULL &&
gattServerInstance->reset() != BLE_ERROR_NONE) {
return BLE_ERROR_INVALID_STATE;
}
if (securityManagerInstance != NULL &&
securityManagerInstance->reset() != BLE_ERROR_NONE) {
return BLE_ERROR_INVALID_STATE;
}
/* S110 does not support BLE client features, nothing to reset. */
#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
if (GattServer::shutdown() != BLE_ERROR_NONE ||
SecurityManager::shutdown() != BLE_ERROR_NONE ||
GattClient::shutdown() != BLE_ERROR_NONE ||
Gap::shutdown() != BLE_ERROR_NONE) {
#else
if (GattServer::shutdown() != BLE_ERROR_NONE ||
SecurityManager::shutdown() != BLE_ERROR_NONE ||
Gap::shutdown() != BLE_ERROR_NONE) {
if (gattClientInstance != NULL &&
gattClientInstance->reset() != BLE_ERROR_NONE) {
return BLE_ERROR_INVALID_STATE;
}
#endif
if (gapInstance != NULL &&
gapInstance->reset() != BLE_ERROR_NONE) {
return BLE_ERROR_INVALID_STATE;
}

View file

@ -41,32 +41,153 @@ public:
virtual ble_error_t shutdown(void);
virtual const char *getVersion(void);
/**
* Accessors to GAP. This function checks whether gapInstance points to an
* object. If if does not, then the gapInstance is updated to
* &_getInstance before returning.
*
* @return A reference to GattServer.
*
* @note Unlike the GattClient, GattServer and SecurityManager, Gap is
* always needed in a BLE application. Therefore it is allocated
* statically.
*/
virtual Gap &getGap() {
return nRF5xGap::getInstance();
};
virtual const Gap &getGap() const {
return nRF5xGap::getInstance();
if (gapInstance == NULL) {
gapInstance = &_gapInstance;
}
return *gapInstance;
};
/**
* Accessors to GATT Server. This function checks whether a GattServer
* object was previously instantiated. If such object does not exist, then
* it is created before returning.
*
* @return A reference to GattServer.
*/
virtual GattServer &getGattServer() {
return nRF5xGattServer::getInstance();
};
virtual const GattServer &getGattServer() const {
return nRF5xGattServer::getInstance();
if (gattServerInstance == NULL) {
gattServerInstance = new nRF5xGattServer();
}
return *gattServerInstance;
};
/**
* Accessors to GATT Client. This function checks whether a GattClient
* object was previously instantiated. If such object does not exist, then
* it is created before returning.
*
* @return A reference to GattClient.
*/
virtual GattClient &getGattClient() {
return nRF5xGattClient::getInstance();
}
virtual const SecurityManager &getSecurityManager() const {
return nRF5xSecurityManager::getInstance();
if (gattClientInstance == NULL) {
gattClientInstance = new nRF5xGattClient();
}
return *gattClientInstance;
}
/**
* Accessors to Security Manager. This function checks whether a SecurityManager
* object was previously instantiated. If such object does not exist, then
* it is created before returning.
*
* @return A reference to GattServer.
*/
virtual SecurityManager &getSecurityManager() {
return nRF5xSecurityManager::getInstance();
if (securityManagerInstance == NULL) {
securityManagerInstance = new nRF5xSecurityManager();
}
return *securityManagerInstance;
}
/**
* Accessors to GAP. This function checks whether gapInstance points to an
* object. If if does not, then the gapInstance is updated to
* &_getInstance before returning.
*
* @return A const reference to GattServer.
*
* @note Unlike the GattClient, GattServer and SecurityManager, Gap is
* always needed in a BLE application. Therefore it is allocated
* statically.
*
* @note The accessor is able to modify the object's state because the
* internal pointer has been declared mutable.
*/
virtual const Gap &getGap() const {
if (gapInstance == NULL) {
gapInstance = &_gapInstance;
}
return *gapInstance;
};
/**
* Accessors to GATT Server. This function checks whether a GattServer
* object was previously instantiated. If such object does not exist, then
* it is created before returning.
*
* @return A const reference to GattServer.
*
* @note The accessor is able to modify the object's state because the
* internal pointer has been declared mutable.
*/
virtual const GattServer &getGattServer() const {
if (gattServerInstance == NULL) {
gattServerInstance = new nRF5xGattServer();
}
return *gattServerInstance;
};
/**
* Accessors to Security Manager. This function checks whether a SecurityManager
* object was previously instantiated. If such object does not exist, then
* it is created before returning.
*
* @return A const reference to GattServer.
*
* @note The accessor is able to modify the object's state because the
* internal pointer has been declared mutable.
*/
virtual const SecurityManager &getSecurityManager() const {
if (securityManagerInstance == NULL) {
securityManagerInstance = new nRF5xSecurityManager();
}
return *securityManagerInstance;
}
virtual void waitForEvent(void);
public:
static nRF5xn& Instance(BLE::InstanceID_t instanceId);
private:
bool initialized;
BLE::InstanceID_t instanceID;
private:
static nRF5xGap _gapInstance; /**< Gap instance whose reference is returned from a call to
* getGap(). Unlike the GattClient, GattServer and
* SecurityManager, Gap is always needed in a BLE application.
* Therefore it is allocated statically. */
private:
mutable nRF5xGap *gapInstance; /**< Pointer to the Gap object instance.
* If NULL, then Gap has not been initialized.
* The pointer has been declared as 'mutable' so that
* it can be assigned inside a 'const' function. */
mutable nRF5xGattServer *gattServerInstance; /**< Pointer to the GattServer object instance.
* If NULL, then GattServer has not been initialized.
* The pointer has been declared as 'mutable' so that
* it can be assigned inside a 'const' function. */
mutable nRF5xGattClient *gattClientInstance; /**< Pointer to the GattClient object instance.
* If NULL, then GattClient has not been initialized.
* The pointer has been declared as 'mutable' so that
* it can be assigned inside a 'const' function. */
mutable nRF5xSecurityManager *securityManagerInstance; /**< Pointer to the SecurityManager object instance.
* If NULL, then SecurityManager has not been initialized.
* The pointer has been declared as 'mutable' so that
* it can be assigned inside a 'const' function. */
};
#endif