smart ball test board code

Dependencies:   nrf51-sdk

Fork of nRF51822 by Nordic Semiconductor

Committer:
vcoubard
Date:
Fri Apr 08 11:05:55 2016 +0100
Revision:
622:1d79da5c393e
Parent:
621:98998cc3789b
Child:
626:19a7a530044b
Synchronized with git rev a18eb4a3
Author: Vincent Coubard
Fix incorrect handles of characteristics descriptors.

The variable descriptorCount is used as an index, and this index is used to set
the handle of the last registered descriptor.

Prior to this fix, descriptorCount was incremented before the handle the update
of the handle of a characteristics.

Short story, all characteristics descriptors handle were equaols to 0 instead
of the actual value.

Who changed what in which revision?

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