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)
112 int rval = EPERS_NOT_INITIALIZED;
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;
155 int pclKeyHandleGetSize(int key_handle)
157 int size = EPERS_NOT_INITIALIZED;
159 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleGetSize: "),
160 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
162 if(gPclInitialized >= PCLinitialized)
164 if(key_handle < MaxPersHandle)
166 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
168 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
170 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_size != NULL) )
172 size = gPersCustomFuncs[idx].custom_plugin_get_size(gKeyHandleArray[key_handle].dbPath);
176 size = EPERS_NOPLUGINFUNCT;
181 size = pers_db_get_key_size(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
182 &gKeyHandleArray[key_handle].info);
187 size = EPERS_MAXHANDLE;
196 int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size)
198 int size = EPERS_NOT_INITIALIZED;
200 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleReadData: "),
201 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
203 if(gPclInitialized >= PCLinitialized)
205 if(key_handle < MaxPersHandle)
207 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
209 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
211 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_get_data != NULL) )
213 size = gPersCustomFuncs[idx].custom_plugin_handle_get_data(key_handle, (char*)buffer, buffer_size-1);
217 size = EPERS_NOPLUGINFUNCT;
222 size = pers_db_read_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
223 &gKeyHandleArray[key_handle].info, buffer, buffer_size);
228 size = EPERS_MAXHANDLE;
237 int pclKeyHandleRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
239 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: "),
240 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
242 return handleRegNotifyOnChange(key_handle, callback, Notify_register);
245 int pclKeyHandleUnRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
247 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleUnRegisterNotifyOnChange: "),
248 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
250 return handleRegNotifyOnChange(key_handle, callback, Notify_unregister);
255 int handleRegNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
257 int rval = EPERS_NOT_INITIALIZED;
259 if(gPclInitialized >= PCLinitialized)
261 if(key_handle < MaxPersHandle)
263 rval = regNotifyOnChange(gKeyHandleArray[key_handle].info.context.ldbid,
264 gKeyHandleArray[key_handle].resourceID,
265 gKeyHandleArray[key_handle].info.context.user_no,
266 gKeyHandleArray[key_handle].info.context.seat_no,
272 rval = EPERS_MAXHANDLE;
280 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
282 int size = EPERS_NOT_INITIALIZED;
284 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleWriteData: "),
285 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
287 if(gPclInitialized >= PCLinitialized)
289 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
291 if(buffer_size <= gMaxKeyValDataSize) // check data size
293 if(key_handle < MaxPersHandle)
295 if(gKeyHandleArray[key_handle].info.configKey.permission != PersistencePermission_ReadOnly) // don't write to a read only resource
297 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
299 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
301 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
303 size = gPersCustomFuncs[idx].custom_plugin_handle_set_data(key_handle, (char*)buffer, buffer_size-1);
305 if(size >= 0) // success ==> send change notification
307 int rval = pers_send_Notification_Signal(gKeyHandleArray[key_handle].dbKey,
308 &(gKeyHandleArray[key_handle].info.context), pclNotifyStatus_changed);
312 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleWriteData: error - failed to send notification"));
319 size = EPERS_NOPLUGINFUNCT;
324 size = pers_db_write_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
325 &gKeyHandleArray[key_handle].info, buffer, buffer_size);
330 size = EPERS_RESOURCE_READ_ONLY;
336 size = EPERS_MAXHANDLE;
341 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
342 size = EPERS_MAX_BUFF_SIZE;
358 // ----------------------------------------------------------------------------
359 // ----------------------------------------------------------------------------
360 // functions to be used directly without a handle
361 // ----------------------------------------------------------------------------
362 // ----------------------------------------------------------------------------
364 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
366 int rval = EPERS_NOT_INITIALIZED;
368 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyDelete: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
370 if(gPclInitialized >= PCLinitialized)
372 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
374 PersistenceInfo_s dbContext;
376 char dbKey[DbKeyMaxLen] = {0}; // database key
377 char dbPath[DbPathMaxLen] = {0}; // database location
379 dbContext.context.ldbid = ldbid;
380 dbContext.context.seat_no = seat_no;
381 dbContext.context.user_no = user_no;
383 // get database context: database path and database key
384 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
386 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type is matching
388 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
389 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
391 rval = pers_db_delete_key(dbPath, dbKey, &dbContext);
411 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
413 int data_size = EPERS_NOT_INITIALIZED;
415 if(gPclInitialized >= PCLinitialized)
417 PersistenceInfo_s dbContext;
419 char dbKey[DbKeyMaxLen] = {0}; // database key
420 char dbPath[DbPathMaxLen] = {0}; // database location
422 dbContext.context.ldbid = ldbid;
423 dbContext.context.seat_no = seat_no;
424 dbContext.context.user_no = user_no;
426 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyGetSize: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
428 // get database context: database path and database key
429 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
431 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type matches
433 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
434 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
436 data_size = pers_db_get_key_size(dbPath, dbKey, &dbContext);
440 data_size = EPERS_BADPOL;
445 data_size = EPERS_BADPOL;
455 int pclKeyReadData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
456 unsigned char* buffer, int buffer_size)
458 int data_size = EPERS_NOT_INITIALIZED;
460 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyReadData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
462 if(gPclInitialized >= PCLinitialized)
464 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
466 PersistenceInfo_s dbContext;
468 char dbKey[DbKeyMaxLen] = {0}; // database key
469 char dbPath[DbPathMaxLen] = {0}; // database location
471 dbContext.context.ldbid = ldbid;
472 dbContext.context.seat_no = seat_no;
473 dbContext.context.user_no = user_no;
475 // get database context: database path and database key
476 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
478 && (dbContext.configKey.type == PersistenceResourceType_key) )
481 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
482 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
484 data_size = pers_db_read_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
488 data_size = EPERS_BADPOL;
493 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
498 data_size = EPERS_LOCKFS;
507 int pclKeyWriteData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
508 unsigned char* buffer, int buffer_size)
510 int data_size = EPERS_NOT_INITIALIZED;
512 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyWriteData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
514 if(gPclInitialized >= PCLinitialized)
516 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
518 if(buffer_size <= gMaxKeyValDataSize) // check data size
520 PersistenceInfo_s dbContext;
522 unsigned int hash_val_data = 0;
524 char dbKey[DbKeyMaxLen] = {0}; // database key
525 char dbPath[DbPathMaxLen] = {0}; // database location
527 dbContext.context.ldbid = ldbid;
528 dbContext.context.seat_no = seat_no;
529 dbContext.context.user_no = user_no;
531 // get database context: database path and database key
532 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
534 && (dbContext.configKey.type == PersistenceResourceType_key))
536 if(dbContext.configKey.permission != PersistencePermission_ReadOnly) // don't write to a read only resource
538 // get hash value of data to verify storing
539 hash_val_data = pclCrc32(hash_val_data, buffer, buffer_size);
542 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
543 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
545 data_size = pers_db_write_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
549 data_size = EPERS_BADPOL;
554 data_size = EPERS_RESOURCE_READ_ONLY;
559 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
564 data_size = EPERS_BUFLIMIT;
565 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
570 data_size = EPERS_LOCKFS;
579 int pclKeyUnRegisterNotifyOnChange( unsigned int ldbid, const char * resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
581 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyUnRegisterNotifyOnChange: "),
582 // DLT_INT(ldbid), DLT_STRING(resource_id) );
584 return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_unregister);
588 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
590 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "),
591 // DLT_INT(ldbid), DLT_STRING(resource_id) );
593 return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_register);
599 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
601 int rval = EPERS_NOT_INITIALIZED;
603 if(gPclInitialized >= PCLinitialized)
605 PersistenceInfo_s dbContext;
607 // unsigned int hash_val_data = 0;
608 char dbKey[DbKeyMaxLen] = {0}; // database key
609 char dbPath[DbPathMaxLen] = {0}; // database location
611 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
613 dbContext.context.ldbid = ldbid;
614 dbContext.context.seat_no = seat_no;
615 dbContext.context.user_no = user_no;
617 // get database context: database path and database key
618 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
620 // registration is only on shared and custom keys possible
621 if( (dbContext.configKey.storage != PersistenceStorage_local)
622 && (dbContext.configKey.type == PersistenceResourceType_key) )
624 rval = persistence_notify_on_change(dbKey, ldbid, user_no, seat_no, callback, regPolicy);
628 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyRegisterNotifyOnChange: error - resource is not a shared resource or resource is not a key"));
629 rval = EPERS_NOTIFY_NOT_ALLOWED;