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 strncpy(gKeyHandleArray[key_handle].dbPath, "", DbPathMaxLen);
141 strncpy(gKeyHandleArray[key_handle].dbKey ,"", DbKeyMaxLen);
142 gKeyHandleArray[key_handle].info.configKey.storage = -1;
147 rval = EPERS_MAXHANDLE;
156 int pclKeyHandleGetSize(int key_handle)
158 int size = EPERS_NOT_INITIALIZED;
160 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleGetSize: "),
161 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
163 if(gPclInitialized >= PCLinitialized)
165 if(key_handle < MaxPersHandle)
167 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
169 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
171 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_size != NULL) )
173 size = gPersCustomFuncs[idx].custom_plugin_get_size(gKeyHandleArray[key_handle].dbPath);
177 size = EPERS_NOPLUGINFUNCT;
182 size = pers_db_get_key_size(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
183 &gKeyHandleArray[key_handle].info);
193 int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size)
195 int size = EPERS_NOT_INITIALIZED;
197 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleReadData: "),
198 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
200 if(gPclInitialized >= PCLinitialized)
202 if(key_handle < MaxPersHandle)
204 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
206 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
208 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_get_data != NULL) )
210 size = gPersCustomFuncs[idx].custom_plugin_handle_get_data(key_handle, (char*)buffer, buffer_size-1);
214 size = EPERS_NOPLUGINFUNCT;
219 size = pers_db_read_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
220 &gKeyHandleArray[key_handle].info, buffer, buffer_size);
230 int pclKeyHandleRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
232 int rval = EPERS_NOT_INITIALIZED;
234 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: "),
235 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
237 if(gPclInitialized >= PCLinitialized)
239 if(key_handle < MaxPersHandle)
241 rval = pclKeyRegisterNotifyOnChange(gKeyHandleArray[key_handle].info.context.ldbid,
242 gKeyHandleArray[key_handle].resourceID,
243 gKeyHandleArray[key_handle].info.context.user_no,
244 gKeyHandleArray[key_handle].info.context.seat_no, callback);
253 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
255 int size = EPERS_NOT_INITIALIZED;
257 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleWriteData: "),
258 // DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
260 if(gPclInitialized >= PCLinitialized)
262 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
264 if(buffer_size <= gMaxKeyValDataSize) // check data size
266 if(key_handle < MaxPersHandle)
268 if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage)
270 int idx = custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
272 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
274 size = gPersCustomFuncs[idx].custom_plugin_handle_set_data(key_handle, (char*)buffer, buffer_size-1);
278 size = EPERS_NOPLUGINFUNCT;
283 size = pers_db_write_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
284 &gKeyHandleArray[key_handle].info, buffer, buffer_size);
289 size = EPERS_MAXHANDLE;
294 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
310 // ----------------------------------------------------------------------------
311 // ----------------------------------------------------------------------------
312 // functions to be used directly without a handle
313 // ----------------------------------------------------------------------------
314 // ----------------------------------------------------------------------------
316 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
318 int rval = EPERS_NOT_INITIALIZED;
320 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyDelete: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
322 if(gPclInitialized >= PCLinitialized)
324 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
326 PersistenceInfo_s dbContext;
328 char dbKey[DbKeyMaxLen] = {0}; // database key
329 char dbPath[DbPathMaxLen] = {0}; // database location
331 dbContext.context.ldbid = ldbid;
332 dbContext.context.seat_no = seat_no;
333 dbContext.context.user_no = user_no;
335 // get database context: database path and database key
336 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
338 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type is matching
340 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
341 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
343 rval = pers_db_delete_key(dbPath, dbKey, &dbContext);
363 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
365 int data_size = EPERS_NOT_INITIALIZED;
367 if(gPclInitialized >= PCLinitialized)
369 PersistenceInfo_s dbContext;
371 char dbKey[DbKeyMaxLen] = {0}; // database key
372 char dbPath[DbPathMaxLen] = {0}; // database location
374 dbContext.context.ldbid = ldbid;
375 dbContext.context.seat_no = seat_no;
376 dbContext.context.user_no = user_no;
378 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyGetSize: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
380 // get database context: database path and database key
381 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
383 && (dbContext.configKey.type == PersistenceResourceType_key) ) // check if type matches
385 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
386 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
388 data_size = pers_db_get_key_size(dbPath, dbKey, &dbContext);
392 data_size = EPERS_BADPOL;
397 data_size = EPERS_BADPOL;
407 int pclKeyReadData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
408 unsigned char* buffer, int buffer_size)
410 int data_size = EPERS_NOT_INITIALIZED;
412 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyReadData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
414 if(gPclInitialized >= PCLinitialized)
416 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
418 PersistenceInfo_s dbContext;
420 char dbKey[DbKeyMaxLen] = {0}; // database key
421 char dbPath[DbPathMaxLen] = {0}; // database location
423 dbContext.context.ldbid = ldbid;
424 dbContext.context.seat_no = seat_no;
425 dbContext.context.user_no = user_no;
427 // get database context: database path and database key
428 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
430 && (dbContext.configKey.type == PersistenceResourceType_key) )
433 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
434 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
436 data_size = pers_db_read_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
440 data_size = EPERS_BADPOL;
445 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
450 data_size = EPERS_LOCKFS;
459 int pclKeyWriteData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
460 unsigned char* buffer, int buffer_size)
462 int data_size = EPERS_NOT_INITIALIZED;
464 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyWriteData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
466 if(gPclInitialized >= PCLinitialized)
468 if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
470 if(buffer_size <= gMaxKeyValDataSize) // check data size
472 PersistenceInfo_s dbContext;
474 unsigned int hash_val_data = 0;
476 char dbKey[DbKeyMaxLen] = {0}; // database key
477 char dbPath[DbPathMaxLen] = {0}; // database location
479 dbContext.context.ldbid = ldbid;
480 dbContext.context.seat_no = seat_no;
481 dbContext.context.user_no = user_no;
483 // get database context: database path and database key
484 data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
486 && (dbContext.configKey.type == PersistenceResourceType_key))
488 // get hash value of data to verify storing
489 hash_val_data = crc32(hash_val_data, buffer, buffer_size);
492 if( dbContext.configKey.storage < PersistenceStorage_LastEntry
493 && dbContext.configKey.storage >= PersistenceStorage_local) // check if store policy is valid
495 data_size = pers_db_write_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
499 data_size = EPERS_BADPOL;
504 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
509 data_size = EPERS_BUFLIMIT;
510 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
515 data_size = EPERS_LOCKFS;
523 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
525 int rval = EPERS_NOT_INITIALIZED;
527 if(gPclInitialized >= PCLinitialized)
529 PersistenceInfo_s dbContext;
531 // unsigned int hash_val_data = 0;
532 char dbKey[DbKeyMaxLen] = {0}; // database key
533 char dbPath[DbPathMaxLen] = {0}; // database location
535 //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
537 dbContext.context.ldbid = ldbid;
538 dbContext.context.seat_no = seat_no;
539 dbContext.context.user_no = user_no;
541 // get database context: database path and database key
542 rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
544 // registration is only on shared key possible
545 if( (dbContext.configKey.storage == PersistenceStorage_shared)
546 && (dbContext.configKey.type == PersistenceResourceType_key) )
548 rval = persistence_reg_notify_on_change(dbPath, dbKey, ldbid, user_no, seat_no, callback);
552 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyRegisterNotifyOnChange: error - resource is not a shared resource or resource is not a key"));
553 rval = EPERS_RES_NO_KEY;