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)
45 int handle = EPERS_NOT_INITIALIZED;
47 if(gPclInitialized >= PCLinitialized)
49 PersistenceInfo_s dbContext;
51 char dbKey[DbKeyMaxLen] = {0}; // database key
52 char dbPath[DbPathMaxLen] = {0}; // database location
54 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleOpen: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
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 handle = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
62 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type matches
64 if(dbContext.configKey.storage < PersistenceStorage_LastEntry) // check if store policy is valid
66 if(PersistenceStorage_custom == dbContext.configKey.storage)
68 int idx = custom_client_name_to_id(dbPath, 1);
69 char workaroundPath[128]; // workaround, because /sys/ can not be accessed on host!!!!
70 snprintf(workaroundPath, 128, "%s%s", "/Data", dbPath );
72 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_open != NULL) )
74 int flag = 0, mode = 0;
75 gPersCustomFuncs[idx].custom_plugin_handle_open(workaroundPath, flag, mode);
79 handle = EPERS_NOPLUGINFUNCT;
83 // generate handle for custom and for normal key
84 handle = get_persistence_handle_idx();
86 if((handle < MaxPersHandle) && (0 <= handle))
88 // remember data in handle array
89 strncpy(gKeyHandleArray[handle].dbPath, dbPath, DbPathMaxLen);
90 strncpy(gKeyHandleArray[handle].dbKey, dbKey, DbKeyMaxLen);
91 strncpy(gKeyHandleArray[handle].resourceID, resource_id, DbResIDMaxLen);
92 gKeyHandleArray[handle].dbPath[DbPathMaxLen-1] = '\0'; // Ensures 0-Termination
93 gKeyHandleArray[handle].dbKey[ DbKeyMaxLen-1] = '\0'; // Ensures 0-Termination
94 gKeyHandleArray[handle].info = dbContext;
98 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - handleId out of bounds:"), DLT_INT(handle));
104 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - no database context or resource is not a key "));
114 int pclKeyHandleClose(int key_handle)
116 int rval = EPERS_NOT_INITIALIZED;
118 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleClose: "),
119 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
121 if(gPclInitialized >= PCLinitialized)
123 if(key_handle < MaxPersHandle && key_handle > 0)
125 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage )
127 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
129 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_close != NULL) )
131 rval = gPersCustomFuncs[idx].custom_plugin_handle_close(key_handle);
135 rval = EPERS_NOPLUGINFUNCT;
139 if(rval != EPERS_NOPLUGINFUNCT)
141 set_persistence_handle_close_idx(key_handle);
144 // invalidate entries
145 memset(gKeyHandleArray[key_handle].dbPath, 0, DbPathMaxLen);
146 memset(gKeyHandleArray[key_handle].dbKey ,0, DbKeyMaxLen);
147 gKeyHandleArray[key_handle].info.configKey.storage = -1;
152 rval = EPERS_MAXHANDLE;
161 int pclKeyHandleGetSize(int key_handle)
163 int size = EPERS_NOT_INITIALIZED;
165 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleGetSize: "),
166 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
168 if(gPclInitialized >= PCLinitialized)
170 if(key_handle < MaxPersHandle && key_handle > 0)
172 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
174 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
176 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_size != NULL) )
178 size = gPersCustomFuncs[idx].custom_plugin_get_size(gKeyHandleArray[key_handle].dbPath);
182 size = EPERS_NOPLUGINFUNCT;
187 size = persistence_get_data_size(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
188 &gKeyHandleArray[key_handle].info);
193 size = EPERS_MAXHANDLE;
202 int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size)
204 int size = EPERS_NOT_INITIALIZED;
206 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleReadData: "),
207 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
209 if(gPclInitialized >= PCLinitialized)
211 if(key_handle < MaxPersHandle && key_handle > 0)
213 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
215 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
217 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_get_data != NULL) )
219 size = gPersCustomFuncs[idx].custom_plugin_handle_get_data(key_handle, (char*)buffer, buffer_size-1);
223 size = EPERS_NOPLUGINFUNCT;
228 size = persistence_get_data(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
229 &gKeyHandleArray[key_handle].info, buffer, buffer_size);
234 size = EPERS_MAXHANDLE;
243 int pclKeyHandleRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
245 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: "),
246 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
248 return handleRegNotifyOnChange(key_handle, callback, Notify_register);
251 int pclKeyHandleUnRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
253 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleUnRegisterNotifyOnChange: "),
254 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
256 return handleRegNotifyOnChange(key_handle, callback, Notify_unregister);
261 int handleRegNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
263 int rval = EPERS_NOT_INITIALIZED;
265 if(gPclInitialized >= PCLinitialized)
267 if(key_handle < MaxPersHandle && key_handle > 0)
269 rval = regNotifyOnChange(gKeyHandleArray[key_handle].info.context.ldbid,
270 gKeyHandleArray[key_handle].resourceID,
271 gKeyHandleArray[key_handle].info.context.user_no,
272 gKeyHandleArray[key_handle].info.context.seat_no,
278 rval = EPERS_MAXHANDLE;
286 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
288 int size = EPERS_NOT_INITIALIZED;
290 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleWriteData: "),
291 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
293 if(gPclInitialized >= PCLinitialized)
295 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
297 if(buffer_size <= gMaxKeyValDataSize) // check data size
299 if(key_handle < MaxPersHandle && key_handle > 0)
301 if(gKeyHandleArray[key_handle].info.configKey.permission != PersistencePermission_ReadOnly) // don't write to a read only resource
303 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
305 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
307 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
309 size = gPersCustomFuncs[idx].custom_plugin_handle_set_data(key_handle, (char*)buffer, buffer_size-1);
311 if(size >= 0) // success ==> send change notification
313 int rval = pers_send_Notification_Signal(gKeyHandleArray[key_handle].dbKey,
314 &(gKeyHandleArray[key_handle].info.context), pclNotifyStatus_changed);
318 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleWriteData: error - failed to send notification"));
325 size = EPERS_NOPLUGINFUNCT;
330 size = persistence_set_data(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
331 &gKeyHandleArray[key_handle].info, buffer, buffer_size);
336 size = EPERS_RESOURCE_READ_ONLY;
342 size = EPERS_MAXHANDLE;
347 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
348 size = EPERS_MAX_BUFF_SIZE;
364 // ----------------------------------------------------------------------------
365 // ----------------------------------------------------------------------------
366 // functions to be used directly without a handle
367 // ----------------------------------------------------------------------------
368 // ----------------------------------------------------------------------------
370 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
372 int rval = EPERS_NOT_INITIALIZED;
374 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyDelete: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
376 if(gPclInitialized >= PCLinitialized)
378 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
380 PersistenceInfo_s dbContext;
382 char dbKey[DbKeyMaxLen] = {0}; // database key
383 char dbPath[DbPathMaxLen] = {0}; // database location
385 dbContext.context.ldbid = ldbid;
386 dbContext.context.seat_no = seat_no;
387 dbContext.context.user_no = user_no;
389 // get database context: database path and database key
390 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
392 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type is matching
394 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
395 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
397 rval = persistence_delete_data(dbPath, dbKey, &dbContext);
417 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
419 int data_size = EPERS_NOT_INITIALIZED;
421 if(gPclInitialized >= PCLinitialized)
423 PersistenceInfo_s dbContext;
425 char dbKey[DbKeyMaxLen] = {0}; // database key
426 char dbPath[DbPathMaxLen] = {0}; // database location
428 dbContext.context.ldbid = ldbid;
429 dbContext.context.seat_no = seat_no;
430 dbContext.context.user_no = user_no;
432 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyGetSize: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
434 // get database context: database path and database key
435 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
437 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type matches
439 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
440 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
442 data_size = persistence_get_data_size(dbPath, dbKey, &dbContext);
446 data_size = EPERS_BADPOL;
451 data_size = EPERS_BADPOL;
461 int pclKeyReadData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
462 unsigned char* buffer, int buffer_size)
464 int data_size = EPERS_NOT_INITIALIZED;
466 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyReadData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
468 if(gPclInitialized >= PCLinitialized)
470 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
472 PersistenceInfo_s dbContext;
474 char dbKey[DbKeyMaxLen] = {0}; // database key
475 char dbPath[DbPathMaxLen] = {0}; // database location
477 dbContext.context.ldbid = ldbid;
478 dbContext.context.seat_no = seat_no;
479 dbContext.context.user_no = user_no;
481 // get database context: database path and database key
482 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
484 && (dbContext.configKey.type == PersistenceResourceType_key) )
487 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
488 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
490 data_size = persistence_get_data(dbPath, dbKey, &dbContext, buffer, buffer_size);
494 data_size = EPERS_BADPOL;
499 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
504 data_size = EPERS_LOCKFS;
513 int pclKeyWriteData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
514 unsigned char* buffer, int buffer_size)
516 int data_size = EPERS_NOT_INITIALIZED;
518 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyWriteData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
520 if(gPclInitialized >= PCLinitialized)
522 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
524 if(buffer_size <= gMaxKeyValDataSize) // check data size
526 PersistenceInfo_s dbContext;
528 unsigned int hash_val_data = 0;
530 char dbKey[DbKeyMaxLen] = {0}; // database key
531 char dbPath[DbPathMaxLen] = {0}; // database location
533 dbContext.context.ldbid = ldbid;
534 dbContext.context.seat_no = seat_no;
535 dbContext.context.user_no = user_no;
537 // get database context: database path and database key
538 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
540 && (dbContext.configKey.type == PersistenceResourceType_key))
542 if(dbContext.configKey.permission != PersistencePermission_ReadOnly) // don't write to a read only resource
544 // get hash value of data to verify storing
545 hash_val_data = pclCrc32(hash_val_data, buffer, buffer_size);
548 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
549 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
551 data_size = persistence_set_data(dbPath, dbKey, &dbContext, buffer, buffer_size);
555 data_size = EPERS_BADPOL;
560 data_size = EPERS_RESOURCE_READ_ONLY;
565 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
570 data_size = EPERS_BUFLIMIT;
571 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
576 data_size = EPERS_LOCKFS;
584 int pclKeyUnRegisterNotifyOnChange( unsigned int ldbid, const char * resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
586 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyUnRegisterNotifyOnChange: "),
587 // DLT_INT(ldbid), DLT_STRING(resource_id) );
589 return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_unregister);
593 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
595 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "),
596 // DLT_INT(ldbid), DLT_STRING(resource_id) );
598 return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_register);
604 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
606 int rval = EPERS_NOT_INITIALIZED;
608 if(gPclInitialized >= PCLinitialized)
610 PersistenceInfo_s dbContext;
612 // unsigned int hash_val_data = 0;
613 char dbKey[DbKeyMaxLen] = {0}; // database key
614 char dbPath[DbPathMaxLen] = {0}; // database location
616 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
618 dbContext.context.ldbid = ldbid;
619 dbContext.context.seat_no = seat_no;
620 dbContext.context.user_no = user_no;
622 // get database context: database path and database key
623 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
625 // registration is only on shared and custom keys possible
626 if( (dbContext.configKey.storage != PersistenceStorage_local)
627 && (dbContext.configKey.type == PersistenceResourceType_key) )
629 rval = persistence_notify_on_change(dbKey, ldbid, user_no, seat_no, callback, regPolicy);
633 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyRegisterNotifyOnChange: error - resource is not a shared resource or resource is not a key"));
634 rval = EPERS_NOTIFY_NOT_ALLOWED;