4986bef12be07c4058c4ff4316b96127362f6f9d
[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 = 1;
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          memset(gKeyHandleArray[key_handle].dbPath, 0, DbPathMaxLen);
141          memset(gKeyHandleArray[key_handle].dbKey  ,0, DbKeyMaxLen);
142          gKeyHandleArray[key_handle].info.configKey.storage = -1;
143       }
144       else
145       {
146          rval = EPERS_MAXHANDLE;
147       }
148    }
149    else
150    {
151       rval = EPERS_NOT_INITIALIZED;
152    }
153
154    return rval;
155 }
156
157
158
159 int pclKeyHandleGetSize(int key_handle)
160 {
161    int size = EPERS_NOT_INITIALIZED;
162
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) );
165
166    if(gPclInitialized >= PCLinitialized)
167    {
168       if(key_handle < MaxPersHandle)
169       {
170          if(PersistenceStorage_custom ==  gKeyHandleArray[key_handle].info.configKey.storage)
171          {
172             int idx =  custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
173
174             if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_size != NULL) )
175             {
176                size = gPersCustomFuncs[idx].custom_plugin_get_size(gKeyHandleArray[key_handle].dbPath);
177             }
178             else
179             {
180                size = EPERS_NOPLUGINFUNCT;
181             }
182          }
183          else
184          {
185             size = pers_db_get_key_size(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
186                                              &gKeyHandleArray[key_handle].info);
187          }
188       }
189       else
190       {
191          size = EPERS_MAXHANDLE;
192       }
193    }
194
195    return size;
196 }
197
198
199
200 int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size)
201 {
202    int size = EPERS_NOT_INITIALIZED;
203
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) );
206
207    if(gPclInitialized >= PCLinitialized)
208    {
209       if(key_handle < MaxPersHandle)
210       {
211          if(PersistenceStorage_custom ==  gKeyHandleArray[key_handle].info.configKey.storage)
212          {
213             int idx =  custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
214
215             if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_get_data != NULL) )
216             {
217                size = gPersCustomFuncs[idx].custom_plugin_handle_get_data(key_handle, (char*)buffer, buffer_size-1);
218             }
219             else
220             {
221                size = EPERS_NOPLUGINFUNCT;
222             }
223          }
224          else
225          {
226             size = pers_db_read_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
227                                         &gKeyHandleArray[key_handle].info, buffer, buffer_size);
228          }
229       }
230       else
231       {
232          size = EPERS_MAXHANDLE;
233       }
234    }
235
236    return size;
237 }
238
239
240
241 int pclKeyHandleRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
242 {
243    DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: "),
244                DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
245
246    return handleRegNotifyOnChange(key_handle, callback, Notify_register);
247 }
248
249 int pclKeyHandleUnRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
250 {
251    DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleUnRegisterNotifyOnChange: "),
252             DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
253
254    return handleRegNotifyOnChange(key_handle, callback, Notify_unregister);
255 }
256
257
258
259 int handleRegNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
260 {
261    int rval = EPERS_NOT_INITIALIZED;
262
263    if(gPclInitialized >= PCLinitialized)
264    {
265       if(key_handle < MaxPersHandle)
266       {
267          rval = regNotifyOnChange(gKeyHandleArray[key_handle].info.context.ldbid,
268                                   gKeyHandleArray[key_handle].resourceID,
269                                   gKeyHandleArray[key_handle].info.context.user_no,
270                                   gKeyHandleArray[key_handle].info.context.seat_no,
271                                   callback,
272                                   regPolicy);
273       }
274       else
275       {
276          rval = EPERS_MAXHANDLE;
277       }
278    }
279    return rval;
280 }
281
282
283
284 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
285 {
286    int size = EPERS_NOT_INITIALIZED;
287
288    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleWriteData: "),
289    //                DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
290
291    if(gPclInitialized >= PCLinitialized)
292    {
293       if(AccessNoLock != isAccessLocked() )     // check if access to persistent data is locked
294       {
295          if(buffer_size <= gMaxKeyValDataSize)  // check data size
296          {
297             if(key_handle < MaxPersHandle)
298             {
299                if(PersistenceStorage_custom ==  gKeyHandleArray[key_handle].info.configKey.storage)
300                {
301                   int idx =  custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
302
303                   if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
304                   {
305                      size = gPersCustomFuncs[idx].custom_plugin_handle_set_data(key_handle, (char*)buffer, buffer_size-1);
306                   }
307                   else
308                   {
309                      size = EPERS_NOPLUGINFUNCT;
310                   }
311                }
312                else
313                {
314                   size = pers_db_write_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
315                                            &gKeyHandleArray[key_handle].info, buffer, buffer_size);
316                }
317             }
318             else
319             {
320                size = EPERS_MAXHANDLE;
321             }
322          }
323          else
324          {
325             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
326             size = EPERS_MAX_BUFF_SIZE;
327          }
328       }
329       else
330       {
331          size = EPERS_LOCKFS;
332       }
333    }
334
335    return size;
336 }
337
338
339
340
341
342 // ----------------------------------------------------------------------------
343 // ----------------------------------------------------------------------------
344 // functions to be used directly without a handle
345 // ----------------------------------------------------------------------------
346 // ----------------------------------------------------------------------------
347
348 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
349 {
350    int rval = EPERS_NOT_INITIALIZED;
351
352    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyDelete: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
353
354    if(gPclInitialized >= PCLinitialized)
355    {
356       if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
357       {
358          PersistenceInfo_s dbContext;
359
360         char dbKey[DbKeyMaxLen]   = {0};      // database key
361         char dbPath[DbPathMaxLen] = {0};    // database location
362
363         dbContext.context.ldbid   = ldbid;
364         dbContext.context.seat_no = seat_no;
365         dbContext.context.user_no = user_no;
366
367         // get database context: database path and database key
368         rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
369         if(   (rval >= 0)
370            && (dbContext.configKey.type == PersistenceResourceType_key) )  // check if type is matching
371         {
372            if(   dbContext.configKey.storage < PersistenceStorage_LastEntry
373               && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
374            {
375               rval = pers_db_delete_key(dbPath, dbKey, &dbContext);
376            }
377            else
378            {
379              rval = EPERS_BADPOL;
380            }
381         }
382       }
383       else
384       {
385          rval = EPERS_LOCKFS;
386       }
387    }
388
389    return rval;
390 }
391
392
393
394 // status: OK
395 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
396 {
397    int data_size = EPERS_NOT_INITIALIZED;
398
399    if(gPclInitialized >= PCLinitialized)
400    {
401       PersistenceInfo_s dbContext;
402
403       char dbKey[DbKeyMaxLen]   = {0};      // database key
404       char dbPath[DbPathMaxLen] = {0};    // database location
405
406       dbContext.context.ldbid   = ldbid;
407       dbContext.context.seat_no = seat_no;
408       dbContext.context.user_no = user_no;
409
410       //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyGetSize: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
411
412       // get database context: database path and database key
413       data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
414       if(   (data_size >= 0)
415          && (dbContext.configKey.type == PersistenceResourceType_key) )    // check if type matches
416       {
417          if(   dbContext.configKey.storage < PersistenceStorage_LastEntry
418             && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
419          {
420             data_size = pers_db_get_key_size(dbPath, dbKey, &dbContext);
421          }
422          else
423          {
424            data_size = EPERS_BADPOL;
425          }
426       }
427       else
428       {
429         data_size = EPERS_BADPOL;
430       }
431    }
432
433    return data_size;
434 }
435
436
437
438 // status: OK
439 int pclKeyReadData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
440                   unsigned char* buffer, int buffer_size)
441 {
442    int data_size = EPERS_NOT_INITIALIZED;
443
444    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyReadData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
445
446    if(gPclInitialized >= PCLinitialized)
447    {
448       if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
449       {
450          PersistenceInfo_s dbContext;
451
452          char dbKey[DbKeyMaxLen]   = {0};      // database key
453          char dbPath[DbPathMaxLen] = {0};    // database location
454
455          dbContext.context.ldbid   = ldbid;
456          dbContext.context.seat_no = seat_no;
457          dbContext.context.user_no = user_no;
458
459          // get database context: database path and database key
460          data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
461          if(   (data_size >= 0)
462             && (dbContext.configKey.type == PersistenceResourceType_key) )
463          {
464
465             if(   dbContext.configKey.storage <  PersistenceStorage_LastEntry
466                && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
467             {
468                   data_size = pers_db_read_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
469             }
470             else
471             {
472                data_size = EPERS_BADPOL;
473             }
474          }
475          else
476          {
477             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
478          }
479       }
480       else
481       {
482          data_size = EPERS_LOCKFS;
483       }
484    }
485
486    return data_size;
487 }
488
489
490
491 int pclKeyWriteData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
492                    unsigned char* buffer, int buffer_size)
493 {
494    int data_size = EPERS_NOT_INITIALIZED;
495
496    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyWriteData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
497
498    if(gPclInitialized >= PCLinitialized)
499    {
500       if(AccessNoLock != isAccessLocked() )     // check if access to persistent data is locked
501       {
502          if(buffer_size <= gMaxKeyValDataSize)  // check data size
503          {
504             PersistenceInfo_s dbContext;
505
506             unsigned int hash_val_data = 0;
507
508             char dbKey[DbKeyMaxLen]   = {0};      // database key
509             char dbPath[DbPathMaxLen] = {0};    // database location
510
511             dbContext.context.ldbid   = ldbid;
512             dbContext.context.seat_no = seat_no;
513             dbContext.context.user_no = user_no;
514
515             // get database context: database path and database key
516             data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
517             if(   (data_size >= 0)
518                && (dbContext.configKey.type == PersistenceResourceType_key))
519             {
520                // get hash value of data to verify storing
521                hash_val_data = crc32(hash_val_data, buffer, buffer_size);
522
523                // store data
524                if(   dbContext.configKey.storage <  PersistenceStorage_LastEntry
525                   && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
526                {
527                   data_size = pers_db_write_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
528                }
529                else
530                {
531                   data_size = EPERS_BADPOL;
532                }
533             }
534             else
535             {
536                DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
537             }
538          }
539          else
540          {
541             data_size = EPERS_BUFLIMIT;
542             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
543          }
544       }
545       else
546       {
547          data_size = EPERS_LOCKFS;
548       }
549    }
550
551    return data_size;
552 }
553
554
555
556 int pclKeyUnRegisterNotifyOnChange( unsigned int  ldbid, const char *  resource_id, unsigned int  user_no, unsigned int  seat_no, pclChangeNotifyCallback_t  callback)
557 {
558    DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyUnRegisterNotifyOnChange: "),
559                DLT_INT(ldbid), DLT_STRING(resource_id) );
560
561    return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_unregister);
562 }
563
564
565 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
566 {
567    DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "),
568                DLT_INT(ldbid), DLT_STRING(resource_id) );
569    return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_register);
570 }
571
572
573
574
575 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
576 {
577    int rval = EPERS_NOT_INITIALIZED;
578
579    if(gPclInitialized >= PCLinitialized)
580    {
581       PersistenceInfo_s dbContext;
582
583       //   unsigned int hash_val_data = 0;
584       char dbKey[DbKeyMaxLen]   = {0};      // database key
585       char dbPath[DbPathMaxLen] = {0};    // database location
586
587       //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
588
589       dbContext.context.ldbid   = ldbid;
590       dbContext.context.seat_no = seat_no;
591       dbContext.context.user_no = user_no;
592
593       // get database context: database path and database key
594       rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
595
596       // registration is only on shared key possible
597       if(   (dbContext.configKey.storage == PersistenceStorage_shared)
598         && (dbContext.configKey.type    == PersistenceResourceType_key) )
599       {
600          rval = persistence_notify_on_change(dbPath, dbKey, ldbid, user_no, seat_no, callback, regPolicy);
601       }
602       else
603       {
604          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyRegisterNotifyOnChange: error - resource is not a shared resource or resource is not a key"));
605          rval = EPERS_RES_NO_KEY;
606       }
607    }
608
609    return rval;
610 }
611
612
613
614
615
616
617