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