No changes

Fork of nRF51822 by Nordic Semiconductor

Committer:
vcoubard
Date:
Mon Jan 11 10:19:15 2016 +0000
Revision:
561:613dbbdeed27
Parent:
549:3f782c64d014
Child:
563:9c4b96f7be8d
Synchronized with git rev 7bf81e7e
Author: Andres Amaya Garcia
Improve shutdown to clear BLE API and not just SD

Improve the shutdown functionality, such that a call to ble.shutdown() from
the user application clears the API and nRF5x state and NOT only the
SoftDevice. To achieve this the following changes are introduced:

* Add a protected member cleanup() to nRF5xGap, nRF5xGattClient,
nRF5xGattServer, nRF5xSecurityManager and nRF5xServiceDiscovery.
* Modify the shutdown() implementation in nRF5xn such that it also calls the
static member shutdown() exposed by the BLE API in Gap.h, SecurityManager.h,
GattClient.h and GattServer.h.
* Modify nRF5xGattClient, nRF5xGattServer and nRF5xSecurityManager
classes so that they dynamically create their respective objects only if
needed. Previously the GattClient, GattServer and SecurityManager objects were
declared as static, which means that they were always present even though they
were not always needed. This increases memory consumption unnecessarily.
Furthermore, pointers to the object instances are stored in static members of
the classes as specified by the BLE API base classes. This ensures that
calls to shutdown do not require calls to getInstance() functions that would
otherwise result in undesired memory allocations.
* nRF5xGap object is always needed, so this remains allocated statically. But
the reference in Gap is pointed to this object.

The shutdown procedure is as follows:

1. The user calls ble.shutdown() which executes the code in nRF5xn::shutdown()
1. The SoftDevice is shutdown
1. The static members of Gap.h, SecurityManager.h, GattClient.h and
GattServer.h are called to clean up their own state.

