Nordic stack and drivers for the mbed BLE API

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate writable_gatt ... more

Committer:
vcoubard
Date:
Fri Apr 08 11:05:55 2016 +0100
Revision:
621:1d79da5c393e
Parent:
620:98998cc3789b
Child:
625:19a7a530044b
Synchronized with git rev a18eb4a3
Author: Vincent Coubard
Fix incorrect handles of characteristics descriptors.

The variable descriptorCount is used as an index, and this index is used to set
the handle of the last registered descriptor.

Prior to this fix, descriptorCount was incremented before the handle the update
of the handle of a characteristics.

Short story, all characteristics descriptors handle were equaols to 0 instead
of the actual value.

Who changed what in which revision?

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