SG RFID nRF51822 fork
Fork of nRF51822 by
Embed:
(wiki syntax)
Show/hide line numbers
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 "ble_srv_common.h " 00018 #include "app_util.h " 00019 #include "mbed.h" 00020 00021 static ble_conn_params_init_t m_conn_params_config; /**< Configuration as specified by the application. */ 00022 static ble_gap_conn_params_t m_preferred_conn_params; /**< Connection parameters preferred by the application. */ 00023 static uint8_t m_update_count; /**< Number of Connection Parameter Update messages that has currently been sent. */ 00024 static uint16_t m_conn_handle; /**< Current connection handle. */ 00025 static ble_gap_conn_params_t m_current_conn_params; /**< Connection parameters received in the most recent Connect event. */ 00026 static Ticker m_conn_params_timer; 00027 00028 static bool m_change_param = false; 00029 00030 static bool is_conn_params_ok(ble_gap_conn_params_t * p_conn_params) 00031 { 00032 // Check if interval is within the acceptable range. 00033 // NOTE: Using max_conn_interval in the received event data because this contains 00034 // the client's connection interval. 00035 if ((p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval) && 00036 (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval)) { 00037 return true; 00038 } else { 00039 return false; 00040 } 00041 } 00042 00043 00044 static void update_timeout_handler(void) 00045 { 00046 m_conn_params_timer.detach(); /* this is supposed to be a single-shot timer callback */ 00047 if (m_conn_handle != BLE_CONN_HANDLE_INVALID) 00048 { 00049 // Check if we have reached the maximum number of attempts 00050 m_update_count++; 00051 if (m_update_count <= m_conn_params_config.max_conn_params_update_count) 00052 { 00053 uint32_t err_code; 00054 00055 // Parameters are not ok, send connection parameters update request. 00056 err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params); 00057 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00058 { 00059 m_conn_params_config.error_handler(err_code); 00060 } 00061 } 00062 else 00063 { 00064 m_update_count = 0; 00065 00066 // Negotiation failed, disconnect automatically if this has been configured 00067 if (m_conn_params_config.disconnect_on_fail) 00068 { 00069 uint32_t err_code; 00070 00071 err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); 00072 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) 00073 { 00074 m_conn_params_config.error_handler(err_code); 00075 } 00076 } 00077 00078 // Notify the application that the procedure has failed 00079 if (m_conn_params_config.evt_handler != NULL) 00080 { 00081 ble_conn_params_evt_t evt; 00082 00083 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED; 00084 m_conn_params_config.evt_handler(&evt); 00085 } 00086 } 00087 } 00088 } 00089 00090 00091 uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init) 00092 { 00093 uint32_t err_code; 00094 00095 m_conn_params_config = *p_init; 00096 m_change_param = false; 00097 if (p_init->p_conn_params != NULL) 00098 { 00099 m_preferred_conn_params = *p_init->p_conn_params; 00100 00101 // Set the connection params in stack 00102 err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params); 00103 if (err_code != NRF_SUCCESS) 00104 { 00105 return err_code; 00106 } 00107 } 00108 else 00109 { 00110 // Fetch the connection params from stack 00111 err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params); 00112 if (err_code != NRF_SUCCESS) 00113 { 00114 return err_code; 00115 } 00116 } 00117 00118 m_conn_handle = BLE_CONN_HANDLE_INVALID; 00119 m_update_count = 0; 00120 00121 return NRF_SUCCESS; 00122 } 00123 00124 00125 uint32_t ble_conn_params_stop(void) 00126 { 00127 m_conn_params_timer.detach(); 00128 return NRF_SUCCESS; 00129 } 00130 00131 00132 static void conn_params_negotiation(void) 00133 { 00134 // Start negotiation if the received connection parameters are not acceptable 00135 if (!is_conn_params_ok(&m_current_conn_params)) 00136 { 00137 uint32_t timeout_ticks; 00138 00139 if (m_change_param) 00140 { 00141 // Notify the application that the procedure has failed 00142 if (m_conn_params_config.evt_handler != NULL) 00143 { 00144 ble_conn_params_evt_t evt; 00145 00146 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED; 00147 m_conn_params_config.evt_handler(&evt); 00148 } 00149 } 00150 else 00151 { 00152 if (m_update_count == 0) 00153 { 00154 // First connection parameter update 00155 timeout_ticks = m_conn_params_config.first_conn_params_update_delay; 00156 } 00157 else 00158 { 00159 timeout_ticks = m_conn_params_config.next_conn_params_update_delay; 00160 } 00161 00162 m_conn_params_timer.attach(update_timeout_handler, timeout_ticks / 32768); 00163 } 00164 } 00165 else 00166 { 00167 // Notify the application that the procedure has succeded 00168 if (m_conn_params_config.evt_handler != NULL) 00169 { 00170 ble_conn_params_evt_t evt; 00171 00172 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED; 00173 m_conn_params_config.evt_handler(&evt); 00174 } 00175 } 00176 m_change_param = false; 00177 } 00178 00179 00180 static void on_connect(ble_evt_t * p_ble_evt) 00181 { 00182 // Save connection parameters 00183 m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; 00184 m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params; 00185 m_update_count = 0; // Connection parameter negotiation should re-start every connection 00186 00187 // Check if we shall handle negotiation on connect 00188 if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID) 00189 { 00190 conn_params_negotiation(); 00191 } 00192 } 00193 00194 00195 static void on_disconnect(ble_evt_t * p_ble_evt) 00196 { 00197 m_conn_handle = BLE_CONN_HANDLE_INVALID; 00198 00199 // Stop timer if running 00200 m_update_count = 0; // Connection parameters updates should happen during every connection 00201 00202 m_conn_params_timer.detach(); 00203 } 00204 00205 00206 static void on_write(ble_evt_t * p_ble_evt) 00207 { 00208 ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; 00209 00210 // Check if this the correct CCCD 00211 if ( 00212 (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle) 00213 && 00214 (p_evt_write->len == 2) 00215 ) 00216 { 00217 // Check if this is a 'start notification' 00218 if (ble_srv_is_notification_enabled(p_evt_write->data)) 00219 { 00220 // Do connection parameter negotiation if necessary 00221 conn_params_negotiation(); 00222 } 00223 else 00224 { 00225 // Stop timer if running 00226 m_conn_params_timer.detach(); 00227 } 00228 } 00229 } 00230 00231 00232 static void on_conn_params_update(ble_evt_t * p_ble_evt) 00233 { 00234 // Copy the parameters 00235 m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params; 00236 00237 conn_params_negotiation(); 00238 } 00239 00240 00241 void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt) 00242 { 00243 switch (p_ble_evt->header.evt_id) 00244 { 00245 case BLE_GAP_EVT_CONNECTED: 00246 on_connect(p_ble_evt); 00247 break; 00248 00249 case BLE_GAP_EVT_DISCONNECTED: 00250 on_disconnect(p_ble_evt); 00251 break; 00252 00253 case BLE_GATTS_EVT_WRITE: 00254 on_write(p_ble_evt); 00255 break; 00256 00257 case BLE_GAP_EVT_CONN_PARAM_UPDATE: 00258 on_conn_params_update(p_ble_evt); 00259 break; 00260 00261 default: 00262 // No implementation needed. 00263 break; 00264 } 00265 } 00266 00267 uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params) 00268 { 00269 uint32_t err_code; 00270 00271 m_preferred_conn_params = *new_params; 00272 // Set the connection params in stack 00273 err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params); 00274 if (err_code == NRF_SUCCESS) 00275 { 00276 if (!is_conn_params_ok(&m_current_conn_params)) 00277 { 00278 m_change_param = true; 00279 err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params); 00280 m_update_count = 1; 00281 } 00282 else 00283 { 00284 // Notify the application that the procedure has succeded 00285 if (m_conn_params_config.evt_handler != NULL) 00286 { 00287 ble_conn_params_evt_t evt; 00288 00289 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED; 00290 m_conn_params_config.evt_handler(&evt); 00291 } 00292 err_code = NRF_SUCCESS; 00293 } 00294 } 00295 return err_code; 00296 }
Generated on Tue Jul 12 2022 15:07:43 by 1.7.2