Nordic stack and drivers for the mbed BLE API. Version to work around build bug.

Dependents:   microbit_rubber_ducky microbit_mouse_BLE microbit_mouse_BLE_daybreak_version microbit_presenter

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Thu Aug 13 13:23:19 2015 +0100
Revision:
426:3edd435c8364
Parent:
424:28ea27dcba79
Child:
429:bff56e081b6e
Synchronized with git rev 74c70768
Author: Rohit Grover
setup an event handler to post BLE events to Minar.
Stack and system events now get scheduled through minar.

Who changed what in which revision?

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