Nordic stack and drivers for the mbed BLE API

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate writable_gatt ... more

Committer:
vcoubard
Date:
Mon Jan 11 10:19:19 2016 +0000
Revision:
567:e1800bd55a9e
Parent:
566:e425ad9e5d6e
Child:
570:f162898cb6c4
Synchronized with git rev 59ced0b4
Author: Vincent Coubard
rename remainingCharacteristic member, now it is named
discoveredCharacteristic. Add doc to the discovery process and the
rationale behind discoveredCharacteristic member.

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