Removed findings after code review; removed memset for arrays, let the compiler do...
[profile/ivi/persistence-client-library.git] / src / persistence_client_library_key.c
1 /******************************************************************************
2  * Project         Persistency
3  * (c) copyright   2012
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 ******************************************************************************/
11  /**
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
17  * @see            
18  */
19
20 #include "persistence_client_library_key.h"
21
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"
25
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"
30
31
32 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
34 // function with handle
35 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
37
38 int pclKeyHandleOpen(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
39 {
40    int handle = EPERS_NOT_INITIALIZED;
41
42    if(gPclInitialized >= PCLinitialized)
43    {
44       PersistenceInfo_s dbContext;
45
46       char dbKey[DbKeyMaxLen]   = {0};      // database key
47       char dbPath[DbPathMaxLen] = {0};    // database location
48
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;
53
54       // get database context: database path and database key
55       handle = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
56       if(   (handle >= 0)
57          && (dbContext.configKey.type == PersistenceResourceType_key) )          // check if type matches
58       {
59          if(dbContext.configKey.storage < PersistenceStorage_LastEntry)    // check if store policy is valid
60          {
61             if(PersistenceStorage_custom ==  dbContext.configKey.storage)
62             {
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  );
66
67                if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_open != NULL) )
68                {
69                   int flag = 0, mode = 0;
70                   handle = gPersCustomFuncs[idx].custom_plugin_handle_open(workaroundPath, flag, mode);
71                }
72                else
73                {
74                   handle = EPERS_NOPLUGINFUNCT;
75                }
76             }
77             else
78             {
79                handle = get_persistence_handle_idx();
80             }
81
82             if((handle < MaxPersHandle) && (0 <= handle))
83             {
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;
91             }
92             else
93             {
94                DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - handleId out of bounds:"), DLT_INT(handle));
95             }
96          }
97       }
98       else
99       {
100          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - no database context or resource is not a key "));
101       }
102    }
103
104
105    return handle;
106 }
107
108
109
110 int pclKeyHandleClose(int key_handle)
111 {
112    int rval = EPERS_NOT_INITIALIZED;
113
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) );
116
117    if(gPclInitialized >= PCLinitialized)
118    {
119       if(key_handle < MaxPersHandle)
120       {
121          if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage )
122          {
123             int idx =  custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
124
125             if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_close != NULL) )
126             {
127                rval = gPersCustomFuncs[idx].custom_plugin_handle_close(key_handle);
128             }
129             else
130             {
131                rval = EPERS_NOPLUGINFUNCT;
132             }
133          }
134          else
135          {
136             set_persistence_handle_close_idx(key_handle);
137          }
138
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;
143          rval = 1;
144       }
145       else
146       {
147          rval = EPERS_MAXHANDLE;
148       }
149    }
150
151    return rval;
152 }
153
154
155
156 int pclKeyHandleGetSize(int key_handle)
157 {
158    int size = EPERS_NOT_INITIALIZED;
159
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) );
162
163    if(gPclInitialized >= PCLinitialized)
164    {
165       if(key_handle < MaxPersHandle)
166       {
167          if(PersistenceStorage_custom ==  gKeyHandleArray[key_handle].info.configKey.storage)
168          {
169             int idx =  custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
170
171             if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_size != NULL) )
172             {
173                size = gPersCustomFuncs[idx].custom_plugin_get_size(gKeyHandleArray[key_handle].dbPath);
174             }
175             else
176             {
177                size = EPERS_NOPLUGINFUNCT;
178             }
179          }
180          else
181          {
182             size = pers_db_get_key_size(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
183                                              &gKeyHandleArray[key_handle].info);
184          }
185       }
186    }
187
188    return size;
189 }
190
191
192
193 int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size)
194 {
195    int size = EPERS_NOT_INITIALIZED;
196
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) );
199
200    if(gPclInitialized >= PCLinitialized)
201    {
202       if(key_handle < MaxPersHandle)
203       {
204          if(PersistenceStorage_custom ==  gKeyHandleArray[key_handle].info.configKey.storage)
205          {
206             int idx =  custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
207
208             if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_get_data != NULL) )
209             {
210                size = gPersCustomFuncs[idx].custom_plugin_handle_get_data(key_handle, (char*)buffer, buffer_size-1);
211             }
212             else
213             {
214                size = EPERS_NOPLUGINFUNCT;
215             }
216          }
217          else
218          {
219             size = pers_db_read_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
220                                         &gKeyHandleArray[key_handle].info, buffer, buffer_size);
221          }
222       }
223    }
224
225    return size;
226 }
227
228
229
230 int pclKeyHandleRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
231 {
232    int rval = EPERS_NOT_INITIALIZED;
233
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) );
236
237    if(gPclInitialized >= PCLinitialized)
238    {
239       if(key_handle < MaxPersHandle)
240       {
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);
245       }
246    }
247
248    return rval;
249 }
250
251
252
253 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
254 {
255    int size = EPERS_NOT_INITIALIZED;
256
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) );
259
260    if(gPclInitialized >= PCLinitialized)
261    {
262       if(AccessNoLock != isAccessLocked() )     // check if access to persistent data is locked
263       {
264          if(buffer_size <= gMaxKeyValDataSize)  // check data size
265          {
266             if(key_handle < MaxPersHandle)
267             {
268                if(PersistenceStorage_custom ==  gKeyHandleArray[key_handle].info.configKey.storage)
269                {
270                   int idx =  custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
271
272                   if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
273                   {
274                      size = gPersCustomFuncs[idx].custom_plugin_handle_set_data(key_handle, (char*)buffer, buffer_size-1);
275                   }
276                   else
277                   {
278                      size = EPERS_NOPLUGINFUNCT;
279                   }
280                }
281                else
282                {
283                   size = pers_db_write_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
284                                            &gKeyHandleArray[key_handle].info, buffer, buffer_size);
285                }
286             }
287             else
288             {
289                size = EPERS_MAXHANDLE;
290             }
291          }
292          else
293          {
294             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
295          }
296       }
297       else
298       {
299          size = EPERS_LOCKFS;
300       }
301    }
302
303    return size;
304 }
305
306
307
308
309
310 // ----------------------------------------------------------------------------
311 // ----------------------------------------------------------------------------
312 // functions to be used directly without a handle
313 // ----------------------------------------------------------------------------
314 // ----------------------------------------------------------------------------
315
316 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
317 {
318    int rval = EPERS_NOT_INITIALIZED;
319
320    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyDelete: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
321
322    if(gPclInitialized >= PCLinitialized)
323    {
324       if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
325       {
326          PersistenceInfo_s dbContext;
327
328         char dbKey[DbKeyMaxLen]   = {0};      // database key
329         char dbPath[DbPathMaxLen] = {0};    // database location
330
331         dbContext.context.ldbid   = ldbid;
332         dbContext.context.seat_no = seat_no;
333         dbContext.context.user_no = user_no;
334
335         // get database context: database path and database key
336         rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
337         if(   (rval >= 0)
338            && (dbContext.configKey.type == PersistenceResourceType_key) )  // check if type is matching
339         {
340            if(   dbContext.configKey.storage < PersistenceStorage_LastEntry
341               && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
342            {
343               rval = pers_db_delete_key(dbPath, dbKey, &dbContext);
344            }
345            else
346            {
347              rval = EPERS_BADPOL;
348            }
349         }
350       }
351       else
352       {
353          rval = EPERS_LOCKFS;
354       }
355    }
356
357    return rval;
358 }
359
360
361
362 // status: OK
363 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
364 {
365    int data_size = EPERS_NOT_INITIALIZED;
366
367    if(gPclInitialized >= PCLinitialized)
368    {
369       PersistenceInfo_s dbContext;
370
371       char dbKey[DbKeyMaxLen]   = {0};      // database key
372       char dbPath[DbPathMaxLen] = {0};    // database location
373
374       dbContext.context.ldbid   = ldbid;
375       dbContext.context.seat_no = seat_no;
376       dbContext.context.user_no = user_no;
377
378       //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyGetSize: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
379
380       // get database context: database path and database key
381       data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
382       if(   (data_size >= 0)
383          && (dbContext.configKey.type == PersistenceResourceType_key) )    // check if type matches
384       {
385          if(   dbContext.configKey.storage < PersistenceStorage_LastEntry
386             && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
387          {
388             data_size = pers_db_get_key_size(dbPath, dbKey, &dbContext);
389          }
390          else
391          {
392            data_size = EPERS_BADPOL;
393          }
394       }
395       else
396       {
397         data_size = EPERS_BADPOL;
398       }
399    }
400
401    return data_size;
402 }
403
404
405
406 // status: OK
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)
409 {
410    int data_size = EPERS_NOT_INITIALIZED;
411
412    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyReadData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
413
414    if(gPclInitialized >= PCLinitialized)
415    {
416       if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
417       {
418          PersistenceInfo_s dbContext;
419
420          char dbKey[DbKeyMaxLen]   = {0};      // database key
421          char dbPath[DbPathMaxLen] = {0};    // database location
422
423          dbContext.context.ldbid   = ldbid;
424          dbContext.context.seat_no = seat_no;
425          dbContext.context.user_no = user_no;
426
427          // get database context: database path and database key
428          data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
429          if(   (data_size >= 0)
430             && (dbContext.configKey.type == PersistenceResourceType_key) )
431          {
432
433             if(   dbContext.configKey.storage <  PersistenceStorage_LastEntry
434                && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
435             {
436                   data_size = pers_db_read_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
437             }
438             else
439             {
440                data_size = EPERS_BADPOL;
441             }
442          }
443          else
444          {
445             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
446          }
447       }
448       else
449       {
450          data_size = EPERS_LOCKFS;
451       }
452    }
453
454    return data_size;
455 }
456
457
458
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)
461 {
462    int data_size = EPERS_NOT_INITIALIZED;
463
464    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyWriteData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
465
466    if(gPclInitialized >= PCLinitialized)
467    {
468       if(AccessNoLock != isAccessLocked() )     // check if access to persistent data is locked
469       {
470          if(buffer_size <= gMaxKeyValDataSize)  // check data size
471          {
472             PersistenceInfo_s dbContext;
473
474             unsigned int hash_val_data = 0;
475
476             char dbKey[DbKeyMaxLen]   = {0};      // database key
477             char dbPath[DbPathMaxLen] = {0};    // database location
478
479             dbContext.context.ldbid   = ldbid;
480             dbContext.context.seat_no = seat_no;
481             dbContext.context.user_no = user_no;
482
483             // get database context: database path and database key
484             data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
485             if(   (data_size >= 0)
486                && (dbContext.configKey.type == PersistenceResourceType_key))
487             {
488                // get hash value of data to verify storing
489                hash_val_data = crc32(hash_val_data, buffer, buffer_size);
490
491                // store data
492                if(   dbContext.configKey.storage <  PersistenceStorage_LastEntry
493                   && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
494                {
495                   data_size = pers_db_write_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
496                }
497                else
498                {
499                   data_size = EPERS_BADPOL;
500                }
501             }
502             else
503             {
504                DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
505             }
506          }
507          else
508          {
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));
511          }
512       }
513       else
514       {
515          data_size = EPERS_LOCKFS;
516       }
517    }
518
519    return data_size;
520 }
521
522
523 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
524 {
525    int rval = EPERS_NOT_INITIALIZED;
526
527    if(gPclInitialized >= PCLinitialized)
528    {
529       PersistenceInfo_s dbContext;
530
531       //   unsigned int hash_val_data = 0;
532       char dbKey[DbKeyMaxLen]   = {0};      // database key
533       char dbPath[DbPathMaxLen] = {0};    // database location
534
535       //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
536
537       dbContext.context.ldbid   = ldbid;
538       dbContext.context.seat_no = seat_no;
539       dbContext.context.user_no = user_no;
540
541       // get database context: database path and database key
542       rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
543
544       // registration is only on shared key possible
545       if(   (dbContext.configKey.storage == PersistenceStorage_shared)
546          && (dbContext.configKey.type    == PersistenceResourceType_key) )
547       {
548          rval = persistence_reg_notify_on_change(dbPath, dbKey, ldbid, user_no, seat_no, callback);
549       }
550       else
551       {
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;
554       }
555    }
556
557    return rval;
558 }
559
560
561
562
563
564
565
566