0616acef134a1c82dfc9f469f5852ea27d7eebbb
[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    int rval = EPERS_NOT_INITIALIZED;
244
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) );
247
248    if(gPclInitialized >= PCLinitialized)
249    {
250       if(key_handle < MaxPersHandle)
251       {
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,
256                                   callback,
257                                   Notify_register);
258       }
259       else
260       {
261          rval = EPERS_MAXHANDLE;
262       }
263    }
264    return rval;
265 }
266
267 int pclKeyHandleUnRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
268 {
269    int rval = EPERS_NOT_INITIALIZED;
270
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) );
273
274    if(gPclInitialized >= PCLinitialized)
275    {
276       if(key_handle < MaxPersHandle)
277       {
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,
282                                   callback,
283                                   Notify_unregister);
284       }
285       else
286       {
287          rval = EPERS_MAXHANDLE;
288       }
289    }
290    return rval;
291 }
292
293
294 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
295 {
296    int size = EPERS_NOT_INITIALIZED;
297
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) );
300
301    if(gPclInitialized >= PCLinitialized)
302    {
303       if(AccessNoLock != isAccessLocked() )     // check if access to persistent data is locked
304       {
305          if(buffer_size <= gMaxKeyValDataSize)  // check data size
306          {
307             if(key_handle < MaxPersHandle)
308             {
309                if(PersistenceStorage_custom ==  gKeyHandleArray[key_handle].info.configKey.storage)
310                {
311                   int idx =  custom_client_name_to_id(gKeyHandleArray[key_handle].dbPath, 1);
312
313                   if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
314                   {
315                      size = gPersCustomFuncs[idx].custom_plugin_handle_set_data(key_handle, (char*)buffer, buffer_size-1);
316                   }
317                   else
318                   {
319                      size = EPERS_NOPLUGINFUNCT;
320                   }
321                }
322                else
323                {
324                   size = pers_db_write_key(gKeyHandleArray[key_handle].dbPath, gKeyHandleArray[key_handle].dbKey,
325                                            &gKeyHandleArray[key_handle].info, buffer, buffer_size);
326                }
327             }
328             else
329             {
330                size = EPERS_MAXHANDLE;
331             }
332          }
333          else
334          {
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;
337          }
338       }
339       else
340       {
341          size = EPERS_LOCKFS;
342       }
343    }
344
345    return size;
346 }
347
348
349
350
351
352 // ----------------------------------------------------------------------------
353 // ----------------------------------------------------------------------------
354 // functions to be used directly without a handle
355 // ----------------------------------------------------------------------------
356 // ----------------------------------------------------------------------------
357
358 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
359 {
360    int rval = EPERS_NOT_INITIALIZED;
361
362    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyDelete: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
363
364    if(gPclInitialized >= PCLinitialized)
365    {
366       if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
367       {
368          PersistenceInfo_s dbContext;
369
370         char dbKey[DbKeyMaxLen]   = {0};      // database key
371         char dbPath[DbPathMaxLen] = {0};    // database location
372
373         dbContext.context.ldbid   = ldbid;
374         dbContext.context.seat_no = seat_no;
375         dbContext.context.user_no = user_no;
376
377         // get database context: database path and database key
378         rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
379         if(   (rval >= 0)
380            && (dbContext.configKey.type == PersistenceResourceType_key) )  // check if type is matching
381         {
382            if(   dbContext.configKey.storage < PersistenceStorage_LastEntry
383               && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
384            {
385               rval = pers_db_delete_key(dbPath, dbKey, &dbContext);
386            }
387            else
388            {
389              rval = EPERS_BADPOL;
390            }
391         }
392       }
393       else
394       {
395          rval = EPERS_LOCKFS;
396       }
397    }
398
399    return rval;
400 }
401
402
403
404 // status: OK
405 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
406 {
407    int data_size = EPERS_NOT_INITIALIZED;
408
409    if(gPclInitialized >= PCLinitialized)
410    {
411       PersistenceInfo_s dbContext;
412
413       char dbKey[DbKeyMaxLen]   = {0};      // database key
414       char dbPath[DbPathMaxLen] = {0};    // database location
415
416       dbContext.context.ldbid   = ldbid;
417       dbContext.context.seat_no = seat_no;
418       dbContext.context.user_no = user_no;
419
420       //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyGetSize: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
421
422       // get database context: database path and database key
423       data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
424       if(   (data_size >= 0)
425          && (dbContext.configKey.type == PersistenceResourceType_key) )    // check if type matches
426       {
427          if(   dbContext.configKey.storage < PersistenceStorage_LastEntry
428             && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
429          {
430             data_size = pers_db_get_key_size(dbPath, dbKey, &dbContext);
431          }
432          else
433          {
434            data_size = EPERS_BADPOL;
435          }
436       }
437       else
438       {
439         data_size = EPERS_BADPOL;
440       }
441    }
442
443    return data_size;
444 }
445
446
447
448 // status: OK
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)
451 {
452    int data_size = EPERS_NOT_INITIALIZED;
453
454    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyReadData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
455
456    if(gPclInitialized >= PCLinitialized)
457    {
458       if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
459       {
460          PersistenceInfo_s dbContext;
461
462          char dbKey[DbKeyMaxLen]   = {0};      // database key
463          char dbPath[DbPathMaxLen] = {0};    // database location
464
465          dbContext.context.ldbid   = ldbid;
466          dbContext.context.seat_no = seat_no;
467          dbContext.context.user_no = user_no;
468
469          // get database context: database path and database key
470          data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
471          if(   (data_size >= 0)
472             && (dbContext.configKey.type == PersistenceResourceType_key) )
473          {
474
475             if(   dbContext.configKey.storage <  PersistenceStorage_LastEntry
476                && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
477             {
478                   data_size = pers_db_read_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
479             }
480             else
481             {
482                data_size = EPERS_BADPOL;
483             }
484          }
485          else
486          {
487             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
488          }
489       }
490       else
491       {
492          data_size = EPERS_LOCKFS;
493       }
494    }
495
496    return data_size;
497 }
498
499
500
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)
503 {
504    int data_size = EPERS_NOT_INITIALIZED;
505
506    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyWriteData: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
507
508    if(gPclInitialized >= PCLinitialized)
509    {
510       if(AccessNoLock != isAccessLocked() )     // check if access to persistent data is locked
511       {
512          if(buffer_size <= gMaxKeyValDataSize)  // check data size
513          {
514             PersistenceInfo_s dbContext;
515
516             unsigned int hash_val_data = 0;
517
518             char dbKey[DbKeyMaxLen]   = {0};      // database key
519             char dbPath[DbPathMaxLen] = {0};    // database location
520
521             dbContext.context.ldbid   = ldbid;
522             dbContext.context.seat_no = seat_no;
523             dbContext.context.user_no = user_no;
524
525             // get database context: database path and database key
526             data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
527             if(   (data_size >= 0)
528                && (dbContext.configKey.type == PersistenceResourceType_key))
529             {
530                // get hash value of data to verify storing
531                hash_val_data = crc32(hash_val_data, buffer, buffer_size);
532
533                // store data
534                if(   dbContext.configKey.storage <  PersistenceStorage_LastEntry
535                   && dbContext.configKey.storage >= PersistenceStorage_local)   // check if store policy is valid
536                {
537                   data_size = pers_db_write_key(dbPath, dbKey, &dbContext, buffer, buffer_size);
538                }
539                else
540                {
541                   data_size = EPERS_BADPOL;
542                }
543             }
544             else
545             {
546                DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
547             }
548          }
549          else
550          {
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));
553          }
554       }
555       else
556       {
557          data_size = EPERS_LOCKFS;
558       }
559    }
560
561    return data_size;
562 }
563
564
565
566 int pclKeyUnRegisterNotifyOnChange( unsigned int  ldbid, const char *  resource_id, unsigned int  user_no, unsigned int  seat_no, pclChangeNotifyCallback_t  callback)
567 {
568    return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_unregister);
569 }
570
571
572 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
573 {
574
575    return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_register);
576 }
577
578
579
580
581 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback, PersistenceNotifyRegPolicy_e regPolicy)
582 {
583    int rval = EPERS_NOT_INITIALIZED;
584
585    if(gPclInitialized >= PCLinitialized)
586    {
587       PersistenceInfo_s dbContext;
588
589       //   unsigned int hash_val_data = 0;
590       char dbKey[DbKeyMaxLen]   = {0};      // database key
591       char dbPath[DbPathMaxLen] = {0};    // database location
592
593       //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "), DLT_INT(ldbid), DLT_STRING(resource_id) );
594
595       dbContext.context.ldbid   = ldbid;
596       dbContext.context.seat_no = seat_no;
597       dbContext.context.user_no = user_no;
598
599       // get database context: database path and database key
600       rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
601
602       // registration is only on shared key possible
603       if(   (dbContext.configKey.storage == PersistenceStorage_shared)
604         && (dbContext.configKey.type    == PersistenceResourceType_key) )
605       {
606          rval = persistence_notify_on_change(dbPath, dbKey, ldbid, user_no, seat_no, callback, regPolicy);
607       }
608       else
609       {
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;
612       }
613    }
614
615    return rval;
616 }
617
618
619
620
621
622
623