1 /******************************************************************************
4 * Company XS Embedded GmbH
5 *****************************************************************************/
6 /******************************************************************************
7 * This Source Code Form is subject to the terms of the
8 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
9 * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 ******************************************************************************/
12 * @file persistence_client_library_key.c
13 * @ingroup Persistence client library
14 * @author Ingo Huerner
15 * @brief Implementation of the persistence client library.
16 * Library provides an API to access persistent data
20 #include "persistence_client_library_key.h"
21 #include "persistence_client_library_handle.h"
22 #include "persistence_client_library_pas_interface.h"
23 #include "persistence_client_library_custom_loader.h"
24 #include "persistence_client_library_prct_access.h"
25 #include "persistence_client_library_db_access.h"
28 #include <persComRct.h>
32 // function declaration
33 int handleRegNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy);
34 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
35 pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy);
37 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
39 // function with handle
40 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 int pclKeyHandleOpen(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
46 int handle = EPERS_NOT_INITIALIZED;
48 if(gPclInitialized >= PCLinitialized)
50 PersistenceInfo_s dbContext;
52 char dbKey[DbKeyMaxLen] = {0}; // database key
53 char dbPath[DbPathMaxLen] = {0}; // database location
55 dbContext.context.ldbid = ldbid;
56 dbContext.context.seat_no = seat_no;
57 dbContext.context.user_no = user_no;
59 // get database context: database path and database key
60 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
61 if((rval >= 0) && (dbContext.configKey.type == PersistenceResourceType_key)) // check if type matches
63 if(dbContext.configKey.storage < PersistenceStorage_LastEntry) // check if store policy is valid
65 // generate handle for custom and for normal key
66 handle = get_persistence_handle_idx();
68 if((handle < MaxPersHandle) && (0 < handle))
70 // remember data in handle array
71 strncpy(gKeyHandleArray[handle].resource_id, resource_id, DbResIDMaxLen);
72 gKeyHandleArray[handle].resource_id[DbResIDMaxLen-1] = '\0'; /* Ensures 0-Termination */
73 gKeyHandleArray[handle].ldbid = ldbid;
74 gKeyHandleArray[handle].user_no = user_no;
75 gKeyHandleArray[handle].seat_no = seat_no;
79 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - handleId out of bounds:"), DLT_INT(handle));
84 handle = EPERS_BADPOL;
89 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - no database context or resource is not a key "));
98 int pclKeyHandleClose(int key_handle)
100 int rval = EPERS_NOT_INITIALIZED;
102 if(gPclInitialized >= PCLinitialized)
104 if((key_handle < MaxPersHandle) && (key_handle > 0))
106 if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
108 /* Invalidate key handle data */
109 set_persistence_handle_close_idx(key_handle);
110 memset(&gKeyHandleArray[key_handle], 0, sizeof(gKeyHandleArray[key_handle]));
115 rval = EPERS_INVALID_HANDLE;
120 rval = EPERS_MAXHANDLE;
129 int pclKeyHandleGetSize(int key_handle)
131 int size = EPERS_NOT_INITIALIZED;
133 if(gPclInitialized >= PCLinitialized)
135 if((key_handle < MaxPersHandle) && (key_handle > 0))
137 if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
139 size = pclKeyGetSize(gKeyHandleArray[key_handle].ldbid,
140 gKeyHandleArray[key_handle].resource_id,
141 gKeyHandleArray[key_handle].user_no,
142 gKeyHandleArray[key_handle].seat_no);
146 size = EPERS_INVALID_HANDLE;
151 size = EPERS_MAXHANDLE;
160 int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size)
162 int size = EPERS_NOT_INITIALIZED;
164 if(gPclInitialized >= PCLinitialized)
166 if((key_handle < MaxPersHandle) && (key_handle > 0))
168 if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
170 size = pclKeyReadData(gKeyHandleArray[key_handle].ldbid,
171 gKeyHandleArray[key_handle].resource_id,
172 gKeyHandleArray[key_handle].user_no,
173 gKeyHandleArray[key_handle].seat_no,
179 size = EPERS_INVALID_HANDLE;
184 size = EPERS_MAXHANDLE;
193 int pclKeyHandleRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
195 int rval = EPERS_COMMON;
196 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: "),
197 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
198 if((gChangeNotifyCallback == callback) || (gChangeNotifyCallback == NULL))
200 rval = handleRegNotifyOnChange(key_handle, callback, Notify_register);
204 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: Only one callback is allowed for change notifications."));
205 rval = EPERS_NOTIFY_NOT_ALLOWED;
210 int pclKeyHandleUnRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
212 return handleRegNotifyOnChange(key_handle, callback, Notify_unregister);
217 int handleRegNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
219 int rval = EPERS_NOT_INITIALIZED;
221 if(gPclInitialized >= PCLinitialized)
223 if((key_handle < MaxPersHandle) && (key_handle > 0))
225 if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
227 rval = regNotifyOnChange(gKeyHandleArray[key_handle].ldbid,
228 gKeyHandleArray[key_handle].resource_id,
229 gKeyHandleArray[key_handle].user_no,
230 gKeyHandleArray[key_handle].seat_no,
236 rval = EPERS_INVALID_HANDLE;
241 rval = EPERS_MAXHANDLE;
249 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
251 int size = EPERS_NOT_INITIALIZED;
253 if(gPclInitialized >= PCLinitialized)
255 if((key_handle < MaxPersHandle) && (key_handle > 0))
257 if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
259 size = pclKeyWriteData(gKeyHandleArray[key_handle].ldbid,
260 gKeyHandleArray[key_handle].resource_id,
261 gKeyHandleArray[key_handle].user_no,
262 gKeyHandleArray[key_handle].seat_no,
268 size = EPERS_INVALID_HANDLE;
273 size = EPERS_MAXHANDLE;
284 // ----------------------------------------------------------------------------
285 // ----------------------------------------------------------------------------
286 // functions to be used directly without a handle
287 // ----------------------------------------------------------------------------
288 // ----------------------------------------------------------------------------
290 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
292 int rval = EPERS_NOT_INITIALIZED;
294 if(gPclInitialized >= PCLinitialized)
296 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
298 PersistenceInfo_s dbContext;
300 char dbKey[DbKeyMaxLen] = {0}; // database key
301 char dbPath[DbPathMaxLen] = {0}; // database location
303 dbContext.context.ldbid = ldbid;
304 dbContext.context.seat_no = seat_no;
305 dbContext.context.user_no = user_no;
307 // get database context: database path and database key
308 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
310 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type is matching
312 if( dbContext.configKey.storage < PersistenceStorage_LastEntry) // check if store policy is valid
314 rval = persistence_delete_data(dbPath, dbKey, &dbContext);
334 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
336 int data_size = EPERS_NOT_INITIALIZED;
338 if(gPclInitialized >= PCLinitialized)
340 PersistenceInfo_s dbContext;
342 char dbKey[DbKeyMaxLen] = {0}; // database key
343 char dbPath[DbPathMaxLen] = {0}; // database location
345 dbContext.context.ldbid = ldbid;
346 dbContext.context.seat_no = seat_no;
347 dbContext.context.user_no = user_no;
349 // get database context: database path and database key
350 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
352 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type matches
354 if( dbContext.configKey.storage < PersistenceStorage_LastEntry) // check if store policy is valid
356 data_size = persistence_get_data_size(dbPath, dbKey, &dbContext);
360 data_size = EPERS_BADPOL;
365 data_size = EPERS_BADPOL;
375 int pclKeyReadData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
376 unsigned char* buffer, int buffer_size)
378 int data_size = EPERS_NOT_INITIALIZED;
380 if(gPclInitialized >= PCLinitialized)
382 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
384 PersistenceInfo_s dbContext;
386 char dbKey[DbKeyMaxLen] = {0}; // database key
387 char dbPath[DbPathMaxLen] = {0}; // database location
389 dbContext.context.ldbid = ldbid;
390 dbContext.context.seat_no = seat_no;
391 dbContext.context.user_no = user_no;
393 // get database context: database path and database key
394 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
396 && (dbContext.configKey.type == PersistenceResourceType_key) )
399 if( dbContext.configKey.storage < PersistenceStorage_LastEntry) // check if store policy is valid
401 data_size = persistence_get_data(dbPath, dbKey, resource_id, &dbContext, buffer, buffer_size);
405 data_size = EPERS_BADPOL;
410 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
415 data_size = EPERS_LOCKFS;
424 int pclKeyWriteData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
425 unsigned char* buffer, int buffer_size)
427 int data_size = EPERS_NOT_INITIALIZED;
429 if(gPclInitialized >= PCLinitialized)
431 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
433 if(buffer_size <= gMaxKeyValDataSize) // check data size
435 PersistenceInfo_s dbContext;
437 unsigned int hash_val_data = 0;
439 char dbKey[DbKeyMaxLen] = {0}; // database key
440 char dbPath[DbPathMaxLen] = {0}; // database location
442 dbContext.context.ldbid = ldbid;
443 dbContext.context.seat_no = seat_no;
444 dbContext.context.user_no = user_no;
446 // get database context: database path and database key
447 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
449 && (dbContext.configKey.type == PersistenceResourceType_key))
451 if(dbContext.configKey.permission != PersistencePermission_ReadOnly) // don't write to a read only resource
453 // get hash value of data to verify storing
454 hash_val_data = pclCrc32(hash_val_data, buffer, buffer_size);
457 if( dbContext.configKey.storage < PersistenceStorage_LastEntry) // check if store policy is valid
459 data_size = persistence_set_data(dbPath, dbKey, &dbContext, buffer, buffer_size);
463 data_size = EPERS_BADPOL;
468 data_size = EPERS_RESOURCE_READ_ONLY;
473 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
478 data_size = EPERS_BUFLIMIT;
479 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
484 data_size = EPERS_LOCKFS;
492 int pclKeyUnRegisterNotifyOnChange( unsigned int ldbid, const char * resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
494 return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_unregister);
498 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
500 int rval = EPERS_COMMON;
501 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "),
502 // DLT_INT(ldbid), DLT_STRING(resource_id) );
503 if((gChangeNotifyCallback == callback) || (gChangeNotifyCallback == NULL))
505 rval = regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_register);
509 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyRegisterNotifyOnChange: Only one callback is allowed for change notifications."));
510 rval = EPERS_NOTIFY_NOT_ALLOWED;
518 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
520 int rval = EPERS_NOT_INITIALIZED;
522 if(gPclInitialized >= PCLinitialized)
524 PersistenceInfo_s dbContext;
526 // unsigned int hash_val_data = 0;
527 char dbKey[DbKeyMaxLen] = {0}; // database key
528 char dbPath[DbPathMaxLen] = {0}; // database location
530 dbContext.context.ldbid = ldbid;
531 dbContext.context.seat_no = seat_no;
532 dbContext.context.user_no = user_no;
534 // get database context: database path and database key
535 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
537 if (rval==0) // no error, key found
539 // registration is only on shared and custom keys possible
540 if( (dbContext.configKey.storage != PersistenceStorage_local)
541 && (dbContext.configKey.type == PersistenceResourceType_key) )
543 rval = persistence_notify_on_change(resource_id, ldbid, user_no, seat_no, callback, regPolicy);
547 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR,
548 DLT_STRING("regNotifyOnChange: Not allowed! Resource is local or it is a file:"),
549 DLT_STRING(resource_id),
550 DLT_STRING("LDBID:"),
552 rval = EPERS_NOTIFY_NOT_ALLOWED;
557 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR,
558 DLT_STRING("regNotifyOnChange: Not possible! get_db_context() returned:"),