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 nrf51-sdk by
ble_conn_state.c
00001 /* 00002 * Copyright (c) Nordic Semiconductor ASA 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without modification, 00006 * are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, this 00009 * list of conditions and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, this 00012 * list of conditions and the following disclaimer in the documentation and/or 00013 * other materials provided with the distribution. 00014 * 00015 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 00016 * contributors to this software may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00021 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00023 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00024 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00027 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 */ 00032 00033 #include "ble_conn_state.h " 00034 #include <stdbool.h> 00035 #include <stdint.h> 00036 #include <string.h> 00037 #include "nrf_ble.h" 00038 #include "sdk_mapped_flags.h " 00039 #include "app_error.h " 00040 00041 00042 #if defined(__CC_ARM) 00043 #pragma push 00044 #pragma anon_unions 00045 #elif defined(__ICCARM__) 00046 #pragma language=extended 00047 #elif defined(__GNUC__) 00048 /* anonymous unions are enabled by default */ 00049 #endif 00050 00051 00052 #define BLE_CONN_STATE_N_DEFAULT_FLAGS 5 /**< The number of flags kept for each connection, excluding user flags. */ 00053 #define BLE_CONN_STATE_N_FLAGS (BLE_CONN_STATE_N_DEFAULT_FLAGS + BLE_CONN_STATE_N_USER_FLAGS) /**< The number of flags kept for each connection, including user flags. */ 00054 00055 00056 /**@brief Structure containing all the flag collections maintained by the Connection State module. 00057 */ 00058 typedef struct 00059 { 00060 sdk_mapped_flags_t valid_flags; /**< Flags indicating which connection handles are valid. */ 00061 sdk_mapped_flags_t connected_flags; /**< Flags indicating which connections are connected, since disconnected connection handles will not immediately be invalidated. */ 00062 sdk_mapped_flags_t central_flags; /**< Flags indicating in which connections the local device is the central. */ 00063 sdk_mapped_flags_t encrypted_flags; /**< Flags indicating which connections are encrypted. */ 00064 sdk_mapped_flags_t mitm_protected_flags; /**< Flags indicating which connections have encryption with protection from man-in-the-middle attacks. */ 00065 sdk_mapped_flags_t user_flags[BLE_CONN_STATE_N_USER_FLAGS]; /**< Flags that can be reserved by the user. The flags will be cleared when a connection is invalidated, otherwise, the user is wholly responsible for the flag states. */ 00066 } ble_conn_state_flag_collections_t; 00067 00068 00069 /**@brief Structure containing the internal state of the Connection State module. 00070 */ 00071 typedef struct 00072 { 00073 uint16_t acquired_flags; /**< Bitmap for keeping track of which user flags have been acquired. */ 00074 uint16_t valid_conn_handles[SDK_MAPPED_FLAGS_N_KEYS]; /**< List of connection handles used as keys for the sdk_mapped_flags module. */ 00075 union 00076 { 00077 ble_conn_state_flag_collections_t flags; /**< Flag collections kept by the Connection State module. */ 00078 sdk_mapped_flags_t flag_array[BLE_CONN_STATE_N_FLAGS]; /**< Flag collections as array to allow use of @ref sdk_mapped_flags_bulk_update_by_key() when setting all flags. */ 00079 }; 00080 } ble_conn_state_t; 00081 00082 00083 #if defined(__CC_ARM) 00084 #pragma pop 00085 #elif defined(__ICCARM__) 00086 /* leave anonymous unions enabled */ 00087 #elif defined(__GNUC__) 00088 /* anonymous unions are enabled by default */ 00089 #endif 00090 00091 00092 static ble_conn_state_t m_bcs = {0}; /**< Instantiation of the internal state. */ 00093 00094 00095 /**@brief Function for resetting all internal memory to the values it had at initialization. 00096 */ 00097 void bcs_internal_state_reset(void) 00098 { 00099 memset( &m_bcs, 0, sizeof(ble_conn_state_t) ); 00100 } 00101 00102 00103 /**@brief Function for activating a connection record. 00104 * 00105 * @param p_record The record to activate. 00106 * @param conn_handle The connection handle to copy into the record. 00107 * @param role The role of the connection. 00108 * 00109 * @return whether the record was activated successfully. 00110 */ 00111 static bool record_activate(uint16_t conn_handle) 00112 { 00113 uint16_t available_index = sdk_mapped_flags_first_key_index_get(~m_bcs.flags.valid_flags); 00114 00115 if (available_index != SDK_MAPPED_FLAGS_INVALID_INDEX) 00116 { 00117 m_bcs.valid_conn_handles[available_index] = conn_handle; 00118 sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, 00119 &m_bcs.flags.connected_flags, 00120 conn_handle, 00121 1); 00122 sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, 00123 &m_bcs.flags.valid_flags, 00124 conn_handle, 00125 1); 00126 00127 return true; 00128 } 00129 00130 return false; 00131 } 00132 00133 00134 /**@brief Function for marking a connection record as invalid and resetting the values. 00135 * 00136 * @param p_record The record to invalidate. 00137 */ 00138 static void record_invalidate(uint16_t conn_handle) 00139 { 00140 sdk_mapped_flags_bulk_update_by_key(m_bcs.valid_conn_handles, 00141 m_bcs.flag_array, 00142 BLE_CONN_STATE_N_FLAGS, 00143 conn_handle, 00144 0); 00145 } 00146 00147 00148 /**@brief Function for marking a connection as disconnected. See @ref BLE_CONN_STATUS_DISCONNECTED. 00149 * 00150 * @param p_record The record of the connection to set as disconnected. 00151 */ 00152 static void record_set_disconnected(uint16_t conn_handle) 00153 { 00154 sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, 00155 &m_bcs.flags.connected_flags, 00156 conn_handle, 00157 0); 00158 } 00159 00160 00161 /**@brief Function for invalidating records with a @ref BLE_CONN_STATUS_DISCONNECTED 00162 * connection status 00163 */ 00164 static void record_purge_disconnected() 00165 { 00166 sdk_mapped_flags_key_list_t disconnected_list; 00167 00168 disconnected_list = sdk_mapped_flags_key_list_get( 00169 m_bcs.valid_conn_handles, 00170 (~m_bcs.flags.connected_flags) & (m_bcs.flags.valid_flags)); 00171 00172 for (int i = 0; i < disconnected_list.len; i++) 00173 { 00174 record_invalidate(disconnected_list.flag_keys[i]); 00175 } 00176 } 00177 00178 00179 /**@brief Function for checking if a user flag has been acquired. 00180 * 00181 * @param[in] flag_id Which flag to check. 00182 * 00183 * @return Whether the flag has been acquired. 00184 */ 00185 static bool user_flag_is_acquired(ble_conn_state_user_flag_id_t flag_id) 00186 { 00187 return ((m_bcs.acquired_flags & (1 << flag_id)) != 0); 00188 } 00189 00190 00191 /**@brief Function for marking a user flag as acquired. 00192 * 00193 * @param[in] flag_id Which flag to mark. 00194 */ 00195 static void user_flag_acquire(ble_conn_state_user_flag_id_t flag_id) 00196 { 00197 m_bcs.acquired_flags |= (1 << flag_id); 00198 } 00199 00200 00201 void ble_conn_state_init(void) 00202 { 00203 bcs_internal_state_reset(); 00204 } 00205 00206 00207 void ble_conn_state_on_ble_evt(ble_evt_t * p_ble_evt) 00208 { 00209 switch (p_ble_evt->header.evt_id) 00210 { 00211 case BLE_GAP_EVT_CONNECTED: 00212 record_purge_disconnected(); 00213 00214 if ( !record_activate(p_ble_evt->evt.gap_evt.conn_handle) ) 00215 { 00216 // No more records available. Should not happen. 00217 APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); 00218 } 00219 else 00220 { 00221 #if defined(TARGET_MCU_NRF51_16K_S110) || defined(TARGET_MCU_NRF51_32K_S110) 00222 bool is_central = false; 00223 #elif defined(TARGET_MCU_NRF51_16K_S120) || defined(TARGET_MCU_NRF51_32K_S120) 00224 bool is_central = true; 00225 #else 00226 bool is_central = 00227 (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_CENTRAL); 00228 #endif 00229 00230 sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, 00231 &m_bcs.flags.central_flags, 00232 p_ble_evt->evt.gap_evt.conn_handle, 00233 is_central); 00234 } 00235 00236 break; 00237 00238 case BLE_GAP_EVT_DISCONNECTED: 00239 record_set_disconnected(p_ble_evt->evt.gap_evt.conn_handle); 00240 break; 00241 00242 case BLE_GAP_EVT_CONN_SEC_UPDATE: 00243 sdk_mapped_flags_update_by_key( 00244 m_bcs.valid_conn_handles, 00245 &m_bcs.flags.encrypted_flags, 00246 p_ble_evt->evt.gap_evt.conn_handle, 00247 (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 1)); 00248 sdk_mapped_flags_update_by_key( 00249 m_bcs.valid_conn_handles, 00250 &m_bcs.flags.mitm_protected_flags, 00251 p_ble_evt->evt.gap_evt.conn_handle, 00252 (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 2)); 00253 break; 00254 } 00255 } 00256 00257 00258 bool ble_conn_state_valid(uint16_t conn_handle) 00259 { 00260 return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, 00261 m_bcs.flags.valid_flags, 00262 conn_handle); 00263 } 00264 00265 00266 uint8_t ble_conn_state_role(uint16_t conn_handle) 00267 { 00268 uint8_t role = BLE_GAP_ROLE_INVALID; 00269 00270 if ( sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, m_bcs.flags.valid_flags, conn_handle) ) 00271 { 00272 bool central = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, 00273 m_bcs.flags.central_flags, 00274 conn_handle); 00275 00276 role = central ? BLE_GAP_ROLE_CENTRAL : BLE_GAP_ROLE_PERIPH; 00277 } 00278 00279 return role; 00280 } 00281 00282 00283 ble_conn_state_status_t ble_conn_state_status(uint16_t conn_handle) 00284 { 00285 ble_conn_state_status_t conn_status = BLE_CONN_STATUS_INVALID; 00286 bool valid = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, 00287 m_bcs.flags.valid_flags, 00288 conn_handle); 00289 00290 if (valid) 00291 { 00292 bool connected = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, 00293 m_bcs.flags.connected_flags, 00294 conn_handle); 00295 00296 conn_status = connected ? BLE_CONN_STATUS_CONNECTED : BLE_CONN_STATUS_DISCONNECTED; 00297 } 00298 00299 return conn_status; 00300 } 00301 00302 00303 bool ble_conn_state_encrypted(uint16_t conn_handle) 00304 { 00305 return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, 00306 m_bcs.flags.encrypted_flags, 00307 conn_handle); 00308 } 00309 00310 00311 bool ble_conn_state_mitm_protected(uint16_t conn_handle) 00312 { 00313 return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, 00314 m_bcs.flags.mitm_protected_flags, 00315 conn_handle); 00316 } 00317 00318 00319 uint32_t ble_conn_state_n_connections(void) 00320 { 00321 return sdk_mapped_flags_n_flags_set(m_bcs.flags.connected_flags); 00322 } 00323 00324 00325 uint32_t ble_conn_state_n_centrals(void) 00326 { 00327 return sdk_mapped_flags_n_flags_set((m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags)); 00328 } 00329 00330 00331 uint32_t ble_conn_state_n_peripherals(void) 00332 { 00333 return sdk_mapped_flags_n_flags_set((~m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags)); 00334 } 00335 00336 00337 sdk_mapped_flags_key_list_t ble_conn_state_conn_handles(void) 00338 { 00339 return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles, m_bcs.flags.valid_flags); 00340 } 00341 00342 00343 sdk_mapped_flags_key_list_t ble_conn_state_central_handles(void) 00344 { 00345 return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles, 00346 (m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags)); 00347 } 00348 00349 00350 sdk_mapped_flags_key_list_t ble_conn_state_periph_handles(void) 00351 { 00352 return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles, 00353 (~m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags)); 00354 } 00355 00356 00357 ble_conn_state_user_flag_id_t ble_conn_state_user_flag_acquire(void) 00358 { 00359 for (ble_conn_state_user_flag_id_t i = BLE_CONN_STATE_USER_FLAG0; 00360 i < BLE_CONN_STATE_N_USER_FLAGS; 00361 i++) 00362 { 00363 if ( !user_flag_is_acquired(i) ) 00364 { 00365 user_flag_acquire(i); 00366 return i; 00367 } 00368 } 00369 00370 return BLE_CONN_STATE_USER_FLAG_INVALID; 00371 } 00372 00373 00374 bool ble_conn_state_user_flag_get(uint16_t conn_handle, ble_conn_state_user_flag_id_t flag_id) 00375 { 00376 if (user_flag_is_acquired(flag_id)) 00377 { 00378 return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, 00379 m_bcs.flags.user_flags[flag_id], 00380 conn_handle); 00381 } 00382 else 00383 { 00384 return false; 00385 } 00386 } 00387 00388 00389 void ble_conn_state_user_flag_set(uint16_t conn_handle, 00390 ble_conn_state_user_flag_id_t flag_id, 00391 bool value) 00392 { 00393 if (user_flag_is_acquired(flag_id)) 00394 { 00395 sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, 00396 &m_bcs.flags.user_flags[flag_id], 00397 conn_handle, 00398 value); 00399 } 00400 } 00401 00402 00403 sdk_mapped_flags_t ble_conn_state_user_flag_collection(ble_conn_state_user_flag_id_t flag_id) 00404 { 00405 if ( user_flag_is_acquired(flag_id) ) 00406 { 00407 return m_bcs.flags.user_flags[flag_id]; 00408 } 00409 else 00410 { 00411 return 0; 00412 } 00413 }
Generated on Tue Jul 12 2022 14:11:18 by
