nordic

Fork of nRF51822 by Nordic Semiconductor

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