Nordic stack and drivers for the mbed BLE API

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate writable_gatt ... more

Committer:
Vincent Coubard
Date:
Wed Sep 14 14:39:43 2016 +0100
Revision:
638:c90ae1400bf2
Sync with bdab10dc0f90748b6989c8b577771bb403ca6bd8 from ARMmbed/mbed-os.

Who changed what in which revision?

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