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 BLE_WallbotBLE_Challenge 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 ((p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval) && 00037 (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval)) { 00038 return true; 00039 } else { 00040 return false; 00041 } 00042 } 00043 00044 00045 static void update_timeout_handler(void * p_context) 00046 { 00047 UNUSED_PARAMETER(p_context); 00048 00049 if (m_conn_handle != BLE_CONN_HANDLE_INVALID) 00050 { 00051 // Check if we have reached the maximum number of attempts 00052 m_update_count++; 00053 if (m_update_count <= m_conn_params_config.max_conn_params_update_count) 00054 { 00055 uint32_t err_code; 00056 00057 // Parameters are not ok, send connection parameters update request. 00058 err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params); 00059 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00060 { 00061 m_conn_params_config.error_handler(err_code); 00062 } 00063 } 00064 else 00065 { 00066 m_update_count = 0; 00067 00068 // Negotiation failed, disconnect automatically if this has been configured 00069 if (m_conn_params_config.disconnect_on_fail) 00070 { 00071 uint32_t err_code; 00072 00073 err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); 00074 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00075 { 00076 m_conn_params_config.error_handler(err_code); 00077 } 00078 } 00079 00080 // Notify the application that the procedure has failed 00081 if (m_conn_params_config.evt_handler != NULL) 00082 { 00083 ble_conn_params_evt_t evt; 00084 00085 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED; 00086 m_conn_params_config.evt_handler(&evt); 00087 } 00088 } 00089 } 00090 } 00091 00092 00093 uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init) 00094 { 00095 uint32_t err_code; 00096 00097 m_conn_params_config = *p_init; 00098 m_change_param = false; 00099 if (p_init->p_conn_params != NULL) 00100 { 00101 m_preferred_conn_params = *p_init->p_conn_params; 00102 00103 // Set the connection params in stack 00104 err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params); 00105 if (err_code != NRF_SUCCESS) 00106 { 00107 return err_code; 00108 } 00109 } 00110 else 00111 { 00112 // Fetch the connection params from stack 00113 err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params); 00114 if (err_code != NRF_SUCCESS) 00115 { 00116 return err_code; 00117 } 00118 } 00119 00120 m_conn_handle = BLE_CONN_HANDLE_INVALID; 00121 m_update_count = 0; 00122 00123 return app_timer_create(&m_conn_params_timer_id, 00124 APP_TIMER_MODE_SINGLE_SHOT, 00125 update_timeout_handler); 00126 } 00127 00128 00129 uint32_t ble_conn_params_stop(void) 00130 { 00131 return app_timer_stop(m_conn_params_timer_id); 00132 } 00133 00134 00135 static void conn_params_negotiation(void) 00136 { 00137 // Start negotiation if the received connection parameters are not acceptable 00138 if (!is_conn_params_ok(&m_current_conn_params)) 00139 { 00140 uint32_t err_code; 00141 uint32_t timeout_ticks; 00142 00143 if (m_change_param) 00144 { 00145 // Notify the application that the procedure has failed 00146 if (m_conn_params_config.evt_handler != NULL) 00147 { 00148 ble_conn_params_evt_t evt; 00149 00150 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED; 00151 m_conn_params_config.evt_handler(&evt); 00152 } 00153 } 00154 else 00155 { 00156 if (m_update_count == 0) 00157 { 00158 // First connection parameter update 00159 timeout_ticks = m_conn_params_config.first_conn_params_update_delay; 00160 } 00161 else 00162 { 00163 timeout_ticks = m_conn_params_config.next_conn_params_update_delay; 00164 } 00165 00166 err_code = app_timer_start(m_conn_params_timer_id, timeout_ticks, NULL); 00167 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00168 { 00169 m_conn_params_config.error_handler(err_code); 00170 } 00171 } 00172 } 00173 else 00174 { 00175 // Notify the application that the procedure has succeded 00176 if (m_conn_params_config.evt_handler != NULL) 00177 { 00178 ble_conn_params_evt_t evt; 00179 00180 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED; 00181 m_conn_params_config.evt_handler(&evt); 00182 } 00183 } 00184 m_change_param = false; 00185 } 00186 00187 00188 static void on_connect(ble_evt_t * p_ble_evt) 00189 { 00190 // Save connection parameters 00191 m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; 00192 m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params; 00193 m_update_count = 0; // Connection parameter negotiation should re-start every connection 00194 00195 // Check if we shall handle negotiation on connect 00196 if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID) 00197 { 00198 conn_params_negotiation(); 00199 } 00200 } 00201 00202 00203 static void on_disconnect(ble_evt_t * p_ble_evt) 00204 { 00205 uint32_t err_code; 00206 00207 m_conn_handle = BLE_CONN_HANDLE_INVALID; 00208 00209 // Stop timer if running 00210 m_update_count = 0; // Connection parameters updates should happen during every connection 00211 00212 err_code = app_timer_stop(m_conn_params_timer_id); 00213 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00214 { 00215 m_conn_params_config.error_handler(err_code); 00216 } 00217 } 00218 00219 00220 static void on_write(ble_evt_t * p_ble_evt) 00221 { 00222 ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; 00223 00224 // Check if this the correct CCCD 00225 if ( 00226 (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle) 00227 && 00228 (p_evt_write->len == 2) 00229 ) 00230 { 00231 // Check if this is a 'start notification' 00232 if (ble_srv_is_notification_enabled(p_evt_write->data)) 00233 { 00234 // Do connection parameter negotiation if necessary 00235 conn_params_negotiation(); 00236 } 00237 else 00238 { 00239 uint32_t err_code; 00240 00241 // Stop timer if running 00242 err_code = app_timer_stop(m_conn_params_timer_id); 00243 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00244 { 00245 m_conn_params_config.error_handler(err_code); 00246 } 00247 } 00248 } 00249 } 00250 00251 00252 static void on_conn_params_update(ble_evt_t * p_ble_evt) 00253 { 00254 // Copy the parameters 00255 m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params; 00256 00257 conn_params_negotiation(); 00258 } 00259 00260 00261 void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt) 00262 { 00263 switch (p_ble_evt->header.evt_id) 00264 { 00265 case BLE_GAP_EVT_CONNECTED: 00266 on_connect(p_ble_evt); 00267 break; 00268 00269 case BLE_GAP_EVT_DISCONNECTED: 00270 on_disconnect(p_ble_evt); 00271 break; 00272 00273 case BLE_GATTS_EVT_WRITE: 00274 on_write(p_ble_evt); 00275 break; 00276 00277 case BLE_GAP_EVT_CONN_PARAM_UPDATE: 00278 on_conn_params_update(p_ble_evt); 00279 break; 00280 00281 default: 00282 // No implementation needed. 00283 break; 00284 } 00285 } 00286 00287 uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params) 00288 { 00289 uint32_t err_code; 00290 00291 m_preferred_conn_params = *new_params; 00292 // Set the connection params in stack 00293 err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params); 00294 if (err_code == NRF_SUCCESS) 00295 { 00296 if (!is_conn_params_ok(&m_current_conn_params)) 00297 { 00298 m_change_param = true; 00299 err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params); 00300 m_update_count = 1; 00301 } 00302 else 00303 { 00304 // Notify the application that the procedure has succeded 00305 if (m_conn_params_config.evt_handler != NULL) 00306 { 00307 ble_conn_params_evt_t evt; 00308 00309 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED; 00310 m_conn_params_config.evt_handler(&evt); 00311 } 00312 err_code = NRF_SUCCESS; 00313 } 00314 } 00315 return err_code; 00316 }
Generated on Tue Jul 12 2022 13:52:30 by
