123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726 |
- #include "sdk_common.h"
- #if NRF_MODULE_ENABLED(PEER_MANAGER)
- #include "peer_database.h"
- #include <string.h>
- #include "peer_manager_types.h"
- #include "peer_manager_internal.h"
- #include "peer_data_storage.h"
- #include "pm_buffer.h"
- #define NRF_LOG_MODULE_NAME peer_manager_pdb
- #if PM_LOG_ENABLED
- #define NRF_LOG_LEVEL PM_LOG_LEVEL
- #define NRF_LOG_INFO_COLOR PM_LOG_INFO_COLOR
- #define NRF_LOG_DEBUG_COLOR PM_LOG_DEBUG_COLOR
- #else
- #define NRF_LOG_LEVEL 0
- #endif
- #include "nrf_log.h"
- #include "nrf_log_ctrl.h"
- NRF_LOG_MODULE_REGISTER();
- #include "nrf_strerror.h"
- #define VERIFY_DATA_ID_WRITE_BUF(data_id) \
- do \
- { \
- if (((data_id) != PM_PEER_DATA_ID_BONDING) && ((data_id) != PM_PEER_DATA_ID_GATT_LOCAL)) \
- { \
- return NRF_ERROR_INVALID_PARAM; \
- } \
- } while (0)
- #define PDB_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0]))
- extern void pm_pdb_evt_handler(pm_evt_t * p_event);
- extern void sm_pdb_evt_handler(pm_evt_t * p_event);
- #if !defined(PM_SERVICE_CHANGED_ENABLED) || (PM_SERVICE_CHANGED_ENABLED == 1)
- extern void gscm_pdb_evt_handler(pm_evt_t * p_event);
- #endif
- extern void gcm_pdb_evt_handler(pm_evt_t * p_event);
- static pm_evt_handler_internal_t const m_evt_handlers[] =
- {
- pm_pdb_evt_handler,
- sm_pdb_evt_handler,
- #if !defined(PM_SERVICE_CHANGED_ENABLED) || (PM_SERVICE_CHANGED_ENABLED == 1)
- gscm_pdb_evt_handler,
- #endif
- gcm_pdb_evt_handler,
- };
- typedef struct
- {
- pm_peer_id_t peer_id;
- pm_peer_data_id_t data_id;
- pm_store_token_t store_token;
- uint8_t n_bufs;
- uint8_t buffer_block_id;
- uint8_t store_flash_full : 1;
- uint8_t store_busy : 1;
- } pdb_buffer_record_t;
- static bool m_module_initialized;
- static pm_buffer_t m_write_buffer;
- static pdb_buffer_record_t m_write_buffer_records[PM_FLASH_BUFFERS];
- static bool m_pending_store = false;
- static void write_buffer_record_invalidate(pdb_buffer_record_t * p_record)
- {
- p_record->peer_id = PM_PEER_ID_INVALID;
- p_record->data_id = PM_PEER_DATA_ID_INVALID;
- p_record->buffer_block_id = PM_BUFFER_INVALID_ID;
- p_record->store_busy = false;
- p_record->store_flash_full = false;
- p_record->n_bufs = 0;
- p_record->store_token = PM_STORE_TOKEN_INVALID;
- }
- static pdb_buffer_record_t * write_buffer_record_find_next(pm_peer_id_t peer_id, uint32_t * p_index)
- {
- for (uint32_t i = *p_index; i < PM_FLASH_BUFFERS; i++)
- {
- if ((m_write_buffer_records[i].peer_id == peer_id))
- {
- *p_index = i;
- return &m_write_buffer_records[i];
- }
- }
- return NULL;
- }
- static pdb_buffer_record_t * write_buffer_record_find(pm_peer_id_t peer_id,
- pm_peer_data_id_t data_id)
- {
- uint32_t index = 0;
- pdb_buffer_record_t * p_record = write_buffer_record_find_next(peer_id, &index);
- while ((p_record != NULL) && ( (p_record->data_id != data_id)
- || (p_record->store_busy)
- || (p_record->store_flash_full)
- || (p_record->store_token != PM_STORE_TOKEN_INVALID)))
- {
- index++;
- p_record = write_buffer_record_find_next(peer_id, &index);
- }
- return p_record;
- }
- static pdb_buffer_record_t * write_buffer_record_find_stored(pm_store_token_t store_token)
- {
- for (int i = 0; i < PM_FLASH_BUFFERS; i++)
- {
- if (m_write_buffer_records[i].store_token == store_token)
- {
- return &m_write_buffer_records[i];
- }
- }
- return NULL;
- }
- static pdb_buffer_record_t * write_buffer_record_find_unused(void)
- {
- return write_buffer_record_find(PM_PEER_ID_INVALID, PM_PEER_DATA_ID_INVALID);
- }
- static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record)
- {
- for (uint32_t i = 0; i < p_write_buffer_record->n_bufs; i++)
- {
- pm_buffer_release(&m_write_buffer, p_write_buffer_record->buffer_block_id + i);
- }
- write_buffer_record_invalidate(p_write_buffer_record);
- }
- static void write_buffer_record_acquire(pdb_buffer_record_t ** pp_write_buffer_record,
- pm_peer_id_t peer_id,
- pm_peer_data_id_t data_id)
- {
- if (pp_write_buffer_record == NULL)
- {
- return;
- }
- *pp_write_buffer_record = write_buffer_record_find_unused();
- if (*pp_write_buffer_record == NULL)
- {
-
- return;
- }
- (*pp_write_buffer_record)->peer_id = peer_id;
- (*pp_write_buffer_record)->data_id = data_id;
- }
- static void pdb_evt_send(pm_evt_t * p_event)
- {
- for (uint32_t i = 0; i < PDB_EVENT_HANDLERS_CNT; i++)
- {
- m_evt_handlers[i](p_event);
- }
- }
- static void internal_state_reset()
- {
- for (uint32_t i = 0; i < PM_FLASH_BUFFERS; i++)
- {
- write_buffer_record_invalidate(&m_write_buffer_records[i]);
- }
- }
- 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)
- {
- uint16_t n_bytes = n_bufs * PDB_WRITE_BUF_SIZE;
- p_peer_data->data_id = data_id;
- p_peer_data->p_all_data = (pm_peer_data_bonding_t *)p_buffer_memory;
- p_peer_data->length_words = BYTES_TO_WORDS(n_bytes);
- }
- 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)
- {
- peer_data_point_to_buffer((pm_peer_data_t*)p_peer_data, data_id, p_buffer_memory, n_bufs);
- }
- static void write_buf_length_words_set(pm_peer_data_const_t * p_peer_data)
- {
- switch (p_peer_data->data_id)
- {
- case PM_PEER_DATA_ID_BONDING:
- p_peer_data->length_words = PM_BONDING_DATA_N_WORDS();
- break;
- case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
- p_peer_data->length_words = PM_SC_STATE_N_WORDS();
- break;
- case PM_PEER_DATA_ID_PEER_RANK:
- p_peer_data->length_words = PM_USAGE_INDEX_N_WORDS();
- break;
- case PM_PEER_DATA_ID_GATT_LOCAL:
- p_peer_data->length_words = PM_LOCAL_DB_N_WORDS(p_peer_data->p_local_gatt_db->len);
- break;
- default:
-
- break;
- }
- }
- ret_code_t write_buf_store(pdb_buffer_record_t * p_write_buffer_record)
- {
- ret_code_t err_code = NRF_SUCCESS;
- pm_peer_data_const_t peer_data = {.data_id = p_write_buffer_record->data_id};
- uint8_t * p_buffer_memory;
- p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, p_write_buffer_record->buffer_block_id);
- if (p_buffer_memory == NULL)
- {
- NRF_LOG_ERROR("pm_buffer_ptr_get() could not retrieve RAM buffer. block_id: %d",
- p_write_buffer_record->buffer_block_id);
- return NRF_ERROR_INTERNAL;
- }
- peer_data_const_point_to_buffer(&peer_data,
- p_write_buffer_record->data_id,
- p_buffer_memory,
- p_write_buffer_record->n_bufs);
- write_buf_length_words_set(&peer_data);
- err_code = pds_peer_data_store(p_write_buffer_record->peer_id,
- &peer_data,
- &p_write_buffer_record->store_token);
- switch (err_code)
- {
- case NRF_SUCCESS:
- p_write_buffer_record->store_busy = false;
- p_write_buffer_record->store_flash_full = false;
- break;
- case NRF_ERROR_BUSY:
- p_write_buffer_record->store_busy = true;
- p_write_buffer_record->store_flash_full = false;
- m_pending_store = true;
- err_code = NRF_SUCCESS;
- break;
- case NRF_ERROR_STORAGE_FULL:
- p_write_buffer_record->store_busy = false;
- p_write_buffer_record->store_flash_full = true;
- m_pending_store = true;
- break;
- case NRF_ERROR_INVALID_PARAM:
-
- break;
- default:
- NRF_LOG_ERROR("pds_peer_data_store() returned %s. peer_id: %d",
- nrf_strerror_get(err_code),
- p_write_buffer_record->peer_id);
- err_code = NRF_ERROR_INTERNAL;
- break;
- }
- return err_code;
- }
- static bool write_buf_store_in_event(pdb_buffer_record_t * p_write_buffer_record)
- {
- ret_code_t err_code;
- pm_evt_t event;
- err_code = write_buf_store(p_write_buffer_record);
- if (err_code != NRF_SUCCESS)
- {
- event.conn_handle = BLE_CONN_HANDLE_INVALID;
- event.peer_id = p_write_buffer_record->peer_id;
- if (err_code == NRF_ERROR_STORAGE_FULL)
- {
- event.evt_id = PM_EVT_STORAGE_FULL;
- }
- else
- {
- event.evt_id = PM_EVT_ERROR_UNEXPECTED;
- event.params.error_unexpected.error = err_code;
- NRF_LOG_ERROR("Some peer data was not properly written to flash. write_buf_store() "\
- "returned %s for peer_id: %d",
- nrf_strerror_get(err_code),
- p_write_buffer_record->peer_id);
- }
- pdb_evt_send(&event);
- return false;
- }
- return true;
- }
- static void reattempt_previous_operations(bool retry_flash_full)
- {
- if (!m_pending_store)
- {
- return;
- }
- m_pending_store = false;
- for (uint32_t i = 0; i < PM_FLASH_BUFFERS; i++)
- {
- if ((m_write_buffer_records[i].store_busy)
- || (m_write_buffer_records[i].store_flash_full))
- {
- m_pending_store = true;
- if (m_write_buffer_records[i].store_busy || retry_flash_full)
- {
- if (!write_buf_store_in_event(&m_write_buffer_records[i]))
- {
- return;
- }
- }
- }
- }
- }
- void pdb_pds_evt_handler(pm_evt_t * p_event)
- {
- pdb_buffer_record_t * p_write_buffer_record;
- bool evt_send = true;
- bool retry_flash_full = false;
- p_write_buffer_record = write_buffer_record_find_stored(p_event->params.peer_data_update_succeeded.token);
- switch (p_event->evt_id)
- {
- case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
- if ( (p_event->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
- && (p_write_buffer_record != NULL))
- {
-
- write_buffer_record_release(p_write_buffer_record);
- }
- break;
- case PM_EVT_PEER_DATA_UPDATE_FAILED:
- if ( (p_event->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
- && (p_write_buffer_record != NULL))
- {
-
- p_write_buffer_record->store_token = PM_STORE_TOKEN_INVALID;
- p_write_buffer_record->store_busy = true;
- m_pending_store = true;
- evt_send = false;
- }
- break;
- case PM_EVT_FLASH_GARBAGE_COLLECTED:
- retry_flash_full = true;
- break;
- default:
- break;
- }
- if (evt_send)
- {
-
- pdb_evt_send(p_event);
- }
- reattempt_previous_operations(retry_flash_full);
- }
- ret_code_t pdb_init()
- {
- ret_code_t err_code;
- NRF_PM_DEBUG_CHECK(!m_module_initialized);
- internal_state_reset();
- PM_BUFFER_INIT(&m_write_buffer, PM_FLASH_BUFFERS, PDB_WRITE_BUF_SIZE, err_code);
- if (err_code != NRF_SUCCESS)
- {
- NRF_LOG_ERROR("PM_BUFFER_INIT() returned %s.", nrf_strerror_get(err_code));
- return NRF_ERROR_INTERNAL;
- }
- m_module_initialized = true;
- return NRF_SUCCESS;
- }
- ret_code_t pdb_peer_free(pm_peer_id_t peer_id)
- {
- ret_code_t err_code;
- NRF_PM_DEBUG_CHECK(m_module_initialized);
- uint32_t index = 0;
- pdb_buffer_record_t * p_record = write_buffer_record_find_next(peer_id, &index);
- while (p_record != NULL)
- {
- err_code = pdb_write_buf_release(peer_id, p_record->data_id);
- UNUSED_VARIABLE(err_code);
- if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_NOT_FOUND))
- {
- NRF_LOG_ERROR("pdb_write_buf_release() returned %s which should not happen. peer_id: %d, "\
- "data_id: %d",
- nrf_strerror_get(err_code),
- peer_id,
- p_record->data_id);
- return NRF_ERROR_INTERNAL;
- }
- index++;
- p_record = write_buffer_record_find_next(peer_id, &index);
- }
- err_code = pds_peer_id_free(peer_id);
- if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_INVALID_PARAM))
- {
- return err_code;
- }
- else
- {
- NRF_LOG_ERROR("Peer ID %d was not properly released. pds_peer_id_free() returned %s. "\
- "peer_id: %d",
- peer_id,
- nrf_strerror_get(err_code));
- return NRF_ERROR_INTERNAL;
- }
- }
- ret_code_t pdb_peer_data_ptr_get(pm_peer_id_t peer_id,
- pm_peer_data_id_t data_id,
- pm_peer_data_flash_t * const p_peer_data)
- {
- NRF_PM_DEBUG_CHECK(m_module_initialized);
- NRF_PM_DEBUG_CHECK(p_peer_data != NULL);
-
- return pds_peer_data_read(peer_id, data_id, (pm_peer_data_t*)p_peer_data, NULL);
- }
- ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id,
- pm_peer_data_id_t data_id,
- uint32_t n_bufs,
- pm_peer_data_t * p_peer_data)
- {
- NRF_PM_DEBUG_CHECK(m_module_initialized);
- VERIFY_PARAM_NOT_NULL(p_peer_data);
- VERIFY_DATA_ID_WRITE_BUF(data_id);
- if ((n_bufs == 0) || (n_bufs > PM_FLASH_BUFFERS))
- {
- return NRF_ERROR_INVALID_PARAM;
- }
- pdb_buffer_record_t * p_write_buffer_record;
- uint8_t * p_buffer_memory;
- bool new_record = false;
- p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
- if (p_write_buffer_record == NULL)
- {
-
- write_buffer_record_acquire(&p_write_buffer_record, peer_id, data_id);
- if (p_write_buffer_record == NULL)
- {
- return NRF_ERROR_BUSY;
- }
- }
- else if (p_write_buffer_record->n_bufs != n_bufs)
- {
-
- return NRF_ERROR_FORBIDDEN;
- }
- if (p_write_buffer_record->buffer_block_id == PM_BUFFER_INVALID_ID)
- {
- p_write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_write_buffer, n_bufs);
- if (p_write_buffer_record->buffer_block_id == PM_BUFFER_INVALID_ID)
- {
- write_buffer_record_invalidate(p_write_buffer_record);
- return NRF_ERROR_BUSY;
- }
- new_record = true;
- }
- p_write_buffer_record->n_bufs = n_bufs;
- p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, p_write_buffer_record->buffer_block_id);
- if (p_buffer_memory == NULL)
- {
- NRF_LOG_ERROR("Cannot store data to flash because pm_buffer_ptr_get() could not retrieve "\
- "RAM buffer. Is block_id %d not allocated?",
- p_write_buffer_record->buffer_block_id);
- return NRF_ERROR_INTERNAL;
- }
- peer_data_point_to_buffer(p_peer_data, data_id, p_buffer_memory, n_bufs);
- if (new_record && (data_id == PM_PEER_DATA_ID_GATT_LOCAL))
- {
- p_peer_data->p_local_gatt_db->len = PM_LOCAL_DB_LEN(p_peer_data->length_words);
- }
- return NRF_SUCCESS;
- }
- ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
- {
- NRF_PM_DEBUG_CHECK(m_module_initialized);
- pdb_buffer_record_t * p_write_buffer_record;
- p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
- if (p_write_buffer_record == NULL)
- {
- return NRF_ERROR_NOT_FOUND;
- }
- write_buffer_record_release(p_write_buffer_record);
- return NRF_SUCCESS;
- }
- ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id,
- pm_peer_data_id_t data_id,
- pm_peer_id_t new_peer_id)
- {
- NRF_PM_DEBUG_CHECK(m_module_initialized);
- VERIFY_DATA_ID_WRITE_BUF(data_id);
- if (!pds_peer_id_is_allocated(new_peer_id))
- {
- return NRF_ERROR_INVALID_PARAM;
- }
- pdb_buffer_record_t * p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
- if (p_write_buffer_record == NULL)
- {
- return NRF_ERROR_NOT_FOUND;
- }
- p_write_buffer_record->peer_id = new_peer_id;
- p_write_buffer_record->data_id = data_id;
- return write_buf_store(p_write_buffer_record);
- }
- #endif
|