No changes

Fork of nRF51822 by Nordic Semiconductor

Committer:
vcoubard
Date:
Fri Apr 08 11:05:53 2016 +0100
Revision:
620:98998cc3789b
Parent:
618:6eb60aaf0724
Child:
621:1d79da5c393e
Synchronized with git rev a008a20b
Author: Il
fixed pull request as requested by @bearsh

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 620:98998cc3789b 192 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
vcoubard 617:a7c074f5f875 193 // Close all pending discoveries for this connection
vcoubard 617:a7c074f5f875 194 nRF5xGattClient& gattClient = ble.getGattClient();
vcoubard 617:a7c074f5f875 195 gattClient.characteristicDescriptorDiscoverer().terminate(handle, BLE_ERROR_INVALID_STATE);
vcoubard 617:a7c074f5f875 196 gattClient.discovery().terminate(handle);
vcoubard 620:98998cc3789b 197 #endif
vcoubard 617:a7c074f5f875 198
vcoubard 617:a7c074f5f875 199 gap.processDisconnectionEvent(handle, reason);
vcoubard 617:a7c074f5f875 200 break;
vcoubard 617:a7c074f5f875 201 }
vcoubard 617:a7c074f5f875 202
vcoubard 617:a7c074f5f875 203 case BLE_GAP_EVT_PASSKEY_DISPLAY:
vcoubard 617:a7c074f5f875 204 securityManager.processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
vcoubard 617:a7c074f5f875 205 break;
vcoubard 617:a7c074f5f875 206
vcoubard 617:a7c074f5f875 207 case BLE_GAP_EVT_TIMEOUT:
vcoubard 617:a7c074f5f875 208 gap.processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
vcoubard 617:a7c074f5f875 209 break;
vcoubard 617:a7c074f5f875 210
vcoubard 617:a7c074f5f875 211 case BLE_GATTC_EVT_TIMEOUT:
vcoubard 617:a7c074f5f875 212 case BLE_GATTS_EVT_TIMEOUT:
vcoubard 617:a7c074f5f875 213 // Disconnect on GATT Server and Client timeout events.
vcoubard 617:a7c074f5f875 214 // ASSERT_STATUS_RET_VOID (sd_ble_gap_disconnect(m_conn_handle,
vcoubard 617:a7c074f5f875 215 // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
vcoubard 617:a7c074f5f875 216 break;
vcoubard 617:a7c074f5f875 217
vcoubard 617:a7c074f5f875 218 case BLE_GAP_EVT_ADV_REPORT: {
vcoubard 617:a7c074f5f875 219 const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report;
vcoubard 617:a7c074f5f875 220 gap.processAdvertisementReport(advReport->peer_addr.addr,
vcoubard 617:a7c074f5f875 221 advReport->rssi,
vcoubard 617:a7c074f5f875 222 advReport->scan_rsp,
vcoubard 617:a7c074f5f875 223 static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type),
vcoubard 617:a7c074f5f875 224 advReport->dlen,
vcoubard 617:a7c074f5f875 225 advReport->data);
vcoubard 617:a7c074f5f875 226 break;
vcoubard 617:a7c074f5f875 227 }
vcoubard 617:a7c074f5f875 228
vcoubard 617:a7c074f5f875 229 default:
vcoubard 617:a7c074f5f875 230 break;
vcoubard 617:a7c074f5f875 231 }
vcoubard 617:a7c074f5f875 232
vcoubard 617:a7c074f5f875 233 gattServer.hwCallback(p_ble_evt);
vcoubard 617:a7c074f5f875 234 }
vcoubard 617:a7c074f5f875 235
vcoubard 617:a7c074f5f875 236 /*! @brief Callback when an error occurs inside the SoftDevice */
vcoubard 617:a7c074f5f875 237 void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name)
vcoubard 617:a7c074f5f875 238 {
vcoubard 617:a7c074f5f875 239 ASSERT(false, (void) 0);
vcoubard 617:a7c074f5f875 240 }
vcoubard 617:a7c074f5f875 241
vcoubard 617:a7c074f5f875 242 /*!
vcoubard 617:a7c074f5f875 243 @brief Handler for general errors above the SoftDevice layer.
vcoubard 617:a7c074f5f875 244 Typically we can' recover from this so we do a reset.
vcoubard 617:a7c074f5f875 245 */
vcoubard 617:a7c074f5f875 246 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name)
vcoubard 617:a7c074f5f875 247 {
vcoubard 617:a7c074f5f875 248 ASSERT_STATUS_RET_VOID( error_code );
vcoubard 617:a7c074f5f875 249 NVIC_SystemReset();
rgrover1 77:9886b2865631 250 }