Nordic stack and drivers for the mbed BLE API
Dependents: Sensen-classic-v8-IAQ_copy_4
Fork of nRF51822 by
TARGET_MCU_NRF51822/sdk/source/ble/peer_manager/id_manager.c@638:c90ae1400bf2, 2016-09-14 (annotated)
- Committer:
- Vincent Coubard
- Date:
- Wed Sep 14 14:39:43 2016 +0100
- Revision:
- 638:c90ae1400bf2
Sync with bdab10dc0f90748b6989c8b577771bb403ca6bd8 from ARMmbed/mbed-os.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Vincent Coubard |
638:c90ae1400bf2 | 1 | /* |
Vincent Coubard |
638:c90ae1400bf2 | 2 | * Copyright (c) Nordic Semiconductor ASA |
Vincent Coubard |
638:c90ae1400bf2 | 3 | * All rights reserved. |
Vincent Coubard |
638:c90ae1400bf2 | 4 | * |
Vincent Coubard |
638:c90ae1400bf2 | 5 | * Redistribution and use in source and binary forms, with or without modification, |
Vincent Coubard |
638:c90ae1400bf2 | 6 | * are permitted provided that the following conditions are met: |
Vincent Coubard |
638:c90ae1400bf2 | 7 | * |
Vincent Coubard |
638:c90ae1400bf2 | 8 | * 1. Redistributions of source code must retain the above copyright notice, this |
Vincent Coubard |
638:c90ae1400bf2 | 9 | * list of conditions and the following disclaimer. |
Vincent Coubard |
638:c90ae1400bf2 | 10 | * |
Vincent Coubard |
638:c90ae1400bf2 | 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, this |
Vincent Coubard |
638:c90ae1400bf2 | 12 | * list of conditions and the following disclaimer in the documentation and/or |
Vincent Coubard |
638:c90ae1400bf2 | 13 | * other materials provided with the distribution. |
Vincent Coubard |
638:c90ae1400bf2 | 14 | * |
Vincent Coubard |
638:c90ae1400bf2 | 15 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of other |
Vincent Coubard |
638:c90ae1400bf2 | 16 | * contributors to this software may be used to endorse or promote products |
Vincent Coubard |
638:c90ae1400bf2 | 17 | * derived from this software without specific prior written permission. |
Vincent Coubard |
638:c90ae1400bf2 | 18 | * |
Vincent Coubard |
638:c90ae1400bf2 | 19 | * |
Vincent Coubard |
638:c90ae1400bf2 | 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
Vincent Coubard |
638:c90ae1400bf2 | 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
Vincent Coubard |
638:c90ae1400bf2 | 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
Vincent Coubard |
638:c90ae1400bf2 | 23 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
Vincent Coubard |
638:c90ae1400bf2 | 24 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
Vincent Coubard |
638:c90ae1400bf2 | 25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
Vincent Coubard |
638:c90ae1400bf2 | 26 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
Vincent Coubard |
638:c90ae1400bf2 | 27 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
Vincent Coubard |
638:c90ae1400bf2 | 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
Vincent Coubard |
638:c90ae1400bf2 | 29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Vincent Coubard |
638:c90ae1400bf2 | 30 | * |
Vincent Coubard |
638:c90ae1400bf2 | 31 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 32 | |
Vincent Coubard |
638:c90ae1400bf2 | 33 | #include "id_manager.h" |
Vincent Coubard |
638:c90ae1400bf2 | 34 | |
Vincent Coubard |
638:c90ae1400bf2 | 35 | #include <string.h> |
Vincent Coubard |
638:c90ae1400bf2 | 36 | #include "nrf_soc.h" |
Vincent Coubard |
638:c90ae1400bf2 | 37 | #include "ble_gap.h" |
Vincent Coubard |
638:c90ae1400bf2 | 38 | #include "ble_conn_state.h" |
Vincent Coubard |
638:c90ae1400bf2 | 39 | #include "peer_manager_types.h" |
Vincent Coubard |
638:c90ae1400bf2 | 40 | #include "peer_database.h" |
Vincent Coubard |
638:c90ae1400bf2 | 41 | #include "nordic_common.h" |
Vincent Coubard |
638:c90ae1400bf2 | 42 | |
Vincent Coubard |
638:c90ae1400bf2 | 43 | #define IM_MAX_CONN_HANDLES 8 |
Vincent Coubard |
638:c90ae1400bf2 | 44 | #define IM_NO_INVALID_CONN_HANDLES 0xFF |
Vincent Coubard |
638:c90ae1400bf2 | 45 | #define MAX_REGISTRANTS 3 |
Vincent Coubard |
638:c90ae1400bf2 | 46 | #define WHITELIST_MAX_COUNT MAX(BLE_GAP_WHITELIST_ADDR_MAX_COUNT, \ |
Vincent Coubard |
638:c90ae1400bf2 | 47 | BLE_GAP_WHITELIST_IRK_MAX_COUNT) |
Vincent Coubard |
638:c90ae1400bf2 | 48 | #define IM_ADDR_CLEARTEXT_LENGTH 3 |
Vincent Coubard |
638:c90ae1400bf2 | 49 | #define IM_ADDR_CIPHERTEXT_LENGTH 3 |
Vincent Coubard |
638:c90ae1400bf2 | 50 | |
Vincent Coubard |
638:c90ae1400bf2 | 51 | #define MODULE_INITIALIZED (m_im.n_registrants > 0) |
Vincent Coubard |
638:c90ae1400bf2 | 52 | |
Vincent Coubard |
638:c90ae1400bf2 | 53 | #define VERIFY_MODULE_INITIALIZED() \ |
Vincent Coubard |
638:c90ae1400bf2 | 54 | do \ |
Vincent Coubard |
638:c90ae1400bf2 | 55 | { \ |
Vincent Coubard |
638:c90ae1400bf2 | 56 | if (!MODULE_INITIALIZED) \ |
Vincent Coubard |
638:c90ae1400bf2 | 57 | { \ |
Vincent Coubard |
638:c90ae1400bf2 | 58 | return NRF_ERROR_INVALID_STATE; \ |
Vincent Coubard |
638:c90ae1400bf2 | 59 | } \ |
Vincent Coubard |
638:c90ae1400bf2 | 60 | } while(0) |
Vincent Coubard |
638:c90ae1400bf2 | 61 | |
Vincent Coubard |
638:c90ae1400bf2 | 62 | #define VERIFY_PARAM_NOT_NULL(param) \ |
Vincent Coubard |
638:c90ae1400bf2 | 63 | do \ |
Vincent Coubard |
638:c90ae1400bf2 | 64 | { \ |
Vincent Coubard |
638:c90ae1400bf2 | 65 | if (param == NULL) \ |
Vincent Coubard |
638:c90ae1400bf2 | 66 | { \ |
Vincent Coubard |
638:c90ae1400bf2 | 67 | return NRF_ERROR_NULL; \ |
Vincent Coubard |
638:c90ae1400bf2 | 68 | } \ |
Vincent Coubard |
638:c90ae1400bf2 | 69 | } while(0) |
Vincent Coubard |
638:c90ae1400bf2 | 70 | |
Vincent Coubard |
638:c90ae1400bf2 | 71 | |
Vincent Coubard |
638:c90ae1400bf2 | 72 | typedef struct |
Vincent Coubard |
638:c90ae1400bf2 | 73 | { |
Vincent Coubard |
638:c90ae1400bf2 | 74 | pm_peer_id_t peer_id; |
Vincent Coubard |
638:c90ae1400bf2 | 75 | uint16_t conn_handle; |
Vincent Coubard |
638:c90ae1400bf2 | 76 | ble_gap_addr_t peer_address; |
Vincent Coubard |
638:c90ae1400bf2 | 77 | } im_connection_t; |
Vincent Coubard |
638:c90ae1400bf2 | 78 | |
Vincent Coubard |
638:c90ae1400bf2 | 79 | typedef struct |
Vincent Coubard |
638:c90ae1400bf2 | 80 | { |
Vincent Coubard |
638:c90ae1400bf2 | 81 | im_evt_handler_t evt_handlers[MAX_REGISTRANTS]; |
Vincent Coubard |
638:c90ae1400bf2 | 82 | uint8_t n_registrants; |
Vincent Coubard |
638:c90ae1400bf2 | 83 | im_connection_t connections[8]; |
Vincent Coubard |
638:c90ae1400bf2 | 84 | pm_peer_id_t whitelist_peer_ids[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; |
Vincent Coubard |
638:c90ae1400bf2 | 85 | ble_gap_irk_t whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; |
Vincent Coubard |
638:c90ae1400bf2 | 86 | ble_gap_addr_t whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; |
Vincent Coubard |
638:c90ae1400bf2 | 87 | uint8_t n_whitelist_peer_ids; |
Vincent Coubard |
638:c90ae1400bf2 | 88 | ble_conn_state_user_flag_id_t conn_state_user_flag_id; |
Vincent Coubard |
638:c90ae1400bf2 | 89 | } im_t; |
Vincent Coubard |
638:c90ae1400bf2 | 90 | |
Vincent Coubard |
638:c90ae1400bf2 | 91 | static im_t m_im = {.n_registrants = 0}; |
Vincent Coubard |
638:c90ae1400bf2 | 92 | |
Vincent Coubard |
638:c90ae1400bf2 | 93 | static void internal_state_reset() |
Vincent Coubard |
638:c90ae1400bf2 | 94 | { |
Vincent Coubard |
638:c90ae1400bf2 | 95 | memset(&m_im, 0, sizeof(im_t)); |
Vincent Coubard |
638:c90ae1400bf2 | 96 | m_im.n_registrants = 0; |
Vincent Coubard |
638:c90ae1400bf2 | 97 | m_im.n_whitelist_peer_ids = 0; |
Vincent Coubard |
638:c90ae1400bf2 | 98 | m_im.conn_state_user_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID; |
Vincent Coubard |
638:c90ae1400bf2 | 99 | for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 100 | { |
Vincent Coubard |
638:c90ae1400bf2 | 101 | m_im.connections[i].conn_handle = BLE_CONN_HANDLE_INVALID; |
Vincent Coubard |
638:c90ae1400bf2 | 102 | } |
Vincent Coubard |
638:c90ae1400bf2 | 103 | } |
Vincent Coubard |
638:c90ae1400bf2 | 104 | |
Vincent Coubard |
638:c90ae1400bf2 | 105 | |
Vincent Coubard |
638:c90ae1400bf2 | 106 | /**@brief Function for sending an event to all registered event handlers. |
Vincent Coubard |
638:c90ae1400bf2 | 107 | * |
Vincent Coubard |
638:c90ae1400bf2 | 108 | * @param[in] p_event The event to distribute. |
Vincent Coubard |
638:c90ae1400bf2 | 109 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 110 | static void evt_send(im_evt_t * p_event) |
Vincent Coubard |
638:c90ae1400bf2 | 111 | { |
Vincent Coubard |
638:c90ae1400bf2 | 112 | for (uint32_t i = 0; i < m_im.n_registrants; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 113 | { |
Vincent Coubard |
638:c90ae1400bf2 | 114 | m_im.evt_handlers[i](p_event); |
Vincent Coubard |
638:c90ae1400bf2 | 115 | } |
Vincent Coubard |
638:c90ae1400bf2 | 116 | } |
Vincent Coubard |
638:c90ae1400bf2 | 117 | |
Vincent Coubard |
638:c90ae1400bf2 | 118 | /**@brief Function finding a free position in m_im.connections. |
Vincent Coubard |
638:c90ae1400bf2 | 119 | * |
Vincent Coubard |
638:c90ae1400bf2 | 120 | * @detail All connection handles in the m_im.connections array are checked against the connection |
Vincent Coubard |
638:c90ae1400bf2 | 121 | * state module. The index of the first one that is not a connection handle for a current |
Vincent Coubard |
638:c90ae1400bf2 | 122 | * connection is returned. This position in the array can safely be used for a new connection. |
Vincent Coubard |
638:c90ae1400bf2 | 123 | * |
Vincent Coubard |
638:c90ae1400bf2 | 124 | * @return Either the index of a free position in the array or IM_NO_INVALID_CONN_HANDLES if no free |
Vincent Coubard |
638:c90ae1400bf2 | 125 | position exists. |
Vincent Coubard |
638:c90ae1400bf2 | 126 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 127 | uint8_t get_free_connection() |
Vincent Coubard |
638:c90ae1400bf2 | 128 | { |
Vincent Coubard |
638:c90ae1400bf2 | 129 | for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 130 | { |
Vincent Coubard |
638:c90ae1400bf2 | 131 | // Query the connection state module to check if the connection handle does not belong to a |
Vincent Coubard |
638:c90ae1400bf2 | 132 | // valid connection. |
Vincent Coubard |
638:c90ae1400bf2 | 133 | if (!ble_conn_state_user_flag_get(m_im.connections[i].conn_handle, m_im.conn_state_user_flag_id)) |
Vincent Coubard |
638:c90ae1400bf2 | 134 | { |
Vincent Coubard |
638:c90ae1400bf2 | 135 | return i; |
Vincent Coubard |
638:c90ae1400bf2 | 136 | } |
Vincent Coubard |
638:c90ae1400bf2 | 137 | } |
Vincent Coubard |
638:c90ae1400bf2 | 138 | // If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES. |
Vincent Coubard |
638:c90ae1400bf2 | 139 | return IM_NO_INVALID_CONN_HANDLES; |
Vincent Coubard |
638:c90ae1400bf2 | 140 | } |
Vincent Coubard |
638:c90ae1400bf2 | 141 | |
Vincent Coubard |
638:c90ae1400bf2 | 142 | |
Vincent Coubard |
638:c90ae1400bf2 | 143 | /**@brief Function finding a particular connection handle m_im.connections. |
Vincent Coubard |
638:c90ae1400bf2 | 144 | * |
Vincent Coubard |
638:c90ae1400bf2 | 145 | * @param[in] conn_handle The handle to find. |
Vincent Coubard |
638:c90ae1400bf2 | 146 | * |
Vincent Coubard |
638:c90ae1400bf2 | 147 | * @return Either the index of the conn_handle in the array or IM_NO_INVALID_CONN_HANDLES if the |
Vincent Coubard |
638:c90ae1400bf2 | 148 | * handle was not found. |
Vincent Coubard |
638:c90ae1400bf2 | 149 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 150 | uint8_t get_connection_by_conn_handle(uint16_t conn_handle) |
Vincent Coubard |
638:c90ae1400bf2 | 151 | { |
Vincent Coubard |
638:c90ae1400bf2 | 152 | if (ble_conn_state_user_flag_get(conn_handle, m_im.conn_state_user_flag_id)) |
Vincent Coubard |
638:c90ae1400bf2 | 153 | { |
Vincent Coubard |
638:c90ae1400bf2 | 154 | for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 155 | { |
Vincent Coubard |
638:c90ae1400bf2 | 156 | if (m_im.connections[i].conn_handle == conn_handle) |
Vincent Coubard |
638:c90ae1400bf2 | 157 | { |
Vincent Coubard |
638:c90ae1400bf2 | 158 | return i; |
Vincent Coubard |
638:c90ae1400bf2 | 159 | } |
Vincent Coubard |
638:c90ae1400bf2 | 160 | } |
Vincent Coubard |
638:c90ae1400bf2 | 161 | } |
Vincent Coubard |
638:c90ae1400bf2 | 162 | // If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES. |
Vincent Coubard |
638:c90ae1400bf2 | 163 | return IM_NO_INVALID_CONN_HANDLES; |
Vincent Coubard |
638:c90ae1400bf2 | 164 | } |
Vincent Coubard |
638:c90ae1400bf2 | 165 | |
Vincent Coubard |
638:c90ae1400bf2 | 166 | |
Vincent Coubard |
638:c90ae1400bf2 | 167 | /**@brief Function for registering a new connection instance. |
Vincent Coubard |
638:c90ae1400bf2 | 168 | * |
Vincent Coubard |
638:c90ae1400bf2 | 169 | * @param[in] conn_handle The handle of the new connection. |
Vincent Coubard |
638:c90ae1400bf2 | 170 | * @param[in] p_ble_addr The address used to connect. |
Vincent Coubard |
638:c90ae1400bf2 | 171 | * |
Vincent Coubard |
638:c90ae1400bf2 | 172 | * @return Either the index of the new connection in the array or IM_NO_INVALID_CONN_HANDLES if no |
Vincent Coubard |
638:c90ae1400bf2 | 173 | * free position exists. |
Vincent Coubard |
638:c90ae1400bf2 | 174 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 175 | uint8_t new_connection(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr) |
Vincent Coubard |
638:c90ae1400bf2 | 176 | { |
Vincent Coubard |
638:c90ae1400bf2 | 177 | uint8_t conn_index = IM_NO_INVALID_CONN_HANDLES; |
Vincent Coubard |
638:c90ae1400bf2 | 178 | |
Vincent Coubard |
638:c90ae1400bf2 | 179 | if ((p_ble_addr != NULL) && (conn_handle != BLE_CONN_HANDLE_INVALID)) |
Vincent Coubard |
638:c90ae1400bf2 | 180 | { |
Vincent Coubard |
638:c90ae1400bf2 | 181 | ble_conn_state_user_flag_set(conn_handle, m_im.conn_state_user_flag_id, true); |
Vincent Coubard |
638:c90ae1400bf2 | 182 | |
Vincent Coubard |
638:c90ae1400bf2 | 183 | conn_index = get_connection_by_conn_handle(conn_handle); |
Vincent Coubard |
638:c90ae1400bf2 | 184 | if (conn_index == IM_NO_INVALID_CONN_HANDLES) |
Vincent Coubard |
638:c90ae1400bf2 | 185 | { |
Vincent Coubard |
638:c90ae1400bf2 | 186 | conn_index = get_free_connection(); |
Vincent Coubard |
638:c90ae1400bf2 | 187 | } |
Vincent Coubard |
638:c90ae1400bf2 | 188 | |
Vincent Coubard |
638:c90ae1400bf2 | 189 | if (conn_index != IM_NO_INVALID_CONN_HANDLES) |
Vincent Coubard |
638:c90ae1400bf2 | 190 | { |
Vincent Coubard |
638:c90ae1400bf2 | 191 | m_im.connections[conn_index].conn_handle = conn_handle; |
Vincent Coubard |
638:c90ae1400bf2 | 192 | m_im.connections[conn_index].peer_id = PM_PEER_ID_INVALID; |
Vincent Coubard |
638:c90ae1400bf2 | 193 | m_im.connections[conn_index].peer_address = *p_ble_addr; |
Vincent Coubard |
638:c90ae1400bf2 | 194 | } |
Vincent Coubard |
638:c90ae1400bf2 | 195 | } |
Vincent Coubard |
638:c90ae1400bf2 | 196 | return conn_index; |
Vincent Coubard |
638:c90ae1400bf2 | 197 | } |
Vincent Coubard |
638:c90ae1400bf2 | 198 | |
Vincent Coubard |
638:c90ae1400bf2 | 199 | |
Vincent Coubard |
638:c90ae1400bf2 | 200 | /**@brief Function checking the validity of an IRK |
Vincent Coubard |
638:c90ae1400bf2 | 201 | * |
Vincent Coubard |
638:c90ae1400bf2 | 202 | * @detail An all-zero IRK is not valid. This function will check if a given IRK is valid. |
Vincent Coubard |
638:c90ae1400bf2 | 203 | * |
Vincent Coubard |
638:c90ae1400bf2 | 204 | * @param[in] irk The IRK for which the validity is going to be checked. |
Vincent Coubard |
638:c90ae1400bf2 | 205 | * |
Vincent Coubard |
638:c90ae1400bf2 | 206 | * @retval true The IRK is valid. |
Vincent Coubard |
638:c90ae1400bf2 | 207 | * @retval false The IRK is invalid. |
Vincent Coubard |
638:c90ae1400bf2 | 208 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 209 | bool is_valid_irk(ble_gap_irk_t const * irk) |
Vincent Coubard |
638:c90ae1400bf2 | 210 | { |
Vincent Coubard |
638:c90ae1400bf2 | 211 | for (uint32_t i = 0; i < BLE_GAP_SEC_KEY_LEN; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 212 | { |
Vincent Coubard |
638:c90ae1400bf2 | 213 | if (irk->irk[i] != 0) |
Vincent Coubard |
638:c90ae1400bf2 | 214 | { |
Vincent Coubard |
638:c90ae1400bf2 | 215 | return true; |
Vincent Coubard |
638:c90ae1400bf2 | 216 | } |
Vincent Coubard |
638:c90ae1400bf2 | 217 | } |
Vincent Coubard |
638:c90ae1400bf2 | 218 | return false; |
Vincent Coubard |
638:c90ae1400bf2 | 219 | } |
Vincent Coubard |
638:c90ae1400bf2 | 220 | |
Vincent Coubard |
638:c90ae1400bf2 | 221 | |
Vincent Coubard |
638:c90ae1400bf2 | 222 | /**@brief Function for comparing two addresses to determine if they are identical |
Vincent Coubard |
638:c90ae1400bf2 | 223 | * |
Vincent Coubard |
638:c90ae1400bf2 | 224 | * @note The address type need to be identical, as well as every bit in the address itself. |
Vincent Coubard |
638:c90ae1400bf2 | 225 | * |
Vincent Coubard |
638:c90ae1400bf2 | 226 | * @param[in] p_addr1 The first address to be compared. |
Vincent Coubard |
638:c90ae1400bf2 | 227 | * @param[in] p_addr2 The second address to be compared. |
Vincent Coubard |
638:c90ae1400bf2 | 228 | * |
Vincent Coubard |
638:c90ae1400bf2 | 229 | * @retval true The addresses are identical. |
Vincent Coubard |
638:c90ae1400bf2 | 230 | * @retval false The addresses are not identical. |
Vincent Coubard |
638:c90ae1400bf2 | 231 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 232 | bool addr_compare(ble_gap_addr_t const * p_addr1, ble_gap_addr_t const * p_addr2) |
Vincent Coubard |
638:c90ae1400bf2 | 233 | { |
Vincent Coubard |
638:c90ae1400bf2 | 234 | if ((p_addr1 == NULL) || (p_addr2 == NULL)) |
Vincent Coubard |
638:c90ae1400bf2 | 235 | { |
Vincent Coubard |
638:c90ae1400bf2 | 236 | return false; |
Vincent Coubard |
638:c90ae1400bf2 | 237 | } |
Vincent Coubard |
638:c90ae1400bf2 | 238 | |
Vincent Coubard |
638:c90ae1400bf2 | 239 | // Check that the addr type is identical, return false if it is not |
Vincent Coubard |
638:c90ae1400bf2 | 240 | if (p_addr1->addr_type != p_addr2->addr_type) |
Vincent Coubard |
638:c90ae1400bf2 | 241 | { |
Vincent Coubard |
638:c90ae1400bf2 | 242 | return false; |
Vincent Coubard |
638:c90ae1400bf2 | 243 | } |
Vincent Coubard |
638:c90ae1400bf2 | 244 | // Check if the addr bytes are is identical |
Vincent Coubard |
638:c90ae1400bf2 | 245 | return (memcmp(p_addr1->addr, p_addr2->addr, BLE_GAP_ADDR_LEN) == 0); |
Vincent Coubard |
638:c90ae1400bf2 | 246 | } |
Vincent Coubard |
638:c90ae1400bf2 | 247 | |
Vincent Coubard |
638:c90ae1400bf2 | 248 | |
Vincent Coubard |
638:c90ae1400bf2 | 249 | void im_ble_evt_handler(ble_evt_t * ble_evt) |
Vincent Coubard |
638:c90ae1400bf2 | 250 | { |
Vincent Coubard |
638:c90ae1400bf2 | 251 | ret_code_t err_code; |
Vincent Coubard |
638:c90ae1400bf2 | 252 | switch (ble_evt->header.evt_id) |
Vincent Coubard |
638:c90ae1400bf2 | 253 | { |
Vincent Coubard |
638:c90ae1400bf2 | 254 | case BLE_GAP_EVT_CONNECTED: |
Vincent Coubard |
638:c90ae1400bf2 | 255 | { |
Vincent Coubard |
638:c90ae1400bf2 | 256 | pm_peer_id_t bonded_matching_peer_id = PM_PEER_ID_INVALID; |
Vincent Coubard |
638:c90ae1400bf2 | 257 | |
Vincent Coubard |
638:c90ae1400bf2 | 258 | if (ble_evt->evt.gap_evt.params.connected.irk_match == 1) |
Vincent Coubard |
638:c90ae1400bf2 | 259 | { |
Vincent Coubard |
638:c90ae1400bf2 | 260 | // The peer was matched using a whitelist. |
Vincent Coubard |
638:c90ae1400bf2 | 261 | bonded_matching_peer_id |
Vincent Coubard |
638:c90ae1400bf2 | 262 | = m_im.whitelist_peer_ids[ble_evt->evt.gap_evt.params.connected.irk_match_idx]; |
Vincent Coubard |
638:c90ae1400bf2 | 263 | } |
Vincent Coubard |
638:c90ae1400bf2 | 264 | else if ( ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type |
Vincent Coubard |
638:c90ae1400bf2 | 265 | != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) |
Vincent Coubard |
638:c90ae1400bf2 | 266 | { |
Vincent Coubard |
638:c90ae1400bf2 | 267 | /* Search the database for bonding data matching the one that triggered the event. |
Vincent Coubard |
638:c90ae1400bf2 | 268 | * Public and static addresses can be matched on address alone, while resolvable |
Vincent Coubard |
638:c90ae1400bf2 | 269 | * random addresses can be resolved agains known IRKs. Non-resolvable random addresses |
Vincent Coubard |
638:c90ae1400bf2 | 270 | * are never matching because they are not longterm form of identification. |
Vincent Coubard |
638:c90ae1400bf2 | 271 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 272 | pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); |
Vincent Coubard |
638:c90ae1400bf2 | 273 | while ( (compared_peer_id != PM_PEER_ID_INVALID) |
Vincent Coubard |
638:c90ae1400bf2 | 274 | && (bonded_matching_peer_id == PM_PEER_ID_INVALID)) |
Vincent Coubard |
638:c90ae1400bf2 | 275 | { |
Vincent Coubard |
638:c90ae1400bf2 | 276 | pm_peer_data_flash_t compared_data; |
Vincent Coubard |
638:c90ae1400bf2 | 277 | switch (ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type) |
Vincent Coubard |
638:c90ae1400bf2 | 278 | { |
Vincent Coubard |
638:c90ae1400bf2 | 279 | case BLE_GAP_ADDR_TYPE_PUBLIC: |
Vincent Coubard |
638:c90ae1400bf2 | 280 | /* fall-through */ |
Vincent Coubard |
638:c90ae1400bf2 | 281 | case BLE_GAP_ADDR_TYPE_RANDOM_STATIC: |
Vincent Coubard |
638:c90ae1400bf2 | 282 | err_code = pdb_read_buf_get(compared_peer_id, |
Vincent Coubard |
638:c90ae1400bf2 | 283 | PM_PEER_DATA_ID_BONDING, |
Vincent Coubard |
638:c90ae1400bf2 | 284 | &compared_data, |
Vincent Coubard |
638:c90ae1400bf2 | 285 | NULL); |
Vincent Coubard |
638:c90ae1400bf2 | 286 | if ((err_code == NRF_SUCCESS) && |
Vincent Coubard |
638:c90ae1400bf2 | 287 | addr_compare(&ble_evt->evt.gap_evt.params.connected.peer_addr, |
Vincent Coubard |
638:c90ae1400bf2 | 288 | &compared_data.data.p_bonding_data->peer_id.id_addr_info) |
Vincent Coubard |
638:c90ae1400bf2 | 289 | ) |
Vincent Coubard |
638:c90ae1400bf2 | 290 | { |
Vincent Coubard |
638:c90ae1400bf2 | 291 | bonded_matching_peer_id = compared_peer_id; |
Vincent Coubard |
638:c90ae1400bf2 | 292 | } |
Vincent Coubard |
638:c90ae1400bf2 | 293 | break; |
Vincent Coubard |
638:c90ae1400bf2 | 294 | |
Vincent Coubard |
638:c90ae1400bf2 | 295 | case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE: |
Vincent Coubard |
638:c90ae1400bf2 | 296 | err_code = pdb_read_buf_get(compared_peer_id, |
Vincent Coubard |
638:c90ae1400bf2 | 297 | PM_PEER_DATA_ID_BONDING, |
Vincent Coubard |
638:c90ae1400bf2 | 298 | &compared_data, |
Vincent Coubard |
638:c90ae1400bf2 | 299 | NULL); |
Vincent Coubard |
638:c90ae1400bf2 | 300 | if (err_code == NRF_SUCCESS && |
Vincent Coubard |
638:c90ae1400bf2 | 301 | im_address_resolve(&ble_evt->evt.gap_evt.params.connected.peer_addr, |
Vincent Coubard |
638:c90ae1400bf2 | 302 | &compared_data.data.p_bonding_data->peer_id.id_info) |
Vincent Coubard |
638:c90ae1400bf2 | 303 | ) |
Vincent Coubard |
638:c90ae1400bf2 | 304 | { |
Vincent Coubard |
638:c90ae1400bf2 | 305 | bonded_matching_peer_id = compared_peer_id; |
Vincent Coubard |
638:c90ae1400bf2 | 306 | } |
Vincent Coubard |
638:c90ae1400bf2 | 307 | break; |
Vincent Coubard |
638:c90ae1400bf2 | 308 | |
Vincent Coubard |
638:c90ae1400bf2 | 309 | case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE: |
Vincent Coubard |
638:c90ae1400bf2 | 310 | // Should not happen. |
Vincent Coubard |
638:c90ae1400bf2 | 311 | break; |
Vincent Coubard |
638:c90ae1400bf2 | 312 | |
Vincent Coubard |
638:c90ae1400bf2 | 313 | default: |
Vincent Coubard |
638:c90ae1400bf2 | 314 | break; |
Vincent Coubard |
638:c90ae1400bf2 | 315 | } |
Vincent Coubard |
638:c90ae1400bf2 | 316 | compared_peer_id = pdb_next_peer_id_get(compared_peer_id); |
Vincent Coubard |
638:c90ae1400bf2 | 317 | } |
Vincent Coubard |
638:c90ae1400bf2 | 318 | } |
Vincent Coubard |
638:c90ae1400bf2 | 319 | new_connection(ble_evt->evt.gap_evt.conn_handle, &ble_evt->evt.gap_evt.params.connected.peer_addr); |
Vincent Coubard |
638:c90ae1400bf2 | 320 | |
Vincent Coubard |
638:c90ae1400bf2 | 321 | if (bonded_matching_peer_id != PM_PEER_ID_INVALID) |
Vincent Coubard |
638:c90ae1400bf2 | 322 | { |
Vincent Coubard |
638:c90ae1400bf2 | 323 | im_new_peer_id(ble_evt->evt.gap_evt.conn_handle, bonded_matching_peer_id); |
Vincent Coubard |
638:c90ae1400bf2 | 324 | |
Vincent Coubard |
638:c90ae1400bf2 | 325 | // Send a bonded peer event |
Vincent Coubard |
638:c90ae1400bf2 | 326 | im_evt_t im_evt; |
Vincent Coubard |
638:c90ae1400bf2 | 327 | im_evt.conn_handle = ble_evt->evt.gap_evt.conn_handle; |
Vincent Coubard |
638:c90ae1400bf2 | 328 | im_evt.evt_id = IM_EVT_BONDED_PEER_CONNECTED; |
Vincent Coubard |
638:c90ae1400bf2 | 329 | evt_send(&im_evt); |
Vincent Coubard |
638:c90ae1400bf2 | 330 | } |
Vincent Coubard |
638:c90ae1400bf2 | 331 | } |
Vincent Coubard |
638:c90ae1400bf2 | 332 | } |
Vincent Coubard |
638:c90ae1400bf2 | 333 | } |
Vincent Coubard |
638:c90ae1400bf2 | 334 | |
Vincent Coubard |
638:c90ae1400bf2 | 335 | |
Vincent Coubard |
638:c90ae1400bf2 | 336 | /**@brief Function to compare two sets of bonding data to check if they belong to the same device. |
Vincent Coubard |
638:c90ae1400bf2 | 337 | * @note Invalid irks will never match even though they are identical. |
Vincent Coubard |
638:c90ae1400bf2 | 338 | * |
Vincent Coubard |
638:c90ae1400bf2 | 339 | * @param[in] p_bonding_data1 First bonding data for comparison |
Vincent Coubard |
638:c90ae1400bf2 | 340 | * @param[in] p_bonding_data2 Second bonding data for comparison |
Vincent Coubard |
638:c90ae1400bf2 | 341 | * |
Vincent Coubard |
638:c90ae1400bf2 | 342 | * @return True if the input matches, false if it does not. |
Vincent Coubard |
638:c90ae1400bf2 | 343 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 344 | bool is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1, |
Vincent Coubard |
638:c90ae1400bf2 | 345 | pm_peer_data_bonding_t const * p_bonding_data2) |
Vincent Coubard |
638:c90ae1400bf2 | 346 | { |
Vincent Coubard |
638:c90ae1400bf2 | 347 | bool valid_irk = is_valid_irk(&p_bonding_data1->peer_id.id_info); |
Vincent Coubard |
638:c90ae1400bf2 | 348 | bool duplicate_irk = valid_irk && |
Vincent Coubard |
638:c90ae1400bf2 | 349 | (memcmp(p_bonding_data1->peer_id.id_info.irk, |
Vincent Coubard |
638:c90ae1400bf2 | 350 | p_bonding_data2->peer_id.id_info.irk, |
Vincent Coubard |
638:c90ae1400bf2 | 351 | BLE_GAP_SEC_KEY_LEN) == 0 |
Vincent Coubard |
638:c90ae1400bf2 | 352 | ); |
Vincent Coubard |
638:c90ae1400bf2 | 353 | bool duplicate_addr = addr_compare(&p_bonding_data1->peer_id.id_addr_info, |
Vincent Coubard |
638:c90ae1400bf2 | 354 | &p_bonding_data2->peer_id.id_addr_info |
Vincent Coubard |
638:c90ae1400bf2 | 355 | ); |
Vincent Coubard |
638:c90ae1400bf2 | 356 | return duplicate_irk || duplicate_addr; |
Vincent Coubard |
638:c90ae1400bf2 | 357 | } |
Vincent Coubard |
638:c90ae1400bf2 | 358 | |
Vincent Coubard |
638:c90ae1400bf2 | 359 | |
Vincent Coubard |
638:c90ae1400bf2 | 360 | /**@brief Event handler for events from the peer_database module. |
Vincent Coubard |
638:c90ae1400bf2 | 361 | * |
Vincent Coubard |
638:c90ae1400bf2 | 362 | * @param[in] p_event The event that has happend with peer id and flags. |
Vincent Coubard |
638:c90ae1400bf2 | 363 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 364 | static void pdb_evt_handler(pdb_evt_t const * p_event) |
Vincent Coubard |
638:c90ae1400bf2 | 365 | { |
Vincent Coubard |
638:c90ae1400bf2 | 366 | ret_code_t err_code; |
Vincent Coubard |
638:c90ae1400bf2 | 367 | if ((p_event != NULL) && (p_event->evt_id == PDB_EVT_WRITE_BUF_STORED)) |
Vincent Coubard |
638:c90ae1400bf2 | 368 | { |
Vincent Coubard |
638:c90ae1400bf2 | 369 | // If new data about peer id has been stored it is compared to other peers peer ids in |
Vincent Coubard |
638:c90ae1400bf2 | 370 | // search of duplicates. |
Vincent Coubard |
638:c90ae1400bf2 | 371 | if (p_event->data_id == PM_PEER_DATA_ID_BONDING) |
Vincent Coubard |
638:c90ae1400bf2 | 372 | { |
Vincent Coubard |
638:c90ae1400bf2 | 373 | pm_peer_data_flash_t written_data; |
Vincent Coubard |
638:c90ae1400bf2 | 374 | err_code = pdb_read_buf_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &written_data, NULL); |
Vincent Coubard |
638:c90ae1400bf2 | 375 | if (err_code == NRF_SUCCESS) |
Vincent Coubard |
638:c90ae1400bf2 | 376 | { |
Vincent Coubard |
638:c90ae1400bf2 | 377 | pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); |
Vincent Coubard |
638:c90ae1400bf2 | 378 | while (compared_peer_id != PM_PEER_ID_INVALID) |
Vincent Coubard |
638:c90ae1400bf2 | 379 | { |
Vincent Coubard |
638:c90ae1400bf2 | 380 | pm_peer_data_flash_t compared_data; |
Vincent Coubard |
638:c90ae1400bf2 | 381 | err_code = pdb_read_buf_get(compared_peer_id, |
Vincent Coubard |
638:c90ae1400bf2 | 382 | PM_PEER_DATA_ID_BONDING, |
Vincent Coubard |
638:c90ae1400bf2 | 383 | &compared_data, |
Vincent Coubard |
638:c90ae1400bf2 | 384 | NULL); |
Vincent Coubard |
638:c90ae1400bf2 | 385 | if ( err_code == NRF_SUCCESS && |
Vincent Coubard |
638:c90ae1400bf2 | 386 | p_event->peer_id != compared_peer_id && |
Vincent Coubard |
638:c90ae1400bf2 | 387 | is_duplicate_bonding_data(written_data.data.p_bonding_data, |
Vincent Coubard |
638:c90ae1400bf2 | 388 | compared_data.data.p_bonding_data) |
Vincent Coubard |
638:c90ae1400bf2 | 389 | ) |
Vincent Coubard |
638:c90ae1400bf2 | 390 | { |
Vincent Coubard |
638:c90ae1400bf2 | 391 | im_evt_t im_evt; |
Vincent Coubard |
638:c90ae1400bf2 | 392 | im_evt.conn_handle = im_conn_handle_get(p_event->peer_id); |
Vincent Coubard |
638:c90ae1400bf2 | 393 | im_evt.evt_id = IM_EVT_DUPLICATE_ID; |
Vincent Coubard |
638:c90ae1400bf2 | 394 | im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id; |
Vincent Coubard |
638:c90ae1400bf2 | 395 | im_evt.params.duplicate_id.peer_id_2 = compared_peer_id; |
Vincent Coubard |
638:c90ae1400bf2 | 396 | evt_send(&im_evt); |
Vincent Coubard |
638:c90ae1400bf2 | 397 | } |
Vincent Coubard |
638:c90ae1400bf2 | 398 | compared_peer_id = pdb_next_peer_id_get(compared_peer_id); |
Vincent Coubard |
638:c90ae1400bf2 | 399 | } |
Vincent Coubard |
638:c90ae1400bf2 | 400 | } |
Vincent Coubard |
638:c90ae1400bf2 | 401 | } |
Vincent Coubard |
638:c90ae1400bf2 | 402 | } |
Vincent Coubard |
638:c90ae1400bf2 | 403 | } |
Vincent Coubard |
638:c90ae1400bf2 | 404 | |
Vincent Coubard |
638:c90ae1400bf2 | 405 | |
Vincent Coubard |
638:c90ae1400bf2 | 406 | ret_code_t im_register(im_evt_handler_t evt_handler) |
Vincent Coubard |
638:c90ae1400bf2 | 407 | { |
Vincent Coubard |
638:c90ae1400bf2 | 408 | VERIFY_PARAM_NOT_NULL(evt_handler); |
Vincent Coubard |
638:c90ae1400bf2 | 409 | ret_code_t err_code = NRF_SUCCESS; |
Vincent Coubard |
638:c90ae1400bf2 | 410 | |
Vincent Coubard |
638:c90ae1400bf2 | 411 | if (!MODULE_INITIALIZED) |
Vincent Coubard |
638:c90ae1400bf2 | 412 | { |
Vincent Coubard |
638:c90ae1400bf2 | 413 | internal_state_reset(); |
Vincent Coubard |
638:c90ae1400bf2 | 414 | m_im.conn_state_user_flag_id = ble_conn_state_user_flag_acquire(); |
Vincent Coubard |
638:c90ae1400bf2 | 415 | if (m_im.conn_state_user_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) |
Vincent Coubard |
638:c90ae1400bf2 | 416 | { |
Vincent Coubard |
638:c90ae1400bf2 | 417 | err_code = NRF_ERROR_NO_MEM; |
Vincent Coubard |
638:c90ae1400bf2 | 418 | } |
Vincent Coubard |
638:c90ae1400bf2 | 419 | else |
Vincent Coubard |
638:c90ae1400bf2 | 420 | { |
Vincent Coubard |
638:c90ae1400bf2 | 421 | err_code = pdb_register(pdb_evt_handler); |
Vincent Coubard |
638:c90ae1400bf2 | 422 | } |
Vincent Coubard |
638:c90ae1400bf2 | 423 | } |
Vincent Coubard |
638:c90ae1400bf2 | 424 | if (err_code == NRF_SUCCESS) |
Vincent Coubard |
638:c90ae1400bf2 | 425 | { |
Vincent Coubard |
638:c90ae1400bf2 | 426 | if ((m_im.n_registrants < MAX_REGISTRANTS)) |
Vincent Coubard |
638:c90ae1400bf2 | 427 | { |
Vincent Coubard |
638:c90ae1400bf2 | 428 | m_im.evt_handlers[m_im.n_registrants++] = evt_handler; |
Vincent Coubard |
638:c90ae1400bf2 | 429 | } |
Vincent Coubard |
638:c90ae1400bf2 | 430 | else |
Vincent Coubard |
638:c90ae1400bf2 | 431 | { |
Vincent Coubard |
638:c90ae1400bf2 | 432 | err_code = NRF_ERROR_NO_MEM; |
Vincent Coubard |
638:c90ae1400bf2 | 433 | } |
Vincent Coubard |
638:c90ae1400bf2 | 434 | } |
Vincent Coubard |
638:c90ae1400bf2 | 435 | return err_code; |
Vincent Coubard |
638:c90ae1400bf2 | 436 | } |
Vincent Coubard |
638:c90ae1400bf2 | 437 | |
Vincent Coubard |
638:c90ae1400bf2 | 438 | |
Vincent Coubard |
638:c90ae1400bf2 | 439 | pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle) |
Vincent Coubard |
638:c90ae1400bf2 | 440 | { |
Vincent Coubard |
638:c90ae1400bf2 | 441 | uint8_t conn_index = get_connection_by_conn_handle(conn_handle); |
Vincent Coubard |
638:c90ae1400bf2 | 442 | |
Vincent Coubard |
638:c90ae1400bf2 | 443 | if (MODULE_INITIALIZED && (conn_index != IM_NO_INVALID_CONN_HANDLES)) |
Vincent Coubard |
638:c90ae1400bf2 | 444 | { |
Vincent Coubard |
638:c90ae1400bf2 | 445 | return m_im.connections[conn_index].peer_id; |
Vincent Coubard |
638:c90ae1400bf2 | 446 | } |
Vincent Coubard |
638:c90ae1400bf2 | 447 | |
Vincent Coubard |
638:c90ae1400bf2 | 448 | return PM_PEER_ID_INVALID; |
Vincent Coubard |
638:c90ae1400bf2 | 449 | } |
Vincent Coubard |
638:c90ae1400bf2 | 450 | |
Vincent Coubard |
638:c90ae1400bf2 | 451 | |
Vincent Coubard |
638:c90ae1400bf2 | 452 | ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr) |
Vincent Coubard |
638:c90ae1400bf2 | 453 | { |
Vincent Coubard |
638:c90ae1400bf2 | 454 | VERIFY_MODULE_INITIALIZED(); |
Vincent Coubard |
638:c90ae1400bf2 | 455 | VERIFY_PARAM_NOT_NULL(p_ble_addr); |
Vincent Coubard |
638:c90ae1400bf2 | 456 | |
Vincent Coubard |
638:c90ae1400bf2 | 457 | uint8_t conn_index = get_connection_by_conn_handle(conn_handle); |
Vincent Coubard |
638:c90ae1400bf2 | 458 | if (conn_index != IM_NO_INVALID_CONN_HANDLES) |
Vincent Coubard |
638:c90ae1400bf2 | 459 | { |
Vincent Coubard |
638:c90ae1400bf2 | 460 | *p_ble_addr = m_im.connections[conn_index].peer_address; |
Vincent Coubard |
638:c90ae1400bf2 | 461 | return NRF_SUCCESS; |
Vincent Coubard |
638:c90ae1400bf2 | 462 | } |
Vincent Coubard |
638:c90ae1400bf2 | 463 | |
Vincent Coubard |
638:c90ae1400bf2 | 464 | return NRF_ERROR_NOT_FOUND; |
Vincent Coubard |
638:c90ae1400bf2 | 465 | } |
Vincent Coubard |
638:c90ae1400bf2 | 466 | |
Vincent Coubard |
638:c90ae1400bf2 | 467 | |
Vincent Coubard |
638:c90ae1400bf2 | 468 | /**@brief Function for comparing two master ids |
Vincent Coubard |
638:c90ae1400bf2 | 469 | * @note Two invalid master IDs will not match. |
Vincent Coubard |
638:c90ae1400bf2 | 470 | * |
Vincent Coubard |
638:c90ae1400bf2 | 471 | * @param[in] p_master_id1 First master id for comparison |
Vincent Coubard |
638:c90ae1400bf2 | 472 | * @param[in] p_master_id2 Second master id for comparison |
Vincent Coubard |
638:c90ae1400bf2 | 473 | * |
Vincent Coubard |
638:c90ae1400bf2 | 474 | * @return True if the input matches, false if it does not. |
Vincent Coubard |
638:c90ae1400bf2 | 475 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 476 | bool master_id_compare(ble_gap_master_id_t const * p_master_id1, |
Vincent Coubard |
638:c90ae1400bf2 | 477 | ble_gap_master_id_t const * p_master_id2) |
Vincent Coubard |
638:c90ae1400bf2 | 478 | { |
Vincent Coubard |
638:c90ae1400bf2 | 479 | if(!im_master_id_is_valid(p_master_id1)) |
Vincent Coubard |
638:c90ae1400bf2 | 480 | { |
Vincent Coubard |
638:c90ae1400bf2 | 481 | return false; |
Vincent Coubard |
638:c90ae1400bf2 | 482 | } |
Vincent Coubard |
638:c90ae1400bf2 | 483 | if (p_master_id1->ediv != p_master_id2->ediv) |
Vincent Coubard |
638:c90ae1400bf2 | 484 | { |
Vincent Coubard |
638:c90ae1400bf2 | 485 | return false; |
Vincent Coubard |
638:c90ae1400bf2 | 486 | } |
Vincent Coubard |
638:c90ae1400bf2 | 487 | return (memcmp(p_master_id1->rand, p_master_id2->rand, BLE_GAP_SEC_RAND_LEN) == 0); |
Vincent Coubard |
638:c90ae1400bf2 | 488 | } |
Vincent Coubard |
638:c90ae1400bf2 | 489 | |
Vincent Coubard |
638:c90ae1400bf2 | 490 | |
Vincent Coubard |
638:c90ae1400bf2 | 491 | pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t * p_master_id) |
Vincent Coubard |
638:c90ae1400bf2 | 492 | { |
Vincent Coubard |
638:c90ae1400bf2 | 493 | ret_code_t err_code; |
Vincent Coubard |
638:c90ae1400bf2 | 494 | // For each stored peer, check if the master_id match p_master_id |
Vincent Coubard |
638:c90ae1400bf2 | 495 | pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); |
Vincent Coubard |
638:c90ae1400bf2 | 496 | while (compared_peer_id != PM_PEER_ID_INVALID) |
Vincent Coubard |
638:c90ae1400bf2 | 497 | { |
Vincent Coubard |
638:c90ae1400bf2 | 498 | pm_peer_data_flash_t compared_data; |
Vincent Coubard |
638:c90ae1400bf2 | 499 | ble_gap_master_id_t const * p_compared_master_id; |
Vincent Coubard |
638:c90ae1400bf2 | 500 | |
Vincent Coubard |
638:c90ae1400bf2 | 501 | err_code = pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL); |
Vincent Coubard |
638:c90ae1400bf2 | 502 | if (err_code == NRF_SUCCESS) |
Vincent Coubard |
638:c90ae1400bf2 | 503 | { |
Vincent Coubard |
638:c90ae1400bf2 | 504 | p_compared_master_id = &compared_data.data.p_bonding_data->own_ltk.master_id; |
Vincent Coubard |
638:c90ae1400bf2 | 505 | if (compared_data.data.p_bonding_data->own_role == BLE_GAP_ROLE_CENTRAL) |
Vincent Coubard |
638:c90ae1400bf2 | 506 | { |
Vincent Coubard |
638:c90ae1400bf2 | 507 | p_compared_master_id = &compared_data.data.p_bonding_data->peer_ltk.master_id; |
Vincent Coubard |
638:c90ae1400bf2 | 508 | } |
Vincent Coubard |
638:c90ae1400bf2 | 509 | if (master_id_compare(p_master_id, p_compared_master_id)) |
Vincent Coubard |
638:c90ae1400bf2 | 510 | { |
Vincent Coubard |
638:c90ae1400bf2 | 511 | // If a matching master_id is found return the peer_id |
Vincent Coubard |
638:c90ae1400bf2 | 512 | return compared_peer_id; |
Vincent Coubard |
638:c90ae1400bf2 | 513 | } |
Vincent Coubard |
638:c90ae1400bf2 | 514 | } |
Vincent Coubard |
638:c90ae1400bf2 | 515 | compared_peer_id = pdb_next_peer_id_get(compared_peer_id); |
Vincent Coubard |
638:c90ae1400bf2 | 516 | } |
Vincent Coubard |
638:c90ae1400bf2 | 517 | // If no matching master_id is found return the PM_PEER_ID_INVALID |
Vincent Coubard |
638:c90ae1400bf2 | 518 | return PM_PEER_ID_INVALID; |
Vincent Coubard |
638:c90ae1400bf2 | 519 | } |
Vincent Coubard |
638:c90ae1400bf2 | 520 | |
Vincent Coubard |
638:c90ae1400bf2 | 521 | |
Vincent Coubard |
638:c90ae1400bf2 | 522 | pm_peer_id_t im_peer_id_get_by_irk_match_idx(uint8_t irk_match_idx) |
Vincent Coubard |
638:c90ae1400bf2 | 523 | { |
Vincent Coubard |
638:c90ae1400bf2 | 524 | // Verify that the requested idx is within the list |
Vincent Coubard |
638:c90ae1400bf2 | 525 | if (irk_match_idx < m_im.n_whitelist_peer_ids) |
Vincent Coubard |
638:c90ae1400bf2 | 526 | { |
Vincent Coubard |
638:c90ae1400bf2 | 527 | // Return the peer_id from the white list |
Vincent Coubard |
638:c90ae1400bf2 | 528 | return m_im.whitelist_peer_ids[irk_match_idx]; |
Vincent Coubard |
638:c90ae1400bf2 | 529 | } |
Vincent Coubard |
638:c90ae1400bf2 | 530 | else |
Vincent Coubard |
638:c90ae1400bf2 | 531 | { |
Vincent Coubard |
638:c90ae1400bf2 | 532 | // Return PM_PEER_ID_INVALID to indicate that there was no peer with the requested idx |
Vincent Coubard |
638:c90ae1400bf2 | 533 | return PM_PEER_ID_INVALID; |
Vincent Coubard |
638:c90ae1400bf2 | 534 | } |
Vincent Coubard |
638:c90ae1400bf2 | 535 | } |
Vincent Coubard |
638:c90ae1400bf2 | 536 | |
Vincent Coubard |
638:c90ae1400bf2 | 537 | |
Vincent Coubard |
638:c90ae1400bf2 | 538 | uint16_t im_conn_handle_get(pm_peer_id_t peer_id) |
Vincent Coubard |
638:c90ae1400bf2 | 539 | { |
Vincent Coubard |
638:c90ae1400bf2 | 540 | for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 541 | { |
Vincent Coubard |
638:c90ae1400bf2 | 542 | if (peer_id == m_im.connections[i].peer_id) |
Vincent Coubard |
638:c90ae1400bf2 | 543 | { |
Vincent Coubard |
638:c90ae1400bf2 | 544 | return m_im.connections[i].conn_handle; |
Vincent Coubard |
638:c90ae1400bf2 | 545 | } |
Vincent Coubard |
638:c90ae1400bf2 | 546 | } |
Vincent Coubard |
638:c90ae1400bf2 | 547 | return BLE_CONN_HANDLE_INVALID; |
Vincent Coubard |
638:c90ae1400bf2 | 548 | } |
Vincent Coubard |
638:c90ae1400bf2 | 549 | |
Vincent Coubard |
638:c90ae1400bf2 | 550 | |
Vincent Coubard |
638:c90ae1400bf2 | 551 | bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id) |
Vincent Coubard |
638:c90ae1400bf2 | 552 | { |
Vincent Coubard |
638:c90ae1400bf2 | 553 | |
Vincent Coubard |
638:c90ae1400bf2 | 554 | if (p_master_id->ediv != 0) |
Vincent Coubard |
638:c90ae1400bf2 | 555 | { |
Vincent Coubard |
638:c90ae1400bf2 | 556 | return true; |
Vincent Coubard |
638:c90ae1400bf2 | 557 | } |
Vincent Coubard |
638:c90ae1400bf2 | 558 | for (uint32_t i = 0; i < BLE_GAP_SEC_RAND_LEN; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 559 | { |
Vincent Coubard |
638:c90ae1400bf2 | 560 | if (p_master_id->rand[i] != 0) |
Vincent Coubard |
638:c90ae1400bf2 | 561 | { |
Vincent Coubard |
638:c90ae1400bf2 | 562 | return true; |
Vincent Coubard |
638:c90ae1400bf2 | 563 | } |
Vincent Coubard |
638:c90ae1400bf2 | 564 | } |
Vincent Coubard |
638:c90ae1400bf2 | 565 | return false; |
Vincent Coubard |
638:c90ae1400bf2 | 566 | } |
Vincent Coubard |
638:c90ae1400bf2 | 567 | |
Vincent Coubard |
638:c90ae1400bf2 | 568 | |
Vincent Coubard |
638:c90ae1400bf2 | 569 | void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id) |
Vincent Coubard |
638:c90ae1400bf2 | 570 | { |
Vincent Coubard |
638:c90ae1400bf2 | 571 | uint8_t conn_index = get_connection_by_conn_handle(conn_handle); |
Vincent Coubard |
638:c90ae1400bf2 | 572 | if (conn_index != IM_NO_INVALID_CONN_HANDLES) |
Vincent Coubard |
638:c90ae1400bf2 | 573 | { |
Vincent Coubard |
638:c90ae1400bf2 | 574 | m_im.connections[conn_index].peer_id = peer_id; |
Vincent Coubard |
638:c90ae1400bf2 | 575 | } |
Vincent Coubard |
638:c90ae1400bf2 | 576 | } |
Vincent Coubard |
638:c90ae1400bf2 | 577 | |
Vincent Coubard |
638:c90ae1400bf2 | 578 | |
Vincent Coubard |
638:c90ae1400bf2 | 579 | ret_code_t im_wlist_create(pm_peer_id_t * p_peer_ids, |
Vincent Coubard |
638:c90ae1400bf2 | 580 | uint8_t n_peer_ids, |
Vincent Coubard |
638:c90ae1400bf2 | 581 | ble_gap_whitelist_t * p_whitelist) |
Vincent Coubard |
638:c90ae1400bf2 | 582 | { |
Vincent Coubard |
638:c90ae1400bf2 | 583 | VERIFY_MODULE_INITIALIZED(); |
Vincent Coubard |
638:c90ae1400bf2 | 584 | VERIFY_PARAM_NOT_NULL(p_whitelist); |
Vincent Coubard |
638:c90ae1400bf2 | 585 | ret_code_t err_code; |
Vincent Coubard |
638:c90ae1400bf2 | 586 | p_whitelist->addr_count = 0; |
Vincent Coubard |
638:c90ae1400bf2 | 587 | p_whitelist->irk_count = 0; |
Vincent Coubard |
638:c90ae1400bf2 | 588 | m_im.n_whitelist_peer_ids = 0; |
Vincent Coubard |
638:c90ae1400bf2 | 589 | for (uint32_t peer_index = 0; peer_index < n_peer_ids; peer_index++) |
Vincent Coubard |
638:c90ae1400bf2 | 590 | { |
Vincent Coubard |
638:c90ae1400bf2 | 591 | bool peer_connected = false; |
Vincent Coubard |
638:c90ae1400bf2 | 592 | for (uint32_t conn_index = 0; conn_index < IM_MAX_CONN_HANDLES; conn_index++) |
Vincent Coubard |
638:c90ae1400bf2 | 593 | { |
Vincent Coubard |
638:c90ae1400bf2 | 594 | if (p_peer_ids[peer_index] == m_im.connections[conn_index].peer_id && |
Vincent Coubard |
638:c90ae1400bf2 | 595 | ble_conn_state_user_flag_get(m_im.connections[conn_index].conn_handle, m_im.conn_state_user_flag_id) |
Vincent Coubard |
638:c90ae1400bf2 | 596 | ) |
Vincent Coubard |
638:c90ae1400bf2 | 597 | { |
Vincent Coubard |
638:c90ae1400bf2 | 598 | peer_connected = true; |
Vincent Coubard |
638:c90ae1400bf2 | 599 | break; |
Vincent Coubard |
638:c90ae1400bf2 | 600 | } |
Vincent Coubard |
638:c90ae1400bf2 | 601 | } |
Vincent Coubard |
638:c90ae1400bf2 | 602 | if (!peer_connected) |
Vincent Coubard |
638:c90ae1400bf2 | 603 | { |
Vincent Coubard |
638:c90ae1400bf2 | 604 | pm_peer_data_flash_t peer_data; |
Vincent Coubard |
638:c90ae1400bf2 | 605 | err_code = pdb_read_buf_get(p_peer_ids[peer_index], PM_PEER_DATA_ID_BONDING, &peer_data, NULL); |
Vincent Coubard |
638:c90ae1400bf2 | 606 | if (err_code == NRF_ERROR_INVALID_PARAM || err_code == NRF_ERROR_NOT_FOUND) |
Vincent Coubard |
638:c90ae1400bf2 | 607 | { |
Vincent Coubard |
638:c90ae1400bf2 | 608 | return NRF_ERROR_INVALID_PARAM; |
Vincent Coubard |
638:c90ae1400bf2 | 609 | } |
Vincent Coubard |
638:c90ae1400bf2 | 610 | if (p_whitelist->pp_addrs != NULL && |
Vincent Coubard |
638:c90ae1400bf2 | 611 | peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type |
Vincent Coubard |
638:c90ae1400bf2 | 612 | != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE && |
Vincent Coubard |
638:c90ae1400bf2 | 613 | peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type |
Vincent Coubard |
638:c90ae1400bf2 | 614 | != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE |
Vincent Coubard |
638:c90ae1400bf2 | 615 | ) |
Vincent Coubard |
638:c90ae1400bf2 | 616 | { |
Vincent Coubard |
638:c90ae1400bf2 | 617 | memcpy(m_im.whitelist_addrs[peer_index].addr, |
Vincent Coubard |
638:c90ae1400bf2 | 618 | peer_data.data.p_bonding_data->peer_id.id_addr_info.addr, |
Vincent Coubard |
638:c90ae1400bf2 | 619 | BLE_GAP_ADDR_LEN |
Vincent Coubard |
638:c90ae1400bf2 | 620 | ); |
Vincent Coubard |
638:c90ae1400bf2 | 621 | m_im.whitelist_addrs[peer_index].addr_type = |
Vincent Coubard |
638:c90ae1400bf2 | 622 | peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type; |
Vincent Coubard |
638:c90ae1400bf2 | 623 | p_whitelist->pp_addrs[peer_index] = &m_im.whitelist_addrs[peer_index]; |
Vincent Coubard |
638:c90ae1400bf2 | 624 | p_whitelist->addr_count++; |
Vincent Coubard |
638:c90ae1400bf2 | 625 | } |
Vincent Coubard |
638:c90ae1400bf2 | 626 | if (p_whitelist->pp_irks != NULL && |
Vincent Coubard |
638:c90ae1400bf2 | 627 | is_valid_irk(&(peer_data.data.p_bonding_data->peer_id.id_info)) |
Vincent Coubard |
638:c90ae1400bf2 | 628 | ) |
Vincent Coubard |
638:c90ae1400bf2 | 629 | { |
Vincent Coubard |
638:c90ae1400bf2 | 630 | memcpy(m_im.whitelist_irks[peer_index].irk, |
Vincent Coubard |
638:c90ae1400bf2 | 631 | peer_data.data.p_bonding_data->peer_id.id_info.irk, |
Vincent Coubard |
638:c90ae1400bf2 | 632 | BLE_GAP_SEC_KEY_LEN |
Vincent Coubard |
638:c90ae1400bf2 | 633 | ); |
Vincent Coubard |
638:c90ae1400bf2 | 634 | p_whitelist->pp_irks[peer_index] = &m_im.whitelist_irks[peer_index]; |
Vincent Coubard |
638:c90ae1400bf2 | 635 | p_whitelist->irk_count++; |
Vincent Coubard |
638:c90ae1400bf2 | 636 | m_im.whitelist_peer_ids[peer_index] = p_peer_ids[peer_index]; |
Vincent Coubard |
638:c90ae1400bf2 | 637 | m_im.n_whitelist_peer_ids++; |
Vincent Coubard |
638:c90ae1400bf2 | 638 | } |
Vincent Coubard |
638:c90ae1400bf2 | 639 | } |
Vincent Coubard |
638:c90ae1400bf2 | 640 | } |
Vincent Coubard |
638:c90ae1400bf2 | 641 | return NRF_SUCCESS; |
Vincent Coubard |
638:c90ae1400bf2 | 642 | } |
Vincent Coubard |
638:c90ae1400bf2 | 643 | |
Vincent Coubard |
638:c90ae1400bf2 | 644 | |
Vincent Coubard |
638:c90ae1400bf2 | 645 | ret_code_t im_wlist_set(ble_gap_whitelist_t * p_whitelist) |
Vincent Coubard |
638:c90ae1400bf2 | 646 | { |
Vincent Coubard |
638:c90ae1400bf2 | 647 | pm_peer_id_t new_whitelist_peer_ids[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; |
Vincent Coubard |
638:c90ae1400bf2 | 648 | uint32_t n_new_whitelist_peer_ids = 0; |
Vincent Coubard |
638:c90ae1400bf2 | 649 | VERIFY_PARAM_NOT_NULL(p_whitelist); |
Vincent Coubard |
638:c90ae1400bf2 | 650 | for (uint32_t i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 651 | { |
Vincent Coubard |
638:c90ae1400bf2 | 652 | new_whitelist_peer_ids[i] = PM_PEER_ID_INVALID; |
Vincent Coubard |
638:c90ae1400bf2 | 653 | } |
Vincent Coubard |
638:c90ae1400bf2 | 654 | pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); |
Vincent Coubard |
638:c90ae1400bf2 | 655 | while (compared_peer_id != PM_PEER_ID_INVALID) |
Vincent Coubard |
638:c90ae1400bf2 | 656 | { |
Vincent Coubard |
638:c90ae1400bf2 | 657 | pm_peer_data_flash_t compared_data; |
Vincent Coubard |
638:c90ae1400bf2 | 658 | pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL); |
Vincent Coubard |
638:c90ae1400bf2 | 659 | for (uint32_t i = 0; i < p_whitelist->irk_count; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 660 | { |
Vincent Coubard |
638:c90ae1400bf2 | 661 | bool valid_irk = is_valid_irk(&compared_data.data.p_bonding_data->peer_id.id_info); |
Vincent Coubard |
638:c90ae1400bf2 | 662 | bool duplicate_irk = valid_irk && |
Vincent Coubard |
638:c90ae1400bf2 | 663 | (memcmp(p_whitelist->pp_irks[i]->irk, |
Vincent Coubard |
638:c90ae1400bf2 | 664 | compared_data.data.p_bonding_data->peer_id.id_info.irk, |
Vincent Coubard |
638:c90ae1400bf2 | 665 | BLE_GAP_SEC_KEY_LEN) == 0 |
Vincent Coubard |
638:c90ae1400bf2 | 666 | ); |
Vincent Coubard |
638:c90ae1400bf2 | 667 | if (duplicate_irk) |
Vincent Coubard |
638:c90ae1400bf2 | 668 | { |
Vincent Coubard |
638:c90ae1400bf2 | 669 | new_whitelist_peer_ids[i] = compared_peer_id; |
Vincent Coubard |
638:c90ae1400bf2 | 670 | n_new_whitelist_peer_ids++; |
Vincent Coubard |
638:c90ae1400bf2 | 671 | } |
Vincent Coubard |
638:c90ae1400bf2 | 672 | } |
Vincent Coubard |
638:c90ae1400bf2 | 673 | compared_peer_id = pdb_next_peer_id_get(compared_peer_id); |
Vincent Coubard |
638:c90ae1400bf2 | 674 | } |
Vincent Coubard |
638:c90ae1400bf2 | 675 | if (n_new_whitelist_peer_ids != p_whitelist->irk_count) |
Vincent Coubard |
638:c90ae1400bf2 | 676 | { |
Vincent Coubard |
638:c90ae1400bf2 | 677 | return NRF_ERROR_NOT_FOUND; |
Vincent Coubard |
638:c90ae1400bf2 | 678 | } |
Vincent Coubard |
638:c90ae1400bf2 | 679 | else |
Vincent Coubard |
638:c90ae1400bf2 | 680 | { |
Vincent Coubard |
638:c90ae1400bf2 | 681 | for (uint32_t i = 0; i < n_new_whitelist_peer_ids; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 682 | { |
Vincent Coubard |
638:c90ae1400bf2 | 683 | m_im.whitelist_peer_ids[i] = new_whitelist_peer_ids[i]; |
Vincent Coubard |
638:c90ae1400bf2 | 684 | } |
Vincent Coubard |
638:c90ae1400bf2 | 685 | m_im.n_whitelist_peer_ids = n_new_whitelist_peer_ids; |
Vincent Coubard |
638:c90ae1400bf2 | 686 | return NRF_SUCCESS; |
Vincent Coubard |
638:c90ae1400bf2 | 687 | } |
Vincent Coubard |
638:c90ae1400bf2 | 688 | } |
Vincent Coubard |
638:c90ae1400bf2 | 689 | |
Vincent Coubard |
638:c90ae1400bf2 | 690 | |
Vincent Coubard |
638:c90ae1400bf2 | 691 | /**@brief Function for calculating the ah() hash function described in Bluetooth core specification |
Vincent Coubard |
638:c90ae1400bf2 | 692 | * 4.2 section 3.H.2.2.2. |
Vincent Coubard |
638:c90ae1400bf2 | 693 | * |
Vincent Coubard |
638:c90ae1400bf2 | 694 | * @detail BLE uses a hash function to calculate the first half of a resolvable address |
Vincent Coubard |
638:c90ae1400bf2 | 695 | * from the second half of the address and an irk. This function will use the ECB |
Vincent Coubard |
638:c90ae1400bf2 | 696 | * periferal to hash these data acording to the Bluetooth core specification. |
Vincent Coubard |
638:c90ae1400bf2 | 697 | * |
Vincent Coubard |
638:c90ae1400bf2 | 698 | * @note The ECB expect little endian input and output. |
Vincent Coubard |
638:c90ae1400bf2 | 699 | * This function expect big endian and will reverse the data as necessary. |
Vincent Coubard |
638:c90ae1400bf2 | 700 | * |
Vincent Coubard |
638:c90ae1400bf2 | 701 | * @param[in] p_k The key used in the hash function. |
Vincent Coubard |
638:c90ae1400bf2 | 702 | * For address resolution this is should be the irk. |
Vincent Coubard |
638:c90ae1400bf2 | 703 | * The array must have a length of 16. |
Vincent Coubard |
638:c90ae1400bf2 | 704 | * @param[in] p_r The rand used in the hash function. For generating a new address |
Vincent Coubard |
638:c90ae1400bf2 | 705 | * this would be a random number. For resolving a resolvable address |
Vincent Coubard |
638:c90ae1400bf2 | 706 | * this would be the last half of the address being resolved. |
Vincent Coubard |
638:c90ae1400bf2 | 707 | * The array must have a length of 3. |
Vincent Coubard |
638:c90ae1400bf2 | 708 | * @param[out] p_local_hash The result of the hash operation. For address resolution this |
Vincent Coubard |
638:c90ae1400bf2 | 709 | * will match the first half of the address being resolved if and only |
Vincent Coubard |
638:c90ae1400bf2 | 710 | * if the irk used in the hash function is the same one used to generate |
Vincent Coubard |
638:c90ae1400bf2 | 711 | * the address. |
Vincent Coubard |
638:c90ae1400bf2 | 712 | * The array must have a length of 16. |
Vincent Coubard |
638:c90ae1400bf2 | 713 | */ |
Vincent Coubard |
638:c90ae1400bf2 | 714 | void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash) |
Vincent Coubard |
638:c90ae1400bf2 | 715 | { |
Vincent Coubard |
638:c90ae1400bf2 | 716 | nrf_ecb_hal_data_t ecb_hal_data; |
Vincent Coubard |
638:c90ae1400bf2 | 717 | for (uint32_t i = 0; i < SOC_ECB_KEY_LENGTH; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 718 | { |
Vincent Coubard |
638:c90ae1400bf2 | 719 | ecb_hal_data.key[i] = p_k[SOC_ECB_KEY_LENGTH - 1 - i]; |
Vincent Coubard |
638:c90ae1400bf2 | 720 | } |
Vincent Coubard |
638:c90ae1400bf2 | 721 | memset(ecb_hal_data.cleartext, 0, SOC_ECB_KEY_LENGTH - IM_ADDR_CLEARTEXT_LENGTH); |
Vincent Coubard |
638:c90ae1400bf2 | 722 | |
Vincent Coubard |
638:c90ae1400bf2 | 723 | for (uint32_t i = 0; i < IM_ADDR_CLEARTEXT_LENGTH; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 724 | { |
Vincent Coubard |
638:c90ae1400bf2 | 725 | ecb_hal_data.cleartext[SOC_ECB_KEY_LENGTH - 1 - i] = p_r[i]; |
Vincent Coubard |
638:c90ae1400bf2 | 726 | } |
Vincent Coubard |
638:c90ae1400bf2 | 727 | |
Vincent Coubard |
638:c90ae1400bf2 | 728 | sd_ecb_block_encrypt(&ecb_hal_data); |
Vincent Coubard |
638:c90ae1400bf2 | 729 | |
Vincent Coubard |
638:c90ae1400bf2 | 730 | for (uint32_t i = 0; i < IM_ADDR_CIPHERTEXT_LENGTH; i++) |
Vincent Coubard |
638:c90ae1400bf2 | 731 | { |
Vincent Coubard |
638:c90ae1400bf2 | 732 | p_local_hash[i] = ecb_hal_data.ciphertext[SOC_ECB_KEY_LENGTH - 1 - i]; |
Vincent Coubard |
638:c90ae1400bf2 | 733 | } |
Vincent Coubard |
638:c90ae1400bf2 | 734 | } |
Vincent Coubard |
638:c90ae1400bf2 | 735 | |
Vincent Coubard |
638:c90ae1400bf2 | 736 | |
Vincent Coubard |
638:c90ae1400bf2 | 737 | bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk) |
Vincent Coubard |
638:c90ae1400bf2 | 738 | { |
Vincent Coubard |
638:c90ae1400bf2 | 739 | if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE) |
Vincent Coubard |
638:c90ae1400bf2 | 740 | { |
Vincent Coubard |
638:c90ae1400bf2 | 741 | return false; |
Vincent Coubard |
638:c90ae1400bf2 | 742 | } |
Vincent Coubard |
638:c90ae1400bf2 | 743 | uint8_t hash[IM_ADDR_CIPHERTEXT_LENGTH]; |
Vincent Coubard |
638:c90ae1400bf2 | 744 | uint8_t local_hash[IM_ADDR_CIPHERTEXT_LENGTH]; |
Vincent Coubard |
638:c90ae1400bf2 | 745 | uint8_t prand[IM_ADDR_CLEARTEXT_LENGTH]; |
Vincent Coubard |
638:c90ae1400bf2 | 746 | memcpy(hash, p_addr->addr, IM_ADDR_CIPHERTEXT_LENGTH); |
Vincent Coubard |
638:c90ae1400bf2 | 747 | memcpy(prand, &p_addr->addr[IM_ADDR_CIPHERTEXT_LENGTH], IM_ADDR_CLEARTEXT_LENGTH); |
Vincent Coubard |
638:c90ae1400bf2 | 748 | ah(p_irk->irk, prand, local_hash); |
Vincent Coubard |
638:c90ae1400bf2 | 749 | |
Vincent Coubard |
638:c90ae1400bf2 | 750 | return (memcmp(hash, local_hash, IM_ADDR_CIPHERTEXT_LENGTH) == 0); |
Vincent Coubard |
638:c90ae1400bf2 | 751 | } |