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
peer_database.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 00034 #include "peer_database.h" 00035 00036 #include <string.h> 00037 #include "peer_manager_types.h " 00038 #include "peer_data_storage.h" 00039 #include "pm_buffer.h" 00040 00041 00042 #define MAX_REGISTRANTS 6 /**< The number of user that can register with the module. */ 00043 00044 #define MODULE_INITIALIZED (m_pdb.n_registrants > 0) /**< Expression which is true when the module is initialized. */ 00045 00046 #define N_WRITE_BUFFERS 8 /**< The number of write buffers available. */ 00047 #define N_WRITE_BUFFER_RECORDS (N_WRITE_BUFFERS) /**< The number of write buffer records. */ 00048 00049 /**@brief Macro for verifying that the module is initialized. It will cause the function to return 00050 * @ref NRF_ERROR_INVALID_STATE if not. 00051 */ 00052 #define VERIFY_MODULE_INITIALIZED() \ 00053 do \ 00054 { \ 00055 if (!MODULE_INITIALIZED) \ 00056 { \ 00057 return NRF_ERROR_INVALID_STATE; \ 00058 } \ 00059 } while(0) 00060 00061 00062 /**@brief Macro for verifying that the module is initialized. It will cause the function to return 00063 * if not. 00064 */ 00065 #define VERIFY_MODULE_INITIALIZED_VOID()\ 00066 do \ 00067 { \ 00068 if (!MODULE_INITIALIZED) \ 00069 { \ 00070 return; \ 00071 } \ 00072 } while(0) 00073 00074 00075 /**@brief Macro for verifying that the module is initialized. It will cause the function to return 00076 * if not. 00077 * 00078 * @param[in] param The variable to check if is NULL. 00079 */ 00080 #define VERIFY_PARAM_NOT_NULL(param) \ 00081 do \ 00082 { \ 00083 if (param == NULL) \ 00084 { \ 00085 return NRF_ERROR_NULL; \ 00086 } \ 00087 } while(0) 00088 00089 00090 typedef struct 00091 { 00092 pm_peer_id_t peer_id; 00093 pm_peer_data_id_t data_id; 00094 uint8_t buffer_block_id; 00095 uint8_t store_busy : 1; 00096 uint8_t store_flash_full : 1; 00097 uint8_t store_requested : 1; 00098 uint32_t n_bufs; 00099 pm_prepare_token_t prepare_token; 00100 pm_store_token_t store_token; 00101 } pdb_buffer_record_t; 00102 00103 typedef struct 00104 { 00105 pdb_evt_handler_t evt_handlers[MAX_REGISTRANTS]; 00106 uint8_t n_registrants; 00107 pm_buffer_t write_buffer; 00108 pdb_buffer_record_t write_buffer_records[N_WRITE_BUFFER_RECORDS]; 00109 uint32_t n_writes; 00110 } pdb_t; 00111 00112 static pdb_t m_pdb = {.n_registrants = 0}; 00113 00114 00115 /**@brief Function for invalidating a record of a write buffer allocation. 00116 * 00117 * @param[in] p_record The record to invalidate. 00118 */ 00119 static void write_buffer_record_invalidate(pdb_buffer_record_t * p_record) 00120 { 00121 p_record->peer_id = PM_PEER_ID_INVALID; 00122 p_record->data_id = PM_PEER_DATA_ID_INVALID; 00123 p_record->buffer_block_id = BUFFER_INVALID_ID; 00124 p_record->store_busy = false; 00125 p_record->store_flash_full = false; 00126 p_record->store_requested = false; 00127 p_record->n_bufs = 0; 00128 p_record->prepare_token = PDS_PREPARE_TOKEN_INVALID; 00129 p_record->store_token = PDS_STORE_TOKEN_INVALID; 00130 } 00131 00132 00133 /**@brief Function for finding a record of a write buffer allocation. 00134 * 00135 * @param[in] peer_id The peer ID in the record. 00136 * @param[in] data_id The data ID in the record. 00137 * 00138 * @return A pointer to the matching record, or NULL if none was found. 00139 */ 00140 static pdb_buffer_record_t * write_buffer_record_find(pm_peer_id_t peer_id, 00141 pm_peer_data_id_t data_id) 00142 { 00143 for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++) 00144 { 00145 if ((m_pdb.write_buffer_records[i].peer_id == peer_id) 00146 && (m_pdb.write_buffer_records[i].data_id == data_id)) 00147 { 00148 return &m_pdb.write_buffer_records[i]; 00149 } 00150 } 00151 return NULL; 00152 } 00153 00154 00155 /**@brief Function for finding an available record for write buffer allocation. 00156 * 00157 * @return A pointer to the available record, or NULL if none was found. 00158 */ 00159 static pdb_buffer_record_t * write_buffer_record_find_unused(void) 00160 { 00161 return write_buffer_record_find(PM_PEER_ID_INVALID, PM_PEER_DATA_ID_INVALID); 00162 } 00163 00164 00165 /**@brief Function for gracefully deactivating a write buffer record. 00166 * 00167 * @details This function will first release any buffers, then invalidate the record. 00168 * 00169 * @param[inout] p_write_buffer_record The record to release. 00170 * 00171 * @return A pointer to the matching record, or NULL if none was found. 00172 */ 00173 static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record) 00174 { 00175 for (int i = 0; i < p_write_buffer_record->n_bufs; i++) 00176 { 00177 pm_buffer_release(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id + i); 00178 } 00179 00180 write_buffer_record_invalidate(p_write_buffer_record); 00181 } 00182 00183 00184 static void write_buffer_record_get(pdb_buffer_record_t ** pp_write_buffer_record, pm_peer_id_t peer_id, pm_peer_data_id_t data_id) 00185 { 00186 if (pp_write_buffer_record == NULL) 00187 { 00188 return; 00189 } 00190 *pp_write_buffer_record = write_buffer_record_find_unused(); 00191 if (*pp_write_buffer_record == NULL) 00192 { 00193 // This also means the buffer is full. 00194 return; 00195 } 00196 (*pp_write_buffer_record)->peer_id = peer_id; 00197 (*pp_write_buffer_record)->data_id = data_id; 00198 } 00199 00200 00201 /**@brief Function for dispatching outbound events to all registered event handlers. 00202 * 00203 * @param[in] p_event The event to dispatch. 00204 */ 00205 static void pdb_evt_send(pdb_evt_t * p_event) 00206 { 00207 for (int i = 0; i < m_pdb.n_registrants; i++) 00208 { 00209 m_pdb.evt_handlers[i](p_event); 00210 } 00211 } 00212 00213 00214 /**@brief Function for resetting the internal state of the Peer Database module. 00215 * 00216 * @param[out] p_event The event to dispatch. 00217 */ 00218 static void internal_state_reset(pdb_t * pdb) 00219 { 00220 memset(pdb, 0, sizeof(pdb_t)); 00221 for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++) 00222 { 00223 write_buffer_record_invalidate(&pdb->write_buffer_records[i]); 00224 } 00225 } 00226 00227 00228 /**@brief Function for handling events from the Peer Data Storage module. 00229 * 00230 * @param[in] p_event The event to handle. 00231 */ 00232 static void pds_evt_handler(pds_evt_t const * p_event) 00233 { 00234 ret_code_t err_code; 00235 pdb_buffer_record_t * p_write_buffer_record; 00236 bool retry_flash_full = false; 00237 pdb_evt_t event = 00238 { 00239 .peer_id = p_event->peer_id, 00240 .data_id = p_event->data_id, 00241 }; 00242 00243 p_write_buffer_record = write_buffer_record_find(p_event->peer_id, p_event->data_id); 00244 00245 switch (p_event->evt_id) 00246 { 00247 case PDS_EVT_STORED: 00248 if ( (p_write_buffer_record != NULL) 00249 //&& (p_write_buffer_record->store_token == p_event->store_token) 00250 && (p_write_buffer_record->store_requested)) 00251 { 00252 write_buffer_record_release(p_write_buffer_record); 00253 event.evt_id = PDB_EVT_WRITE_BUF_STORED; 00254 pdb_evt_send(&event); 00255 } 00256 else 00257 { 00258 event.evt_id = PDB_EVT_RAW_STORED; 00259 pdb_evt_send(&event); 00260 } 00261 break; 00262 case PDS_EVT_ERROR_STORE: 00263 if ( (p_write_buffer_record != NULL) 00264 && (p_write_buffer_record->store_token == p_event->store_token) 00265 && (p_write_buffer_record->store_requested)) 00266 { 00267 // Retry if internal buffer. 00268 m_pdb.n_writes++; 00269 p_write_buffer_record->store_requested = false; 00270 p_write_buffer_record->store_busy = true; 00271 } 00272 else 00273 { 00274 event.evt_id = PDB_EVT_RAW_STORE_FAILED; 00275 pdb_evt_send(&event); 00276 } 00277 break; 00278 case PDS_EVT_CLEARED: 00279 event.evt_id = PDB_EVT_CLEARED; 00280 pdb_evt_send(&event); 00281 break; 00282 case PDS_EVT_ERROR_CLEAR: 00283 event.evt_id = PDB_EVT_CLEAR_FAILED; 00284 pdb_evt_send(&event); 00285 break; 00286 case PDS_EVT_COMPRESSED: 00287 retry_flash_full = true; 00288 event.evt_id = PDB_EVT_COMPRESSED; 00289 pdb_evt_send(&event); 00290 break; 00291 default: 00292 break; 00293 } 00294 00295 if (m_pdb.n_writes > 0) 00296 { 00297 for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++) 00298 { 00299 if ((m_pdb.write_buffer_records[i].store_busy) 00300 || (m_pdb.write_buffer_records[i].store_flash_full && retry_flash_full)) 00301 { 00302 err_code = pdb_write_buf_store(m_pdb.write_buffer_records[i].peer_id, 00303 m_pdb.write_buffer_records[i].data_id); 00304 if (err_code != NRF_SUCCESS) 00305 { 00306 event.peer_id = m_pdb.write_buffer_records[i].peer_id; 00307 event.data_id = m_pdb.write_buffer_records[i].data_id; 00308 if (err_code == NRF_ERROR_NO_MEM) 00309 { 00310 event.evt_id = PDB_EVT_ERROR_NO_MEM; 00311 } 00312 else 00313 { 00314 event.evt_id = PDB_EVT_ERROR_UNEXPECTED; 00315 } 00316 00317 pdb_evt_send(&event); 00318 break; 00319 } 00320 } 00321 } 00322 } 00323 } 00324 00325 00326 ret_code_t pdb_register(pdb_evt_handler_t evt_handler) 00327 { 00328 if (m_pdb.n_registrants >= MAX_REGISTRANTS) 00329 { 00330 return NRF_ERROR_NO_MEM; 00331 } 00332 00333 VERIFY_PARAM_NOT_NULL(evt_handler); 00334 00335 if (!MODULE_INITIALIZED) 00336 { 00337 ret_code_t err_code; 00338 00339 internal_state_reset(&m_pdb); 00340 err_code = pds_register(pds_evt_handler); 00341 if (err_code != NRF_SUCCESS) 00342 { 00343 return err_code; 00344 } 00345 PM_BUFFER_INIT(&m_pdb.write_buffer, N_WRITE_BUFFERS, PDB_WRITE_BUF_SIZE, err_code); 00346 if (err_code != NRF_SUCCESS) 00347 { 00348 return err_code; 00349 } 00350 } 00351 00352 m_pdb.evt_handlers[m_pdb.n_registrants] = evt_handler; 00353 m_pdb.n_registrants += 1; 00354 00355 return NRF_SUCCESS; 00356 } 00357 00358 00359 pm_peer_id_t pdb_peer_allocate(void) 00360 { 00361 if (!MODULE_INITIALIZED) 00362 { 00363 return PM_PEER_ID_INVALID; 00364 } 00365 00366 return pds_peer_id_allocate(); 00367 } 00368 00369 00370 ret_code_t pdb_peer_free(pm_peer_id_t peer_id) 00371 { 00372 VERIFY_MODULE_INITIALIZED(); 00373 00374 return pds_peer_id_free(peer_id); 00375 } 00376 00377 00378 ret_code_t pdb_read_buf_get(pm_peer_id_t peer_id, 00379 pm_peer_data_id_t data_id, 00380 pm_peer_data_flash_t * p_peer_data, 00381 pm_store_token_t * p_token) 00382 { 00383 VERIFY_MODULE_INITIALIZED(); 00384 00385 return pds_peer_data_read_ptr_get(peer_id, data_id, p_peer_data, p_token); 00386 } 00387 00388 00389 static void peer_data_point_to_buffer(pm_peer_data_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint16_t n_bufs) 00390 { 00391 uint16_t n_bytes = n_bufs * PDB_WRITE_BUF_SIZE; 00392 p_peer_data->data_type = data_id; 00393 00394 switch(p_peer_data->data_type) 00395 { 00396 case PM_PEER_DATA_ID_BONDING: 00397 p_peer_data->data.p_bonding_data = (pm_peer_data_bonding_t *)p_buffer_memory; 00398 p_peer_data->length_words = PM_BONDING_DATA_N_WORDS(); 00399 break; 00400 case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING: 00401 p_peer_data->data.p_service_changed_pending = (bool *)p_buffer_memory; 00402 p_peer_data->length_words = PM_SC_STATE_N_WORDS(); 00403 break; 00404 case PM_PEER_DATA_ID_GATT_LOCAL: 00405 p_peer_data->data.p_local_gatt_db = (pm_peer_data_local_gatt_db_t *)p_buffer_memory; 00406 p_peer_data->length_words = PM_LOCAL_DB_N_WORDS(n_bytes); 00407 break; 00408 case PM_PEER_DATA_ID_GATT_REMOTE: 00409 p_peer_data->data.p_remote_gatt_db = (pm_peer_data_remote_gatt_db_t *)p_buffer_memory; 00410 p_peer_data->length_words = PM_REMOTE_DB_N_WORDS(n_bytes / sizeof(ble_gatt_db_srv_t)); 00411 break; 00412 case PM_PEER_DATA_ID_APPLICATION: 00413 p_peer_data->data.p_application_data = p_buffer_memory; 00414 p_peer_data->length_words = PM_N_WORDS(n_bytes); 00415 break; 00416 default: 00417 p_peer_data->length_words = 0; 00418 break; 00419 } 00420 } 00421 00422 00423 static void peer_data_const_point_to_buffer(pm_peer_data_const_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint32_t n_bufs) 00424 { 00425 peer_data_point_to_buffer((pm_peer_data_t*)p_peer_data, data_id, p_buffer_memory, n_bufs); 00426 } 00427 00428 00429 ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, 00430 pm_peer_data_id_t data_id, 00431 uint32_t n_bufs, 00432 pm_peer_data_t * p_peer_data) 00433 { 00434 VERIFY_MODULE_INITIALIZED(); 00435 VERIFY_PARAM_NOT_NULL(p_peer_data); 00436 if ( !PM_PEER_DATA_ID_IS_VALID(data_id) 00437 || (n_bufs == 0) 00438 || (n_bufs > N_WRITE_BUFFERS) 00439 || !pds_peer_id_is_allocated(peer_id)) 00440 { 00441 return NRF_ERROR_INVALID_PARAM; 00442 } 00443 00444 pdb_buffer_record_t * write_buffer_record; 00445 uint8_t * p_buffer_memory; 00446 00447 write_buffer_record = write_buffer_record_find(peer_id, data_id); 00448 00449 if ((write_buffer_record != NULL) && (write_buffer_record->n_bufs < n_bufs)) 00450 { 00451 // @TODO: Copy? 00452 // Existing buffer is too small. 00453 for (uint8_t i = 0; i < write_buffer_record->n_bufs; i++) 00454 { 00455 pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i); 00456 } 00457 write_buffer_record_invalidate(write_buffer_record); 00458 write_buffer_record = NULL; 00459 } 00460 else if ((write_buffer_record != NULL) && write_buffer_record->n_bufs > n_bufs) 00461 { 00462 // Release excess blocks. 00463 for (uint8_t i = n_bufs; i < write_buffer_record->n_bufs; i++) 00464 { 00465 pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i); 00466 } 00467 } 00468 00469 if (write_buffer_record == NULL) 00470 { 00471 write_buffer_record_get(&write_buffer_record, peer_id, data_id); 00472 if (write_buffer_record == NULL) 00473 { 00474 return NRF_ERROR_BUSY; 00475 } 00476 } 00477 00478 if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID) 00479 { 00480 write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_pdb.write_buffer, n_bufs); 00481 00482 if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID) 00483 { 00484 write_buffer_record_invalidate(write_buffer_record); 00485 return NRF_ERROR_BUSY; 00486 } 00487 } 00488 00489 write_buffer_record->n_bufs = n_bufs; 00490 00491 p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, write_buffer_record->buffer_block_id); 00492 00493 if (p_buffer_memory == NULL) 00494 { 00495 return NRF_ERROR_INTERNAL; 00496 } 00497 00498 peer_data_point_to_buffer(p_peer_data, data_id, p_buffer_memory, n_bufs); 00499 switch(data_id) 00500 { 00501 case PM_PEER_DATA_ID_BONDING: 00502 /* No action needed. */ 00503 break; 00504 case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING: 00505 /* No action needed. */ 00506 break; 00507 case PM_PEER_DATA_ID_GATT_LOCAL: 00508 { 00509 uint32_t size_offset = sizeof(pm_peer_data_local_gatt_db_t); 00510 p_peer_data->data.p_local_gatt_db->p_data = &p_buffer_memory[size_offset]; 00511 p_peer_data->data.p_local_gatt_db->len = (PDB_WRITE_BUF_SIZE*n_bufs)-size_offset; 00512 } 00513 break; 00514 case PM_PEER_DATA_ID_GATT_REMOTE: 00515 { 00516 uint32_t size_offset = sizeof(pm_peer_data_remote_gatt_db_t); 00517 p_peer_data->data.p_remote_gatt_db->p_data = (ble_gatt_db_srv_t*)&(p_buffer_memory[size_offset]); 00518 p_peer_data->data.p_remote_gatt_db->service_count 00519 = ((PDB_WRITE_BUF_SIZE*n_bufs)-size_offset)/sizeof(ble_gatt_db_srv_t); 00520 } 00521 break; 00522 case PM_PEER_DATA_ID_APPLICATION: 00523 { 00524 p_peer_data->data.p_application_data = p_buffer_memory; 00525 } 00526 break; 00527 default: 00528 // Invalid data_id. This should have been picked up earlier. 00529 return NRF_ERROR_INTERNAL; 00530 } 00531 00532 return NRF_SUCCESS; 00533 } 00534 00535 00536 ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) 00537 { 00538 VERIFY_MODULE_INITIALIZED(); 00539 00540 ret_code_t err_code = NRF_SUCCESS; 00541 pdb_buffer_record_t * p_write_buffer_record; 00542 p_write_buffer_record = write_buffer_record_find(peer_id, data_id); 00543 00544 if (p_write_buffer_record == NULL) 00545 { 00546 return NRF_ERROR_NOT_FOUND; 00547 } 00548 00549 if (p_write_buffer_record->prepare_token != PDS_PREPARE_TOKEN_INVALID) 00550 { 00551 err_code = pds_peer_data_write_prepare_cancel(p_write_buffer_record->prepare_token); 00552 if (err_code != NRF_SUCCESS) 00553 { 00554 err_code = NRF_ERROR_INTERNAL; 00555 } 00556 } 00557 00558 write_buffer_record_release(p_write_buffer_record); 00559 00560 return err_code; 00561 } 00562 00563 00564 ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) 00565 { 00566 VERIFY_MODULE_INITIALIZED(); 00567 00568 ret_code_t err_code = NRF_SUCCESS; 00569 pdb_buffer_record_t * p_write_buffer_record; 00570 p_write_buffer_record = write_buffer_record_find(peer_id, data_id); 00571 00572 if (p_write_buffer_record == NULL) 00573 { 00574 return NRF_ERROR_NOT_FOUND; 00575 } 00576 00577 if (p_write_buffer_record->prepare_token == PDS_PREPARE_TOKEN_INVALID) 00578 { 00579 uint8_t * p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id); 00580 pm_peer_data_const_t peer_data = {.data_type = data_id}; 00581 00582 if (p_buffer_memory == NULL) 00583 { 00584 return NRF_ERROR_INTERNAL; 00585 } 00586 00587 peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs); 00588 00589 err_code = pds_peer_data_write_prepare(&peer_data, &p_write_buffer_record->prepare_token); 00590 if (err_code == NRF_ERROR_INVALID_LENGTH) 00591 { 00592 return NRF_ERROR_INTERNAL; 00593 } 00594 } 00595 00596 return err_code; 00597 } 00598 00599 00600 static ret_code_t write_or_update(pm_peer_id_t peer_id, 00601 pm_peer_data_id_t data_id, 00602 pm_peer_data_const_t * p_peer_data, 00603 pm_store_token_t * p_store_token, 00604 pm_prepare_token_t prepare_token) 00605 { 00606 pm_peer_data_flash_t old_peer_data; 00607 pm_store_token_t old_store_token; 00608 ret_code_t err_code = pds_peer_data_read_ptr_get(peer_id, data_id, &old_peer_data, &old_store_token); 00609 00610 if (err_code == NRF_SUCCESS) 00611 { 00612 pds_peer_data_write_prepare_cancel(prepare_token); 00613 err_code = pds_peer_data_update(peer_id, p_peer_data, old_store_token, p_store_token); 00614 } 00615 else if (err_code == NRF_ERROR_NOT_FOUND) 00616 { 00617 if (prepare_token == PDS_PREPARE_TOKEN_INVALID) 00618 { 00619 err_code = pds_peer_data_write(peer_id, p_peer_data, p_store_token); 00620 } 00621 else 00622 { 00623 err_code = pds_peer_data_write_prepared(peer_id, p_peer_data, prepare_token, p_store_token); 00624 } 00625 } 00626 return err_code; 00627 } 00628 00629 00630 ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id, 00631 pm_peer_data_id_t data_id) 00632 { 00633 VERIFY_MODULE_INITIALIZED(); 00634 00635 ret_code_t err_code = NRF_SUCCESS; 00636 pdb_buffer_record_t * p_write_buffer_record; 00637 uint8_t * p_buffer_memory; 00638 pm_peer_data_const_t peer_data = {.data_type = data_id}; 00639 00640 00641 p_write_buffer_record = write_buffer_record_find(peer_id, data_id); 00642 00643 if (p_write_buffer_record == NULL) 00644 { 00645 return NRF_ERROR_NOT_FOUND; 00646 } 00647 00648 if (p_write_buffer_record->store_requested) 00649 { 00650 return NRF_SUCCESS; 00651 } 00652 00653 p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id); 00654 00655 if (p_buffer_memory == NULL) 00656 { 00657 return NRF_ERROR_INTERNAL; 00658 } 00659 00660 peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs); 00661 00662 switch (data_id) 00663 { 00664 case PM_PEER_DATA_ID_BONDING: 00665 peer_data.length_words = PM_BONDING_DATA_N_WORDS(); 00666 break; 00667 case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING: 00668 peer_data.length_words = PM_SC_STATE_N_WORDS(); 00669 break; 00670 case PM_PEER_DATA_ID_GATT_LOCAL: 00671 peer_data.length_words = PM_LOCAL_DB_N_WORDS(peer_data.data.p_local_gatt_db->len); 00672 break; 00673 case PM_PEER_DATA_ID_GATT_REMOTE: 00674 peer_data.length_words = PM_REMOTE_DB_N_WORDS(peer_data.data.p_remote_gatt_db->service_count); 00675 break; 00676 case PM_PEER_DATA_ID_APPLICATION: 00677 peer_data.length_words = PM_N_WORDS(p_write_buffer_record->n_bufs * PDB_WRITE_BUF_SIZE); 00678 break; 00679 default: 00680 return NRF_ERROR_INVALID_PARAM; 00681 } 00682 00683 err_code = write_or_update(peer_id, data_id, &peer_data, &p_write_buffer_record->store_token, p_write_buffer_record->prepare_token); 00684 00685 if (p_write_buffer_record->store_busy && p_write_buffer_record->store_flash_full) 00686 { 00687 m_pdb.n_writes--; 00688 } 00689 00690 if (err_code == NRF_SUCCESS) 00691 { 00692 p_write_buffer_record->store_requested = true; 00693 p_write_buffer_record->store_busy = false; 00694 p_write_buffer_record->store_flash_full = false; 00695 } 00696 else 00697 { 00698 if (err_code == NRF_ERROR_BUSY) 00699 { 00700 m_pdb.n_writes++; 00701 p_write_buffer_record->store_busy = true; 00702 p_write_buffer_record->store_flash_full = false; 00703 err_code = NRF_SUCCESS; 00704 } 00705 else if (err_code == NRF_ERROR_NO_MEM) 00706 { 00707 m_pdb.n_writes++; 00708 p_write_buffer_record->store_busy = false; 00709 p_write_buffer_record->store_flash_full = true; 00710 } 00711 else if ((err_code != NRF_ERROR_NO_MEM) && (err_code != NRF_ERROR_INVALID_PARAM)) 00712 { 00713 err_code = NRF_ERROR_INTERNAL; 00714 } 00715 } 00716 00717 return err_code; 00718 } 00719 00720 00721 ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) 00722 { 00723 VERIFY_MODULE_INITIALIZED(); 00724 00725 return pds_peer_data_clear(peer_id, data_id); 00726 } 00727 00728 00729 uint32_t pdb_n_peers(void) 00730 { 00731 if (!MODULE_INITIALIZED) 00732 { 00733 return 0; 00734 } 00735 00736 return pds_n_peers(); 00737 } 00738 00739 00740 pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id) 00741 { 00742 if (!MODULE_INITIALIZED) 00743 { 00744 return PM_PEER_ID_INVALID; 00745 } 00746 00747 return pds_next_peer_id_get(prev_peer_id); 00748 } 00749 00750 00751 ret_code_t pdb_raw_read(pm_peer_id_t peer_id, 00752 pm_peer_data_id_t data_id, 00753 pm_peer_data_t * p_peer_data) 00754 { 00755 VERIFY_MODULE_INITIALIZED(); 00756 return pds_peer_data_read(peer_id, data_id, p_peer_data, &p_peer_data->length_words); 00757 } 00758 00759 00760 ret_code_t pdb_raw_store(pm_peer_id_t peer_id, 00761 pm_peer_data_const_t * p_peer_data, 00762 pm_store_token_t * p_store_token) 00763 { 00764 VERIFY_MODULE_INITIALIZED(); 00765 00766 return write_or_update(peer_id, p_peer_data->data_type, p_peer_data, p_store_token, PDS_PREPARE_TOKEN_INVALID); 00767 }
Generated on Tue Jul 12 2022 14:11:20 by
