test

Dependencies:   nrf51-sdk

Dependents:   microbit-dal

Fork of nRF51822 by Lancaster University

Committer:
rgrover1
Date:
Tue Aug 11 15:14:23 2015 +0100
Revision:
416:5b7d26035f2b
Parent:
404:fccbe137c4ac
Child:
417:d79a89cccddd
Synchronized with git rev 3eabc779
Author: Jean-Philippe Brucker
Disable GattClient features when using S110 SoftDevice

S110 compatibility is already present, but this patch adds proper handling
of observer/central related features:
* Gap::startScan will return BLE_ERRROR_NOT_IMPLEMENTED (instead of
PARAM_OUT_OF_RANGE)
* nRF5xGattClient uses the default GattClient implementation when S110 is
in use. All if its methods return NOT_IMPLEMENTED.

Example: for an application that acts as both a central and a peripheral,
using S110 will make the ble.gap().startScan() call return
BLE_ERROR_NOT_IMPLEMENTED, and advertisement features will continue
running normally.
In addition, with GCC, this patch will free 344 bytes of RAM and 2504
bytes of flash.

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
Rohit Grover 22:c6ee8136847e 53 error_t btle_init(void)
Rohit Grover 22:c6ee8136847e 54 {
rgrover1 404:fccbe137c4ac 55 if (NRF_CLOCK->LFCLKSRC & (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos)) {
rgrover1 402:448a564f5c9e 56 SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL);
rgrover1 404:fccbe137c4ac 57 } else {
rgrover1 402:448a564f5c9e 58 SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, NULL);
rgrover1 404:fccbe137c4ac 59 }
Rohit Grover 56:a1071b629aa3 60
Rohit Grover 56:a1071b629aa3 61 // Enable BLE stack
Rohit Grover 56:a1071b629aa3 62 /**
Rohit Grover 56:a1071b629aa3 63 * Using this call, the application can select whether to include the
Rohit Grover 56:a1071b629aa3 64 * Service Changed characteristic in the GATT Server. The default in all
Rohit Grover 56:a1071b629aa3 65 * previous releases has been to include the Service Changed characteristic,
Rohit Grover 56:a1071b629aa3 66 * but this affects how GATT clients behave. Specifically, it requires
Rohit Grover 56:a1071b629aa3 67 * clients to subscribe to this attribute and not to cache attribute handles
Rohit Grover 56:a1071b629aa3 68 * between connections unless the devices are bonded. If the application
Rohit Grover 56:a1071b629aa3 69 * does not need to change the structure of the GATT server attributes at
Rohit Grover 56:a1071b629aa3 70 * runtime this adds unnecessary complexity to the interaction with peer
Rohit Grover 56:a1071b629aa3 71 * clients. If the SoftDevice is enabled with the Service Changed
Rohit Grover 56:a1071b629aa3 72 * Characteristics turned off, then clients are allowed to cache attribute
Rohit Grover 56:a1071b629aa3 73 * handles making applications simpler on both sides.
Rohit Grover 56:a1071b629aa3 74 */
Rohit Grover 68:936d81c963fe 75 static const bool IS_SRVC_CHANGED_CHARACT_PRESENT = true;
Rohit Grover 56:a1071b629aa3 76 ble_enable_params_t enableParams = {
Rohit Grover 56:a1071b629aa3 77 .gatts_enable_params = {
Rohit Grover 56:a1071b629aa3 78 .service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT
Rohit Grover 56:a1071b629aa3 79 }
Rohit Grover 56:a1071b629aa3 80 };
Rohit Grover 56:a1071b629aa3 81 if (sd_ble_enable(&enableParams) != NRF_SUCCESS) {
Rohit Grover 56:a1071b629aa3 82 return ERROR_INVALID_PARAM;
Rohit Grover 56:a1071b629aa3 83 }
Rohit Grover 56:a1071b629aa3 84
Rohit Grover 56:a1071b629aa3 85 ble_gap_addr_t addr;
Rohit Grover 56:a1071b629aa3 86 if (sd_ble_gap_address_get(&addr) != NRF_SUCCESS) {
Rohit Grover 56:a1071b629aa3 87 return ERROR_INVALID_PARAM;
Rohit Grover 56:a1071b629aa3 88 }
Rohit Grover 56:a1071b629aa3 89 if (sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr) != NRF_SUCCESS) {
Rohit Grover 56:a1071b629aa3 90 return ERROR_INVALID_PARAM;
Rohit Grover 56:a1071b629aa3 91 }
Rohit Grover 22:c6ee8136847e 92
Rohit Grover 22:c6ee8136847e 93 ASSERT_STATUS( softdevice_ble_evt_handler_set(btle_handler));
Rohit Grover 22:c6ee8136847e 94 ASSERT_STATUS( softdevice_sys_evt_handler_set(sys_evt_dispatch));
Rohit Grover 22:c6ee8136847e 95
rgrover1 127:bd1e1fe607e0 96 btle_gap_init();
rgrover1 127:bd1e1fe607e0 97
rgrover1 127:bd1e1fe607e0 98 return ERROR_NONE;
rgrover1 127:bd1e1fe607e0 99 }
rgrover1 127:bd1e1fe607e0 100
Rohit Grover 22:c6ee8136847e 101 static void btle_handler(ble_evt_t *p_ble_evt)
Rohit Grover 22:c6ee8136847e 102 {
Rohit Grover 22:c6ee8136847e 103 /* Library service handlers */
Rohit Grover 56:a1071b629aa3 104 #if SDK_CONN_PARAMS_MODULE_ENABLE
Rohit Grover 22:c6ee8136847e 105 ble_conn_params_on_ble_evt(p_ble_evt);
Rohit Grover 56:a1071b629aa3 106 #endif
Rohit Grover 22:c6ee8136847e 107
rgrover1 125:35e4f65364bc 108 dm_ble_evt_handler(p_ble_evt);
rgrover1 125:35e4f65364bc 109
rgrover1 416:5b7d26035f2b 110 #if !defined(MCU_NORDIC_16K_S110) && !defined(MCU_NORDIC_32K_S110)
rgrover1 371:8f7d2137727a 111 bleGattcEventHandler(p_ble_evt);
rgrover1 416:5b7d26035f2b 112 #endif
rgrover1 371:8f7d2137727a 113
Rohit Grover 22:c6ee8136847e 114 /* Custom event handler */
Rohit Grover 22:c6ee8136847e 115 switch (p_ble_evt->header.evt_id) {
Rohit Grover 41:6e66cd970659 116 case BLE_GAP_EVT_CONNECTED: {
Rohit Grover 41:6e66cd970659 117 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
rgrover1 399:a471c3da4806 118 #if defined(MCU_NORDIC_16K_S110) || defined(MCU_NORDIC_32K_S110)
rgrover1 399:a471c3da4806 119 /* Only peripheral role is supported by S110 */
rgrover1 399:a471c3da4806 120 Gap::Role_t role = Gap::PERIPHERAL;
rgrover1 399:a471c3da4806 121 #else
rgrover1 399:a471c3da4806 122 Gap::Role_t role = static_cast<Gap::Role_t>(p_ble_evt->evt.gap_evt.params.connected.role);
rgrover1 399:a471c3da4806 123 #endif
rgrover1 393:0f7c5048efb3 124 nRF5xGap::getInstance().setConnectionHandle(handle);
Rohit Grover 56:a1071b629aa3 125 const Gap::ConnectionParams_t *params = reinterpret_cast<Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params));
rgrover1 77:9886b2865631 126 const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr;
rgrover1 112:737b08b3b995 127 const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr;
rgrover1 393:0f7c5048efb3 128 nRF5xGap::getInstance().processConnectionEvent(handle,
rgrover1 399:a471c3da4806 129 role,
rgrover1 179:10e4c13360d9 130 static_cast<Gap::AddressType_t>(peer->addr_type), peer->addr,
rgrover1 179:10e4c13360d9 131 static_cast<Gap::AddressType_t>(own->addr_type), own->addr,
rgrover1 112:737b08b3b995 132 params);
Rohit Grover 22:c6ee8136847e 133 break;
Rohit Grover 41:6e66cd970659 134 }
Rohit Grover 22:c6ee8136847e 135
Rohit Grover 41:6e66cd970659 136 case BLE_GAP_EVT_DISCONNECTED: {
Rohit Grover 41:6e66cd970659 137 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
Rohit Grover 22:c6ee8136847e 138 // Since we are not in a connection and have not started advertising,
Rohit Grover 22:c6ee8136847e 139 // store bonds
rgrover1 393:0f7c5048efb3 140 nRF5xGap::getInstance().setConnectionHandle (BLE_CONN_HANDLE_INVALID);
Rohit Grover 56:a1071b629aa3 141
Rohit Grover 65:98215c4f3a25 142 Gap::DisconnectionReason_t reason;
Rohit Grover 65:98215c4f3a25 143 switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) {
Rohit Grover 65:98215c4f3a25 144 case BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION:
Rohit Grover 65:98215c4f3a25 145 reason = Gap::LOCAL_HOST_TERMINATED_CONNECTION;
Rohit Grover 65:98215c4f3a25 146 break;
Rohit Grover 65:98215c4f3a25 147 case BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION:
Rohit Grover 65:98215c4f3a25 148 reason = Gap::REMOTE_USER_TERMINATED_CONNECTION;
Rohit Grover 65:98215c4f3a25 149 break;
Rohit Grover 65:98215c4f3a25 150 case BLE_HCI_CONN_INTERVAL_UNACCEPTABLE:
Rohit Grover 65:98215c4f3a25 151 reason = Gap::CONN_INTERVAL_UNACCEPTABLE;
Rohit Grover 65:98215c4f3a25 152 break;
Rohit Grover 65:98215c4f3a25 153 default:
Rohit Grover 65:98215c4f3a25 154 /* Please refer to the underlying transport library for an
Rohit Grover 65:98215c4f3a25 155 * interpretion of this reason's value. */
Rohit Grover 65:98215c4f3a25 156 reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason);
Rohit Grover 65:98215c4f3a25 157 break;
Rohit Grover 56:a1071b629aa3 158 }
rgrover1 393:0f7c5048efb3 159 nRF5xGap::getInstance().processDisconnectionEvent(handle, reason);
Rohit Grover 22:c6ee8136847e 160 break;
Rohit Grover 41:6e66cd970659 161 }
Rohit Grover 22:c6ee8136847e 162
rgrover1 161:6712855a0107 163 case BLE_GAP_EVT_PASSKEY_DISPLAY:
rgrover1 393:0f7c5048efb3 164 nRF5xSecurityManager::getInstance().processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
rgrover1 161:6712855a0107 165 break;
rgrover1 161:6712855a0107 166
Rohit Grover 22:c6ee8136847e 167 case BLE_GAP_EVT_TIMEOUT:
rgrover1 393:0f7c5048efb3 168 nRF5xGap::getInstance().processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
Rohit Grover 22:c6ee8136847e 169 break;
Rohit Grover 22:c6ee8136847e 170
Rohit Grover 22:c6ee8136847e 171 case BLE_GATTC_EVT_TIMEOUT:
Rohit Grover 22:c6ee8136847e 172 case BLE_GATTS_EVT_TIMEOUT:
Rohit Grover 22:c6ee8136847e 173 // Disconnect on GATT Server and Client timeout events.
Rohit Grover 22:c6ee8136847e 174 // ASSERT_STATUS_RET_VOID (sd_ble_gap_disconnect(m_conn_handle,
Rohit Grover 22:c6ee8136847e 175 // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
Rohit Grover 22:c6ee8136847e 176 break;
Rohit Grover 22:c6ee8136847e 177
rgrover1 165:67fcad70785a 178 case BLE_GAP_EVT_ADV_REPORT: {
rgrover1 165:67fcad70785a 179 const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report;
rgrover1 393:0f7c5048efb3 180 nRF5xGap::getInstance().processAdvertisementReport(advReport->peer_addr.addr,
rgrover1 167:66ee4f876396 181 advReport->rssi,
rgrover1 167:66ee4f876396 182 advReport->scan_rsp,
rgrover1 371:8f7d2137727a 183 static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type),
rgrover1 167:66ee4f876396 184 advReport->dlen,
rgrover1 167:66ee4f876396 185 advReport->data);
rgrover1 167:66ee4f876396 186 break;
rgrover1 165:67fcad70785a 187 }
rgrover1 165:67fcad70785a 188
Rohit Grover 22:c6ee8136847e 189 default:
Rohit Grover 22:c6ee8136847e 190 break;
Rohit Grover 22:c6ee8136847e 191 }
Rohit Grover 22:c6ee8136847e 192
rgrover1 393:0f7c5048efb3 193 nRF5xGattServer::getInstance().hwCallback(p_ble_evt);
Rohit Grover 22:c6ee8136847e 194 }
Rohit Grover 22:c6ee8136847e 195
rgrover1 160:7d04579fdb2a 196 /*! @brief Callback when an error occurs inside the SoftDevice */
Rohit Grover 22:c6ee8136847e 197 void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name)
Rohit Grover 22:c6ee8136847e 198 {
Rohit Grover 22:c6ee8136847e 199 ASSERT(false, (void) 0);
Rohit Grover 22:c6ee8136847e 200 }
Rohit Grover 22:c6ee8136847e 201
Rohit Grover 22:c6ee8136847e 202 /*!
Rohit Grover 22:c6ee8136847e 203 @brief Handler for general errors above the SoftDevice layer.
Rohit Grover 22:c6ee8136847e 204 Typically we can' recover from this so we do a reset.
Rohit Grover 22:c6ee8136847e 205 */
rgrover1 160:7d04579fdb2a 206 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name)
Rohit Grover 22:c6ee8136847e 207 {
Rohit Grover 22:c6ee8136847e 208 ASSERT_STATUS_RET_VOID( error_code );
Rohit Grover 22:c6ee8136847e 209 NVIC_SystemReset();
rgrover1 77:9886b2865631 210 }