Nordic stack and drivers for the mbed BLE API

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate writable_gatt ... more

Committer:
Vincent Coubard
Date:
Wed Sep 14 14:39:43 2016 +0100
Revision:
638:c90ae1400bf2
Sync with bdab10dc0f90748b6989c8b577771bb403ca6bd8 from ARMmbed/mbed-os.

Who changed what in which revision?

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