// @note emdi: unused.. ret_code_t pds_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { ret_code_t ret; fds_record_desc_t record_desc; NRF_PM_DEBUG_CHECK(m_module_initialized); VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PEER_DATA_ID_IN_RANGE(data_id); ret = peer_data_find(peer_id, data_id, &record_desc); if (ret != NRF_SUCCESS) { return NRF_ERROR_NOT_FOUND; } ret = fds_record_delete(&record_desc); switch (ret) { case FDS_SUCCESS: return NRF_SUCCESS; case FDS_ERR_NO_SPACE_IN_QUEUES: return NRF_ERROR_BUSY; default: return NRF_ERROR_INTERNAL; } }
ret_code_t pds_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { ret_code_t retval; uint16_t file_id; uint16_t record_key; fds_record_desc_t record_desc; fds_find_token_t find_tok = {0}; VERIFY_MODULE_INITIALIZED(); VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PEER_DATA_ID_IN_RANGE(data_id); file_id = peer_id_to_file_id(peer_id); record_key = peer_data_id_to_record_key(data_id); retval = fds_record_find(file_id, record_key, &record_desc, &find_tok); if(retval != FDS_SUCCESS) { return NRF_ERROR_NOT_FOUND; } retval = fds_record_delete(&record_desc); switch (retval) { case FDS_SUCCESS: return NRF_SUCCESS; case FDS_ERR_NO_SPACE_IN_QUEUES: return NRF_ERROR_BUSY; default: return NRF_ERROR_INTERNAL; } }
ret_code_t pds_peer_data_read(pm_peer_id_t peer_id, pm_peer_data_id_t data_id, pm_peer_data_t * p_data, uint16_t * p_len_words) { ret_code_t retval; pm_peer_data_flash_t peer_data_flash; VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PEER_DATA_ID_IN_RANGE(data_id); VERIFY_PARAM_NOT_NULL(p_len_words); VERIFY_PARAM_NOT_NULL(p_data); retval = pds_peer_data_read_ptr_get(peer_id, data_id, &peer_data_flash, NULL); if (retval != NRF_SUCCESS) { return retval; } if ((*p_len_words) == 0) { (*p_len_words) = peer_data_flash.length_words; return NRF_SUCCESS; } else if ((*p_len_words) < peer_data_flash.length_words) { return NRF_ERROR_NO_MEM; } VERIFY_PARAM_NOT_NULL(p_data->p_all_data); retval = peer_data_deserialize(&peer_data_flash, p_data); return retval; }
ret_code_t pds_peer_id_free(pm_peer_id_t peer_id) { NRF_PM_DEBUG_CHECK(m_module_initialized); VERIFY_PEER_ID_IN_RANGE(peer_id); (void)peer_id_delete(peer_id); peer_data_delete(); return NRF_SUCCESS; }
ret_code_t pds_peer_data_update(pm_peer_id_t peer_id, pm_peer_data_const_t const * p_peer_data, pm_store_token_t old_token, pm_store_token_t * p_store_token) { ret_code_t retval; fds_record_t record; fds_record_desc_t record_desc; fds_record_chunk_t chunks[2]; uint16_t n_chunks; VERIFY_MODULE_INITIALIZED(); VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PARAM_NOT_NULL(p_peer_data); VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id); // Create chunks. peer_data_parts_get(p_peer_data, chunks, &n_chunks); // Prepare the record to be written. record.file_id = peer_id_to_file_id(peer_id); record.key = peer_data_id_to_record_key(p_peer_data->data_id); record.data.p_chunks = chunks; record.data.num_chunks = n_chunks; // Obtain the descriptor of the record to be updated. // It is safe to ignore the return value if record_desc is different from NULL. (void)fds_descriptor_from_rec_id(&record_desc, (uint32_t)old_token); retval = fds_record_update(&record_desc, &record); if ((retval == FDS_SUCCESS) && (p_store_token != NULL)) { // If fds_record_update() returned sucessfully, it is safe // to ignore the return value from fds_record_id_from_desc() since // the descriptor is valid, and also p_store_token is different from NULL. (void)fds_record_id_from_desc(&record_desc, (uint32_t*)p_store_token); } switch (retval) { case FDS_SUCCESS: return NRF_SUCCESS; case FDS_ERR_BUSY: case FDS_ERR_NO_SPACE_IN_QUEUES: return NRF_ERROR_BUSY; case FDS_ERR_NO_SPACE_IN_FLASH: return NRF_ERROR_NO_MEM; default: return NRF_ERROR_INTERNAL; } }
ret_code_t pds_peer_id_free(pm_peer_id_t peer_id) { VERIFY_MODULE_INITIALIZED(); VERIFY_PEER_ID_IN_RANGE(peer_id); PEER_IDS_INITIALIZE(); (void)peer_id_delete(peer_id); peer_data_clear(); return NRF_SUCCESS; }
static ret_code_t find_fds_item(pm_peer_id_t peer_id, pm_peer_data_id_t data_id, fds_record_desc_t * const p_desc) { fds_find_token_t find_tok = {0}; VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PEER_DATA_ID_IN_RANGE(data_id); // pp_record verified by caller. uint16_t file_id = peer_id_to_file_id(peer_id); uint16_t record_key = peer_data_id_to_record_key(data_id); return fds_record_find(file_id, record_key, p_desc, &find_tok); }
ret_code_t pds_peer_data_read_ptr_get(pm_peer_id_t peer_id, pm_peer_data_id_t data_id, pm_peer_data_flash_t * p_data, pm_store_token_t * p_token) { ret_code_t retval; fds_flash_record_t record; fds_record_desc_t record_desc; VERIFY_MODULE_INITIALIZED(); VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PEER_DATA_ID_IN_RANGE(data_id); VERIFY_PARAM_NOT_NULL(p_data); retval = find_fds_item(peer_id, data_id, &record_desc); if (retval != FDS_SUCCESS) { return NRF_ERROR_NOT_FOUND; } // Shouldn't fail, unless the record was deleted. (void)fds_record_open(&record_desc, &record); if (p_data != NULL) { p_data->data_id = data_id; p_data->length_words = record.p_header->tl.length_words; p_data->p_all_data = record.p_data; } if (p_token != NULL) { *p_token = (uint32_t)record.p_header->record_id; } // Shouldn't fail, unless the record was already closed. (void)fds_record_close(&record_desc); return NRF_SUCCESS; }
ret_code_t pds_peer_data_store(pm_peer_id_t peer_id, pm_peer_data_const_t const * p_peer_data, pm_prepare_token_t prepare_token, pm_store_token_t * p_store_token) { ret_code_t ret; fds_record_t rec; fds_record_desc_t rec_desc; fds_record_chunk_t rec_chunk; NRF_PM_DEBUG_CHECK(m_module_initialized); NRF_PM_DEBUG_CHECK(p_peer_data != NULL); VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id); // Prepare chunk. rec_chunk.p_data = p_peer_data->p_all_data; rec_chunk.length_words = p_peer_data->length_words; // Prepare the record to be stored in flash. rec.file_id = peer_id_to_file_id(peer_id); rec.key = peer_data_id_to_record_key(p_peer_data->data_id); rec.data.p_chunks = &rec_chunk; rec.data.num_chunks = 1; ret = peer_data_find(peer_id, p_peer_data->data_id, &rec_desc); if (ret == NRF_ERROR_NOT_FOUND) { // No previous data exists in flash. if (prepare_token == PDS_PREPARE_TOKEN_INVALID) { // No space was previously reserved. ret = fds_record_write(&rec_desc, &rec); } else { // Space for this record was previously reserved. ret = fds_record_write_reserved(&rec_desc, &rec, (fds_reserve_token_t*)&prepare_token); } } else // NRF_SUCCESS { if (prepare_token != PDS_PREPARE_TOKEN_INVALID) { (void)fds_reserve_cancel((fds_reserve_token_t*)&prepare_token); } // Update existing record. ret = fds_record_update(&rec_desc, &rec); } switch (ret) { case FDS_SUCCESS: if (p_store_token != NULL) { // Update the store token. (void)fds_record_id_from_desc(&rec_desc, (uint32_t*)p_store_token); } return NRF_SUCCESS; case FDS_ERR_BUSY: case FDS_ERR_NO_SPACE_IN_QUEUES: return NRF_ERROR_BUSY; case FDS_ERR_NO_SPACE_IN_FLASH: return NRF_ERROR_STORAGE_FULL; default: return NRF_ERROR_INTERNAL; } }
ret_code_t pds_peer_data_read(pm_peer_id_t peer_id, pm_peer_data_id_t data_id, pm_peer_data_t * const p_data, uint32_t const * const p_buf_len) { ret_code_t ret; fds_record_desc_t rec_desc; fds_flash_record_t rec_flash; NRF_PM_DEBUG_CHECK(m_module_initialized); NRF_PM_DEBUG_CHECK(p_data != NULL); VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PEER_DATA_ID_IN_RANGE(data_id); ret = peer_data_find(peer_id, data_id, &rec_desc); if (ret != NRF_SUCCESS) { return NRF_ERROR_NOT_FOUND; } // Shouldn't fail, unless the record was deleted in the meanwhile or the CRC check has failed. ret = fds_record_open(&rec_desc, &rec_flash); if (ret != NRF_SUCCESS) { return NRF_ERROR_NOT_FOUND; } // @note emdi: could this actually be set by the caller and used instead // of an additional parameter (data_id) ? p_data->data_id = data_id; p_data->length_words = rec_flash.p_header->tl.length_words; // If p_buf_len is NULL, provide a pointer to data in flash, otherwise, // check that the buffer is large enough and copy the data in flash into the buffer. if (p_buf_len != NULL) { uint32_t const data_len_bytes = (p_data->length_words * sizeof(uint32_t)); if ((*p_buf_len) <= data_len_bytes) { memcpy(p_data->p_all_data, rec_flash.p_data, data_len_bytes); } else { return NRF_ERROR_NO_MEM; } } else { // The cast is necessary because if no buffer is provided, we just copy the pointer, // but it that case it should be considered a pointer to const data by the caller, // since it is a pointer to data in flash. p_data->p_all_data = (void*)rec_flash.p_data; } // Shouldn't fail unless the record was already closed, in which case it can be ignored. (void)fds_record_close(&rec_desc); return NRF_SUCCESS; }