No changes

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Mon Jul 06 10:13:27 2015 +0100
Revision:
371:8f7d2137727a
Parent:
370:295f76db798e
Synchronized with git rev 2716309c
Author: Rohit Grover
Release 0.4.0
=============

This is a major release which introduces the GATT Client functionality. It
aligns with release 0.4.0 of BLE_API.

Enhancements
~~~~~~~~~~~~

* Introduce GattClient. This includes functionality for service-discovery,
connections, and attribute-reads and writes. You'll find a demo program for
LEDBlinker on the mbed.org Bluetooth team page to use the new APIs. Some of
the GATT client functionality hasn't been implemented yet, but the APIs have
been added.

* We've added an implementation for the abstract base class for
SecurityManager. All security related APIs have been moved into that.

* There has been a major cleanup of APIs under BLE. APIs have now been
categorized as belonging to Gap, GattServer, GattClient, or SecurityManager.
There are accessors to get references for Gap, GattServer, GattClient, and
SecurityManager. A former call to ble.setAddress(...) is now expected to be
achieved with ble.gap().setAddress(...).

* We've cleaned up our APIs, and this has resulted in dropping some APIs like
BLE::reset().

* We've also dropped GattServer::initializeGattDatabase(). THis was added at
some point to support controllers where a commit point was needed to
indicate when the application had finished constructing the GATT database.
This API would get called internally before Gap::startAdvertising(). We now
expect the underlying port to do the equivalent of initializeGattDatabase()
implicitly upon Gap::startAdvertising().

* We've added a version of Gap::disconnect() which takes a connection handle.
The previous API (which did not take a connection handle) has been
deprecated; it will still work for situations where there's only a single
active connection. We hold on to that API to allow existing code to migrate
to the new API.

Bugfixes
~~~~~~~~

