test

Dependencies:   nrf51-sdk

Dependents:   microbit-dal

Fork of nRF51822 by Lancaster University

Committer:
rgrover1
Date:
Thu Nov 26 14:33:46 2015 +0000
Revision:
475:fe3d08b3a8e9
Parent:
455:e33de7c4574c
Child:
476:a95a18ef5e9c
Synchronized with git rev 348c323d
Author: Liyou Zhou
Take modification out of the nordic sdk files
and put them into ARM written files.

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