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
ble_conn_params.cpp
00001 /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. 00002 * 00003 * The information contained herein is property of Nordic Semiconductor ASA. 00004 * Terms and conditions of usage are described in detail in NORDIC 00005 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 00006 * 00007 * Licensees are granted free, non-transferable use of the information. NO 00008 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 00009 * the file. 00010 * 00011 */ 00012 00013 #include "ble_conn_params.h " 00014 #include <stdlib.h> 00015 #include "nordic_common.h" 00016 #include "ble_hci.h" 00017 #include "app_timer.h " 00018 #include "ble_srv_common.h " 00019 #include "app_util.h " 00020 00021 00022 static ble_conn_params_init_t m_conn_params_config; /**< Configuration as specified by the application. */ 00023 static ble_gap_conn_params_t m_preferred_conn_params; /**< Connection parameters preferred by the application. */ 00024 static uint8_t m_update_count; /**< Number of Connection Parameter Update messages that has currently been sent. */ 00025 static uint16_t m_conn_handle; /**< Current connection handle. */ 00026 static ble_gap_conn_params_t m_current_conn_params; /**< Connection parameters received in the most recent Connect event. */ 00027 static app_timer_id_t m_conn_params_timer_id; /**< Connection parameters timer. */ 00028 00029 static bool m_change_param = false; 00030 00031 static bool is_conn_params_ok(ble_gap_conn_params_t * p_conn_params) 00032 { 00033 // Check if interval is within the acceptable range. 00034 // NOTE: Using max_conn_interval in the received event data because this contains 00035 // the client's connection interval. 00036 if ( 00037 (p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval) 00038 && 00039 (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval) 00040 ) 00041 { 00042 return true; 00043 } 00044 else 00045 { 00046 return false; 00047 } 00048 } 00049 00050 00051 static void update_timeout_handler(void * p_context) 00052 { 00053 UNUSED_PARAMETER(p_context); 00054 00055 if (m_conn_handle != BLE_CONN_HANDLE_INVALID) 00056 { 00057 // Check if we have reached the maximum number of attempts 00058 m_update_count++; 00059 if (m_update_count <= m_conn_params_config.max_conn_params_update_count) 00060 { 00061 uint32_t err_code; 00062 00063 // Parameters are not ok, send connection parameters update request. 00064 err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params); 00065 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00066 { 00067 m_conn_params_config.error_handler(err_code); 00068 } 00069 } 00070 else 00071 { 00072 m_update_count = 0; 00073 00074 // Negotiation failed, disconnect automatically if this has been configured 00075 if (m_conn_params_config.disconnect_on_fail) 00076 { 00077 uint32_t err_code; 00078 00079 err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); 00080 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00081 { 00082 m_conn_params_config.error_handler(err_code); 00083 } 00084 } 00085 00086 // Notify the application that the procedure has failed 00087 if (m_conn_params_config.evt_handler != NULL) 00088 { 00089 ble_conn_params_evt_t evt; 00090 00091 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED; 00092 m_conn_params_config.evt_handler(&evt); 00093 } 00094 } 00095 } 00096 } 00097 00098 00099 uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init) 00100 { 00101 uint32_t err_code; 00102 00103 m_conn_params_config = *p_init; 00104 m_change_param = false; 00105 if (p_init->p_conn_params != NULL) 00106 { 00107 m_preferred_conn_params = *p_init->p_conn_params; 00108 00109 // Set the connection params in stack 00110 err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params); 00111 if (err_code != NRF_SUCCESS) 00112 { 00113 return err_code; 00114 } 00115 } 00116 else 00117 { 00118 // Fetch the connection params from stack 00119 err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params); 00120 if (err_code != NRF_SUCCESS) 00121 { 00122 return err_code; 00123 } 00124 } 00125 00126 m_conn_handle = BLE_CONN_HANDLE_INVALID; 00127 m_update_count = 0; 00128 00129 return app_timer_create(&m_conn_params_timer_id, 00130 APP_TIMER_MODE_SINGLE_SHOT, 00131 update_timeout_handler); 00132 } 00133 00134 00135 uint32_t ble_conn_params_stop(void) 00136 { 00137 return app_timer_stop(m_conn_params_timer_id); 00138 } 00139 00140 00141 static void conn_params_negotiation(void) 00142 { 00143 // Start negotiation if the received connection parameters are not acceptable 00144 if (!is_conn_params_ok(&m_current_conn_params)) 00145 { 00146 uint32_t err_code; 00147 uint32_t timeout_ticks; 00148 00149 if (m_change_param) 00150 { 00151 // Notify the application that the procedure has failed 00152 if (m_conn_params_config.evt_handler != NULL) 00153 { 00154 ble_conn_params_evt_t evt; 00155 00156 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED; 00157 m_conn_params_config.evt_handler(&evt); 00158 } 00159 } 00160 else 00161 { 00162 if (m_update_count == 0) 00163 { 00164 // First connection parameter update 00165 timeout_ticks = m_conn_params_config.first_conn_params_update_delay; 00166 } 00167 else 00168 { 00169 timeout_ticks = m_conn_params_config.next_conn_params_update_delay; 00170 } 00171 00172 err_code = app_timer_start(m_conn_params_timer_id, timeout_ticks, NULL); 00173 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00174 { 00175 m_conn_params_config.error_handler(err_code); 00176 } 00177 } 00178 } 00179 else 00180 { 00181 // Notify the application that the procedure has succeded 00182 if (m_conn_params_config.evt_handler != NULL) 00183 { 00184 ble_conn_params_evt_t evt; 00185 00186 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED; 00187 m_conn_params_config.evt_handler(&evt); 00188 } 00189 } 00190 m_change_param = false; 00191 } 00192 00193 00194 static void on_connect(ble_evt_t * p_ble_evt) 00195 { 00196 // Save connection parameters 00197 m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; 00198 m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params; 00199 m_update_count = 0; // Connection parameter negotiation should re-start every connection 00200 00201 // Check if we shall handle negotiation on connect 00202 if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID) 00203 { 00204 conn_params_negotiation(); 00205 } 00206 } 00207 00208 00209 static void on_disconnect(ble_evt_t * p_ble_evt) 00210 { 00211 uint32_t err_code; 00212 00213 m_conn_handle = BLE_CONN_HANDLE_INVALID; 00214 00215 // Stop timer if running 00216 m_update_count = 0; // Connection parameters updates should happen during every connection 00217 00218 err_code = app_timer_stop(m_conn_params_timer_id); 00219 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00220 { 00221 m_conn_params_config.error_handler(err_code); 00222 } 00223 } 00224 00225 00226 static void on_write(ble_evt_t * p_ble_evt) 00227 { 00228 ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; 00229 00230 // Check if this the correct CCCD 00231 if ( 00232 (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle) 00233 && 00234 (p_evt_write->len == 2) 00235 ) 00236 { 00237 // Check if this is a 'start notification' 00238 if (ble_srv_is_notification_enabled(p_evt_write->data)) 00239 { 00240 // Do connection parameter negotiation if necessary 00241 conn_params_negotiation(); 00242 } 00243 else 00244 { 00245 uint32_t err_code; 00246 00247 // Stop timer if running 00248 err_code = app_timer_stop(m_conn_params_timer_id); 00249 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00250 { 00251 m_conn_params_config.error_handler(err_code); 00252 } 00253 } 00254 } 00255 } 00256 00257 00258 static void on_conn_params_update(ble_evt_t * p_ble_evt) 00259 { 00260 // Copy the parameters 00261 m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params; 00262 00263 conn_params_negotiation(); 00264 } 00265 00266 00267 void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt) 00268 { 00269 switch (p_ble_evt->header.evt_id) 00270 { 00271 case BLE_GAP_EVT_CONNECTED: 00272 on_connect(p_ble_evt); 00273 break; 00274 00275 case BLE_GAP_EVT_DISCONNECTED: 00276 on_disconnect(p_ble_evt); 00277 break; 00278 00279 case BLE_GATTS_EVT_WRITE: 00280 on_write(p_ble_evt); 00281 break; 00282 00283 case BLE_GAP_EVT_CONN_PARAM_UPDATE: 00284 on_conn_params_update(p_ble_evt); 00285 break; 00286 00287 default: 00288 // No implementation needed. 00289 break; 00290 } 00291 } 00292 00293 uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params) 00294 { 00295 uint32_t err_code; 00296 00297 m_preferred_conn_params = *new_params; 00298 // Set the connection params in stack 00299 err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params); 00300 if (err_code == NRF_SUCCESS) 00301 { 00302 if (!is_conn_params_ok(&m_current_conn_params)) 00303 { 00304 m_change_param = true; 00305 err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params); 00306 m_update_count = 1; 00307 } 00308 else 00309 { 00310 // Notify the application that the procedure has succeded 00311 if (m_conn_params_config.evt_handler != NULL) 00312 { 00313 ble_conn_params_evt_t evt; 00314 00315 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED; 00316 m_conn_params_config.evt_handler(&evt); 00317 } 00318 err_code = NRF_SUCCESS; 00319 } 00320 } 00321 return err_code; 00322 }
Generated on Tue Jul 12 2022 19:00:52 by
