test

Dependencies:   nrf51-sdk

Dependents:   microbit-dal

Fork of nRF51822 by Lancaster University

Committer:
vcoubard
Date:
Mon Jan 11 10:19:18 2016 +0000
Revision:
565:cf03471a4ec4
Parent:
563:9c4b96f7be8d
Child:
566:e425ad9e5d6e
Synchronized with git rev 0bcc2e96
Author: Andres Amaya Garcia
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.

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 "common/common.h"
vcoubard 541:884f95bf5351 18 #include "nordic_common.h"
vcoubard 541:884f95bf5351 19
vcoubard 541:884f95bf5351 20 #include "btle.h"
vcoubard 541:884f95bf5351 21
vcoubard 541:884f95bf5351 22 #include "ble_flash.h"
vcoubard 541:884f95bf5351 23 #include "ble_conn_params.h"
vcoubard 541:884f95bf5351 24
vcoubard 541:884f95bf5351 25 #include "btle_gap.h"
vcoubard 541:884f95bf5351 26 #include "btle_advertising.h"
vcoubard 541:884f95bf5351 27 #include "custom/custom_helper.h"
vcoubard 541:884f95bf5351 28
vcoubard 541:884f95bf5351 29 #include "ble/GapEvents.h"
vcoubard 565:cf03471a4ec4 30 #include "nRF5xn.h"
vcoubard 541:884f95bf5351 31
vcoubard 549:3f782c64d014 32 extern "C" {
vcoubard 549:3f782c64d014 33 #include "pstorage.h"
vcoubard 541:884f95bf5351 34 #include "device_manager.h"
vcoubard 549:3f782c64d014 35 #include "softdevice_handler.h"
vcoubard 549:3f782c64d014 36 #include "ble_stack_handler_types.h"
vcoubard 549:3f782c64d014 37 }
vcoubard 541:884f95bf5351 38
vcoubard 541:884f95bf5351 39 #include "ble_hci.h"
vcoubard 541:884f95bf5351 40 #include "btle_discovery.h"
vcoubard 541:884f95bf5351 41
vcoubard 541:884f95bf5351 42 extern "C" void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name);
vcoubard 541:884f95bf5351 43 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name);
vcoubard 541:884f95bf5351 44
vcoubard 541:884f95bf5351 45 static void btle_handler(ble_evt_t *p_ble_evt);
vcoubard 541:884f95bf5351 46
vcoubard 541:884f95bf5351 47 static void sys_evt_dispatch(uint32_t sys_evt)
vcoubard 541:884f95bf5351 48 {
vcoubard 541:884f95bf5351 49 pstorage_sys_event_handler(sys_evt);
vcoubard 541:884f95bf5351 50 }
vcoubard 541:884f95bf5351 51
vcoubard 541:884f95bf5351 52 /**
vcoubard 541:884f95bf5351 53 * This function is called in interrupt context to handle BLE events; i.e. pull
vcoubard 541:884f95bf5351 54 * system and user events out of the pending events-queue of the BLE stack. The
vcoubard 541:884f95bf5351 55 * BLE stack signals the availability of events by the triggering the SWI2
vcoubard 541:884f95bf5351 56 * interrupt, which forwards the handling to this function.
vcoubard 541:884f95bf5351 57 *
vcoubard 541:884f95bf5351 58 * The event processing loop is implemented in intern_softdevice_events_execute().
vcoubard 541:884f95bf5351 59 *
vcoubard 541:884f95bf5351 60 * In mbed OS, a callback for intern_softdevice_events_execute() is posted
vcoubard 541:884f95bf5351 61 * to the scheduler, which then executes in thread mode. In mbed-classic,
vcoubard 541:884f95bf5351 62 * event processing happens right-away in interrupt context (which is more
vcoubard 541:884f95bf5351 63 * risk-prone). In either case, the logic of event processing is identical.
vcoubard 541:884f95bf5351 64 */
vcoubard 541:884f95bf5351 65 static uint32_t eventHandler()
vcoubard 541:884f95bf5351 66 {
vcoubard 541:884f95bf5351 67 #ifdef YOTTA_CFG_MBED_OS
vcoubard 541:884f95bf5351 68 minar::Scheduler::postCallback(intern_softdevice_events_execute);
vcoubard 541:884f95bf5351 69 #else
vcoubard 541:884f95bf5351 70 intern_softdevice_events_execute();
vcoubard 541:884f95bf5351 71 #endif
vcoubard 541:884f95bf5351 72
vcoubard 541:884f95bf5351 73 return NRF_SUCCESS;
vcoubard 541:884f95bf5351 74 }
vcoubard 541:884f95bf5351 75
vcoubard 541:884f95bf5351 76 error_t btle_init(void)
vcoubard 541:884f95bf5351 77 {
vcoubard 541:884f95bf5351 78 nrf_clock_lfclksrc_t clockSource;
vcoubard 541:884f95bf5351 79 if (NRF_CLOCK->LFCLKSRC & (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos)) {
vcoubard 541:884f95bf5351 80 clockSource = NRF_CLOCK_LFCLKSRC_XTAL_20_PPM;
vcoubard 541:884f95bf5351 81 } else {
vcoubard 541:884f95bf5351 82 clockSource = NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION;
vcoubard 541:884f95bf5351 83 }
vcoubard 541:884f95bf5351 84 SOFTDEVICE_HANDLER_INIT(clockSource, eventHandler);
vcoubard 541:884f95bf5351 85
vcoubard 541:884f95bf5351 86 // Enable BLE stack
vcoubard 541:884f95bf5351 87 /**
vcoubard 541:884f95bf5351 88 * Using this call, the application can select whether to include the
vcoubard 541:884f95bf5351 89 * Service Changed characteristic in the GATT Server. The default in all
vcoubard 541:884f95bf5351 90 * previous releases has been to include the Service Changed characteristic,
vcoubard 541:884f95bf5351 91 * but this affects how GATT clients behave. Specifically, it requires
vcoubard 541:884f95bf5351 92 * clients to subscribe to this attribute and not to cache attribute handles
vcoubard 541:884f95bf5351 93 * between connections unless the devices are bonded. If the application
vcoubard 541:884f95bf5351 94 * does not need to change the structure of the GATT server attributes at
vcoubard 541:884f95bf5351 95 * runtime this adds unnecessary complexity to the interaction with peer
vcoubard 541:884f95bf5351 96 * clients. If the SoftDevice is enabled with the Service Changed
vcoubard 541:884f95bf5351 97 * Characteristics turned off, then clients are allowed to cache attribute
vcoubard 541:884f95bf5351 98 * handles making applications simpler on both sides.
vcoubard 541:884f95bf5351 99 */
vcoubard 541:884f95bf5351 100 static const bool IS_SRVC_CHANGED_CHARACT_PRESENT = true;
vcoubard 541:884f95bf5351 101 ble_enable_params_t enableParams = {
vcoubard 541:884f95bf5351 102 .gatts_enable_params = {
vcoubard 541:884f95bf5351 103 .service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT
vcoubard 541:884f95bf5351 104 }
vcoubard 541:884f95bf5351 105 };
vcoubard 541:884f95bf5351 106 if (sd_ble_enable(&enableParams) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 107 return ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 108 }
vcoubard 541:884f95bf5351 109
vcoubard 541:884f95bf5351 110 ble_gap_addr_t addr;
vcoubard 541:884f95bf5351 111 if (sd_ble_gap_address_get(&addr) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 112 return ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 113 }
vcoubard 541:884f95bf5351 114 if (sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 115 return ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 116 }
vcoubard 541:884f95bf5351 117
vcoubard 541:884f95bf5351 118 ASSERT_STATUS( softdevice_ble_evt_handler_set(btle_handler));
vcoubard 541:884f95bf5351 119 ASSERT_STATUS( softdevice_sys_evt_handler_set(sys_evt_dispatch));
vcoubard 541:884f95bf5351 120
vcoubard 541:884f95bf5351 121 btle_gap_init();
vcoubard 541:884f95bf5351 122
vcoubard 541:884f95bf5351 123 return ERROR_NONE;
vcoubard 541:884f95bf5351 124 }
vcoubard 541:884f95bf5351 125
vcoubard 541:884f95bf5351 126 static void btle_handler(ble_evt_t *p_ble_evt)
vcoubard 541:884f95bf5351 127 {
vcoubard 541:884f95bf5351 128 /* Library service handlers */
vcoubard 541:884f95bf5351 129 #if SDK_CONN_PARAMS_MODULE_ENABLE
vcoubard 541:884f95bf5351 130 ble_conn_params_on_ble_evt(p_ble_evt);
vcoubard 541:884f95bf5351 131 #endif
vcoubard 541:884f95bf5351 132
vcoubard 541:884f95bf5351 133 dm_ble_evt_handler(p_ble_evt);
vcoubard 541:884f95bf5351 134
vcoubard 541:884f95bf5351 135 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
vcoubard 541:884f95bf5351 136 bleGattcEventHandler(p_ble_evt);
vcoubard 541:884f95bf5351 137 #endif
vcoubard 541:884f95bf5351 138
vcoubard 565:cf03471a4ec4 139 nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
vcoubard 565:cf03471a4ec4 140 nRF5xGap &gap = (nRF5xGap &) ble.getGap();
vcoubard 565:cf03471a4ec4 141 nRF5xGattServer &gattServer = (nRF5xGattServer &) ble.getGattServer();
vcoubard 565:cf03471a4ec4 142 nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
vcoubard 565:cf03471a4ec4 143
vcoubard 541:884f95bf5351 144 /* Custom event handler */
vcoubard 541:884f95bf5351 145 switch (p_ble_evt->header.evt_id) {
vcoubard 541:884f95bf5351 146 case BLE_GAP_EVT_CONNECTED: {
vcoubard 541:884f95bf5351 147 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
vcoubard 541:884f95bf5351 148 #if defined(TARGET_MCU_NRF51_16K_S110) || defined(TARGET_MCU_NRF51_32K_S110)
vcoubard 541:884f95bf5351 149 /* Only peripheral role is supported by S110 */
vcoubard 541:884f95bf5351 150 Gap::Role_t role = Gap::PERIPHERAL;
vcoubard 541:884f95bf5351 151 #else
vcoubard 541:884f95bf5351 152 Gap::Role_t role = static_cast<Gap::Role_t>(p_ble_evt->evt.gap_evt.params.connected.role);
vcoubard 541:884f95bf5351 153 #endif
vcoubard 565:cf03471a4ec4 154 gap.setConnectionHandle(handle);
vcoubard 541:884f95bf5351 155 const Gap::ConnectionParams_t *params = reinterpret_cast<Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params));
vcoubard 541:884f95bf5351 156 const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr;
vcoubard 541:884f95bf5351 157 const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr;
vcoubard 565:cf03471a4ec4 158 gap.processConnectionEvent(handle,
vcoubard 541:884f95bf5351 159 role,
vcoubard 541:884f95bf5351 160 static_cast<Gap::AddressType_t>(peer->addr_type), peer->addr,
vcoubard 541:884f95bf5351 161 static_cast<Gap::AddressType_t>(own->addr_type), own->addr,
vcoubard 541:884f95bf5351 162 params);
vcoubard 541:884f95bf5351 163 break;
vcoubard 541:884f95bf5351 164 }
vcoubard 541:884f95bf5351 165
vcoubard 541:884f95bf5351 166 case BLE_GAP_EVT_DISCONNECTED: {
vcoubard 541:884f95bf5351 167 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
vcoubard 541:884f95bf5351 168 // Since we are not in a connection and have not started advertising,
vcoubard 541:884f95bf5351 169 // store bonds
vcoubard 565:cf03471a4ec4 170 gap.setConnectionHandle (BLE_CONN_HANDLE_INVALID);
vcoubard 541:884f95bf5351 171
vcoubard 541:884f95bf5351 172 Gap::DisconnectionReason_t reason;
vcoubard 541:884f95bf5351 173 switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) {
vcoubard 541:884f95bf5351 174 case BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION:
vcoubard 541:884f95bf5351 175 reason = Gap::LOCAL_HOST_TERMINATED_CONNECTION;
vcoubard 541:884f95bf5351 176 break;
vcoubard 541:884f95bf5351 177 case BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION:
vcoubard 541:884f95bf5351 178 reason = Gap::REMOTE_USER_TERMINATED_CONNECTION;
vcoubard 541:884f95bf5351 179 break;
vcoubard 541:884f95bf5351 180 case BLE_HCI_CONN_INTERVAL_UNACCEPTABLE:
vcoubard 541:884f95bf5351 181 reason = Gap::CONN_INTERVAL_UNACCEPTABLE;
vcoubard 541:884f95bf5351 182 break;
vcoubard 541:884f95bf5351 183 default:
vcoubard 541:884f95bf5351 184 /* Please refer to the underlying transport library for an
vcoubard 541:884f95bf5351 185 * interpretion of this reason's value. */
vcoubard 541:884f95bf5351 186 reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason);
vcoubard 541:884f95bf5351 187 break;
vcoubard 541:884f95bf5351 188 }
vcoubard 565:cf03471a4ec4 189 gap.processDisconnectionEvent(handle, reason);
vcoubard 541:884f95bf5351 190 break;
vcoubard 541:884f95bf5351 191 }
vcoubard 541:884f95bf5351 192
vcoubard 541:884f95bf5351 193 case BLE_GAP_EVT_PASSKEY_DISPLAY:
vcoubard 565:cf03471a4ec4 194 securityManager.processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
vcoubard 541:884f95bf5351 195 break;
vcoubard 541:884f95bf5351 196
vcoubard 541:884f95bf5351 197 case BLE_GAP_EVT_TIMEOUT:
vcoubard 565:cf03471a4ec4 198 gap.processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
vcoubard 541:884f95bf5351 199 break;
vcoubard 541:884f95bf5351 200
vcoubard 541:884f95bf5351 201 case BLE_GATTC_EVT_TIMEOUT:
vcoubard 541:884f95bf5351 202 case BLE_GATTS_EVT_TIMEOUT:
vcoubard 541:884f95bf5351 203 // Disconnect on GATT Server and Client timeout events.
vcoubard 541:884f95bf5351 204 // ASSERT_STATUS_RET_VOID (sd_ble_gap_disconnect(m_conn_handle,
vcoubard 541:884f95bf5351 205 // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
vcoubard 541:884f95bf5351 206 break;
vcoubard 541:884f95bf5351 207
vcoubard 541:884f95bf5351 208 case BLE_GAP_EVT_ADV_REPORT: {
vcoubard 541:884f95bf5351 209 const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report;
vcoubard 565:cf03471a4ec4 210 gap.processAdvertisementReport(advReport->peer_addr.addr,
vcoubard 565:cf03471a4ec4 211 advReport->rssi,
vcoubard 565:cf03471a4ec4 212 advReport->scan_rsp,
vcoubard 565:cf03471a4ec4 213 static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type),
vcoubard 565:cf03471a4ec4 214 advReport->dlen,
vcoubard 565:cf03471a4ec4 215 advReport->data);
vcoubard 541:884f95bf5351 216 break;
vcoubard 541:884f95bf5351 217 }
vcoubard 541:884f95bf5351 218
vcoubard 541:884f95bf5351 219 default:
vcoubard 541:884f95bf5351 220 break;
vcoubard 541:884f95bf5351 221 }
vcoubard 541:884f95bf5351 222
vcoubard 565:cf03471a4ec4 223 gattServer.hwCallback(p_ble_evt);
vcoubard 541:884f95bf5351 224 }
vcoubard 541:884f95bf5351 225
vcoubard 541:884f95bf5351 226 /*! @brief Callback when an error occurs inside the SoftDevice */
vcoubard 541:884f95bf5351 227 void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name)
vcoubard 541:884f95bf5351 228 {
vcoubard 541:884f95bf5351 229 ASSERT(false, (void) 0);
vcoubard 541:884f95bf5351 230 }
vcoubard 541:884f95bf5351 231
vcoubard 541:884f95bf5351 232 /*!
vcoubard 541:884f95bf5351 233 @brief Handler for general errors above the SoftDevice layer.
vcoubard 541:884f95bf5351 234 Typically we can' recover from this so we do a reset.
vcoubard 541:884f95bf5351 235 */
vcoubard 541:884f95bf5351 236 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name)
vcoubard 541:884f95bf5351 237 {
vcoubard 541:884f95bf5351 238 ASSERT_STATUS_RET_VOID( error_code );
vcoubard 541:884f95bf5351 239 NVIC_SystemReset();
rgrover1 77:9886b2865631 240 }