R1 code for micro:bit based train controller code, requires second micro:bit running rx code to operate - see https://meanderingpi.wordpress.com/ for more information
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 "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 } 00414
Generated on Tue Jul 12 2022 19:00:11 by 1.7.2