* None.

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"
Rohit Grover 22:c6ee8136847e 34 #include "nRF51Gap.h"
Rohit Grover 22:c6ee8136847e 35 #include "nRF51GattServer.h"
rgrover1 371:8f7d2137727a 36 #include "nRF51SecurityManager.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 94:2bac1b3c5cfc 55 #if defined(TARGET_DELTA_DFCM_NNN40) || defined(TARGET_HRM1017)
rgrover1 112:737b08b3b995 56 SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, NULL);
ytsuboi 61:d0158c65d0d7 57 #else
rgrover1 112:737b08b3b995 58 SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL);
ytsuboi 61:d0158c65d0d7 59 #endif
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 371:8f7d2137727a 110 bleGattcEventHandler(p_ble_evt);
rgrover1 371:8f7d2137727a 111
Rohit Grover 22:c6ee8136847e 112 /* Custom event handler */
Rohit Grover 22:c6ee8136847e 113 switch (p_ble_evt->header.evt_id) {
Rohit Grover 41:6e66cd970659 114 case BLE_GAP_EVT_CONNECTED: {
Rohit Grover 41:6e66cd970659 115 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
Rohit Grover 41:6e66cd970659 116 nRF51Gap::getInstance().setConnectionHandle(handle);
Rohit Grover 56:a1071b629aa3 117 const Gap::ConnectionParams_t *params = reinterpret_cast<Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params));
rgrover1 77:9886b2865631 118 const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr;
rgrover1 112:737b08b3b995 119 const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr;
rgrover1 112:737b08b3b995 120 nRF51Gap::getInstance().processConnectionEvent(handle,
rgrover1 371:8f7d2137727a 121 static_cast<Gap::Role_t>(p_ble_evt->evt.gap_evt.params.connected.role),
rgrover1 179:10e4c13360d9 122 static_cast<Gap::AddressType_t>(peer->addr_type), peer->addr,
rgrover1 179:10e4c13360d9 123 static_cast<Gap::AddressType_t>(own->addr_type), own->addr,
rgrover1 112:737b08b3b995 124 params);
Rohit Grover 22:c6ee8136847e 125 break;
Rohit Grover 41:6e66cd970659 126 }
Rohit Grover 22:c6ee8136847e 127
Rohit Grover 41:6e66cd970659 128 case BLE_GAP_EVT_DISCONNECTED: {
Rohit Grover 41:6e66cd970659 129 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
Rohit Grover 22:c6ee8136847e 130 // Since we are not in a connection and have not started advertising,
Rohit Grover 22:c6ee8136847e 131 // store bonds
Rohit Grover 22:c6ee8136847e 132 nRF51Gap::getInstance().setConnectionHandle (BLE_CONN_HANDLE_INVALID);
Rohit Grover 56:a1071b629aa3 133
Rohit Grover 65:98215c4f3a25 134 Gap::DisconnectionReason_t reason;
Rohit Grover 65:98215c4f3a25 135 switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) {
Rohit Grover 65:98215c4f3a25 136 case BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION:
Rohit Grover 65:98215c4f3a25 137 reason = Gap::LOCAL_HOST_TERMINATED_CONNECTION;
Rohit Grover 65:98215c4f3a25 138 break;
Rohit Grover 65:98215c4f3a25 139 case BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION:
Rohit Grover 65:98215c4f3a25 140 reason = Gap::REMOTE_USER_TERMINATED_CONNECTION;
Rohit Grover 65:98215c4f3a25 141 break;
Rohit Grover 65:98215c4f3a25 142 case BLE_HCI_CONN_INTERVAL_UNACCEPTABLE:
Rohit Grover 65:98215c4f3a25 143 reason = Gap::CONN_INTERVAL_UNACCEPTABLE;
Rohit Grover 65:98215c4f3a25 144 break;
Rohit Grover 65:98215c4f3a25 145 default:
Rohit Grover 65:98215c4f3a25 146 /* Please refer to the underlying transport library for an
Rohit Grover 65:98215c4f3a25 147 * interpretion of this reason's value. */
Rohit Grover 65:98215c4f3a25 148 reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason);
Rohit Grover 65:98215c4f3a25 149 break;
Rohit Grover 56:a1071b629aa3 150 }
Rohit Grover 65:98215c4f3a25 151 nRF51Gap::getInstance().processDisconnectionEvent(handle, reason);
Rohit Grover 22:c6ee8136847e 152 break;
Rohit Grover 41:6e66cd970659 153 }
Rohit Grover 22:c6ee8136847e 154
rgrover1 161:6712855a0107 155 case BLE_GAP_EVT_PASSKEY_DISPLAY:
rgrover1 371:8f7d2137727a 156 nRF51SecurityManager::getInstance().processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
rgrover1 161:6712855a0107 157 break;
rgrover1 161:6712855a0107 158
Rohit Grover 22:c6ee8136847e 159 case BLE_GAP_EVT_TIMEOUT:
rgrover1 371:8f7d2137727a 160 nRF51Gap::getInstance().processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
Rohit Grover 22:c6ee8136847e 161 break;
Rohit Grover 22:c6ee8136847e 162
Rohit Grover 22:c6ee8136847e 163 case BLE_GATTC_EVT_TIMEOUT:
Rohit Grover 22:c6ee8136847e 164 case BLE_GATTS_EVT_TIMEOUT:
Rohit Grover 22:c6ee8136847e 165 // Disconnect on GATT Server and Client timeout events.
Rohit Grover 22:c6ee8136847e 166 // ASSERT_STATUS_RET_VOID (sd_ble_gap_disconnect(m_conn_handle,
Rohit Grover 22:c6ee8136847e 167 // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
Rohit Grover 22:c6ee8136847e 168 break;
Rohit Grover 22:c6ee8136847e 169
rgrover1 165:67fcad70785a 170 case BLE_GAP_EVT_ADV_REPORT: {
rgrover1 165:67fcad70785a 171 const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report;
rgrover1 167:66ee4f876396 172 nRF51Gap::getInstance().processAdvertisementReport(advReport->peer_addr.addr,
rgrover1 167:66ee4f876396 173 advReport->rssi,
rgrover1 167:66ee4f876396 174 advReport->scan_rsp,
rgrover1 371:8f7d2137727a 175 static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type),
rgrover1 167:66ee4f876396 176 advReport->dlen,
rgrover1 167:66ee4f876396 177 advReport->data);
rgrover1 167:66ee4f876396 178 break;
rgrover1 165:67fcad70785a 179 }
rgrover1 165:67fcad70785a 180
Rohit Grover 22:c6ee8136847e 181 default:
Rohit Grover 22:c6ee8136847e 182 break;
Rohit Grover 22:c6ee8136847e 183 }
Rohit Grover 22:c6ee8136847e 184
Rohit Grover 22:c6ee8136847e 185 nRF51GattServer::getInstance().hwCallback(p_ble_evt);
Rohit Grover 22:c6ee8136847e 186 }
Rohit Grover 22:c6ee8136847e 187
rgrover1 160:7d04579fdb2a 188 /*! @brief Callback when an error occurs inside the SoftDevice */
Rohit Grover 22:c6ee8136847e 189 void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name)
Rohit Grover 22:c6ee8136847e 190 {
Rohit Grover 22:c6ee8136847e 191 ASSERT(false, (void) 0);
Rohit Grover 22:c6ee8136847e 192 }
Rohit Grover 22:c6ee8136847e 193
Rohit Grover 22:c6ee8136847e 194 /*!
Rohit Grover 22:c6ee8136847e 195 @brief Handler for general errors above the SoftDevice layer.
Rohit Grover 22:c6ee8136847e 196 Typically we can' recover from this so we do a reset.
Rohit Grover 22:c6ee8136847e 197 */
rgrover1 160:7d04579fdb2a 198 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name)
Rohit Grover 22:c6ee8136847e 199 {
Rohit Grover 22:c6ee8136847e 200 ASSERT_STATUS_RET_VOID( error_code );
Rohit Grover 22:c6ee8136847e 201 NVIC_SystemReset();
rgrover1 77:9886b2865631 202 }