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 int rval = EPERS_NOT_INITIALIZED;
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 if(gPclInitialized >= PCLinitialized)
250 if(key_handle < MaxPersHandle)
252 rval = regNotifyOnChange(gKeyHandleArray[key_handle].info.context.ldbid,
253 gKeyHandleArray[key_handle].resourceID,
254 gKeyHandleArray[key_handle].info.context.user_no,
255 gKeyHandleArray[key_handle].info.context.seat_no,
261 rval = EPERS_MAXHANDLE;
267 int pclKeyHandleUnRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
269 int rval = EPERS_NOT_INITIALIZED;
271 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: "),
272 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
274 if(gPclInitialized >= PCLinitialized)
276 if(key_handle < MaxPersHandle)
278 rval = regNotifyOnChange(gKeyHandleArray[key_handle].info.context.ldbid,
279 gKeyHandleArray[key_handle].resourceID,
280 gKeyHandleArray[key_handle].info.context.user_no,
281 gKeyHandleArray[key_handle].info.context.seat_no,
287 rval = EPERS_MAXHANDLE;
294 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
296 int size = EPERS_NOT_INITIALIZED;
298 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleWriteData: "),
299 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
301 if(gPclInitialized >= PCLinitialized)
303 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
305 if(buffer_size <= gMaxKeyValDataSize) // check data size
307 if(key_handle < MaxPersHandle)
309 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
311 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
313 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
315 size = gPersCustomFuncs[idx].custom_plugin_handle_set_data(key_handle, (char*)buffer, buffer_size-1);
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_MAXHANDLE;
335 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
336 size = EPERS_MAX_BUFF_SIZE;
352 // ----------------------------------------------------------------------------
353 // ----------------------------------------------------------------------------
354 // functions to be used directly without a handle
355 // ----------------------------------------------------------------------------
356 // ----------------------------------------------------------------------------
358 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
360 int rval = EPERS_NOT_INITIALIZED;
362 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyDelete: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
364 if(gPclInitialized >= PCLinitialized)
366 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
368 PersistenceInfo_s dbContext;
370 char dbKey[DbKeyMaxLen] = {0}; // database key
371 char dbPath[DbPathMaxLen] = {0}; // database location
373 dbContext.context.ldbid = ldbid;
374 dbContext.context.seat_no = seat_no;
375 dbContext.context.user_no = user_no;
377 // get database context: database path and database key
378 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
380 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type is matching
382 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
383 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
385 rval = pers_db_delete_key(dbPath, dbKey, &dbContext);
405 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
407 int data_size = EPERS_NOT_INITIALIZED;
409 if(gPclInitialized >= PCLinitialized)
411 PersistenceInfo_s dbContext;
413 char dbKey[DbKeyMaxLen] = {0}; // database key
414 char dbPath[DbPathMaxLen] = {0}; // database location
416 dbContext.context.ldbid = ldbid;
417 dbContext.context.seat_no = seat_no;
418 dbContext.context.user_no = user_no;
420 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyGetSize: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
422 // get database context: database path and database key
423 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
425 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type matches
427 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
428 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
430 data_size = pers_db_get_key_size(dbPath, dbKey, &dbContext);
434 data_size = EPERS_BADPOL;
439 data_size = EPERS_BADPOL;
449 int pclKeyReadData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
450 unsigned char* buffer, int buffer_size)
452 int data_size = EPERS_NOT_INITIALIZED;
454 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyReadData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
456 if(gPclInitialized >= PCLinitialized)
458 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
460 PersistenceInfo_s dbContext;
462 char dbKey[DbKeyMaxLen] = {0}; // database key
463 char dbPath[DbPathMaxLen] = {0}; // database location
465 dbContext.context.ldbid = ldbid;
466 dbContext.context.seat_no = seat_no;
467 dbContext.context.user_no = user_no;
469 // get database context: database path and database key
470 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
472 && (dbContext.configKey.type == PersistenceResourceType_key) )
475 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
476 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
478 data_size = pers_db_read_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
482 data_size = EPERS_BADPOL;
487 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
492 data_size = EPERS_LOCKFS;
501 int pclKeyWriteData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
502 unsigned char* buffer, int buffer_size)
504 int data_size = EPERS_NOT_INITIALIZED;
506 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyWriteData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
508 if(gPclInitialized >= PCLinitialized)
510 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
512 if(buffer_size <= gMaxKeyValDataSize) // check data size
514 PersistenceInfo_s dbContext;
516 unsigned int hash_val_data = 0;
518 char dbKey[DbKeyMaxLen] = {0}; // database key
519 char dbPath[DbPathMaxLen] = {0}; // database location
521 dbContext.context.ldbid = ldbid;
522 dbContext.context.seat_no = seat_no;
523 dbContext.context.user_no = user_no;
525 // get database context: database path and database key
526 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
528 && (dbContext.configKey.type == PersistenceResourceType_key))
530 // get hash value of data to verify storing
531 hash_val_data = crc32(hash_val_data, buffer, buffer_size);
534 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
535 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
537 data_size = pers_db_write_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
541 data_size = EPERS_BADPOL;
546 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
551 data_size = EPERS_BUFLIMIT;
552 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
557 data_size = EPERS_LOCKFS;
566 int pclKeyUnRegisterNotifyOnChange( unsigned int ldbid, const char * resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
568 return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_unregister);
572 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
575 return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_register);
581 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback, PersistenceNotifyRegPolicy_e regPolicy)
583 int rval = EPERS_NOT_INITIALIZED;
585 if(gPclInitialized >= PCLinitialized)
587 PersistenceInfo_s dbContext;
589 // unsigned int hash_val_data = 0;
590 char dbKey[DbKeyMaxLen] = {0}; // database key
591 char dbPath[DbPathMaxLen] = {0}; // database location
593 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
595 dbContext.context.ldbid = ldbid;
596 dbContext.context.seat_no = seat_no;
597 dbContext.context.user_no = user_no;
599 // get database context: database path and database key
600 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
602 // registration is only on shared key possible
603 if( (dbContext.configKey.storage == PersistenceStorage_shared)
604 && (dbContext.configKey.type == PersistenceResourceType_key) )
606 rval = persistence_notify_on_change(dbPath, dbKey, ldbid, user_no, seat_no, callback, regPolicy);
610 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyRegisterNotifyOnChange: error - resource is not a shared resource or resource is not a key"));
611 rval = EPERS_RES_NO_KEY;