cvb

Fork of nrf51-sdk by Lancaster University

Committer:
Jonathan Austin
Date:
Wed Apr 06 23:55:04 2016 +0100
Revision:
0:bc2961fa1ef0
Synchronized with git rev 90647e3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 0:bc2961fa1ef0 1 /*
Jonathan Austin 0:bc2961fa1ef0 2 * Copyright (c) Nordic Semiconductor ASA
Jonathan Austin 0:bc2961fa1ef0 3 * All rights reserved.
Jonathan Austin 0:bc2961fa1ef0 4 *
Jonathan Austin 0:bc2961fa1ef0 5 * Redistribution and use in source and binary forms, with or without modification,
Jonathan Austin 0:bc2961fa1ef0 6 * are permitted provided that the following conditions are met:
Jonathan Austin 0:bc2961fa1ef0 7 *
Jonathan Austin 0:bc2961fa1ef0 8 * 1. Redistributions of source code must retain the above copyright notice, this
Jonathan Austin 0:bc2961fa1ef0 9 * list of conditions and the following disclaimer.
Jonathan Austin 0:bc2961fa1ef0 10 *
Jonathan Austin 0:bc2961fa1ef0 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this
Jonathan Austin 0:bc2961fa1ef0 12 * list of conditions and the following disclaimer in the documentation and/or
Jonathan Austin 0:bc2961fa1ef0 13 * other materials provided with the distribution.
Jonathan Austin 0:bc2961fa1ef0 14 *
Jonathan Austin 0:bc2961fa1ef0 15 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other
Jonathan Austin 0:bc2961fa1ef0 16 * contributors to this software may be used to endorse or promote products
Jonathan Austin 0:bc2961fa1ef0 17 * derived from this software without specific prior written permission.
Jonathan Austin 0:bc2961fa1ef0 18 *
Jonathan Austin 0:bc2961fa1ef0 19 *
Jonathan Austin 0:bc2961fa1ef0 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Jonathan Austin 0:bc2961fa1ef0 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Jonathan Austin 0:bc2961fa1ef0 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Jonathan Austin 0:bc2961fa1ef0 23 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
Jonathan Austin 0:bc2961fa1ef0 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Jonathan Austin 0:bc2961fa1ef0 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Jonathan Austin 0:bc2961fa1ef0 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
Jonathan Austin 0:bc2961fa1ef0 27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Jonathan Austin 0:bc2961fa1ef0 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Jonathan Austin 0:bc2961fa1ef0 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Jonathan Austin 0:bc2961fa1ef0 30 *
Jonathan Austin 0:bc2961fa1ef0 31 */
Jonathan Austin 0:bc2961fa1ef0 32
Jonathan Austin 0:bc2961fa1ef0 33
Jonathan Austin 0:bc2961fa1ef0 34 #include "peer_database.h"
Jonathan Austin 0:bc2961fa1ef0 35
Jonathan Austin 0:bc2961fa1ef0 36 #include <string.h>
Jonathan Austin 0:bc2961fa1ef0 37 #include "peer_manager_types.h"
Jonathan Austin 0:bc2961fa1ef0 38 #include "peer_data_storage.h"
Jonathan Austin 0:bc2961fa1ef0 39 #include "pm_buffer.h"
Jonathan Austin 0:bc2961fa1ef0 40
Jonathan Austin 0:bc2961fa1ef0 41
Jonathan Austin 0:bc2961fa1ef0 42 #define MAX_REGISTRANTS 6 /**< The number of user that can register with the module. */
Jonathan Austin 0:bc2961fa1ef0 43
Jonathan Austin 0:bc2961fa1ef0 44 #define MODULE_INITIALIZED (m_pdb.n_registrants > 0) /**< Expression which is true when the module is initialized. */
Jonathan Austin 0:bc2961fa1ef0 45
Jonathan Austin 0:bc2961fa1ef0 46 #define N_WRITE_BUFFERS 8 /**< The number of write buffers available. */
Jonathan Austin 0:bc2961fa1ef0 47 #define N_WRITE_BUFFER_RECORDS (N_WRITE_BUFFERS) /**< The number of write buffer records. */
Jonathan Austin 0:bc2961fa1ef0 48
Jonathan Austin 0:bc2961fa1ef0 49 /**@brief Macro for verifying that the module is initialized. It will cause the function to return
Jonathan Austin 0:bc2961fa1ef0 50 * @ref NRF_ERROR_INVALID_STATE if not.
Jonathan Austin 0:bc2961fa1ef0 51 */
Jonathan Austin 0:bc2961fa1ef0 52 #define VERIFY_MODULE_INITIALIZED() \
Jonathan Austin 0:bc2961fa1ef0 53 do \
Jonathan Austin 0:bc2961fa1ef0 54 { \
Jonathan Austin 0:bc2961fa1ef0 55 if (!MODULE_INITIALIZED) \
Jonathan Austin 0:bc2961fa1ef0 56 { \
Jonathan Austin 0:bc2961fa1ef0 57 return NRF_ERROR_INVALID_STATE; \
Jonathan Austin 0:bc2961fa1ef0 58 } \
Jonathan Austin 0:bc2961fa1ef0 59 } while(0)
Jonathan Austin 0:bc2961fa1ef0 60
Jonathan Austin 0:bc2961fa1ef0 61
Jonathan Austin 0:bc2961fa1ef0 62 /**@brief Macro for verifying that the module is initialized. It will cause the function to return
Jonathan Austin 0:bc2961fa1ef0 63 * if not.
Jonathan Austin 0:bc2961fa1ef0 64 */
Jonathan Austin 0:bc2961fa1ef0 65 #define VERIFY_MODULE_INITIALIZED_VOID()\
Jonathan Austin 0:bc2961fa1ef0 66 do \
Jonathan Austin 0:bc2961fa1ef0 67 { \
Jonathan Austin 0:bc2961fa1ef0 68 if (!MODULE_INITIALIZED) \
Jonathan Austin 0:bc2961fa1ef0 69 { \
Jonathan Austin 0:bc2961fa1ef0 70 return; \
Jonathan Austin 0:bc2961fa1ef0 71 } \
Jonathan Austin 0:bc2961fa1ef0 72 } while(0)
Jonathan Austin 0:bc2961fa1ef0 73
Jonathan Austin 0:bc2961fa1ef0 74
Jonathan Austin 0:bc2961fa1ef0 75 /**@brief Macro for verifying that the module is initialized. It will cause the function to return
Jonathan Austin 0:bc2961fa1ef0 76 * if not.
Jonathan Austin 0:bc2961fa1ef0 77 *
Jonathan Austin 0:bc2961fa1ef0 78 * @param[in] param The variable to check if is NULL.
Jonathan Austin 0:bc2961fa1ef0 79 */
Jonathan Austin 0:bc2961fa1ef0 80 #define VERIFY_PARAM_NOT_NULL(param) \
Jonathan Austin 0:bc2961fa1ef0 81 do \
Jonathan Austin 0:bc2961fa1ef0 82 { \
Jonathan Austin 0:bc2961fa1ef0 83 if (param == NULL) \
Jonathan Austin 0:bc2961fa1ef0 84 { \
Jonathan Austin 0:bc2961fa1ef0 85 return NRF_ERROR_NULL; \
Jonathan Austin 0:bc2961fa1ef0 86 } \
Jonathan Austin 0:bc2961fa1ef0 87 } while(0)
Jonathan Austin 0:bc2961fa1ef0 88
Jonathan Austin 0:bc2961fa1ef0 89
Jonathan Austin 0:bc2961fa1ef0 90 typedef struct
Jonathan Austin 0:bc2961fa1ef0 91 {
Jonathan Austin 0:bc2961fa1ef0 92 pm_peer_id_t peer_id;
Jonathan Austin 0:bc2961fa1ef0 93 pm_peer_data_id_t data_id;
Jonathan Austin 0:bc2961fa1ef0 94 uint8_t buffer_block_id;
Jonathan Austin 0:bc2961fa1ef0 95 uint8_t store_busy : 1;
Jonathan Austin 0:bc2961fa1ef0 96 uint8_t store_flash_full : 1;
Jonathan Austin 0:bc2961fa1ef0 97 uint8_t store_requested : 1;
Jonathan Austin 0:bc2961fa1ef0 98 uint32_t n_bufs;
Jonathan Austin 0:bc2961fa1ef0 99 pm_prepare_token_t prepare_token;
Jonathan Austin 0:bc2961fa1ef0 100 pm_store_token_t store_token;
Jonathan Austin 0:bc2961fa1ef0 101 } pdb_buffer_record_t;
Jonathan Austin 0:bc2961fa1ef0 102
Jonathan Austin 0:bc2961fa1ef0 103 typedef struct
Jonathan Austin 0:bc2961fa1ef0 104 {
Jonathan Austin 0:bc2961fa1ef0 105 pdb_evt_handler_t evt_handlers[MAX_REGISTRANTS];
Jonathan Austin 0:bc2961fa1ef0 106 uint8_t n_registrants;
Jonathan Austin 0:bc2961fa1ef0 107 pm_buffer_t write_buffer;
Jonathan Austin 0:bc2961fa1ef0 108 pdb_buffer_record_t write_buffer_records[N_WRITE_BUFFER_RECORDS];
Jonathan Austin 0:bc2961fa1ef0 109 uint32_t n_writes;
Jonathan Austin 0:bc2961fa1ef0 110 } pdb_t;
Jonathan Austin 0:bc2961fa1ef0 111
Jonathan Austin 0:bc2961fa1ef0 112 static pdb_t m_pdb = {.n_registrants = 0};
Jonathan Austin 0:bc2961fa1ef0 113
Jonathan Austin 0:bc2961fa1ef0 114
Jonathan Austin 0:bc2961fa1ef0 115 /**@brief Function for invalidating a record of a write buffer allocation.
Jonathan Austin 0:bc2961fa1ef0 116 *
Jonathan Austin 0:bc2961fa1ef0 117 * @param[in] p_record The record to invalidate.
Jonathan Austin 0:bc2961fa1ef0 118 */
Jonathan Austin 0:bc2961fa1ef0 119 static void write_buffer_record_invalidate(pdb_buffer_record_t * p_record)
Jonathan Austin 0:bc2961fa1ef0 120 {
Jonathan Austin 0:bc2961fa1ef0 121 p_record->peer_id = PM_PEER_ID_INVALID;
Jonathan Austin 0:bc2961fa1ef0 122 p_record->data_id = PM_PEER_DATA_ID_INVALID;
Jonathan Austin 0:bc2961fa1ef0 123 p_record->buffer_block_id = BUFFER_INVALID_ID;
Jonathan Austin 0:bc2961fa1ef0 124 p_record->store_busy = false;
Jonathan Austin 0:bc2961fa1ef0 125 p_record->store_flash_full = false;
Jonathan Austin 0:bc2961fa1ef0 126 p_record->store_requested = false;
Jonathan Austin 0:bc2961fa1ef0 127 p_record->n_bufs = 0;
Jonathan Austin 0:bc2961fa1ef0 128 p_record->prepare_token = PDS_PREPARE_TOKEN_INVALID;
Jonathan Austin 0:bc2961fa1ef0 129 p_record->store_token = PDS_STORE_TOKEN_INVALID;
Jonathan Austin 0:bc2961fa1ef0 130 }
Jonathan Austin 0:bc2961fa1ef0 131
Jonathan Austin 0:bc2961fa1ef0 132
Jonathan Austin 0:bc2961fa1ef0 133 /**@brief Function for finding a record of a write buffer allocation.
Jonathan Austin 0:bc2961fa1ef0 134 *
Jonathan Austin 0:bc2961fa1ef0 135 * @param[in] peer_id The peer ID in the record.
Jonathan Austin 0:bc2961fa1ef0 136 * @param[in] data_id The data ID in the record.
Jonathan Austin 0:bc2961fa1ef0 137 *
Jonathan Austin 0:bc2961fa1ef0 138 * @return A pointer to the matching record, or NULL if none was found.
Jonathan Austin 0:bc2961fa1ef0 139 */
Jonathan Austin 0:bc2961fa1ef0 140 static pdb_buffer_record_t * write_buffer_record_find(pm_peer_id_t peer_id,
Jonathan Austin 0:bc2961fa1ef0 141 pm_peer_data_id_t data_id)
Jonathan Austin 0:bc2961fa1ef0 142 {
Jonathan Austin 0:bc2961fa1ef0 143 for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++)
Jonathan Austin 0:bc2961fa1ef0 144 {
Jonathan Austin 0:bc2961fa1ef0 145 if ((m_pdb.write_buffer_records[i].peer_id == peer_id)
Jonathan Austin 0:bc2961fa1ef0 146 && (m_pdb.write_buffer_records[i].data_id == data_id))
Jonathan Austin 0:bc2961fa1ef0 147 {
Jonathan Austin 0:bc2961fa1ef0 148 return &m_pdb.write_buffer_records[i];
Jonathan Austin 0:bc2961fa1ef0 149 }
Jonathan Austin 0:bc2961fa1ef0 150 }
Jonathan Austin 0:bc2961fa1ef0 151 return NULL;
Jonathan Austin 0:bc2961fa1ef0 152 }
Jonathan Austin 0:bc2961fa1ef0 153
Jonathan Austin 0:bc2961fa1ef0 154
Jonathan Austin 0:bc2961fa1ef0 155 /**@brief Function for finding an available record for write buffer allocation.
Jonathan Austin 0:bc2961fa1ef0 156 *
Jonathan Austin 0:bc2961fa1ef0 157 * @return A pointer to the available record, or NULL if none was found.
Jonathan Austin 0:bc2961fa1ef0 158 */
Jonathan Austin 0:bc2961fa1ef0 159 static pdb_buffer_record_t * write_buffer_record_find_unused(void)
Jonathan Austin 0:bc2961fa1ef0 160 {
Jonathan Austin 0:bc2961fa1ef0 161 return write_buffer_record_find(PM_PEER_ID_INVALID, PM_PEER_DATA_ID_INVALID);
Jonathan Austin 0:bc2961fa1ef0 162 }
Jonathan Austin 0:bc2961fa1ef0 163
Jonathan Austin 0:bc2961fa1ef0 164
Jonathan Austin 0:bc2961fa1ef0 165 /**@brief Function for gracefully deactivating a write buffer record.
Jonathan Austin 0:bc2961fa1ef0 166 *
Jonathan Austin 0:bc2961fa1ef0 167 * @details This function will first release any buffers, then invalidate the record.
Jonathan Austin 0:bc2961fa1ef0 168 *
Jonathan Austin 0:bc2961fa1ef0 169 * @param[inout] p_write_buffer_record The record to release.
Jonathan Austin 0:bc2961fa1ef0 170 *
Jonathan Austin 0:bc2961fa1ef0 171 * @return A pointer to the matching record, or NULL if none was found.
Jonathan Austin 0:bc2961fa1ef0 172 */
Jonathan Austin 0:bc2961fa1ef0 173 static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record)
Jonathan Austin 0:bc2961fa1ef0 174 {
Jonathan Austin 0:bc2961fa1ef0 175 for (int i = 0; i < p_write_buffer_record->n_bufs; i++)
Jonathan Austin 0:bc2961fa1ef0 176 {
Jonathan Austin 0:bc2961fa1ef0 177 pm_buffer_release(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id + i);
Jonathan Austin 0:bc2961fa1ef0 178 }
Jonathan Austin 0:bc2961fa1ef0 179
Jonathan Austin 0:bc2961fa1ef0 180 write_buffer_record_invalidate(p_write_buffer_record);
Jonathan Austin 0:bc2961fa1ef0 181 }
Jonathan Austin 0:bc2961fa1ef0 182
Jonathan Austin 0:bc2961fa1ef0 183
Jonathan Austin 0:bc2961fa1ef0 184 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)
Jonathan Austin 0:bc2961fa1ef0 185 {
Jonathan Austin 0:bc2961fa1ef0 186 if (pp_write_buffer_record == NULL)
Jonathan Austin 0:bc2961fa1ef0 187 {
Jonathan Austin 0:bc2961fa1ef0 188 return;
Jonathan Austin 0:bc2961fa1ef0 189 }
Jonathan Austin 0:bc2961fa1ef0 190 *pp_write_buffer_record = write_buffer_record_find_unused();
Jonathan Austin 0:bc2961fa1ef0 191 if (*pp_write_buffer_record == NULL)
Jonathan Austin 0:bc2961fa1ef0 192 {
Jonathan Austin 0:bc2961fa1ef0 193 // This also means the buffer is full.
Jonathan Austin 0:bc2961fa1ef0 194 return;
Jonathan Austin 0:bc2961fa1ef0 195 }
Jonathan Austin 0:bc2961fa1ef0 196 (*pp_write_buffer_record)->peer_id = peer_id;
Jonathan Austin 0:bc2961fa1ef0 197 (*pp_write_buffer_record)->data_id = data_id;
Jonathan Austin 0:bc2961fa1ef0 198 }
Jonathan Austin 0:bc2961fa1ef0 199
Jonathan Austin 0:bc2961fa1ef0 200
Jonathan Austin 0:bc2961fa1ef0 201 /**@brief Function for dispatching outbound events to all registered event handlers.
Jonathan Austin 0:bc2961fa1ef0 202 *
Jonathan Austin 0:bc2961fa1ef0 203 * @param[in] p_event The event to dispatch.
Jonathan Austin 0:bc2961fa1ef0 204 */
Jonathan Austin 0:bc2961fa1ef0 205 static void pdb_evt_send(pdb_evt_t * p_event)
Jonathan Austin 0:bc2961fa1ef0 206 {
Jonathan Austin 0:bc2961fa1ef0 207 for (int i = 0; i < m_pdb.n_registrants; i++)
Jonathan Austin 0:bc2961fa1ef0 208 {
Jonathan Austin 0:bc2961fa1ef0 209 m_pdb.evt_handlers[i](p_event);
Jonathan Austin 0:bc2961fa1ef0 210 }
Jonathan Austin 0:bc2961fa1ef0 211 }
Jonathan Austin 0:bc2961fa1ef0 212
Jonathan Austin 0:bc2961fa1ef0 213
Jonathan Austin 0:bc2961fa1ef0 214 /**@brief Function for resetting the internal state of the Peer Database module.
Jonathan Austin 0:bc2961fa1ef0 215 *
Jonathan Austin 0:bc2961fa1ef0 216 * @param[out] p_event The event to dispatch.
Jonathan Austin 0:bc2961fa1ef0 217 */
Jonathan Austin 0:bc2961fa1ef0 218 static void internal_state_reset(pdb_t * pdb)
Jonathan Austin 0:bc2961fa1ef0 219 {
Jonathan Austin 0:bc2961fa1ef0 220 memset(pdb, 0, sizeof(pdb_t));
Jonathan Austin 0:bc2961fa1ef0 221 for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++)
Jonathan Austin 0:bc2961fa1ef0 222 {
Jonathan Austin 0:bc2961fa1ef0 223 write_buffer_record_invalidate(&pdb->write_buffer_records[i]);
Jonathan Austin 0:bc2961fa1ef0 224 }
Jonathan Austin 0:bc2961fa1ef0 225 }
Jonathan Austin 0:bc2961fa1ef0 226
Jonathan Austin 0:bc2961fa1ef0 227
Jonathan Austin 0:bc2961fa1ef0 228 /**@brief Function for handling events from the Peer Data Storage module.
Jonathan Austin 0:bc2961fa1ef0 229 *
Jonathan Austin 0:bc2961fa1ef0 230 * @param[in] p_event The event to handle.
Jonathan Austin 0:bc2961fa1ef0 231 */
Jonathan Austin 0:bc2961fa1ef0 232 static void pds_evt_handler(pds_evt_t const * p_event)
Jonathan Austin 0:bc2961fa1ef0 233 {
Jonathan Austin 0:bc2961fa1ef0 234 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 235 pdb_buffer_record_t * p_write_buffer_record;
Jonathan Austin 0:bc2961fa1ef0 236 bool retry_flash_full = false;
Jonathan Austin 0:bc2961fa1ef0 237 pdb_evt_t event =
Jonathan Austin 0:bc2961fa1ef0 238 {
Jonathan Austin 0:bc2961fa1ef0 239 .peer_id = p_event->peer_id,
Jonathan Austin 0:bc2961fa1ef0 240 .data_id = p_event->data_id,
Jonathan Austin 0:bc2961fa1ef0 241 };
Jonathan Austin 0:bc2961fa1ef0 242
Jonathan Austin 0:bc2961fa1ef0 243 p_write_buffer_record = write_buffer_record_find(p_event->peer_id, p_event->data_id);
Jonathan Austin 0:bc2961fa1ef0 244
Jonathan Austin 0:bc2961fa1ef0 245 switch (p_event->evt_id)
Jonathan Austin 0:bc2961fa1ef0 246 {
Jonathan Austin 0:bc2961fa1ef0 247 case PDS_EVT_STORED:
Jonathan Austin 0:bc2961fa1ef0 248 if ( (p_write_buffer_record != NULL)
Jonathan Austin 0:bc2961fa1ef0 249 //&& (p_write_buffer_record->store_token == p_event->store_token)
Jonathan Austin 0:bc2961fa1ef0 250 && (p_write_buffer_record->store_requested))
Jonathan Austin 0:bc2961fa1ef0 251 {
Jonathan Austin 0:bc2961fa1ef0 252 write_buffer_record_release(p_write_buffer_record);
Jonathan Austin 0:bc2961fa1ef0 253 event.evt_id = PDB_EVT_WRITE_BUF_STORED;
Jonathan Austin 0:bc2961fa1ef0 254 pdb_evt_send(&event);
Jonathan Austin 0:bc2961fa1ef0 255 }
Jonathan Austin 0:bc2961fa1ef0 256 else
Jonathan Austin 0:bc2961fa1ef0 257 {
Jonathan Austin 0:bc2961fa1ef0 258 event.evt_id = PDB_EVT_RAW_STORED;
Jonathan Austin 0:bc2961fa1ef0 259 pdb_evt_send(&event);
Jonathan Austin 0:bc2961fa1ef0 260 }
Jonathan Austin 0:bc2961fa1ef0 261 break;
Jonathan Austin 0:bc2961fa1ef0 262 case PDS_EVT_ERROR_STORE:
Jonathan Austin 0:bc2961fa1ef0 263 if ( (p_write_buffer_record != NULL)
Jonathan Austin 0:bc2961fa1ef0 264 && (p_write_buffer_record->store_token == p_event->store_token)
Jonathan Austin 0:bc2961fa1ef0 265 && (p_write_buffer_record->store_requested))
Jonathan Austin 0:bc2961fa1ef0 266 {
Jonathan Austin 0:bc2961fa1ef0 267 // Retry if internal buffer.
Jonathan Austin 0:bc2961fa1ef0 268 m_pdb.n_writes++;
Jonathan Austin 0:bc2961fa1ef0 269 p_write_buffer_record->store_requested = false;
Jonathan Austin 0:bc2961fa1ef0 270 p_write_buffer_record->store_busy = true;
Jonathan Austin 0:bc2961fa1ef0 271 }
Jonathan Austin 0:bc2961fa1ef0 272 else
Jonathan Austin 0:bc2961fa1ef0 273 {
Jonathan Austin 0:bc2961fa1ef0 274 event.evt_id = PDB_EVT_RAW_STORE_FAILED;
Jonathan Austin 0:bc2961fa1ef0 275 pdb_evt_send(&event);
Jonathan Austin 0:bc2961fa1ef0 276 }
Jonathan Austin 0:bc2961fa1ef0 277 break;
Jonathan Austin 0:bc2961fa1ef0 278 case PDS_EVT_CLEARED:
Jonathan Austin 0:bc2961fa1ef0 279 event.evt_id = PDB_EVT_CLEARED;
Jonathan Austin 0:bc2961fa1ef0 280 pdb_evt_send(&event);
Jonathan Austin 0:bc2961fa1ef0 281 break;
Jonathan Austin 0:bc2961fa1ef0 282 case PDS_EVT_ERROR_CLEAR:
Jonathan Austin 0:bc2961fa1ef0 283 event.evt_id = PDB_EVT_CLEAR_FAILED;
Jonathan Austin 0:bc2961fa1ef0 284 pdb_evt_send(&event);
Jonathan Austin 0:bc2961fa1ef0 285 break;
Jonathan Austin 0:bc2961fa1ef0 286 case PDS_EVT_COMPRESSED:
Jonathan Austin 0:bc2961fa1ef0 287 retry_flash_full = true;
Jonathan Austin 0:bc2961fa1ef0 288 event.evt_id = PDB_EVT_COMPRESSED;
Jonathan Austin 0:bc2961fa1ef0 289 pdb_evt_send(&event);
Jonathan Austin 0:bc2961fa1ef0 290 break;
Jonathan Austin 0:bc2961fa1ef0 291 default:
Jonathan Austin 0:bc2961fa1ef0 292 break;
Jonathan Austin 0:bc2961fa1ef0 293 }
Jonathan Austin 0:bc2961fa1ef0 294
Jonathan Austin 0:bc2961fa1ef0 295 if (m_pdb.n_writes > 0)
Jonathan Austin 0:bc2961fa1ef0 296 {
Jonathan Austin 0:bc2961fa1ef0 297 for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++)
Jonathan Austin 0:bc2961fa1ef0 298 {
Jonathan Austin 0:bc2961fa1ef0 299 if ((m_pdb.write_buffer_records[i].store_busy)
Jonathan Austin 0:bc2961fa1ef0 300 || (m_pdb.write_buffer_records[i].store_flash_full && retry_flash_full))
Jonathan Austin 0:bc2961fa1ef0 301 {
Jonathan Austin 0:bc2961fa1ef0 302 err_code = pdb_write_buf_store(m_pdb.write_buffer_records[i].peer_id,
Jonathan Austin 0:bc2961fa1ef0 303 m_pdb.write_buffer_records[i].data_id);
Jonathan Austin 0:bc2961fa1ef0 304 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 305 {
Jonathan Austin 0:bc2961fa1ef0 306 event.peer_id = m_pdb.write_buffer_records[i].peer_id;
Jonathan Austin 0:bc2961fa1ef0 307 event.data_id = m_pdb.write_buffer_records[i].data_id;
Jonathan Austin 0:bc2961fa1ef0 308 if (err_code == NRF_ERROR_NO_MEM)
Jonathan Austin 0:bc2961fa1ef0 309 {
Jonathan Austin 0:bc2961fa1ef0 310 event.evt_id = PDB_EVT_ERROR_NO_MEM;
Jonathan Austin 0:bc2961fa1ef0 311 }
Jonathan Austin 0:bc2961fa1ef0 312 else
Jonathan Austin 0:bc2961fa1ef0 313 {
Jonathan Austin 0:bc2961fa1ef0 314 event.evt_id = PDB_EVT_ERROR_UNEXPECTED;
Jonathan Austin 0:bc2961fa1ef0 315 }
Jonathan Austin 0:bc2961fa1ef0 316
Jonathan Austin 0:bc2961fa1ef0 317 pdb_evt_send(&event);
Jonathan Austin 0:bc2961fa1ef0 318 break;
Jonathan Austin 0:bc2961fa1ef0 319 }
Jonathan Austin 0:bc2961fa1ef0 320 }
Jonathan Austin 0:bc2961fa1ef0 321 }
Jonathan Austin 0:bc2961fa1ef0 322 }
Jonathan Austin 0:bc2961fa1ef0 323 }
Jonathan Austin 0:bc2961fa1ef0 324
Jonathan Austin 0:bc2961fa1ef0 325
Jonathan Austin 0:bc2961fa1ef0 326 ret_code_t pdb_register(pdb_evt_handler_t evt_handler)
Jonathan Austin 0:bc2961fa1ef0 327 {
Jonathan Austin 0:bc2961fa1ef0 328 if (m_pdb.n_registrants >= MAX_REGISTRANTS)
Jonathan Austin 0:bc2961fa1ef0 329 {
Jonathan Austin 0:bc2961fa1ef0 330 return NRF_ERROR_NO_MEM;
Jonathan Austin 0:bc2961fa1ef0 331 }
Jonathan Austin 0:bc2961fa1ef0 332
Jonathan Austin 0:bc2961fa1ef0 333 VERIFY_PARAM_NOT_NULL(evt_handler);
Jonathan Austin 0:bc2961fa1ef0 334
Jonathan Austin 0:bc2961fa1ef0 335 if (!MODULE_INITIALIZED)
Jonathan Austin 0:bc2961fa1ef0 336 {
Jonathan Austin 0:bc2961fa1ef0 337 ret_code_t err_code;
Jonathan Austin 0:bc2961fa1ef0 338
Jonathan Austin 0:bc2961fa1ef0 339 internal_state_reset(&m_pdb);
Jonathan Austin 0:bc2961fa1ef0 340 err_code = pds_register(pds_evt_handler);
Jonathan Austin 0:bc2961fa1ef0 341 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 342 {
Jonathan Austin 0:bc2961fa1ef0 343 return err_code;
Jonathan Austin 0:bc2961fa1ef0 344 }
Jonathan Austin 0:bc2961fa1ef0 345 PM_BUFFER_INIT(&m_pdb.write_buffer, N_WRITE_BUFFERS, PDB_WRITE_BUF_SIZE, err_code);
Jonathan Austin 0:bc2961fa1ef0 346 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 347 {
Jonathan Austin 0:bc2961fa1ef0 348 return err_code;
Jonathan Austin 0:bc2961fa1ef0 349 }
Jonathan Austin 0:bc2961fa1ef0 350 }
Jonathan Austin 0:bc2961fa1ef0 351
Jonathan Austin 0:bc2961fa1ef0 352 m_pdb.evt_handlers[m_pdb.n_registrants] = evt_handler;
Jonathan Austin 0:bc2961fa1ef0 353 m_pdb.n_registrants += 1;
Jonathan Austin 0:bc2961fa1ef0 354
Jonathan Austin 0:bc2961fa1ef0 355 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 356 }
Jonathan Austin 0:bc2961fa1ef0 357
Jonathan Austin 0:bc2961fa1ef0 358
Jonathan Austin 0:bc2961fa1ef0 359 pm_peer_id_t pdb_peer_allocate(void)
Jonathan Austin 0:bc2961fa1ef0 360 {
Jonathan Austin 0:bc2961fa1ef0 361 if (!MODULE_INITIALIZED)
Jonathan Austin 0:bc2961fa1ef0 362 {
Jonathan Austin 0:bc2961fa1ef0 363 return PM_PEER_ID_INVALID;
Jonathan Austin 0:bc2961fa1ef0 364 }
Jonathan Austin 0:bc2961fa1ef0 365
Jonathan Austin 0:bc2961fa1ef0 366 return pds_peer_id_allocate();
Jonathan Austin 0:bc2961fa1ef0 367 }
Jonathan Austin 0:bc2961fa1ef0 368
Jonathan Austin 0:bc2961fa1ef0 369
Jonathan Austin 0:bc2961fa1ef0 370 ret_code_t pdb_peer_free(pm_peer_id_t peer_id)
Jonathan Austin 0:bc2961fa1ef0 371 {
Jonathan Austin 0:bc2961fa1ef0 372 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 373
Jonathan Austin 0:bc2961fa1ef0 374 return pds_peer_id_free(peer_id);
Jonathan Austin 0:bc2961fa1ef0 375 }
Jonathan Austin 0:bc2961fa1ef0 376
Jonathan Austin 0:bc2961fa1ef0 377
Jonathan Austin 0:bc2961fa1ef0 378 ret_code_t pdb_read_buf_get(pm_peer_id_t peer_id,
Jonathan Austin 0:bc2961fa1ef0 379 pm_peer_data_id_t data_id,
Jonathan Austin 0:bc2961fa1ef0 380 pm_peer_data_flash_t * p_peer_data,
Jonathan Austin 0:bc2961fa1ef0 381 pm_store_token_t * p_token)
Jonathan Austin 0:bc2961fa1ef0 382 {
Jonathan Austin 0:bc2961fa1ef0 383 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 384
Jonathan Austin 0:bc2961fa1ef0 385 return pds_peer_data_read_ptr_get(peer_id, data_id, p_peer_data, p_token);
Jonathan Austin 0:bc2961fa1ef0 386 }
Jonathan Austin 0:bc2961fa1ef0 387
Jonathan Austin 0:bc2961fa1ef0 388
Jonathan Austin 0:bc2961fa1ef0 389 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)
Jonathan Austin 0:bc2961fa1ef0 390 {
Jonathan Austin 0:bc2961fa1ef0 391 uint16_t n_bytes = n_bufs * PDB_WRITE_BUF_SIZE;
Jonathan Austin 0:bc2961fa1ef0 392 p_peer_data->data_type = data_id;
Jonathan Austin 0:bc2961fa1ef0 393
Jonathan Austin 0:bc2961fa1ef0 394 switch(p_peer_data->data_type)
Jonathan Austin 0:bc2961fa1ef0 395 {
Jonathan Austin 0:bc2961fa1ef0 396 case PM_PEER_DATA_ID_BONDING:
Jonathan Austin 0:bc2961fa1ef0 397 p_peer_data->data.p_bonding_data = (pm_peer_data_bonding_t *)p_buffer_memory;
Jonathan Austin 0:bc2961fa1ef0 398 p_peer_data->length_words = PM_BONDING_DATA_N_WORDS();
Jonathan Austin 0:bc2961fa1ef0 399 break;
Jonathan Austin 0:bc2961fa1ef0 400 case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
Jonathan Austin 0:bc2961fa1ef0 401 p_peer_data->data.p_service_changed_pending = (bool *)p_buffer_memory;
Jonathan Austin 0:bc2961fa1ef0 402 p_peer_data->length_words = PM_SC_STATE_N_WORDS();
Jonathan Austin 0:bc2961fa1ef0 403 break;
Jonathan Austin 0:bc2961fa1ef0 404 case PM_PEER_DATA_ID_GATT_LOCAL:
Jonathan Austin 0:bc2961fa1ef0 405 p_peer_data->data.p_local_gatt_db = (pm_peer_data_local_gatt_db_t *)p_buffer_memory;
Jonathan Austin 0:bc2961fa1ef0 406 p_peer_data->length_words = PM_LOCAL_DB_N_WORDS(n_bytes);
Jonathan Austin 0:bc2961fa1ef0 407 break;
Jonathan Austin 0:bc2961fa1ef0 408 case PM_PEER_DATA_ID_GATT_REMOTE:
Jonathan Austin 0:bc2961fa1ef0 409 p_peer_data->data.p_remote_gatt_db = (pm_peer_data_remote_gatt_db_t *)p_buffer_memory;
Jonathan Austin 0:bc2961fa1ef0 410 p_peer_data->length_words = PM_REMOTE_DB_N_WORDS(n_bytes / sizeof(ble_gatt_db_srv_t));
Jonathan Austin 0:bc2961fa1ef0 411 break;
Jonathan Austin 0:bc2961fa1ef0 412 case PM_PEER_DATA_ID_APPLICATION:
Jonathan Austin 0:bc2961fa1ef0 413 p_peer_data->data.p_application_data = p_buffer_memory;
Jonathan Austin 0:bc2961fa1ef0 414 p_peer_data->length_words = PM_N_WORDS(n_bytes);
Jonathan Austin 0:bc2961fa1ef0 415 break;
Jonathan Austin 0:bc2961fa1ef0 416 default:
Jonathan Austin 0:bc2961fa1ef0 417 p_peer_data->length_words = 0;
Jonathan Austin 0:bc2961fa1ef0 418 break;
Jonathan Austin 0:bc2961fa1ef0 419 }
Jonathan Austin 0:bc2961fa1ef0 420 }
Jonathan Austin 0:bc2961fa1ef0 421
Jonathan Austin 0:bc2961fa1ef0 422
Jonathan Austin 0:bc2961fa1ef0 423 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)
Jonathan Austin 0:bc2961fa1ef0 424 {
Jonathan Austin 0:bc2961fa1ef0 425 peer_data_point_to_buffer((pm_peer_data_t*)p_peer_data, data_id, p_buffer_memory, n_bufs);
Jonathan Austin 0:bc2961fa1ef0 426 }
Jonathan Austin 0:bc2961fa1ef0 427
Jonathan Austin 0:bc2961fa1ef0 428
Jonathan Austin 0:bc2961fa1ef0 429 ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id,
Jonathan Austin 0:bc2961fa1ef0 430 pm_peer_data_id_t data_id,
Jonathan Austin 0:bc2961fa1ef0 431 uint32_t n_bufs,
Jonathan Austin 0:bc2961fa1ef0 432 pm_peer_data_t * p_peer_data)
Jonathan Austin 0:bc2961fa1ef0 433 {
Jonathan Austin 0:bc2961fa1ef0 434 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 435 VERIFY_PARAM_NOT_NULL(p_peer_data);
Jonathan Austin 0:bc2961fa1ef0 436 if ( !PM_PEER_DATA_ID_IS_VALID(data_id)
Jonathan Austin 0:bc2961fa1ef0 437 || (n_bufs == 0)
Jonathan Austin 0:bc2961fa1ef0 438 || (n_bufs > N_WRITE_BUFFERS)
Jonathan Austin 0:bc2961fa1ef0 439 || !pds_peer_id_is_allocated(peer_id))
Jonathan Austin 0:bc2961fa1ef0 440 {
Jonathan Austin 0:bc2961fa1ef0 441 return NRF_ERROR_INVALID_PARAM;
Jonathan Austin 0:bc2961fa1ef0 442 }
Jonathan Austin 0:bc2961fa1ef0 443
Jonathan Austin 0:bc2961fa1ef0 444 pdb_buffer_record_t * write_buffer_record;
Jonathan Austin 0:bc2961fa1ef0 445 uint8_t * p_buffer_memory;
Jonathan Austin 0:bc2961fa1ef0 446
Jonathan Austin 0:bc2961fa1ef0 447 write_buffer_record = write_buffer_record_find(peer_id, data_id);
Jonathan Austin 0:bc2961fa1ef0 448
Jonathan Austin 0:bc2961fa1ef0 449 if ((write_buffer_record != NULL) && (write_buffer_record->n_bufs < n_bufs))
Jonathan Austin 0:bc2961fa1ef0 450 {
Jonathan Austin 0:bc2961fa1ef0 451 // @TODO: Copy?
Jonathan Austin 0:bc2961fa1ef0 452 // Existing buffer is too small.
Jonathan Austin 0:bc2961fa1ef0 453 for (uint8_t i = 0; i < write_buffer_record->n_bufs; i++)
Jonathan Austin 0:bc2961fa1ef0 454 {
Jonathan Austin 0:bc2961fa1ef0 455 pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i);
Jonathan Austin 0:bc2961fa1ef0 456 }
Jonathan Austin 0:bc2961fa1ef0 457 write_buffer_record_invalidate(write_buffer_record);
Jonathan Austin 0:bc2961fa1ef0 458 write_buffer_record = NULL;
Jonathan Austin 0:bc2961fa1ef0 459 }
Jonathan Austin 0:bc2961fa1ef0 460 else if ((write_buffer_record != NULL) && write_buffer_record->n_bufs > n_bufs)
Jonathan Austin 0:bc2961fa1ef0 461 {
Jonathan Austin 0:bc2961fa1ef0 462 // Release excess blocks.
Jonathan Austin 0:bc2961fa1ef0 463 for (uint8_t i = n_bufs; i < write_buffer_record->n_bufs; i++)
Jonathan Austin 0:bc2961fa1ef0 464 {
Jonathan Austin 0:bc2961fa1ef0 465 pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i);
Jonathan Austin 0:bc2961fa1ef0 466 }
Jonathan Austin 0:bc2961fa1ef0 467 }
Jonathan Austin 0:bc2961fa1ef0 468
Jonathan Austin 0:bc2961fa1ef0 469 if (write_buffer_record == NULL)
Jonathan Austin 0:bc2961fa1ef0 470 {
Jonathan Austin 0:bc2961fa1ef0 471 write_buffer_record_get(&write_buffer_record, peer_id, data_id);
Jonathan Austin 0:bc2961fa1ef0 472 if (write_buffer_record == NULL)
Jonathan Austin 0:bc2961fa1ef0 473 {
Jonathan Austin 0:bc2961fa1ef0 474 return NRF_ERROR_BUSY;
Jonathan Austin 0:bc2961fa1ef0 475 }
Jonathan Austin 0:bc2961fa1ef0 476 }
Jonathan Austin 0:bc2961fa1ef0 477
Jonathan Austin 0:bc2961fa1ef0 478 if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 479 {
Jonathan Austin 0:bc2961fa1ef0 480 write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_pdb.write_buffer, n_bufs);
Jonathan Austin 0:bc2961fa1ef0 481
Jonathan Austin 0:bc2961fa1ef0 482 if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID)
Jonathan Austin 0:bc2961fa1ef0 483 {
Jonathan Austin 0:bc2961fa1ef0 484 write_buffer_record_invalidate(write_buffer_record);
Jonathan Austin 0:bc2961fa1ef0 485 return NRF_ERROR_BUSY;
Jonathan Austin 0:bc2961fa1ef0 486 }
Jonathan Austin 0:bc2961fa1ef0 487 }
Jonathan Austin 0:bc2961fa1ef0 488
Jonathan Austin 0:bc2961fa1ef0 489 write_buffer_record->n_bufs = n_bufs;
Jonathan Austin 0:bc2961fa1ef0 490
Jonathan Austin 0:bc2961fa1ef0 491 p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, write_buffer_record->buffer_block_id);
Jonathan Austin 0:bc2961fa1ef0 492
Jonathan Austin 0:bc2961fa1ef0 493 if (p_buffer_memory == NULL)
Jonathan Austin 0:bc2961fa1ef0 494 {
Jonathan Austin 0:bc2961fa1ef0 495 return NRF_ERROR_INTERNAL;
Jonathan Austin 0:bc2961fa1ef0 496 }
Jonathan Austin 0:bc2961fa1ef0 497
Jonathan Austin 0:bc2961fa1ef0 498 peer_data_point_to_buffer(p_peer_data, data_id, p_buffer_memory, n_bufs);
Jonathan Austin 0:bc2961fa1ef0 499 switch(data_id)
Jonathan Austin 0:bc2961fa1ef0 500 {
Jonathan Austin 0:bc2961fa1ef0 501 case PM_PEER_DATA_ID_BONDING:
Jonathan Austin 0:bc2961fa1ef0 502 /* No action needed. */
Jonathan Austin 0:bc2961fa1ef0 503 break;
Jonathan Austin 0:bc2961fa1ef0 504 case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
Jonathan Austin 0:bc2961fa1ef0 505 /* No action needed. */
Jonathan Austin 0:bc2961fa1ef0 506 break;
Jonathan Austin 0:bc2961fa1ef0 507 case PM_PEER_DATA_ID_GATT_LOCAL:
Jonathan Austin 0:bc2961fa1ef0 508 {
Jonathan Austin 0:bc2961fa1ef0 509 uint32_t size_offset = sizeof(pm_peer_data_local_gatt_db_t);
Jonathan Austin 0:bc2961fa1ef0 510 p_peer_data->data.p_local_gatt_db->p_data = &p_buffer_memory[size_offset];
Jonathan Austin 0:bc2961fa1ef0 511 p_peer_data->data.p_local_gatt_db->len = (PDB_WRITE_BUF_SIZE*n_bufs)-size_offset;
Jonathan Austin 0:bc2961fa1ef0 512 }
Jonathan Austin 0:bc2961fa1ef0 513 break;
Jonathan Austin 0:bc2961fa1ef0 514 case PM_PEER_DATA_ID_GATT_REMOTE:
Jonathan Austin 0:bc2961fa1ef0 515 {
Jonathan Austin 0:bc2961fa1ef0 516 uint32_t size_offset = sizeof(pm_peer_data_remote_gatt_db_t);
Jonathan Austin 0:bc2961fa1ef0 517 p_peer_data->data.p_remote_gatt_db->p_data = (ble_gatt_db_srv_t*)&(p_buffer_memory[size_offset]);
Jonathan Austin 0:bc2961fa1ef0 518 p_peer_data->data.p_remote_gatt_db->service_count
Jonathan Austin 0:bc2961fa1ef0 519 = ((PDB_WRITE_BUF_SIZE*n_bufs)-size_offset)/sizeof(ble_gatt_db_srv_t);
Jonathan Austin 0:bc2961fa1ef0 520 }
Jonathan Austin 0:bc2961fa1ef0 521 break;
Jonathan Austin 0:bc2961fa1ef0 522 case PM_PEER_DATA_ID_APPLICATION:
Jonathan Austin 0:bc2961fa1ef0 523 {
Jonathan Austin 0:bc2961fa1ef0 524 p_peer_data->data.p_application_data = p_buffer_memory;
Jonathan Austin 0:bc2961fa1ef0 525 }
Jonathan Austin 0:bc2961fa1ef0 526 break;
Jonathan Austin 0:bc2961fa1ef0 527 default:
Jonathan Austin 0:bc2961fa1ef0 528 // Invalid data_id. This should have been picked up earlier.
Jonathan Austin 0:bc2961fa1ef0 529 return NRF_ERROR_INTERNAL;
Jonathan Austin 0:bc2961fa1ef0 530 }
Jonathan Austin 0:bc2961fa1ef0 531
Jonathan Austin 0:bc2961fa1ef0 532 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 533 }
Jonathan Austin 0:bc2961fa1ef0 534
Jonathan Austin 0:bc2961fa1ef0 535
Jonathan Austin 0:bc2961fa1ef0 536 ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
Jonathan Austin 0:bc2961fa1ef0 537 {
Jonathan Austin 0:bc2961fa1ef0 538 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 539
Jonathan Austin 0:bc2961fa1ef0 540 ret_code_t err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 541 pdb_buffer_record_t * p_write_buffer_record;
Jonathan Austin 0:bc2961fa1ef0 542 p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
Jonathan Austin 0:bc2961fa1ef0 543
Jonathan Austin 0:bc2961fa1ef0 544 if (p_write_buffer_record == NULL)
Jonathan Austin 0:bc2961fa1ef0 545 {
Jonathan Austin 0:bc2961fa1ef0 546 return NRF_ERROR_NOT_FOUND;
Jonathan Austin 0:bc2961fa1ef0 547 }
Jonathan Austin 0:bc2961fa1ef0 548
Jonathan Austin 0:bc2961fa1ef0 549 if (p_write_buffer_record->prepare_token != PDS_PREPARE_TOKEN_INVALID)
Jonathan Austin 0:bc2961fa1ef0 550 {
Jonathan Austin 0:bc2961fa1ef0 551 err_code = pds_peer_data_write_prepare_cancel(p_write_buffer_record->prepare_token);
Jonathan Austin 0:bc2961fa1ef0 552 if (err_code != NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 553 {
Jonathan Austin 0:bc2961fa1ef0 554 err_code = NRF_ERROR_INTERNAL;
Jonathan Austin 0:bc2961fa1ef0 555 }
Jonathan Austin 0:bc2961fa1ef0 556 }
Jonathan Austin 0:bc2961fa1ef0 557
Jonathan Austin 0:bc2961fa1ef0 558 write_buffer_record_release(p_write_buffer_record);
Jonathan Austin 0:bc2961fa1ef0 559
Jonathan Austin 0:bc2961fa1ef0 560 return err_code;
Jonathan Austin 0:bc2961fa1ef0 561 }
Jonathan Austin 0:bc2961fa1ef0 562
Jonathan Austin 0:bc2961fa1ef0 563
Jonathan Austin 0:bc2961fa1ef0 564 ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
Jonathan Austin 0:bc2961fa1ef0 565 {
Jonathan Austin 0:bc2961fa1ef0 566 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 567
Jonathan Austin 0:bc2961fa1ef0 568 ret_code_t err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 569 pdb_buffer_record_t * p_write_buffer_record;
Jonathan Austin 0:bc2961fa1ef0 570 p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
Jonathan Austin 0:bc2961fa1ef0 571
Jonathan Austin 0:bc2961fa1ef0 572 if (p_write_buffer_record == NULL)
Jonathan Austin 0:bc2961fa1ef0 573 {
Jonathan Austin 0:bc2961fa1ef0 574 return NRF_ERROR_NOT_FOUND;
Jonathan Austin 0:bc2961fa1ef0 575 }
Jonathan Austin 0:bc2961fa1ef0 576
Jonathan Austin 0:bc2961fa1ef0 577 if (p_write_buffer_record->prepare_token == PDS_PREPARE_TOKEN_INVALID)
Jonathan Austin 0:bc2961fa1ef0 578 {
Jonathan Austin 0:bc2961fa1ef0 579 uint8_t * p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id);
Jonathan Austin 0:bc2961fa1ef0 580 pm_peer_data_const_t peer_data = {.data_type = data_id};
Jonathan Austin 0:bc2961fa1ef0 581
Jonathan Austin 0:bc2961fa1ef0 582 if (p_buffer_memory == NULL)
Jonathan Austin 0:bc2961fa1ef0 583 {
Jonathan Austin 0:bc2961fa1ef0 584 return NRF_ERROR_INTERNAL;
Jonathan Austin 0:bc2961fa1ef0 585 }
Jonathan Austin 0:bc2961fa1ef0 586
Jonathan Austin 0:bc2961fa1ef0 587 peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs);
Jonathan Austin 0:bc2961fa1ef0 588
Jonathan Austin 0:bc2961fa1ef0 589 err_code = pds_peer_data_write_prepare(&peer_data, &p_write_buffer_record->prepare_token);
Jonathan Austin 0:bc2961fa1ef0 590 if (err_code == NRF_ERROR_INVALID_LENGTH)
Jonathan Austin 0:bc2961fa1ef0 591 {
Jonathan Austin 0:bc2961fa1ef0 592 return NRF_ERROR_INTERNAL;
Jonathan Austin 0:bc2961fa1ef0 593 }
Jonathan Austin 0:bc2961fa1ef0 594 }
Jonathan Austin 0:bc2961fa1ef0 595
Jonathan Austin 0:bc2961fa1ef0 596 return err_code;
Jonathan Austin 0:bc2961fa1ef0 597 }
Jonathan Austin 0:bc2961fa1ef0 598
Jonathan Austin 0:bc2961fa1ef0 599
Jonathan Austin 0:bc2961fa1ef0 600 static ret_code_t write_or_update(pm_peer_id_t peer_id,
Jonathan Austin 0:bc2961fa1ef0 601 pm_peer_data_id_t data_id,
Jonathan Austin 0:bc2961fa1ef0 602 pm_peer_data_const_t * p_peer_data,
Jonathan Austin 0:bc2961fa1ef0 603 pm_store_token_t * p_store_token,
Jonathan Austin 0:bc2961fa1ef0 604 pm_prepare_token_t prepare_token)
Jonathan Austin 0:bc2961fa1ef0 605 {
Jonathan Austin 0:bc2961fa1ef0 606 pm_peer_data_flash_t old_peer_data;
Jonathan Austin 0:bc2961fa1ef0 607 pm_store_token_t old_store_token;
Jonathan Austin 0:bc2961fa1ef0 608 ret_code_t err_code = pds_peer_data_read_ptr_get(peer_id, data_id, &old_peer_data, &old_store_token);
Jonathan Austin 0:bc2961fa1ef0 609
Jonathan Austin 0:bc2961fa1ef0 610 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 611 {
Jonathan Austin 0:bc2961fa1ef0 612 pds_peer_data_write_prepare_cancel(prepare_token);
Jonathan Austin 0:bc2961fa1ef0 613 err_code = pds_peer_data_update(peer_id, p_peer_data, old_store_token, p_store_token);
Jonathan Austin 0:bc2961fa1ef0 614 }
Jonathan Austin 0:bc2961fa1ef0 615 else if (err_code == NRF_ERROR_NOT_FOUND)
Jonathan Austin 0:bc2961fa1ef0 616 {
Jonathan Austin 0:bc2961fa1ef0 617 if (prepare_token == PDS_PREPARE_TOKEN_INVALID)
Jonathan Austin 0:bc2961fa1ef0 618 {
Jonathan Austin 0:bc2961fa1ef0 619 err_code = pds_peer_data_write(peer_id, p_peer_data, p_store_token);
Jonathan Austin 0:bc2961fa1ef0 620 }
Jonathan Austin 0:bc2961fa1ef0 621 else
Jonathan Austin 0:bc2961fa1ef0 622 {
Jonathan Austin 0:bc2961fa1ef0 623 err_code = pds_peer_data_write_prepared(peer_id, p_peer_data, prepare_token, p_store_token);
Jonathan Austin 0:bc2961fa1ef0 624 }
Jonathan Austin 0:bc2961fa1ef0 625 }
Jonathan Austin 0:bc2961fa1ef0 626 return err_code;
Jonathan Austin 0:bc2961fa1ef0 627 }
Jonathan Austin 0:bc2961fa1ef0 628
Jonathan Austin 0:bc2961fa1ef0 629
Jonathan Austin 0:bc2961fa1ef0 630 ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id,
Jonathan Austin 0:bc2961fa1ef0 631 pm_peer_data_id_t data_id)
Jonathan Austin 0:bc2961fa1ef0 632 {
Jonathan Austin 0:bc2961fa1ef0 633 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 634
Jonathan Austin 0:bc2961fa1ef0 635 ret_code_t err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 636 pdb_buffer_record_t * p_write_buffer_record;
Jonathan Austin 0:bc2961fa1ef0 637 uint8_t * p_buffer_memory;
Jonathan Austin 0:bc2961fa1ef0 638 pm_peer_data_const_t peer_data = {.data_type = data_id};
Jonathan Austin 0:bc2961fa1ef0 639
Jonathan Austin 0:bc2961fa1ef0 640
Jonathan Austin 0:bc2961fa1ef0 641 p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
Jonathan Austin 0:bc2961fa1ef0 642
Jonathan Austin 0:bc2961fa1ef0 643 if (p_write_buffer_record == NULL)
Jonathan Austin 0:bc2961fa1ef0 644 {
Jonathan Austin 0:bc2961fa1ef0 645 return NRF_ERROR_NOT_FOUND;
Jonathan Austin 0:bc2961fa1ef0 646 }
Jonathan Austin 0:bc2961fa1ef0 647
Jonathan Austin 0:bc2961fa1ef0 648 if (p_write_buffer_record->store_requested)
Jonathan Austin 0:bc2961fa1ef0 649 {
Jonathan Austin 0:bc2961fa1ef0 650 return NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 651 }
Jonathan Austin 0:bc2961fa1ef0 652
Jonathan Austin 0:bc2961fa1ef0 653 p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id);
Jonathan Austin 0:bc2961fa1ef0 654
Jonathan Austin 0:bc2961fa1ef0 655 if (p_buffer_memory == NULL)
Jonathan Austin 0:bc2961fa1ef0 656 {
Jonathan Austin 0:bc2961fa1ef0 657 return NRF_ERROR_INTERNAL;
Jonathan Austin 0:bc2961fa1ef0 658 }
Jonathan Austin 0:bc2961fa1ef0 659
Jonathan Austin 0:bc2961fa1ef0 660 peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs);
Jonathan Austin 0:bc2961fa1ef0 661
Jonathan Austin 0:bc2961fa1ef0 662 switch (data_id)
Jonathan Austin 0:bc2961fa1ef0 663 {
Jonathan Austin 0:bc2961fa1ef0 664 case PM_PEER_DATA_ID_BONDING:
Jonathan Austin 0:bc2961fa1ef0 665 peer_data.length_words = PM_BONDING_DATA_N_WORDS();
Jonathan Austin 0:bc2961fa1ef0 666 break;
Jonathan Austin 0:bc2961fa1ef0 667 case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
Jonathan Austin 0:bc2961fa1ef0 668 peer_data.length_words = PM_SC_STATE_N_WORDS();
Jonathan Austin 0:bc2961fa1ef0 669 break;
Jonathan Austin 0:bc2961fa1ef0 670 case PM_PEER_DATA_ID_GATT_LOCAL:
Jonathan Austin 0:bc2961fa1ef0 671 peer_data.length_words = PM_LOCAL_DB_N_WORDS(peer_data.data.p_local_gatt_db->len);
Jonathan Austin 0:bc2961fa1ef0 672 break;
Jonathan Austin 0:bc2961fa1ef0 673 case PM_PEER_DATA_ID_GATT_REMOTE:
Jonathan Austin 0:bc2961fa1ef0 674 peer_data.length_words = PM_REMOTE_DB_N_WORDS(peer_data.data.p_remote_gatt_db->service_count);
Jonathan Austin 0:bc2961fa1ef0 675 break;
Jonathan Austin 0:bc2961fa1ef0 676 case PM_PEER_DATA_ID_APPLICATION:
Jonathan Austin 0:bc2961fa1ef0 677 peer_data.length_words = PM_N_WORDS(p_write_buffer_record->n_bufs * PDB_WRITE_BUF_SIZE);
Jonathan Austin 0:bc2961fa1ef0 678 break;
Jonathan Austin 0:bc2961fa1ef0 679 default:
Jonathan Austin 0:bc2961fa1ef0 680 return NRF_ERROR_INVALID_PARAM;
Jonathan Austin 0:bc2961fa1ef0 681 }
Jonathan Austin 0:bc2961fa1ef0 682
Jonathan Austin 0:bc2961fa1ef0 683 err_code = write_or_update(peer_id, data_id, &peer_data, &p_write_buffer_record->store_token, p_write_buffer_record->prepare_token);
Jonathan Austin 0:bc2961fa1ef0 684
Jonathan Austin 0:bc2961fa1ef0 685 if (p_write_buffer_record->store_busy && p_write_buffer_record->store_flash_full)
Jonathan Austin 0:bc2961fa1ef0 686 {
Jonathan Austin 0:bc2961fa1ef0 687 m_pdb.n_writes--;
Jonathan Austin 0:bc2961fa1ef0 688 }
Jonathan Austin 0:bc2961fa1ef0 689
Jonathan Austin 0:bc2961fa1ef0 690 if (err_code == NRF_SUCCESS)
Jonathan Austin 0:bc2961fa1ef0 691 {
Jonathan Austin 0:bc2961fa1ef0 692 p_write_buffer_record->store_requested = true;
Jonathan Austin 0:bc2961fa1ef0 693 p_write_buffer_record->store_busy = false;
Jonathan Austin 0:bc2961fa1ef0 694 p_write_buffer_record->store_flash_full = false;
Jonathan Austin 0:bc2961fa1ef0 695 }
Jonathan Austin 0:bc2961fa1ef0 696 else
Jonathan Austin 0:bc2961fa1ef0 697 {
Jonathan Austin 0:bc2961fa1ef0 698 if (err_code == NRF_ERROR_BUSY)
Jonathan Austin 0:bc2961fa1ef0 699 {
Jonathan Austin 0:bc2961fa1ef0 700 m_pdb.n_writes++;
Jonathan Austin 0:bc2961fa1ef0 701 p_write_buffer_record->store_busy = true;
Jonathan Austin 0:bc2961fa1ef0 702 p_write_buffer_record->store_flash_full = false;
Jonathan Austin 0:bc2961fa1ef0 703 err_code = NRF_SUCCESS;
Jonathan Austin 0:bc2961fa1ef0 704 }
Jonathan Austin 0:bc2961fa1ef0 705 else if (err_code == NRF_ERROR_NO_MEM)
Jonathan Austin 0:bc2961fa1ef0 706 {
Jonathan Austin 0:bc2961fa1ef0 707 m_pdb.n_writes++;
Jonathan Austin 0:bc2961fa1ef0 708 p_write_buffer_record->store_busy = false;
Jonathan Austin 0:bc2961fa1ef0 709 p_write_buffer_record->store_flash_full = true;
Jonathan Austin 0:bc2961fa1ef0 710 }
Jonathan Austin 0:bc2961fa1ef0 711 else if ((err_code != NRF_ERROR_NO_MEM) && (err_code != NRF_ERROR_INVALID_PARAM))
Jonathan Austin 0:bc2961fa1ef0 712 {
Jonathan Austin 0:bc2961fa1ef0 713 err_code = NRF_ERROR_INTERNAL;
Jonathan Austin 0:bc2961fa1ef0 714 }
Jonathan Austin 0:bc2961fa1ef0 715 }
Jonathan Austin 0:bc2961fa1ef0 716
Jonathan Austin 0:bc2961fa1ef0 717 return err_code;
Jonathan Austin 0:bc2961fa1ef0 718 }
Jonathan Austin 0:bc2961fa1ef0 719
Jonathan Austin 0:bc2961fa1ef0 720
Jonathan Austin 0:bc2961fa1ef0 721 ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
Jonathan Austin 0:bc2961fa1ef0 722 {
Jonathan Austin 0:bc2961fa1ef0 723 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 724
Jonathan Austin 0:bc2961fa1ef0 725 return pds_peer_data_clear(peer_id, data_id);
Jonathan Austin 0:bc2961fa1ef0 726 }
Jonathan Austin 0:bc2961fa1ef0 727
Jonathan Austin 0:bc2961fa1ef0 728
Jonathan Austin 0:bc2961fa1ef0 729 uint32_t pdb_n_peers(void)
Jonathan Austin 0:bc2961fa1ef0 730 {
Jonathan Austin 0:bc2961fa1ef0 731 if (!MODULE_INITIALIZED)
Jonathan Austin 0:bc2961fa1ef0 732 {
Jonathan Austin 0:bc2961fa1ef0 733 return 0;
Jonathan Austin 0:bc2961fa1ef0 734 }
Jonathan Austin 0:bc2961fa1ef0 735
Jonathan Austin 0:bc2961fa1ef0 736 return pds_n_peers();
Jonathan Austin 0:bc2961fa1ef0 737 }
Jonathan Austin 0:bc2961fa1ef0 738
Jonathan Austin 0:bc2961fa1ef0 739
Jonathan Austin 0:bc2961fa1ef0 740 pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id)
Jonathan Austin 0:bc2961fa1ef0 741 {
Jonathan Austin 0:bc2961fa1ef0 742 if (!MODULE_INITIALIZED)
Jonathan Austin 0:bc2961fa1ef0 743 {
Jonathan Austin 0:bc2961fa1ef0 744 return PM_PEER_ID_INVALID;
Jonathan Austin 0:bc2961fa1ef0 745 }
Jonathan Austin 0:bc2961fa1ef0 746
Jonathan Austin 0:bc2961fa1ef0 747 return pds_next_peer_id_get(prev_peer_id);
Jonathan Austin 0:bc2961fa1ef0 748 }
Jonathan Austin 0:bc2961fa1ef0 749
Jonathan Austin 0:bc2961fa1ef0 750
Jonathan Austin 0:bc2961fa1ef0 751 ret_code_t pdb_raw_read(pm_peer_id_t peer_id,
Jonathan Austin 0:bc2961fa1ef0 752 pm_peer_data_id_t data_id,
Jonathan Austin 0:bc2961fa1ef0 753 pm_peer_data_t * p_peer_data)
Jonathan Austin 0:bc2961fa1ef0 754 {
Jonathan Austin 0:bc2961fa1ef0 755 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 756 return pds_peer_data_read(peer_id, data_id, p_peer_data, &p_peer_data->length_words);
Jonathan Austin 0:bc2961fa1ef0 757 }
Jonathan Austin 0:bc2961fa1ef0 758
Jonathan Austin 0:bc2961fa1ef0 759
Jonathan Austin 0:bc2961fa1ef0 760 ret_code_t pdb_raw_store(pm_peer_id_t peer_id,
Jonathan Austin 0:bc2961fa1ef0 761 pm_peer_data_const_t * p_peer_data,
Jonathan Austin 0:bc2961fa1ef0 762 pm_store_token_t * p_store_token)
Jonathan Austin 0:bc2961fa1ef0 763 {
Jonathan Austin 0:bc2961fa1ef0 764 VERIFY_MODULE_INITIALIZED();
Jonathan Austin 0:bc2961fa1ef0 765
Jonathan Austin 0:bc2961fa1ef0 766 return write_or_update(peer_id, p_peer_data->data_type, p_peer_data, p_store_token, PDS_PREPARE_TOKEN_INVALID);
Jonathan Austin 0:bc2961fa1ef0 767 }
Jonathan Austin 0:bc2961fa1ef0 768