Added thread name to dbus mainloop; optimized closing of db
[profile/ivi/persistence-client-library.git] / src / persistence_client_library_db_access.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_db_access.c
13  * @ingroup        Persistence client library
14  * @author         Ingo Huerner
15  * @brief          Implementation of persistence database access
16  *                 Library provides an API to access persistent data
17  * @see            
18  */
19
20 #include "persistence_client_library_db_access.h"
21 #include "persistence_client_library_custom_loader.h"
22 #include "persistence_client_library_dbus_service.h"
23 #include "persistence_client_library_prct_access.h"
24
25 #include <persComErrors.h>
26 #include <persComDataOrg.h>
27 #include <persComDbAccess.h>
28
29 #include <dbus/dbus.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <errno.h>
34
35
36
37 /// btree array
38 static int gHandlesDB[DbTableSize][PersistencePolicy_LastEntry];
39 static int gHandlesDBCreated[DbTableSize][PersistencePolicy_LastEntry] = { {0} };
40
41
42 // function prototype
43 int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, unsigned int reason);
44
45
46 #if 0
47 char* pers_get_raw_key(char *key)
48 {
49    char *temp = NULL;
50    char *rawKey = key;
51
52    temp = strrchr(key, (int)'/');
53    
54    if (NULL != temp)
55    {
56           rawKey = temp + 1;
57    }
58
59    return rawKey;
60 }
61 #endif
62
63 int pers_db_open_default(const char* dbPath, PersDefaultType_e DefaultType)
64 {
65    int ret = 0;
66    char path[DbPathMaxLen] = {0};
67
68    if (PersDefaultType_Configurable == DefaultType)
69    {
70       snprintf(path, DbPathMaxLen, "%s%s", dbPath, gLocalConfigurableDefault);
71    }
72    else if (PersDefaultType_Factory== DefaultType)
73    {
74       snprintf(path, DbPathMaxLen, "%s%s", dbPath, gLocalFactoryDefault);
75    }
76    else
77    {
78       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open_default ==> unknown DefaultType"));
79       ret = EPERS_COMMON;
80    }
81
82    if (EPERS_COMMON != ret)
83    {
84       ret = persComDbOpen(path, 0);
85       if (ret < 0)
86       {
87          ret = EPERS_COMMON;
88          DLT_LOG(gPclDLTContext, DLT_LOG_WARN,
89                               DLT_STRING("pers_db_open_default() -> persComDbOpen() -> problem open db: "), DLT_STRING(path),
90                               DLT_STRING(" Code: "), DLT_INT(ret));
91       }
92    }
93
94    return ret;
95 }
96
97
98 int pers_get_defaults(char* dbPath, char* key, unsigned char* buffer, unsigned int buffer_size, PersGetDefault_e job)
99 {
100    PersDefaultType_e i = PersDefaultType_Configurable;
101    int handleDefaultDB = -1;
102    int read_size = EPERS_NOKEY;
103    char dltMessage[DbPathMaxLen] = {0};
104
105    for(i=0; i<PersDefaultType_LastEntry; i++)
106    {
107       handleDefaultDB = pers_db_open_default(dbPath, i);
108       if(handleDefaultDB >= 0)
109       {
110          if (PersGetDefault_Data == job)
111          {
112                 read_size = persComDbReadKey(handleDefaultDB, key, (char*)buffer, buffer_size);
113          }
114          else if (PersGetDefault_Size == job)
115          {
116             read_size = persComDbGetKeySize(handleDefaultDB, key);
117          }
118          else
119          {
120             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_get_defaults ==> unknown job"));
121             break;
122          }
123
124          if (0 > persComDbClose(handleDefaultDB))
125          {
126             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_get_defaults ==> persComDbClose returned with error"));
127          }
128
129          if(read_size < 0) // check read_size
130          {
131             if(PERS_COM_ERR_NOT_FOUND == read_size)
132             {
133                read_size = EPERS_NOKEY;
134             }
135          }
136          else /* read_size >= 0 --> default value found */
137          {
138             if (PersDefaultType_Configurable == i)
139             {
140                snprintf(dltMessage, DbPathMaxLen, "%s%s", dbPath, gLocalConfigurableDefault);
141             }
142             if (PersDefaultType_Factory == i)
143             {
144                 snprintf(dltMessage, DbPathMaxLen, "%s%s", dbPath, gLocalFactoryDefault);
145             }
146             DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Default data will be used for Key"), DLT_STRING(key),
147                                                   DLT_STRING("from"), DLT_STRING(dltMessage));
148             break;
149          }
150       }
151    }
152
153    if (read_size < 0)
154    {
155        DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Default data not available for Key"), DLT_STRING(key),
156                                              DLT_STRING("Path:"), DLT_STRING(dbPath));
157    }
158
159    return read_size;
160 }
161
162
163 static int database_get(PersistenceInfo_s* info, const char* dbPath)
164 {
165    int arrayIdx = 0;
166    int handleDB = -1;
167
168    // create array index: index is a combination of resource config table type and group
169    arrayIdx = info->configKey.storage + info->context.ldbid ;
170
171    if(arrayIdx < DbTableSize)
172    {
173       if(gHandlesDBCreated[arrayIdx][info->configKey.policy] == 0)
174       {
175          char path[DbPathMaxLen] = {0};
176
177          if(PersistencePolicy_wt == info->configKey.policy)
178          {
179             snprintf(path, DbPathMaxLen, "%s%s", dbPath, gLocalWt);
180          }
181          else if(PersistencePolicy_wc == info->configKey.policy)
182          {
183             snprintf(path, DbPathMaxLen, "%s%s", dbPath, gLocalCached);
184          }
185          else
186          {
187             handleDB = -2;
188          }
189
190          if (handleDB == -1)
191          {
192             handleDB = persComDbOpen(path, 0x01);
193             if(handleDB >= 0)
194             {
195                gHandlesDB[arrayIdx][info->configKey.policy] = handleDB ;
196                gHandlesDBCreated[arrayIdx][info->configKey.policy] = 1;
197             }
198             else
199             {
200                DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_get ==> persComDbOpen() failed"));
201             }
202          }
203          else
204          {
205             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_get ==> wrong policy! Cannot extend dbPath wit database."));
206          }
207       }
208       else
209       {
210          handleDB = gHandlesDB[arrayIdx][info->configKey.policy];
211       }
212    }
213    else
214    {
215       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_get ==> invalid storage type"), DLT_STRING(dbPath));
216    }
217
218
219
220    return handleDB;
221 }
222
223 #if 0
224 void database_close(PersistenceInfo_s* info)
225 {
226    int arrayIdx = info->configKey.storage + info->context.ldbid;
227
228    if(info->configKey.storage <= PersistenceStorage_shared )
229    {
230       int iErrorCode = persComDbClose(gHandlesDB[arrayIdx][info->configKey.policy]) ;
231       if (iErrorCode < 0)
232       {
233          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_close ==> persComDbClose() failed"));
234       }
235       else
236       {
237         gHandlesDBCreated[arrayIdx][info->configKey.policy] = 0;
238       }
239    }
240    else
241    {
242       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_close ==> invalid storage type"), DLT_INT(info->context.ldbid ));
243    }
244 }
245 #endif
246 void database_close_all()
247 {
248    int i = 0, j = 0;
249
250    for(i=0; i<DbTableSize; i++)
251    {
252         for(j=0; j < PersistencePolicy_na; j++)
253         {
254                         if(gHandlesDBCreated[i][j] == 1)
255                         {
256                                 int iErrorCode = persComDbClose(gHandlesDB[i][j]);
257                                 if (iErrorCode < 0)
258                                 {
259                                         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_close_all => failed to close db => persComDbClose"));
260                                 }
261                                 else
262                                 {
263                                          gHandlesDBCreated[i][j] = 0;
264                                 }
265                         }
266         }
267    }
268 }
269
270
271
272 int persistence_get_data(char* dbPath, char* key, const char* resourceID, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
273 {
274    int read_size = -1;
275    int ret_defaults = -1;
276
277    if(   PersistenceStorage_shared == info->configKey.storage
278       || PersistenceStorage_local == info->configKey.storage)
279    {
280       int handleDB = database_get(info, dbPath);
281       if(handleDB >= 0)
282       {
283          read_size = persComDbReadKey(handleDB, key, (char*)buffer, buffer_size);
284          if(read_size < 0)
285          {
286             read_size = pers_get_defaults(dbPath, (char*)resourceID, buffer, buffer_size, PersGetDefault_Data); /* 0 ==> Get data */
287          }
288       }
289    }
290    else if(PersistenceStorage_custom == info->configKey.storage)   // custom storage implementation via custom library
291    {
292       int idx =  custom_client_name_to_id(dbPath, 1);
293       char workaroundPath[128];                                                                 // workaround, because /sys/ can not be accessed on host!!!!
294       snprintf(workaroundPath, 128, "%s%s", "/Data", dbPath  );
295
296       if(idx < PersCustomLib_LastEntry)
297       {
298         int available = 0;
299         if(gPersCustomFuncs[idx].custom_plugin_get_size == NULL )
300                         {
301                                 if(getCustomLoadingType(idx) == LoadType_OnDemand)
302                                 {
303                                         // plugin not loaded, try to load the requested plugin
304                                         if(load_custom_library(idx, &gPersCustomFuncs[idx]) == 1)
305                                         {
306                                                 // check again if the plugin function is now available
307                                                 if(gPersCustomFuncs[idx].custom_plugin_get_data != NULL)
308                                                 {
309                                                         available = 1;
310                                                 }
311                                         }
312                                 }
313                                 else if(getCustomLoadingType(idx) == LoadType_PclInit)
314                                 {
315                                         if(gPersCustomFuncs[idx].custom_plugin_get_data != NULL)
316                                         {
317                                                 available = 1;
318                                         }
319                                 }
320                                 else
321                                 {
322                                          DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Plugin not available (getData), unknown loading type: "),
323                                                                                DLT_INT(getCustomLoadingType(idx)));
324                                          read_size = EPERS_COMMON;
325                                 }
326                         }
327         else
328         {
329                 available = 1;  // already loaded
330         }
331
332         if(available == 1)
333         {
334                                 char pathKeyString[128] = {0};
335                                 if(info->configKey.customID[0] == '\0')   // if we have not a customID we use the key
336                                 {
337                                         snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
338                                 }
339                                 else
340                                 {
341                                         snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
342                                 }
343                                 read_size = gPersCustomFuncs[idx].custom_plugin_get_data(pathKeyString, (char*)buffer, buffer_size);
344         }
345         else
346         {
347                 read_size = EPERS_NOPLUGINFUNCT;
348         }
349       }
350       else
351       {
352          read_size = EPERS_NOPLUGINFUNCT;
353       }
354
355       if (1 > read_size) /* Try to get default values */
356       {
357          info->configKey.policy = PersistencePolicy_wc;                 /* Set the policy */
358          info->configKey.type   = PersistenceResourceType_key;  /* Set the type */
359
360          (void)get_db_path_and_key(info, key, NULL, dbPath);
361
362          DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Plugin data not available. Try to get default data of key:"), DLT_STRING(key));
363          ret_defaults = pers_get_defaults(dbPath, (char*)resourceID, buffer, buffer_size, PersGetDefault_Data);
364          if (0 < ret_defaults)
365          {
366                    read_size = ret_defaults;
367          }
368       }
369    }
370    return read_size;
371 }
372
373
374
375 int persistence_set_data(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
376 {
377    int write_size = -1;
378
379    if(   PersistenceStorage_local == info->configKey.storage
380       || PersistenceStorage_shared == info->configKey.storage )
381    {
382       int handleDB = -1 ;
383
384
385       handleDB = database_get(info, dbPath);
386       if(handleDB >= 0)
387       {
388          write_size = persComDbWriteKey(handleDB, key, (char*)buffer, buffer_size) ;
389          if(write_size < 0)
390          {
391             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_set_data ==> persComDbWriteKey() failure"));
392          }
393          else
394          {
395             if(PersistenceStorage_shared == info->configKey.storage)
396             {
397                int rval = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_changed);
398                if(rval <= 0)
399                {
400                   DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_set_data ==> failed to send notification signal"));
401                   write_size = rval;
402                }
403             }
404          }
405
406       }
407       else
408       {
409          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_set_data ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
410          write_size = EPERS_NOPRCTABLE;
411       }
412    }
413    else if(PersistenceStorage_custom == info->configKey.storage)   // custom storage implementation via custom library
414    {
415         int available = 0;
416       int idx = custom_client_name_to_id(dbPath, 1);
417       if(idx < PersCustomLib_LastEntry )
418       {
419         if(gPersCustomFuncs[idx].custom_plugin_set_data != NULL)
420         {
421
422                                 if (getCustomLoadingType(idx) == LoadType_OnDemand)
423                                 {
424                                         // plugin not loaded, try to load the requested plugin
425                                         if(load_custom_library(idx, &gPersCustomFuncs[idx]) == 1)
426                                         {
427                                                 // check again if the plugin function is now available
428                                                 if(gPersCustomFuncs[idx].custom_plugin_set_data != NULL)
429                                                 {
430                                                         available = 1;
431                                                 }
432                                         }
433                                 }
434                                 else if(getCustomLoadingType(idx) == LoadType_PclInit)
435                                 {
436                                         if(gPersCustomFuncs[idx].custom_plugin_set_data != NULL)
437                                         {
438                                                 available = 1;
439                                         }
440                                 }
441                                 else
442                                 {
443                                          DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Plugin not available (setData), unknown loading type: "),
444                                                                                DLT_INT(getCustomLoadingType(idx)));
445                                          write_size = EPERS_COMMON;
446                                 }
447                         }
448         else
449         {
450                 available = 1;  // already loaded
451         }
452
453         if(available == 1)
454         {
455                                 char pathKeyString[128] = {0};
456                                 if(info->configKey.customID[0] == '\0')   // if we have not a customID we use the key
457                                 {
458                                         snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
459                                 }
460                                 else
461                                 {
462                                         snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
463                                 }
464                                 write_size = gPersCustomFuncs[idx].custom_plugin_set_data(pathKeyString, (char*)buffer, buffer_size);
465                                 //write_size = persComDbWriteKey(handleDB, key, (char*)buffer, buffer_size) ;
466
467                                 if ((0 < write_size) && ((unsigned int)write_size == buffer_size)) /* Check return value and send notification if OK */
468                                 {
469                                         int rval = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_changed);
470                                         if(rval <= 0)
471                                         {
472                                                 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_set_data ==> failed to send notification signal"));
473                                                 write_size = rval;
474                                         }
475                                 }
476         }
477         else
478         {
479                 write_size = EPERS_NOPLUGINFUNCT;
480         }
481       }
482       else
483       {
484          write_size = EPERS_NOPLUGINFUNCT;
485       }
486    }
487    return write_size;
488 }
489
490
491
492 int persistence_get_data_size(char* dbPath, char* key, const char* resourceID, PersistenceInfo_s* info)
493 {
494    int read_size = -1;
495    int ret_defaults = -1;
496
497    if(   PersistenceStorage_shared == info->configKey.storage
498       || PersistenceStorage_local == info->configKey.storage)
499    {
500       int handleDB = database_get(info, dbPath);
501       if(handleDB >= 0)
502       {
503
504          read_size = persComDbGetKeySize(handleDB, key);
505          if(read_size < 0)
506          {
507             read_size = pers_get_defaults( dbPath, (char*)resourceID, NULL, 0, PersGetDefault_Size);
508          }
509       }
510    }
511    else if(PersistenceStorage_custom == info->configKey.storage)   // custom storage implementation via custom library
512    {
513         int available = 0;
514       int idx = custom_client_name_to_id(dbPath, 1);
515       if(idx < PersCustomLib_LastEntry )
516       {
517         if(gPersCustomFuncs[idx].custom_plugin_get_size == NULL )
518         {
519                 if (getCustomLoadingType(idx) == LoadType_OnDemand)
520                 {
521                                         // plugin not loaded, try to load the requested plugin
522                                         if(load_custom_library(idx, &gPersCustomFuncs[idx]) == 1)
523                                         {
524                                                 // check again if the plugin function is now available
525                                                 if(gPersCustomFuncs[idx].custom_plugin_get_size != NULL)
526                                                 {
527                                                         available = 1;
528                                                 }
529                                         }
530                 }
531                 else if(getCustomLoadingType(idx) == LoadType_PclInit)
532                 {
533                                 if(gPersCustomFuncs[idx].custom_plugin_get_size != NULL)
534                                         {
535                                         available = 1;
536                                         }
537                 }
538                                 else
539                                 {
540                                          DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Plugin not available (getDataSize), unknown loading type: "),
541                                                                                DLT_INT(getCustomLoadingType(idx)));
542                                          read_size = EPERS_COMMON;
543                                 }
544         }
545         else
546         {
547                 available = 1;  // already loaded
548         }
549
550         if(available == 1)
551         {
552                 char pathKeyString[128] = {0};
553                                 if(info->configKey.customID[0] == '\0')   // if we have not a customID we use the key
554                                 {
555                                         snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
556                                 }
557                                 else
558                                 {
559                                         snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
560                                 }
561                                 read_size = gPersCustomFuncs[idx].custom_plugin_get_size(pathKeyString);
562         }
563         else
564         {
565                 read_size = EPERS_NOPLUGINFUNCT;
566         }
567       }
568       else
569       {
570          read_size = EPERS_NOPLUGINFUNCT;
571       }
572
573       if (1 > read_size)
574       {
575          info->configKey.policy = PersistencePolicy_wc;                 /* Set the policy */
576          info->configKey.type   = PersistenceResourceType_key;  /* Set the type */
577          (void)get_db_path_and_key(info, key, NULL, dbPath);
578          DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Plugin data not available. Try to get size of default data for key:"),
579                                             DLT_STRING(key));
580          ret_defaults = pers_get_defaults(dbPath, (char*)resourceID, NULL, 0, PersGetDefault_Size);
581          if (0 < ret_defaults)
582          {
583                  read_size = ret_defaults;
584          }
585       }
586    }
587    return read_size;
588 }
589
590
591
592 int persistence_delete_data(char* dbPath, char* key, PersistenceInfo_s* info)
593 {
594    int ret = 0;
595    if(PersistenceStorage_custom != info->configKey.storage)
596    {
597       int handleDB = database_get(info, dbPath);
598       if(handleDB >= 0)
599       {
600          ret = persComDbDeleteKey(handleDB, key) ;
601          if(ret < 0)
602          {
603             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_delete_data => persComDbDeleteKey failed: "), DLT_STRING(key));
604             if(PERS_COM_ERR_NOT_FOUND == ret)
605             {
606                 ret = EPERS_NOKEY ;
607             }
608             else
609             {
610                 ret = EPERS_DB_ERROR_INTERNAL ;
611             }
612          }
613
614          if(PersistenceStorage_shared == info->configKey.storage)
615          {
616             pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_deleted);
617          }
618       }
619       else
620       {
621          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_delete_data ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
622          ret = EPERS_NOPRCTABLE;
623       }
624    }
625    else   // custom storage implementation via custom library
626    {
627         int available = 0;
628       int idx = custom_client_name_to_id(dbPath, 1);
629       if(idx < PersCustomLib_LastEntry)
630       {
631         if(gPersCustomFuncs[idx].custom_plugin_get_size == NULL )
632                         {
633                                 if (getCustomLoadingType(idx) == LoadType_OnDemand)
634                                 {
635                                         // plugin not loaded, try to load the requested plugin
636                                         if(load_custom_library(idx, &gPersCustomFuncs[idx]) == 1)
637                                         {
638                                                 // check again if the plugin function is now available
639                                                 if(gPersCustomFuncs[idx].custom_plugin_delete_data != NULL)
640                                                 {
641                                                         available = 1;
642                                                 }
643                                         }
644                                 }
645                                 else if(getCustomLoadingType(idx) == LoadType_PclInit)
646                                 {
647                                         if(gPersCustomFuncs[idx].custom_plugin_delete_data != NULL)
648                                         {
649                                                 available = 1;
650                                         }
651                                 }
652                                 else
653                                 {
654                                          DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Plugin not available (deleteData), unknown loading type: "),
655                                                                                DLT_INT(getCustomLoadingType(idx)));
656                                          ret = EPERS_COMMON;
657                                 }
658                         }
659         else
660         {
661                 available = 1;  // already loaded
662         }
663
664         if(available == 1)
665         {
666                                 char pathKeyString[128] = {0};
667                                 if(info->configKey.customID[0] == '\0')   // if we have not a customID we use the key
668                                 {
669                                         snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
670                                 }
671                                 else
672                                 {
673                                         snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
674                                 }
675                                 ret = gPersCustomFuncs[idx].custom_plugin_delete_data(pathKeyString);
676
677                                 if(0 <= ret) /* Check return value and send notification if OK */
678                                 {
679                                         pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_deleted);
680                                 }
681         }
682         else
683         {
684                 ret = EPERS_NOPLUGINFUNCT;
685         }
686       }
687       else
688       {
689          ret = EPERS_NOPLUGINFUNCT;
690       }
691    }
692    return ret;
693 }
694
695
696 int persistence_notify_on_change(const char* key, unsigned int ldbid, unsigned int user_no, unsigned int seat_no,
697                                  pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
698 {
699    int rval = 0;
700
701    if(regPolicy < Notify_lastEntry)
702    {
703         MainLoopData_u data;
704
705         data.message.cmd = (uint32_t)CMD_REG_NOTIFY_SIGNAL;
706         data.message.params[0] = ldbid;
707         data.message.params[1] = user_no;
708         data.message.params[2] = seat_no;
709         data.message.params[3] = regPolicy;
710
711         snprintf(data.message.string, DbKeyMaxLen, "%s", key);
712
713       if(regPolicy == Notify_register)
714       {
715          // assign callback
716          gChangeNotifyCallback = callback;
717       }
718       else if(regPolicy == Notify_unregister)
719       {
720          // remove callback
721          gChangeNotifyCallback = NULL;
722       }
723
724       if(-1 == deliverToMainloop(&data))
725       {
726          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_notify_on_change => failed to write to pipe"), DLT_INT(errno));
727          rval = -1;
728       }
729    }
730    else
731    {
732       rval = -1;
733    }
734
735    return rval;
736 }
737
738
739
740
741
742
743 int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, pclNotifyStatus_e reason)
744 {
745    int rval = 1;
746    if(reason < pclNotifyStatus_lastEntry)
747    {
748         MainLoopData_u data;
749
750         data.message.cmd = (uint32_t)CMD_SEND_NOTIFY_SIGNAL;
751         data.message.params[0] = context->ldbid;
752         data.message.params[1] = context->user_no;
753         data.message.params[2] = context->seat_no;
754         data.message.params[3] = reason;
755
756         snprintf(data.message.string, DbKeyMaxLen, "%s", key);
757
758       if(-1 == deliverToMainloop(&data) )
759       {
760          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_send_Notification_Signal => failed to write to pipe"), DLT_INT(errno));
761          rval = EPERS_NOTIFY_SIG;
762       }
763    }
764    else
765    {
766       rval = EPERS_NOTIFY_SIG;
767    }
768
769    return rval;
770 }
771
772
773 void pers_rct_close_all()
774 {
775    int i = 0;
776
777    // close all open persistence resource configuration tables
778    for(i=0; i< PrctDbTableSize; i++)
779    {
780         if(get_resource_cfg_table_by_idx(i) != -1)
781         {
782                         if(persComRctClose(get_resource_cfg_table_by_idx(i)) != 0)
783                         {
784                                 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("process_prepare_shutdown => failed to close db => index:"), DLT_INT(i));
785                         }
786
787                         invalidate_resource_cfg_table(i);
788         }
789    }
790 }
791