cvb

Fork of nrf51-sdk by Lancaster University

Committer:
tb942
Date:
Tue Aug 14 18:27:20 2018 +0000
Revision:
9:d3dd910b0f4b
Parent:
0:bc2961fa1ef0

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 0:bc2961fa1ef0 1 /*
Jonathan Austin 0:bc2961fa1ef0 2 * Copyright (c) Nordic Semiconductor ASA
Jonathan Austin 0:bc2961fa1ef0 3 * All rights reserved.
Jonathan Austin 0:bc2961fa1ef0 4 *
Jonathan Austin 0:bc2961fa1ef0 5 * Redistribution and use in source and binary forms, with or without modification,
Jonathan Austin 0:bc2961fa1ef0 6 * are permitted provided that the following conditions are met:
Jonathan Austin 0:bc2961fa1ef0 7 *
Jonathan Austin 0:bc2961fa1ef0 8 * 1. Redistributions of source code must retain the above copyright notice, this
Jonathan Austin 0:bc2961fa1ef0 9 * list of conditions and the following disclaimer.
Jonathan Austin 0:bc2961fa1ef0 10 *
Jonathan Austin 0:bc2961fa1ef0 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this
Jonathan Austin 0:bc2961fa1ef0 12 * list of conditions and the following disclaimer in the documentation and/or
Jonathan Austin 0:bc2961fa1ef0 13 * other materials provided with the distribution.
Jonathan Austin 0:bc2961fa1ef0 14 *
Jonathan Austin 0:bc2961fa1ef0 15 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other
Jonathan Austin 0:bc2961fa1ef0 16 * contributors to this software may be used to endorse or promote products
Jonathan Austin 0:bc2961fa1ef0 17 * derived from this software without specific prior written permission.
Jonathan Austin 0:bc2961fa1ef0 18 *
Jonathan Austin 0:bc2961fa1ef0 19 *
Jonathan Austin 0:bc2961fa1ef0 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Jonathan Austin 0:bc2961fa1ef0 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Jonathan Austin 0:bc2961fa1ef0 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Jonathan Austin 0:bc2961fa1ef0 23 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
Jonathan Austin 0:bc2961fa1ef0 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Jonathan Austin 0:bc2961fa1ef0 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Jonathan Austin 0:bc2961fa1ef0 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
Jonathan Austin 0:bc2961fa1ef0 27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Jonathan Austin 0:bc2961fa1ef0 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Jonathan Austin 0:bc2961fa1ef0 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Jonathan Austin 0:bc2961fa1ef0 30 *
Jonathan Austin 0:bc2961fa1ef0 31 */
Jonathan Austin 0:bc2961fa1ef0 32
Jonathan Austin 0:bc2961fa1ef0 33 #include "ble_conn_params.h"
Jonathan Austin 0:bc2961fa1ef0 34 #include <stdlib.h>
Jonathan Austin 0:bc2961fa1ef0 35 #include "nordic_common.h"
Jonathan Austin 0:bc2961fa1ef0 36 #include "ble_hci.h"
Jonathan Austin 0:bc2961fa1ef0 37 #include "ble_srv_common.h"
Jonathan Austin 0:bc2961fa1ef0 38 #include "app_util.h"
Jonathan Austin 0:bc2961fa1ef0 39
Jonathan Austin 0:bc2961fa1ef0 40 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 41 #include "app_timer.h"
Jonathan Austin 0:bc2961fa1ef0 42 #else
Jonathan Austin 0:bc2961fa1ef0 43 #ifdef YOTTA_CFG_MBED_OS
Jonathan Austin 0:bc2961fa1ef0 44 #include "mbed-drivers/mbed.h"
Jonathan Austin 0:bc2961fa1ef0 45 #else
Jonathan Austin 0:bc2961fa1ef0 46 #include "mbed.h"
Jonathan Austin 0:bc2961fa1ef0 47 #endif
Jonathan Austin 0:bc2961fa1ef0 48 #endif
Jonathan Austin 0:bc2961fa1ef0 49
Jonathan Austin 0:bc2961fa1ef0 50 static ble_conn_params_init_t m_conn_params_config; /**< Configuration as specified by the application. */
Jonathan Austin 0:bc2961fa1ef0 51 static ble_gap_conn_params_t m_preferred_conn_params; /**< Connection parameters preferred by the application. */
Jonathan Austin 0:bc2961fa1ef0 52 static uint8_t m_update_count; /**< Number of Connection Parameter Update messages that has currently been sent. */
Jonathan Austin 0:bc2961fa1ef0 53 static uint16_t m_conn_handle; /**< Current connection handle. */
Jonathan Austin 0:bc2961fa1ef0 54 static ble_gap_conn_params_t m_current_conn_params; /**< Connection parameters received in the most recent Connect event. */
Jonathan Austin 0:bc2961fa1ef0 55 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 56 static app_timer_id_t m_conn_params_timer_id; /**< Connection parameters timer. */
Jonathan Austin 0:bc2961fa1ef0 57 #else
Jonathan Austin 0:bc2961fa1ef0 58 static Ticker m_conn_params_timer;
Jonathan Austin 0:bc2961fa1ef0 59 #endif
Jonathan Austin 0:bc2961fa1ef0 60
Jonathan Austin 0:bc2961fa1ef0 61 static bool m_change_param = false;
Jonathan Austin 0:bc2961fa1ef0 62
Jonathan Austin 0:bc2961fa1ef0 63 static bool is_conn_params_ok(ble_gap_conn_params_t * p_conn_params)
Jonathan Austin 0:bc2961fa1ef0 64 {
Jonathan Austin 0:bc2961fa1ef0 65 // Check if interval is within the acceptable range.
Jonathan Austin 0:bc2961fa1ef0 66 // NOTE: Using max_conn_interval in the received event data because this contains
Jonathan Austin 0:bc2961fa1ef0 67 // the client's connection interval.
Jonathan Austin 0:bc2961fa1ef0 68 if (
Jonathan Austin 0:bc2961fa1ef0 69 (p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval)
Jonathan Austin 0:bc2961fa1ef0 70 &&
Jonathan Austin 0:bc2961fa1ef0 71 (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval)
Jonathan Austin 0:bc2961fa1ef0 72 )
Jonathan Austin 0:bc2961fa1ef0 73 {
Jonathan Austin 0:bc2961fa1ef0 74 return true;
Jonathan Austin 0:bc2961fa1ef0 75 }
Jonathan Austin 0:bc2961fa1ef0 76 else
Jonathan Austin 0:bc2961fa1ef0 77 {
Jonathan Austin 0:bc2961fa1ef0 78 return false;
Jonathan Austin 0:bc2961fa1ef0 79 }
Jonathan Austin 0:bc2961fa1ef0 80 }
Jonathan Austin 0:bc2961fa1ef0 81
Jonathan Austin 0:bc2961fa1ef0 82
Jonathan Austin 0:bc2961fa1ef0 83 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 84 static void update_timeout_handler(void * p_context)
Jonathan Austin 0:bc2961fa1ef0 85 {
Jonathan Austin 0:bc2961fa1ef0 86 UNUSED_PARAMETER(p_context);
Jonathan Austin 0:bc2961fa1ef0 87
Jonathan Austin 0:bc2961fa1ef0 88 #else /* #if !USE_APP_TIMER */
Jonathan Austin 0:bc2961fa1ef0 89 static void update_timeout_handler(void)
Jonathan Austin 0:bc2961fa1ef0 90 {
Jonathan Austin 0:bc2961fa1ef0 91 m_conn_params_timer.detach(); /* this is supposed to be a single-shot timer callback */
Jonathan Austin 0:bc2961fa1ef0 92 #endif /* #if !USE_APP_TIMER */
Jonathan Austin 0:bc2961fa1ef0 93 if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
Jonathan Austin 0:bc2961fa1ef0 94 {
Jonathan Austin 0:bc2961fa1ef0 95 // Check if we have reached the maximum number of attempts
Jonathan Austin 0:bc2961fa1ef0 96 m_update_count++;
Jonathan Austin 0:bc2961fa1ef0 97 if (m_update_count <= m_conn_params_config.max_conn_params_update_count)
Jonathan Austin 0:bc2961fa1ef0 98 {
Jonathan Austin 0:bc2961fa1ef0 99 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 100
Jonathan Austin 0:bc2961fa1ef0 101 // Parameters are not ok, send connection parameters update request.
Jonathan Austin 0:bc2961fa1ef0 102 err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
Jonathan Austin 0:bc2961fa1ef0 103 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
Jonathan Austin 0:bc2961fa1ef0 104 {
Jonathan Austin 0:bc2961fa1ef0 105 m_conn_params_config.error_handler(err_code);
Jonathan Austin 0:bc2961fa1ef0 106 }
Jonathan Austin 0:bc2961fa1ef0 107 }
Jonathan Austin 0:bc2961fa1ef0 108 else
Jonathan Austin 0:bc2961fa1ef0 109 {
Jonathan Austin 0:bc2961fa1ef0 110 m_update_count = 0;
Jonathan Austin 0:bc2961fa1ef0 111
Jonathan Austin 0:bc2961fa1ef0 112 // Negotiation failed, disconnect automatically if this has been configured
Jonathan Austin 0:bc2961fa1ef0 113 if (m_conn_params_config.disconnect_on_fail)
Jonathan Austin 0:bc2961fa1ef0 114 {
Jonathan Austin 0:bc2961fa1ef0 115 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 116
Jonathan Austin 0:bc2961fa1ef0 117 err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
Jonathan Austin 0:bc2961fa1ef0 118 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
Jonathan Austin 0:bc2961fa1ef0 119 {
Jonathan Austin 0:bc2961fa1ef0 120 m_conn_params_config.error_handler(err_code);
Jonathan Austin 0:bc2961fa1ef0 121 }
Jonathan Austin 0:bc2961fa1ef0 122 }
Jonathan Austin 0:bc2961fa1ef0 123
Jonathan Austin 0:bc2961fa1ef0 124 // Notify the application that the procedure has failed
Jonathan Austin 0:bc2961fa1ef0 125 if (m_conn_params_config.evt_handler != NULL)
Jonathan Austin 0:bc2961fa1ef0 126 {
Jonathan Austin 0:bc2961fa1ef0 127 ble_conn_params_evt_t evt;
Jonathan Austin 0:bc2961fa1ef0 128
Jonathan Austin 0:bc2961fa1ef0 129 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
Jonathan Austin 0:bc2961fa1ef0 130 m_conn_params_config.evt_handler(&evt);
Jonathan Austin 0:bc2961fa1ef0 131 }
Jonathan Austin 0:bc2961fa1ef0 132 }
Jonathan Austin 0:bc2961fa1ef0 133 }
Jonathan Austin 0:bc2961fa1ef0 134 }
Jonathan Austin 0:bc2961fa1ef0 135
Jonathan Austin 0:bc2961fa1ef0 136
Jonathan Austin 0:bc2961fa1ef0 137 uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init)
Jonathan Austin 0:bc2961fa1ef0 138 {
Jonathan Austin 0:bc2961fa1ef0 139 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 140
Jonathan Austin 0:bc2961fa1ef0 141 m_conn_params_config = *p_init;
Jonathan Austin 0:bc2961fa1ef0 142 m_change_param = false;
Jonathan Austin 0:bc2961fa1ef0 143 if (p_init->p_conn_params != NULL)
Jonathan Austin 0:bc2961fa1ef0 144 {
Jonathan Austin 0:bc2961fa1ef0 145 m_preferred_conn_params = *p_init->p_conn_params;
Jonathan Austin 0:bc2961fa1ef0 146
Jonathan Austin 0:bc2961fa1ef0 147 // Set the connection params in stack
Jonathan Austin 0:bc2961fa1ef0 148 err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
Jonathan Austin 0:bc2961fa1ef0 149 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 150 {
Jonathan Austin 0:bc2961fa1ef0 151 return err_code;
Jonathan Austin 0:bc2961fa1ef0 152 }
Jonathan Austin 0:bc2961fa1ef0 153 }
Jonathan Austin 0:bc2961fa1ef0 154 else
Jonathan Austin 0:bc2961fa1ef0 155 {
Jonathan Austin 0:bc2961fa1ef0 156 // Fetch the connection params from stack
Jonathan Austin 0:bc2961fa1ef0 157 err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params);
Jonathan Austin 0:bc2961fa1ef0 158 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 159 {
Jonathan Austin 0:bc2961fa1ef0 160 return err_code;
Jonathan Austin 0:bc2961fa1ef0 161 }
Jonathan Austin 0:bc2961fa1ef0 162 }
Jonathan Austin 0:bc2961fa1ef0 163
Jonathan Austin 0:bc2961fa1ef0 164 m_conn_handle = BLE_CONN_HANDLE_INVALID;
Jonathan Austin 0:bc2961fa1ef0 165 m_update_count = 0;
Jonathan Austin 0:bc2961fa1ef0 166
Jonathan Austin 0:bc2961fa1ef0 167 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 168 return app_timer_create(&m_conn_params_timer_id,
Jonathan Austin 0:bc2961fa1ef0 169 APP_TIMER_MODE_SINGLE_SHOT,
Jonathan Austin 0:bc2961fa1ef0 170 update_timeout_handler);
Jonathan Austin 0:bc2961fa1ef0 171 #else
Jonathan Austin 0:bc2961fa1ef0 172 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 173 #endif
Jonathan Austin 0:bc2961fa1ef0 174 }
Jonathan Austin 0:bc2961fa1ef0 175
Jonathan Austin 0:bc2961fa1ef0 176
Jonathan Austin 0:bc2961fa1ef0 177 uint32_t ble_conn_params_stop(void)
Jonathan Austin 0:bc2961fa1ef0 178 {
Jonathan Austin 0:bc2961fa1ef0 179 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 180 return app_timer_stop(m_conn_params_timer_id);
Jonathan Austin 0:bc2961fa1ef0 181 #else /* #if !USE_APP_TIMER */
Jonathan Austin 0:bc2961fa1ef0 182 m_conn_params_timer.detach();
Jonathan Austin 0:bc2961fa1ef0 183 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 184 #endif /* #if !USE_APP_TIMER */
Jonathan Austin 0:bc2961fa1ef0 185 }
Jonathan Austin 0:bc2961fa1ef0 186
Jonathan Austin 0:bc2961fa1ef0 187
Jonathan Austin 0:bc2961fa1ef0 188 static void conn_params_negotiation(void)
Jonathan Austin 0:bc2961fa1ef0 189 {
Jonathan Austin 0:bc2961fa1ef0 190 // Start negotiation if the received connection parameters are not acceptable
Jonathan Austin 0:bc2961fa1ef0 191 if (!is_conn_params_ok(&m_current_conn_params))
Jonathan Austin 0:bc2961fa1ef0 192 {
Jonathan Austin 0:bc2961fa1ef0 193 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 194 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 195 #endif
Jonathan Austin 0:bc2961fa1ef0 196 uint32_t timeout_ticks;
Jonathan Austin 0:bc2961fa1ef0 197
Jonathan Austin 0:bc2961fa1ef0 198 if (m_change_param)
Jonathan Austin 0:bc2961fa1ef0 199 {
Jonathan Austin 0:bc2961fa1ef0 200 // Notify the application that the procedure has failed
Jonathan Austin 0:bc2961fa1ef0 201 if (m_conn_params_config.evt_handler != NULL)
Jonathan Austin 0:bc2961fa1ef0 202 {
Jonathan Austin 0:bc2961fa1ef0 203 ble_conn_params_evt_t evt;
Jonathan Austin 0:bc2961fa1ef0 204
Jonathan Austin 0:bc2961fa1ef0 205 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
Jonathan Austin 0:bc2961fa1ef0 206 m_conn_params_config.evt_handler(&evt);
Jonathan Austin 0:bc2961fa1ef0 207 }
Jonathan Austin 0:bc2961fa1ef0 208 }
Jonathan Austin 0:bc2961fa1ef0 209 else
Jonathan Austin 0:bc2961fa1ef0 210 {
Jonathan Austin 0:bc2961fa1ef0 211 if (m_update_count == 0)
Jonathan Austin 0:bc2961fa1ef0 212 {
Jonathan Austin 0:bc2961fa1ef0 213 // First connection parameter update
Jonathan Austin 0:bc2961fa1ef0 214 timeout_ticks = m_conn_params_config.first_conn_params_update_delay;
Jonathan Austin 0:bc2961fa1ef0 215 }
Jonathan Austin 0:bc2961fa1ef0 216 else
Jonathan Austin 0:bc2961fa1ef0 217 {
Jonathan Austin 0:bc2961fa1ef0 218 timeout_ticks = m_conn_params_config.next_conn_params_update_delay;
Jonathan Austin 0:bc2961fa1ef0 219 }
Jonathan Austin 0:bc2961fa1ef0 220
Jonathan Austin 0:bc2961fa1ef0 221 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 222 err_code = app_timer_start(m_conn_params_timer_id, timeout_ticks, NULL);
Jonathan Austin 0:bc2961fa1ef0 223 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
Jonathan Austin 0:bc2961fa1ef0 224 {
Jonathan Austin 0:bc2961fa1ef0 225 m_conn_params_config.error_handler(err_code);
Jonathan Austin 0:bc2961fa1ef0 226 }
Jonathan Austin 0:bc2961fa1ef0 227 #else
Jonathan Austin 0:bc2961fa1ef0 228 m_conn_params_timer.attach(update_timeout_handler, timeout_ticks / 32768);
Jonathan Austin 0:bc2961fa1ef0 229 #endif
Jonathan Austin 0:bc2961fa1ef0 230 }
Jonathan Austin 0:bc2961fa1ef0 231 }
Jonathan Austin 0:bc2961fa1ef0 232 else
Jonathan Austin 0:bc2961fa1ef0 233 {
Jonathan Austin 0:bc2961fa1ef0 234 // Notify the application that the procedure has succeded
Jonathan Austin 0:bc2961fa1ef0 235 if (m_conn_params_config.evt_handler != NULL)
Jonathan Austin 0:bc2961fa1ef0 236 {
Jonathan Austin 0:bc2961fa1ef0 237 ble_conn_params_evt_t evt;
Jonathan Austin 0:bc2961fa1ef0 238
Jonathan Austin 0:bc2961fa1ef0 239 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
Jonathan Austin 0:bc2961fa1ef0 240 m_conn_params_config.evt_handler(&evt);
Jonathan Austin 0:bc2961fa1ef0 241 }
Jonathan Austin 0:bc2961fa1ef0 242 }
Jonathan Austin 0:bc2961fa1ef0 243 m_change_param = false;
Jonathan Austin 0:bc2961fa1ef0 244 }
Jonathan Austin 0:bc2961fa1ef0 245
Jonathan Austin 0:bc2961fa1ef0 246
Jonathan Austin 0:bc2961fa1ef0 247 static void on_connect(ble_evt_t * p_ble_evt)
Jonathan Austin 0:bc2961fa1ef0 248 {
Jonathan Austin 0:bc2961fa1ef0 249 // Save connection parameters
Jonathan Austin 0:bc2961fa1ef0 250 m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
Jonathan Austin 0:bc2961fa1ef0 251 m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params;
Jonathan Austin 0:bc2961fa1ef0 252 m_update_count = 0; // Connection parameter negotiation should re-start every connection
Jonathan Austin 0:bc2961fa1ef0 253
Jonathan Austin 0:bc2961fa1ef0 254 // Check if we shall handle negotiation on connect
Jonathan Austin 0:bc2961fa1ef0 255 if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID)
Jonathan Austin 0:bc2961fa1ef0 256 {
Jonathan Austin 0:bc2961fa1ef0 257 conn_params_negotiation();
Jonathan Austin 0:bc2961fa1ef0 258 }
Jonathan Austin 0:bc2961fa1ef0 259 }
Jonathan Austin 0:bc2961fa1ef0 260
Jonathan Austin 0:bc2961fa1ef0 261
Jonathan Austin 0:bc2961fa1ef0 262 static void on_disconnect(ble_evt_t * p_ble_evt)
Jonathan Austin 0:bc2961fa1ef0 263 {
Jonathan Austin 0:bc2961fa1ef0 264 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 265 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 266 #endif
Jonathan Austin 0:bc2961fa1ef0 267
Jonathan Austin 0:bc2961fa1ef0 268 m_conn_handle = BLE_CONN_HANDLE_INVALID;
Jonathan Austin 0:bc2961fa1ef0 269
Jonathan Austin 0:bc2961fa1ef0 270 // Stop timer if running
Jonathan Austin 0:bc2961fa1ef0 271 m_update_count = 0; // Connection parameters updates should happen during every connection
Jonathan Austin 0:bc2961fa1ef0 272
Jonathan Austin 0:bc2961fa1ef0 273 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 274 err_code = app_timer_stop(m_conn_params_timer_id);
Jonathan Austin 0:bc2961fa1ef0 275 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
Jonathan Austin 0:bc2961fa1ef0 276 {
Jonathan Austin 0:bc2961fa1ef0 277 m_conn_params_config.error_handler(err_code);
Jonathan Austin 0:bc2961fa1ef0 278 }
Jonathan Austin 0:bc2961fa1ef0 279 #else
Jonathan Austin 0:bc2961fa1ef0 280 m_conn_params_timer.detach();
Jonathan Austin 0:bc2961fa1ef0 281 #endif
Jonathan Austin 0:bc2961fa1ef0 282 }
Jonathan Austin 0:bc2961fa1ef0 283
Jonathan Austin 0:bc2961fa1ef0 284
Jonathan Austin 0:bc2961fa1ef0 285 static void on_write(ble_evt_t * p_ble_evt)
Jonathan Austin 0:bc2961fa1ef0 286 {
Jonathan Austin 0:bc2961fa1ef0 287 ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
Jonathan Austin 0:bc2961fa1ef0 288
Jonathan Austin 0:bc2961fa1ef0 289 // Check if this the correct CCCD
Jonathan Austin 0:bc2961fa1ef0 290 if (
Jonathan Austin 0:bc2961fa1ef0 291 (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle)
Jonathan Austin 0:bc2961fa1ef0 292 &&
Jonathan Austin 0:bc2961fa1ef0 293 (p_evt_write->len == 2)
Jonathan Austin 0:bc2961fa1ef0 294 )
Jonathan Austin 0:bc2961fa1ef0 295 {
Jonathan Austin 0:bc2961fa1ef0 296 // Check if this is a 'start notification'
Jonathan Austin 0:bc2961fa1ef0 297 if (ble_srv_is_notification_enabled(p_evt_write->data))
Jonathan Austin 0:bc2961fa1ef0 298 {
Jonathan Austin 0:bc2961fa1ef0 299 // Do connection parameter negotiation if necessary
Jonathan Austin 0:bc2961fa1ef0 300 conn_params_negotiation();
Jonathan Austin 0:bc2961fa1ef0 301 }
Jonathan Austin 0:bc2961fa1ef0 302 else
Jonathan Austin 0:bc2961fa1ef0 303 {
Jonathan Austin 0:bc2961fa1ef0 304 #ifdef USE_APP_TIMER
Jonathan Austin 0:bc2961fa1ef0 305 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 306
Jonathan Austin 0:bc2961fa1ef0 307 // Stop timer if running
Jonathan Austin 0:bc2961fa1ef0 308 err_code = app_timer_stop(m_conn_params_timer_id);
Jonathan Austin 0:bc2961fa1ef0 309 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
Jonathan Austin 0:bc2961fa1ef0 310 {
Jonathan Austin 0:bc2961fa1ef0 311 m_conn_params_config.error_handler(err_code);
Jonathan Austin 0:bc2961fa1ef0 312 }
Jonathan Austin 0:bc2961fa1ef0 313 #else /* #if !USE_APP_TIMER */
Jonathan Austin 0:bc2961fa1ef0 314 m_conn_params_timer.detach();
Jonathan Austin 0:bc2961fa1ef0 315 #endif /* #if !USE_APP_TIMER */
Jonathan Austin 0:bc2961fa1ef0 316 }
Jonathan Austin 0:bc2961fa1ef0 317 }
Jonathan Austin 0:bc2961fa1ef0 318 }
Jonathan Austin 0:bc2961fa1ef0 319
Jonathan Austin 0:bc2961fa1ef0 320
Jonathan Austin 0:bc2961fa1ef0 321 static void on_conn_params_update(ble_evt_t * p_ble_evt)
Jonathan Austin 0:bc2961fa1ef0 322 {
Jonathan Austin 0:bc2961fa1ef0 323 // Copy the parameters
Jonathan Austin 0:bc2961fa1ef0 324 m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params;
Jonathan Austin 0:bc2961fa1ef0 325
Jonathan Austin 0:bc2961fa1ef0 326 conn_params_negotiation();
Jonathan Austin 0:bc2961fa1ef0 327 }
Jonathan Austin 0:bc2961fa1ef0 328
Jonathan Austin 0:bc2961fa1ef0 329
Jonathan Austin 0:bc2961fa1ef0 330 void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt)
Jonathan Austin 0:bc2961fa1ef0 331 {
Jonathan Austin 0:bc2961fa1ef0 332 switch (p_ble_evt->header.evt_id)
Jonathan Austin 0:bc2961fa1ef0 333 {
Jonathan Austin 0:bc2961fa1ef0 334 case BLE_GAP_EVT_CONNECTED:
Jonathan Austin 0:bc2961fa1ef0 335 on_connect(p_ble_evt);
Jonathan Austin 0:bc2961fa1ef0 336 break;
Jonathan Austin 0:bc2961fa1ef0 337
Jonathan Austin 0:bc2961fa1ef0 338 case BLE_GAP_EVT_DISCONNECTED:
Jonathan Austin 0:bc2961fa1ef0 339 on_disconnect(p_ble_evt);
Jonathan Austin 0:bc2961fa1ef0 340 break;
Jonathan Austin 0:bc2961fa1ef0 341
Jonathan Austin 0:bc2961fa1ef0 342 case BLE_GATTS_EVT_WRITE:
Jonathan Austin 0:bc2961fa1ef0 343 on_write(p_ble_evt);
Jonathan Austin 0:bc2961fa1ef0 344 break;
Jonathan Austin 0:bc2961fa1ef0 345
Jonathan Austin 0:bc2961fa1ef0 346 case BLE_GAP_EVT_CONN_PARAM_UPDATE:
Jonathan Austin 0:bc2961fa1ef0 347 on_conn_params_update(p_ble_evt);
Jonathan Austin 0:bc2961fa1ef0 348 break;
Jonathan Austin 0:bc2961fa1ef0 349
Jonathan Austin 0:bc2961fa1ef0 350 default:
Jonathan Austin 0:bc2961fa1ef0 351 // No implementation needed.
Jonathan Austin 0:bc2961fa1ef0 352 break;
Jonathan Austin 0:bc2961fa1ef0 353 }
Jonathan Austin 0:bc2961fa1ef0 354 }
Jonathan Austin 0:bc2961fa1ef0 355
Jonathan Austin 0:bc2961fa1ef0 356
Jonathan Austin 0:bc2961fa1ef0 357 uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t * new_params)
Jonathan Austin 0:bc2961fa1ef0 358 {
Jonathan Austin 0:bc2961fa1ef0 359 uint32_t err_code;
Jonathan Austin 0:bc2961fa1ef0 360
Jonathan Austin 0:bc2961fa1ef0 361 m_preferred_conn_params = *new_params;
Jonathan Austin 0:bc2961fa1ef0 362 // Set the connection params in stack
Jonathan Austin 0:bc2961fa1ef0 363 err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
Jonathan Austin 0:bc2961fa1ef0 364 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 365 {
Jonathan Austin 0:bc2961fa1ef0 366 if (!is_conn_params_ok(&m_current_conn_params))
Jonathan Austin 0:bc2961fa1ef0 367 {
Jonathan Austin 0:bc2961fa1ef0 368 m_change_param = true;
Jonathan Austin 0:bc2961fa1ef0 369 err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
Jonathan Austin 0:bc2961fa1ef0 370 m_update_count = 1;
Jonathan Austin 0:bc2961fa1ef0 371 }
Jonathan Austin 0:bc2961fa1ef0 372 else
Jonathan Austin 0:bc2961fa1ef0 373 {
Jonathan Austin 0:bc2961fa1ef0 374 // Notify the application that the procedure has succeded
Jonathan Austin 0:bc2961fa1ef0 375 if (m_conn_params_config.evt_handler != NULL)
Jonathan Austin 0:bc2961fa1ef0 376 {
Jonathan Austin 0:bc2961fa1ef0 377 ble_conn_params_evt_t evt;
Jonathan Austin 0:bc2961fa1ef0 378
Jonathan Austin 0:bc2961fa1ef0 379 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
Jonathan Austin 0:bc2961fa1ef0 380 m_conn_params_config.evt_handler(&evt);
Jonathan Austin 0:bc2961fa1ef0 381 }
Jonathan Austin 0:bc2961fa1ef0 382 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 383 }
Jonathan Austin 0:bc2961fa1ef0 384 }
Jonathan Austin 0:bc2961fa1ef0 385 return err_code;
Jonathan Austin 0:bc2961fa1ef0 386 }