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"
22 #include "../include_protected/persistence_client_library_db_access.h"
23 #include "../include_protected/persistence_client_library_rc_table.h"
24 #include "../include_protected/crc32.h"
26 #include "persistence_client_library_handle.h"
27 #include "persistence_client_library_pas_interface.h"
28 #include "persistence_client_library_prct_access.h"
29 #include "persistence_client_library_custom_loader.h"
32 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
34 // function with handle
35 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
38 int pclKeyHandleOpen(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
40 int handle = EPERS_NOT_INITIALIZED;
42 if(gPclInitialized >= PCLinitialized)
44 PersistenceInfo_s dbContext;
46 char dbKey[DbKeyMaxLen] = {0}; // database key
47 char dbPath[DbPathMaxLen] = {0}; // database location
49 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleOpen: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
50 dbContext.context.ldbid = ldbid;
51 dbContext.context.seat_no = seat_no;
52 dbContext.context.user_no = user_no;
54 // get database context: database path and database key
55 handle = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
57 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type matches
59 if(dbContext.configKey.storage < PersistenceStorage_LastEntry) // check if store policy is valid
61 if(PersistenceStorage_custom == dbContext.configKey.storage)
63 int idx = custom_client_name_to_id(dbPath, 1);
64 char workaroundPath[128]; // workaround, because /sys/ can not be accessed on host!!!!
65 snprintf(workaroundPath, 128, "%s%s", "/Data", dbPath );
67 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_open != NULL) )
69 int flag = 0, mode = 0;
70 handle = gPersCustomFuncs[idx].custom_plugin_handle_open(workaroundPath, flag, mode);
74 handle = EPERS_NOPLUGINFUNCT;
79 handle = get_persistence_handle_idx();
82 if((handle < MaxPersHandle) && (0 <= handle))
84 // remember data in handle array
85 strncpy(gKeyHandleArray[handle].dbPath, dbPath, DbPathMaxLen);
86 strncpy(gKeyHandleArray[handle].dbKey, dbKey, DbKeyMaxLen);
87 strncpy(gKeyHandleArray[handle].resourceID, resource_id, DbResIDMaxLen);
88 gKeyHandleArray[handle].dbPath[DbPathMaxLen-1] = '\0'; // Ensures 0-Termination
89 gKeyHandleArray[handle].dbKey[ DbPathMaxLen-1] = '\0'; // Ensures 0-Termination
90 gKeyHandleArray[handle].info = dbContext;
94 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - handleId out of bounds:"), DLT_INT(handle));
100 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - no database context or resource is not a key "));
110 int pclKeyHandleClose(int key_handle)
114 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleClose: "),
115 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
117 if(gPclInitialized >= PCLinitialized)
119 if(key_handle < MaxPersHandle)
121 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage )
123 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
125 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_close != NULL) )
127 rval = gPersCustomFuncs[idx].custom_plugin_handle_close(key_handle);
131 rval = EPERS_NOPLUGINFUNCT;
136 set_persistence_handle_close_idx(key_handle);
139 // invalidate entries
140 memset(gKeyHandleArray[key_handle].dbPath, 0, DbPathMaxLen);
141 memset(gKeyHandleArray[key_handle].dbKey ,0, DbKeyMaxLen);
142 gKeyHandleArray[key_handle].info.configKey.storage = -1;
146 rval = EPERS_MAXHANDLE;
151 rval = EPERS_NOT_INITIALIZED;
159 int pclKeyHandleGetSize(int key_handle)
161 int size = EPERS_NOT_INITIALIZED;
163 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleGetSize: "),
164 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
166 if(gPclInitialized >= PCLinitialized)
168 if(key_handle < MaxPersHandle)
170 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
172 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
174 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_size != NULL) )
176 size = gPersCustomFuncs[idx].custom_plugin_get_size(gKeyHandleArray[key_handle].dbPath);
180 size = EPERS_NOPLUGINFUNCT;
185 size = pers_db_get_key_size(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
186 &gKeyHandleArray[key_handle].info);
191 size = EPERS_MAXHANDLE;
200 int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size)
202 int size = EPERS_NOT_INITIALIZED;
204 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleReadData: "),
205 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
207 if(gPclInitialized >= PCLinitialized)
209 if(key_handle < MaxPersHandle)
211 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
213 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
215 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_get_data != NULL) )
217 size = gPersCustomFuncs[idx].custom_plugin_handle_get_data(key_handle, (char*)buffer, buffer_size-1);
221 size = EPERS_NOPLUGINFUNCT;
226 size = pers_db_read_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
227 &gKeyHandleArray[key_handle].info, buffer, buffer_size);
232 size = EPERS_MAXHANDLE;
241 int pclKeyHandleRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
243 DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: "),
244 DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
246 return handleRegNotifyOnChange(key_handle, callback, Notify_register);
249 int pclKeyHandleUnRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
251 DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleUnRegisterNotifyOnChange: "),
252 DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
254 return handleRegNotifyOnChange(key_handle, callback, Notify_unregister);
259 int handleRegNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
261 int rval = EPERS_NOT_INITIALIZED;
263 if(gPclInitialized >= PCLinitialized)
265 if(key_handle < MaxPersHandle)
267 rval = regNotifyOnChange(gKeyHandleArray[key_handle].info.context.ldbid,
268 gKeyHandleArray[key_handle].resourceID,
269 gKeyHandleArray[key_handle].info.context.user_no,
270 gKeyHandleArray[key_handle].info.context.seat_no,
276 rval = EPERS_MAXHANDLE;
284 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
286 int size = EPERS_NOT_INITIALIZED;
288 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleWriteData: "),
289 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
291 if(gPclInitialized >= PCLinitialized)
293 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
295 if(buffer_size <= gMaxKeyValDataSize) // check data size
297 if(key_handle < MaxPersHandle)
299 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
301 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
303 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
305 size = gPersCustomFuncs[idx].custom_plugin_handle_set_data(key_handle, (char*)buffer, buffer_size-1);
309 size = EPERS_NOPLUGINFUNCT;
314 size = pers_db_write_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
315 &gKeyHandleArray[key_handle].info, buffer, buffer_size);
320 size = EPERS_MAXHANDLE;
325 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
326 size = EPERS_MAX_BUFF_SIZE;
342 // ----------------------------------------------------------------------------
343 // ----------------------------------------------------------------------------
344 // functions to be used directly without a handle
345 // ----------------------------------------------------------------------------
346 // ----------------------------------------------------------------------------
348 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
350 int rval = EPERS_NOT_INITIALIZED;
352 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyDelete: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
354 if(gPclInitialized >= PCLinitialized)
356 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
358 PersistenceInfo_s dbContext;
360 char dbKey[DbKeyMaxLen] = {0}; // database key
361 char dbPath[DbPathMaxLen] = {0}; // database location
363 dbContext.context.ldbid = ldbid;
364 dbContext.context.seat_no = seat_no;
365 dbContext.context.user_no = user_no;
367 // get database context: database path and database key
368 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
370 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type is matching
372 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
373 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
375 rval = pers_db_delete_key(dbPath, dbKey, &dbContext);
395 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
397 int data_size = EPERS_NOT_INITIALIZED;
399 if(gPclInitialized >= PCLinitialized)
401 PersistenceInfo_s dbContext;
403 char dbKey[DbKeyMaxLen] = {0}; // database key
404 char dbPath[DbPathMaxLen] = {0}; // database location
406 dbContext.context.ldbid = ldbid;
407 dbContext.context.seat_no = seat_no;
408 dbContext.context.user_no = user_no;
410 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyGetSize: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
412 // get database context: database path and database key
413 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
415 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type matches
417 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
418 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
420 data_size = pers_db_get_key_size(dbPath, dbKey, &dbContext);
424 data_size = EPERS_BADPOL;
429 data_size = EPERS_BADPOL;
439 int pclKeyReadData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
440 unsigned char* buffer, int buffer_size)
442 int data_size = EPERS_NOT_INITIALIZED;
444 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyReadData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
446 if(gPclInitialized >= PCLinitialized)
448 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
450 PersistenceInfo_s dbContext;
452 char dbKey[DbKeyMaxLen] = {0}; // database key
453 char dbPath[DbPathMaxLen] = {0}; // database location
455 dbContext.context.ldbid = ldbid;
456 dbContext.context.seat_no = seat_no;
457 dbContext.context.user_no = user_no;
459 // get database context: database path and database key
460 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
462 && (dbContext.configKey.type == PersistenceResourceType_key) )
465 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
466 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
468 data_size = pers_db_read_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
472 data_size = EPERS_BADPOL;
477 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
482 data_size = EPERS_LOCKFS;
491 int pclKeyWriteData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
492 unsigned char* buffer, int buffer_size)
494 int data_size = EPERS_NOT_INITIALIZED;
496 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyWriteData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
498 if(gPclInitialized >= PCLinitialized)
500 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
502 if(buffer_size <= gMaxKeyValDataSize) // check data size
504 PersistenceInfo_s dbContext;
506 unsigned int hash_val_data = 0;
508 char dbKey[DbKeyMaxLen] = {0}; // database key
509 char dbPath[DbPathMaxLen] = {0}; // database location
511 dbContext.context.ldbid = ldbid;
512 dbContext.context.seat_no = seat_no;
513 dbContext.context.user_no = user_no;
515 // get database context: database path and database key
516 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
518 && (dbContext.configKey.type == PersistenceResourceType_key))
520 // get hash value of data to verify storing
521 hash_val_data = crc32(hash_val_data, buffer, buffer_size);
524 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
525 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
527 data_size = pers_db_write_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
531 data_size = EPERS_BADPOL;
536 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
541 data_size = EPERS_BUFLIMIT;
542 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
547 data_size = EPERS_LOCKFS;
556 int pclKeyUnRegisterNotifyOnChange( unsigned int ldbid, const char * resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
558 DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyUnRegisterNotifyOnChange: "),
559 DLT_INT(ldbid), DLT_STRING(resource_id) );
561 return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_unregister);
565 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
567 DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "),
568 DLT_INT(ldbid), DLT_STRING(resource_id) );
569 return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_register);
575 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
577 int rval = EPERS_NOT_INITIALIZED;
579 if(gPclInitialized >= PCLinitialized)
581 PersistenceInfo_s dbContext;
583 // unsigned int hash_val_data = 0;
584 char dbKey[DbKeyMaxLen] = {0}; // database key
585 char dbPath[DbPathMaxLen] = {0}; // database location
587 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
589 dbContext.context.ldbid = ldbid;
590 dbContext.context.seat_no = seat_no;
591 dbContext.context.user_no = user_no;
593 // get database context: database path and database key
594 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
596 // registration is only on shared key possible
597 if( (dbContext.configKey.storage == PersistenceStorage_shared)
598 && (dbContext.configKey.type == PersistenceResourceType_key) )
600 rval = persistence_notify_on_change(dbPath, dbKey, ldbid, user_no, seat_no, callback, regPolicy);
604 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyRegisterNotifyOnChange: error - resource is not a shared resource or resource is not a key"));
605 rval = EPERS_RES_NO_KEY;