If at any point an error occur during the last step, BLE_ERROR_INVALID_STATE is
returned.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vcoubard 541:884f95bf5351 1 /* mbed Microcontroller Library
vcoubard 541:884f95bf5351 2 * Copyright (c) 2006-2013 ARM Limited
vcoubard 541:884f95bf5351 3 *
vcoubard 541:884f95bf5351 4 * Licensed under the Apache License, Version 2.0 (the "License");
vcoubard 541:884f95bf5351 5 * you may not use this file except in compliance with the License.
vcoubard 541:884f95bf5351 6 * You may obtain a copy of the License at
vcoubard 541:884f95bf5351 7 *
vcoubard 541:884f95bf5351 8 * http://www.apache.org/licenses/LICENSE-2.0
vcoubard 541:884f95bf5351 9 *
vcoubard 541:884f95bf5351 10 * Unless required by applicable law or agreed to in writing, software
vcoubard 541:884f95bf5351 11 * distributed under the License is distributed on an "AS IS" BASIS,
vcoubard 541:884f95bf5351 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vcoubard 541:884f95bf5351 13 * See the License for the specific language governing permissions and
vcoubard 541:884f95bf5351 14 * limitations under the License.
vcoubard 541:884f95bf5351 15 */
vcoubard 541:884f95bf5351 16
vcoubard 541:884f95bf5351 17 #include "mbed.h"
vcoubard 541:884f95bf5351 18 #include "nRF5xn.h"
vcoubard 541:884f95bf5351 19 #include "ble/blecommon.h"
vcoubard 541:884f95bf5351 20 #include "nrf_soc.h"
vcoubard 541:884f95bf5351 21
vcoubard 541:884f95bf5351 22 #include "btle/btle.h"
vcoubard 541:884f95bf5351 23 #include "nrf_delay.h"
vcoubard 541:884f95bf5351 24
vcoubard 549:3f782c64d014 25 extern "C" {
vcoubard 541:884f95bf5351 26 #include "softdevice_handler.h"
vcoubard 549:3f782c64d014 27 }
vcoubard 541:884f95bf5351 28
vcoubard 541:884f95bf5351 29 /**
vcoubard 541:884f95bf5351 30 * The singleton which represents the nRF51822 transport for the BLE.
vcoubard 541:884f95bf5351 31 */
vcoubard 541:884f95bf5351 32 static nRF5xn deviceInstance;
vcoubard 541:884f95bf5351 33
vcoubard 541:884f95bf5351 34 /**
vcoubard 541:884f95bf5351 35 * BLE-API requires an implementation of the following function in order to
vcoubard 541:884f95bf5351 36 * obtain its transport handle.
vcoubard 541:884f95bf5351 37 */
vcoubard 541:884f95bf5351 38 BLEInstanceBase *
vcoubard 541:884f95bf5351 39 createBLEInstance(void)
vcoubard 541:884f95bf5351 40 {
vcoubard 541:884f95bf5351 41 return (&deviceInstance);
vcoubard 541:884f95bf5351 42 }
vcoubard 541:884f95bf5351 43
vcoubard 541:884f95bf5351 44 nRF5xn::nRF5xn(void) : initialized(false), instanceID(BLE::DEFAULT_INSTANCE)
vcoubard 541:884f95bf5351 45 {
vcoubard 541:884f95bf5351 46 }
vcoubard 541:884f95bf5351 47
vcoubard 541:884f95bf5351 48 nRF5xn::~nRF5xn(void)
vcoubard 541:884f95bf5351 49 {
vcoubard 541:884f95bf5351 50 }
vcoubard 541:884f95bf5351 51
vcoubard 541:884f95bf5351 52 const char *nRF5xn::getVersion(void)
vcoubard 541:884f95bf5351 53 {
vcoubard 541:884f95bf5351 54 if (!initialized) {
vcoubard 541:884f95bf5351 55 return "INITIALIZATION_INCOMPLETE";
vcoubard 541:884f95bf5351 56 }
vcoubard 541:884f95bf5351 57
vcoubard 541:884f95bf5351 58 static char versionString[32];
vcoubard 541:884f95bf5351 59 static bool versionFetched = false;
vcoubard 541:884f95bf5351 60
vcoubard 541:884f95bf5351 61 if (!versionFetched) {
vcoubard 541:884f95bf5351 62 ble_version_t version;
vcoubard 541:884f95bf5351 63 if ((sd_ble_version_get(&version) == NRF_SUCCESS) && (version.company_id == 0x0059)) {
vcoubard 541:884f95bf5351 64 switch (version.version_number) {
vcoubard 541:884f95bf5351 65 case 0x07:
vcoubard 541:884f95bf5351 66 case 0x08:
vcoubard 541:884f95bf5351 67 snprintf(versionString, sizeof(versionString), "Nordic BLE4.1 ver:%u fw:%04x", version.version_number, version.subversion_number);
vcoubard 541:884f95bf5351 68 break;
vcoubard 541:884f95bf5351 69 default:
vcoubard 541:884f95bf5351 70 snprintf(versionString, sizeof(versionString), "Nordic (spec unknown) ver:%u fw:%04x", version.version_number, version.subversion_number);
vcoubard 541:884f95bf5351 71 break;
vcoubard 541:884f95bf5351 72 }
vcoubard 541:884f95bf5351 73 versionFetched = true;
vcoubard 541:884f95bf5351 74 } else {
vcoubard 541:884f95bf5351 75 strncpy(versionString, "unknown", sizeof(versionString));
vcoubard 541:884f95bf5351 76 }
vcoubard 541:884f95bf5351 77 }
vcoubard 541:884f95bf5351 78
vcoubard 541:884f95bf5351 79 return versionString;
vcoubard 541:884f95bf5351 80 }
vcoubard 541:884f95bf5351 81
vcoubard 541:884f95bf5351 82 ble_error_t nRF5xn::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback)
vcoubard 541:884f95bf5351 83 {
vcoubard 541:884f95bf5351 84 if (initialized) {
vcoubard 541:884f95bf5351 85 BLE::InitializationCompleteCallbackContext context = {
vcoubard 541:884f95bf5351 86 BLE::Instance(instanceID),
vcoubard 541:884f95bf5351 87 BLE_ERROR_ALREADY_INITIALIZED
vcoubard 541:884f95bf5351 88 };
vcoubard 541:884f95bf5351 89 callback.call(&context);
vcoubard 541:884f95bf5351 90 return BLE_ERROR_ALREADY_INITIALIZED;
vcoubard 541:884f95bf5351 91 }
vcoubard 541:884f95bf5351 92
vcoubard 541:884f95bf5351 93 instanceID = instanceID;
vcoubard 541:884f95bf5351 94
vcoubard 541:884f95bf5351 95 /* ToDo: Clear memory contents, reset the SD, etc. */
vcoubard 541:884f95bf5351 96 btle_init();
vcoubard 541:884f95bf5351 97
vcoubard 541:884f95bf5351 98 initialized = true;
vcoubard 541:884f95bf5351 99 BLE::InitializationCompleteCallbackContext context = {
vcoubard 541:884f95bf5351 100 BLE::Instance(instanceID),
vcoubard 541:884f95bf5351 101 BLE_ERROR_NONE
vcoubard 541:884f95bf5351 102 };
vcoubard 541:884f95bf5351 103 callback.call(&context);
vcoubard 541:884f95bf5351 104 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 105 }
vcoubard 541:884f95bf5351 106
vcoubard 561:613dbbdeed27 107 /**************************************************************************/
vcoubard 561:613dbbdeed27 108 /*!
vcoubard 561:613dbbdeed27 109 @brief Purge the BLE stack of GATT and GAP state.
vcoubard 561:613dbbdeed27 110
vcoubard 561:613dbbdeed27 111 @returns ble_error_t
vcoubard 561:613dbbdeed27 112
vcoubard 561:613dbbdeed27 113 @retval BLE_ERROR_NONE
vcoubard 561:613dbbdeed27 114 Everything executed properly
vcoubard 561:613dbbdeed27 115
vcoubard 561:613dbbdeed27 116 @note When using S110, GattClient::shutdown() will not be called
vcoubard 561:613dbbdeed27 117 since Gatt client features are not supported.
vcoubard 561:613dbbdeed27 118 */
vcoubard 561:613dbbdeed27 119 /**************************************************************************/
vcoubard 541:884f95bf5351 120 ble_error_t nRF5xn::shutdown(void)
vcoubard 541:884f95bf5351 121 {
vcoubard 541:884f95bf5351 122 if (!initialized) {
vcoubard 541:884f95bf5351 123 return BLE_ERROR_INITIALIZATION_INCOMPLETE;
vcoubard 541:884f95bf5351 124 }
vcoubard 541:884f95bf5351 125
vcoubard 561:613dbbdeed27 126 /* Shutdown the SoftDevice */
vcoubard 541:884f95bf5351 127 if(softdevice_handler_sd_disable() != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 128 return BLE_STACK_BUSY;
vcoubard 541:884f95bf5351 129 }
vcoubard 541:884f95bf5351 130
vcoubard 561:613dbbdeed27 131 /* Shutdown the BLE API and nRF51 glue code */
vcoubard 561:613dbbdeed27 132 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
vcoubard 561:613dbbdeed27 133 if (GattServer::shutdown() != BLE_ERROR_NONE ||
vcoubard 561:613dbbdeed27 134 SecurityManager::shutdown() != BLE_ERROR_NONE ||
vcoubard 561:613dbbdeed27 135 GattClient::shutdown() != BLE_ERROR_NONE ||
vcoubard 561:613dbbdeed27 136 Gap::shutdown() != BLE_ERROR_NONE) {
vcoubard 561:613dbbdeed27 137 #else
vcoubard 561:613dbbdeed27 138 if (GattServer::shutdown() != BLE_ERROR_NONE ||
vcoubard 561:613dbbdeed27 139 SecurityManager::shutdown() != BLE_ERROR_NONE ||
vcoubard 561:613dbbdeed27 140 Gap::shutdown() != BLE_ERROR_NONE) {
vcoubard 561:613dbbdeed27 141 #endif
vcoubard 561:613dbbdeed27 142 return BLE_ERROR_INVALID_STATE;
vcoubard 561:613dbbdeed27 143 }
vcoubard 561:613dbbdeed27 144
vcoubard 541:884f95bf5351 145 initialized = false;
vcoubard 541:884f95bf5351 146 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 147 }
vcoubard 541:884f95bf5351 148
vcoubard 541:884f95bf5351 149 void
vcoubard 541:884f95bf5351 150 nRF5xn::waitForEvent(void)
vcoubard 541:884f95bf5351 151 {
vcoubard 541:884f95bf5351 152 sd_app_evt_wait();
rgrover1 388:db85a09c27ef 153 }