41fe58e0a723173a943d99cf460aff7f330437b2
[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 #include "persistence_client_library_handle.h"
22 #include "persistence_client_library_pas_interface.h"
23 #include "persistence_client_library_custom_loader.h"
24 #include "persistence_client_library_prct_access.h"
25 #include "persistence_client_library_db_access.h"
26 #include "crc32.h"
27
28 #include <persComRct.h>
29
30
31
32 // function declaration
33 int handleRegNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy);
34 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
35                       pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy);
36
37 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
39 // function with handle
40 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
42
43 int pclKeyHandleOpen(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
44 {
45    int rval   = 0;
46    int handle = EPERS_NOT_INITIALIZED;
47
48    if(gPclInitialized >= PCLinitialized)
49    {
50       PersistenceInfo_s dbContext;
51
52       char dbKey[DbKeyMaxLen]   = {0};      // database key
53       char dbPath[DbPathMaxLen] = {0};    // database location
54
55       dbContext.context.ldbid   = ldbid;
56       dbContext.context.seat_no = seat_no;
57       dbContext.context.user_no = user_no;
58
59       // get database context: database path and database key
60       rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
61       if((rval >= 0) && (dbContext.configKey.type == PersistenceResourceType_key))          // check if type matches
62       {
63          if(dbContext.configKey.storage < PersistenceStorage_LastEntry)    // check if store policy is valid
64          {
65             // generate handle for custom and for normal key
66             handle = get_persistence_handle_idx();
67
68             if((handle < MaxPersHandle) && (0 < handle))
69             {
70                // remember data in handle array
71                strncpy(gKeyHandleArray[handle].resource_id, resource_id, DbResIDMaxLen);
72                gKeyHandleArray[handle].resource_id[DbResIDMaxLen-1] = '\0'; /* Ensures 0-Termination */
73                gKeyHandleArray[handle].ldbid   = ldbid;
74                gKeyHandleArray[handle].user_no = user_no;
75                gKeyHandleArray[handle].seat_no = seat_no;
76             }
77             else
78             {
79                DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - handleId out of bounds:"), DLT_INT(handle));
80             }
81          }
82          else
83          {
84             handle = EPERS_BADPOL;
85          }
86       }
87       else
88       {
89          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleOpen: error - no database context or resource is not a key "));
90       }
91    }
92
93    return handle;
94 }
95
96
97
98 int pclKeyHandleClose(int key_handle)
99 {
100    int rval = EPERS_NOT_INITIALIZED;
101
102    if(gPclInitialized >= PCLinitialized)
103    {
104       if((key_handle < MaxPersHandle) && (key_handle > 0))
105       {
106          if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
107          {
108             /* Invalidate key handle data */
109                    set_persistence_handle_close_idx(key_handle);
110             memset(&gKeyHandleArray[key_handle], 0, sizeof(gKeyHandleArray[key_handle]));
111             rval = 1;
112          }
113          else
114          {
115             rval = EPERS_INVALID_HANDLE;
116          }
117       }
118       else
119       {
120          rval = EPERS_MAXHANDLE;
121       }
122    }
123
124    return rval;
125 }
126
127
128
129 int pclKeyHandleGetSize(int key_handle)
130 {
131    int size = EPERS_NOT_INITIALIZED;
132
133    if(gPclInitialized >= PCLinitialized)
134    {
135       if((key_handle < MaxPersHandle) && (key_handle > 0))
136       {
137          if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
138          {
139                  size = pclKeyGetSize(gKeyHandleArray[key_handle].ldbid,
140                                gKeyHandleArray[key_handle].resource_id,
141                                gKeyHandleArray[key_handle].user_no,
142                                gKeyHandleArray[key_handle].seat_no);
143          }
144          else
145          {
146                  size = EPERS_INVALID_HANDLE;
147          }
148       }
149       else
150       {
151          size = EPERS_MAXHANDLE;
152       }
153    }
154
155    return size;
156 }
157
158
159
160 int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size)
161 {
162    int size = EPERS_NOT_INITIALIZED;
163
164    if(gPclInitialized >= PCLinitialized)
165    {
166       if((key_handle < MaxPersHandle) && (key_handle > 0))
167       {
168          if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
169          {
170                  size = pclKeyReadData(gKeyHandleArray[key_handle].ldbid,
171                                    gKeyHandleArray[key_handle].resource_id,
172                                    gKeyHandleArray[key_handle].user_no,
173                                    gKeyHandleArray[key_handle].seat_no,
174                                    buffer,
175                                    buffer_size);
176          }
177          else
178          {
179                  size = EPERS_INVALID_HANDLE;
180          }
181       }
182       else
183       {
184          size = EPERS_MAXHANDLE;
185       }
186    }
187
188    return size;
189 }
190
191
192
193 int pclKeyHandleRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
194 {
195    int rval = EPERS_COMMON;
196    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: "),
197    //            DLT_INT(gKeyHandleArray[key_handle].info.context.ldbid), DLT_STRING(gKeyHandleArray[key_handle].resourceID) );
198    if((gChangeNotifyCallback == callback) || (gChangeNotifyCallback == NULL))
199    {
200       rval = handleRegNotifyOnChange(key_handle, callback, Notify_register);
201    }
202    else
203    {
204       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyHandleRegisterNotifyOnChange: Only one callback is allowed for change notifications."));
205       rval = EPERS_NOTIFY_NOT_ALLOWED;
206    }
207    return rval;
208 }
209
210 int pclKeyHandleUnRegisterNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback)
211 {
212    return handleRegNotifyOnChange(key_handle, callback, Notify_unregister);
213 }
214
215
216
217 int handleRegNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
218 {
219    int rval = EPERS_NOT_INITIALIZED;
220
221    if(gPclInitialized >= PCLinitialized)
222    {
223       if((key_handle < MaxPersHandle) && (key_handle > 0))
224       {
225          if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
226          {
227             rval = regNotifyOnChange(gKeyHandleArray[key_handle].ldbid,
228                                      gKeyHandleArray[key_handle].resource_id,
229                                      gKeyHandleArray[key_handle].user_no,
230                                      gKeyHandleArray[key_handle].seat_no,
231                                      callback,
232                                      regPolicy);
233           }
234           else
235           {
236                  rval = EPERS_INVALID_HANDLE;
237           }
238       }
239       else
240       {
241          rval = EPERS_MAXHANDLE;
242       }
243    }
244    return rval;
245 }
246
247
248
249 int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size)
250 {
251    int size = EPERS_NOT_INITIALIZED;
252
253    if(gPclInitialized >= PCLinitialized)
254    {
255       if((key_handle < MaxPersHandle) && (key_handle > 0))
256       {
257          if ('\0' != gKeyHandleArray[key_handle].resource_id[0])
258          {
259                  size = pclKeyWriteData(gKeyHandleArray[key_handle].ldbid,
260                                     gKeyHandleArray[key_handle].resource_id,
261                                     gKeyHandleArray[key_handle].user_no,
262                                     gKeyHandleArray[key_handle].seat_no,
263                                     buffer,
264                                     buffer_size);
265          }
266          else
267          {
268                  size = EPERS_INVALID_HANDLE;
269          }
270       }
271       else
272       {
273          size = EPERS_MAXHANDLE;
274       }
275    }
276
277    return size;
278 }
279
280
281
282
283
284 // ----------------------------------------------------------------------------
285 // ----------------------------------------------------------------------------
286 // functions to be used directly without a handle
287 // ----------------------------------------------------------------------------
288 // ----------------------------------------------------------------------------
289
290 int pclKeyDelete(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
291 {
292    int rval = EPERS_NOT_INITIALIZED;
293
294    if(gPclInitialized >= PCLinitialized)
295    {
296       if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
297       {
298          PersistenceInfo_s dbContext;
299
300         char dbKey[DbKeyMaxLen]   = {0};      // database key
301         char dbPath[DbPathMaxLen] = {0};    // database location
302
303         dbContext.context.ldbid   = ldbid;
304         dbContext.context.seat_no = seat_no;
305         dbContext.context.user_no = user_no;
306
307         // get database context: database path and database key
308         rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
309         if(   (rval >= 0)
310            && (dbContext.configKey.type == PersistenceResourceType_key) )  // check if type is matching
311         {
312            if(   dbContext.configKey.storage < PersistenceStorage_LastEntry)   // check if store policy is valid
313            {
314                    rval = persistence_delete_data(dbPath, dbKey, &dbContext);
315            }
316            else
317            {
318              rval = EPERS_BADPOL;
319            }
320         }
321       }
322       else
323       {
324          rval = EPERS_LOCKFS;
325       }
326    }
327
328    return rval;
329 }
330
331
332
333 // status: OK
334 int pclKeyGetSize(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no)
335 {
336    int data_size = EPERS_NOT_INITIALIZED;
337
338    if(gPclInitialized >= PCLinitialized)
339    {
340       PersistenceInfo_s dbContext;
341
342       char dbKey[DbKeyMaxLen]   = {0};      // database key
343       char dbPath[DbPathMaxLen] = {0};    // database location
344
345       dbContext.context.ldbid   = ldbid;
346       dbContext.context.seat_no = seat_no;
347       dbContext.context.user_no = user_no;
348
349       // get database context: database path and database key
350       data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
351       if(   (data_size >= 0)
352          && (dbContext.configKey.type == PersistenceResourceType_key) )    // check if type matches
353       {
354          if(   dbContext.configKey.storage < PersistenceStorage_LastEntry)   // check if store policy is valid
355          {
356             data_size = persistence_get_data_size(dbPath, dbKey, &dbContext);
357          }
358          else
359          {
360            data_size = EPERS_BADPOL;
361          }
362       }
363       else
364       {
365         data_size = EPERS_BADPOL;
366       }
367    }
368
369    return data_size;
370 }
371
372
373
374 // status: OK
375 int pclKeyReadData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
376                   unsigned char* buffer, int buffer_size)
377 {
378    int data_size = EPERS_NOT_INITIALIZED;
379
380    if(gPclInitialized >= PCLinitialized)
381    {
382       if(AccessNoLock != isAccessLocked() ) // check if access to persistent data is locked
383       {
384          PersistenceInfo_s dbContext;
385
386          char dbKey[DbKeyMaxLen]   = {0};      // database key
387          char dbPath[DbPathMaxLen] = {0};    // database location
388
389          dbContext.context.ldbid   = ldbid;
390          dbContext.context.seat_no = seat_no;
391          dbContext.context.user_no = user_no;
392
393          // get database context: database path and database key
394          data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
395          if(   (data_size >= 0)
396             && (dbContext.configKey.type == PersistenceResourceType_key) )
397          {
398
399             if(   dbContext.configKey.storage < PersistenceStorage_LastEntry)   // check if store policy is valid
400             {
401                   data_size = persistence_get_data(dbPath, dbKey, resource_id, &dbContext, buffer, buffer_size);
402             }
403             else
404             {
405                data_size = EPERS_BADPOL;
406             }
407          }
408          else
409          {
410             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyReadData - error - no database context or resource is not a key"));
411          }
412       }
413       else
414       {
415          data_size = EPERS_LOCKFS;
416       }
417    }
418
419    return data_size;
420 }
421
422
423
424 int pclKeyWriteData(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no,
425                    unsigned char* buffer, int buffer_size)
426 {
427    int data_size = EPERS_NOT_INITIALIZED;
428
429    if(gPclInitialized >= PCLinitialized)
430    {
431       if(AccessNoLock != isAccessLocked() )     // check if access to persistent data is locked
432       {
433          if(buffer_size <= gMaxKeyValDataSize)  // check data size
434          {
435             PersistenceInfo_s dbContext;
436
437             unsigned int hash_val_data = 0;
438
439             char dbKey[DbKeyMaxLen]   = {0};      // database key
440             char dbPath[DbPathMaxLen] = {0};    // database location
441
442             dbContext.context.ldbid   = ldbid;
443             dbContext.context.seat_no = seat_no;
444             dbContext.context.user_no = user_no;
445
446             // get database context: database path and database key
447             data_size = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
448             if(   (data_size >= 0)
449                && (dbContext.configKey.type == PersistenceResourceType_key))
450             {
451                if(dbContext.configKey.permission != PersistencePermission_ReadOnly)  // don't write to a read only resource
452                {
453                   // get hash value of data to verify storing
454                   hash_val_data = pclCrc32(hash_val_data, buffer, buffer_size);
455
456                   // store data
457                   if(   dbContext.configKey.storage < PersistenceStorage_LastEntry)   // check if store policy is valid
458                   {
459                      data_size = persistence_set_data(dbPath, dbKey, &dbContext, buffer, buffer_size);
460                   }
461                   else
462                   {
463                      data_size = EPERS_BADPOL;
464                   }
465                }
466                else
467                {
468                   data_size = EPERS_RESOURCE_READ_ONLY;
469                }
470             }
471             else
472             {
473                DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData - error - no database context or resource is not a key"));
474             }
475          }
476          else
477          {
478             data_size = EPERS_BUFLIMIT;
479             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyWriteData: error - buffer_size to big, limit is [bytes]:"), DLT_INT(gMaxKeyValDataSize));
480          }
481       }
482       else
483       {
484          data_size = EPERS_LOCKFS;
485       }
486    }
487    return data_size;
488 }
489
490
491
492 int pclKeyUnRegisterNotifyOnChange( unsigned int  ldbid, const char *  resource_id, unsigned int  user_no, unsigned int  seat_no, pclChangeNotifyCallback_t  callback)
493 {
494    return regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_unregister);
495 }
496
497
498 int pclKeyRegisterNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback)
499 {
500    int rval = EPERS_COMMON;
501    //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclKeyRegisterNotifyOnChange: "),
502    //            DLT_INT(ldbid), DLT_STRING(resource_id) );
503    if((gChangeNotifyCallback == callback) || (gChangeNotifyCallback == NULL))
504    {
505       rval = regNotifyOnChange(ldbid, resource_id, user_no, seat_no, callback, Notify_register);
506    }
507    else
508    {
509       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclKeyRegisterNotifyOnChange: Only one callback is allowed for change notifications."));
510       rval = EPERS_NOTIFY_NOT_ALLOWED;
511    }
512    return rval;
513 }
514
515
516
517
518 int regNotifyOnChange(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no, pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
519 {
520    int rval = EPERS_NOT_INITIALIZED;
521
522    if(gPclInitialized >= PCLinitialized)
523    {
524       PersistenceInfo_s dbContext;
525
526       //   unsigned int hash_val_data = 0;
527       char dbKey[DbKeyMaxLen]   = {0};      // database key
528       char dbPath[DbPathMaxLen] = {0};    // database location
529
530       dbContext.context.ldbid   = ldbid;
531       dbContext.context.seat_no = seat_no;
532       dbContext.context.user_no = user_no;
533
534       // get database context: database path and database key
535       rval = get_db_context(&dbContext, resource_id, ResIsNoFile, dbKey, dbPath);
536
537       if (rval==0)  // no error, key found
538           { 
539          // registration is only on shared and custom keys possible
540          if(   (dbContext.configKey.storage != PersistenceStorage_local)
541             && (dbContext.configKey.type    == PersistenceResourceType_key) )
542          {
543             rval = persistence_notify_on_change(resource_id, ldbid, user_no, seat_no, callback, regPolicy);
544          }
545          else
546          {
547             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR,
548                                      DLT_STRING("regNotifyOnChange: Not allowed! Resource is local or it is a file:"),
549                                      DLT_STRING(resource_id),
550                                  DLT_STRING("LDBID:"),
551                                  DLT_UINT(ldbid));
552             rval = EPERS_NOTIFY_NOT_ALLOWED;
553          }
554       }
555       else
556       {
557          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR,
558                               DLT_STRING("regNotifyOnChange: Not possible! get_db_context() returned:"),
559                               DLT_INT(rval));
560       }
561    }
562
563    return rval;
564 }
565
566
567
568
569
570
571