3c70f02df52d995fb58a847c8508fcf15bad3761
[profile/ivi/persistence-client-library.git] / src / persistence_client_library.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.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
21 #include "persistence_client_library_lc_interface.h"
22 #include "persistence_client_library_pas_interface.h"
23 #include "persistence_client_library_dbus_service.h"
24 #include "persistence_client_library_handle.h"
25 #include "persistence_client_library_custom_loader.h"
26 #include "persistence_client_library.h"
27 #include "persistence_client_library_backup_filelist.h"
28
29 #include <string.h>
30 #include <errno.h>
31 #include <stdlib.h>
32 #include <dlfcn.h>
33
34 #include <dlt/dlt.h>
35 #include <dlt/dlt_common.h>
36
37 #include <dbus/dbus.h>
38
39 /// debug log and trace (DLT) setup
40 DLT_DECLARE_CONTEXT(gDLTContext);
41
42 // declared in persistence_client_library_dbus_service.c
43 // used to end dbus library
44 extern int bContinue;
45
46 static int gShutdownMode = 0;
47
48 /// loical function declaration
49 void invalidateCustomPlugin(int idx);
50
51
52 int pclInitLibrary(const char* appName, int shutdownMode)
53 {
54    int status = 0;
55    int i = 0, rval = 1;
56
57    if(gPclInitialized == PCLnotInitialized)
58    {
59       gShutdownMode = shutdownMode;
60
61       DLT_REGISTER_CONTEXT(gDLTContext,"pers","Context for persistence client library logging");
62       DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T  Persistence Client Library - "), DLT_STRING(gAppId),
63                            DLT_STRING("- init counter: "), DLT_INT(gPclInitialized) );
64
65       /// environment variable for on demand loading of custom libraries
66       const char *pOnDemandLoad = getenv("PERS_CUSTOM_LIB_LOAD_ON_DEMAND");
67       /// environment variable for max key value data
68       const char *pDataSize = getenv("PERS_MAX_KEY_VAL_DATA_SIZE");
69       /// blacklist path environment variable
70       const char *pBlacklistPath = getenv("PERS_BLACKLIST_PATH");
71
72       pthread_mutex_lock(&gDbusPendingRegMtx);   // block until pending received
73
74       if(pDataSize != NULL)
75       {
76          gMaxKeyValDataSize = atoi(pDataSize);
77       }
78
79       if(pBlacklistPath == NULL)
80       {
81          pBlacklistPath = "/etc/pclBackupBlacklist.txt";   // default path
82       }
83
84       if(readBlacklistConfigFile(pBlacklistPath) == -1)
85       {
86          DLT_LOG(gDLTContext, DLT_LOG_WARN, DLT_STRING("pclInitLibrary -> failed to access blacklist:"), DLT_STRING(pBlacklistPath));
87       }
88
89       if(setup_dbus_mainloop() == -1)
90       {
91          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to setup main loop"));
92          pthread_mutex_unlock(&gDbusPendingRegMtx);
93          return EPERS_DBUS_MAINLOOP;
94       }
95
96       if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE)
97       {
98          // register for lifecycle and persistence admin service dbus messages
99          if(register_lifecycle(shutdownMode) == -1)
100          {
101             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to lifecycle dbus interface"));
102             pthread_mutex_unlock(&gDbusPendingRegMtx);
103             return EPERS_REGISTER_LIFECYCLE;
104          }
105       }
106
107       if(register_pers_admin_service() == -1)
108       {
109          DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to pers admin dbus interface"));
110          pthread_mutex_unlock(&gDbusPendingRegMtx);
111          return EPERS_REGISTER_ADMIN;
112       }
113
114       /// get custom library names to load
115       status = get_custom_libraries();
116       if(status >= 0)
117       {
118          // initialize custom library structure
119          for(i = 0; i < PersCustomLib_LastEntry; i++)
120          {
121             invalidateCustomPlugin(i);
122          }
123
124          if(pOnDemandLoad == NULL)  // load all available libraries now
125          {
126             for(i=0; i < PersCustomLib_LastEntry; i++ )
127             {
128                if(check_valid_idx(i) != -1)
129                {
130                   if(load_custom_library(i, &gPersCustomFuncs[i] ) == 1)
131                   {
132                      if( (gPersCustomFuncs[i].custom_plugin_init) != NULL)
133                      {
134                         DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => Loaded plugin: "),
135                                                            DLT_STRING(get_custom_client_lib_name(i)));
136                         gPersCustomFuncs[i].custom_plugin_init();
137                      }
138                      else
139                      {
140                         DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => E r r o r could not load plugin functions: "),
141                                                             DLT_STRING(get_custom_client_lib_name(i)));
142                      }
143                   }
144                   else
145                   {
146                      DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => E r r o r could not load plugin: "),
147                                           DLT_STRING(get_custom_client_lib_name(i)));
148                   }
149                }
150                else
151                {
152                   continue;
153                }
154             }
155          }
156       }
157       else
158       {
159          DLT_LOG(gDLTContext, DLT_LOG_WARN, DLT_STRING("pclInit => Failed to load custom library config table => error number:"), DLT_INT(status));
160       }
161
162       // assign application name
163       strncpy(gAppId, appName, MaxAppNameLen);
164       gAppId[MaxAppNameLen-1] = '\0';
165
166       // destory mutex
167       pthread_mutex_destroy(&gDbusInitializedMtx);
168       pthread_cond_destroy(&gDbusInitializedCond);
169
170       gPclInitialized++;
171    }
172    else if(gPclInitialized >= PCLinitialized)
173    {
174       gPclInitialized++; // increment init counter
175       DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T  Persistence Client Library - "), DLT_STRING(gAppId),
176                            DLT_STRING("- ONLY INCREMENT init counter: "), DLT_INT(gPclInitialized) );
177    }
178
179    return rval;
180 }
181
182
183
184 int pclDeinitLibrary(void)
185 {
186    int i = 0, rval = 1;
187
188    if(gPclInitialized == PCLinitialized)
189    {
190       DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T  client library - "), DLT_STRING(gAppId),
191                                          DLT_STRING("- init counter: "), DLT_INT(gPclInitialized));
192
193       // unregister for lifecycle and persistence admin service dbus messages
194       if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE)
195          rval = unregister_lifecycle(gShutdownMode);
196
197       rval = unregister_pers_admin_service();
198
199       // unload custom client libraries
200       for(i=0; i<PersCustomLib_LastEntry; i++)
201       {
202          if(gPersCustomFuncs[i].custom_plugin_deinit != NULL)
203          {
204             // deinitialize plugin
205             gPersCustomFuncs[i].custom_plugin_deinit();
206             // close library handle
207             dlclose(gPersCustomFuncs[i].handle);
208
209             invalidateCustomPlugin(i);
210          }
211       }
212
213       gPclInitialized = PCLnotInitialized;
214
215       DLT_UNREGISTER_CONTEXT(gDLTContext);
216    }
217    else if(gPclInitialized > PCLinitialized)
218    {
219       DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T  client library - "), DLT_STRING(gAppId),
220                                            DLT_STRING("- ONLY DECREMENT init counter: "), DLT_INT(gPclInitialized));
221       gPclInitialized--;   // decrement init counter
222    }
223
224    // end dbus library
225    bContinue = FALSE;
226
227    pthread_mutex_destroy(&gDbusPendingRegMtx);
228    return rval;
229 }
230
231
232
233 void invalidateCustomPlugin(int idx)
234 {
235    gPersCustomFuncs[idx].handle  = NULL;
236    gPersCustomFuncs[idx].custom_plugin_init = NULL;
237    gPersCustomFuncs[idx].custom_plugin_deinit = NULL;
238    gPersCustomFuncs[idx].custom_plugin_handle_open = NULL;
239    gPersCustomFuncs[idx].custom_plugin_handle_close = NULL;
240    gPersCustomFuncs[idx].custom_plugin_handle_get_data = NULL;
241    gPersCustomFuncs[idx].custom_plugin_handle_set_data  = NULL;
242    gPersCustomFuncs[idx].custom_plugin_get_data = NULL;
243    gPersCustomFuncs[idx].custom_plugin_set_data = NULL;
244    gPersCustomFuncs[idx].custom_plugin_delete_data = NULL;
245    gPersCustomFuncs[idx].custom_plugin_get_status_notification_clbk = NULL;
246    gPersCustomFuncs[idx].custom_plugin_handle_get_size = NULL;
247    gPersCustomFuncs[idx].custom_plugin_get_size = NULL;
248    gPersCustomFuncs[idx].custom_plugin_create_backup = NULL;
249    gPersCustomFuncs[idx].custom_plugin_get_backup = NULL;
250    gPersCustomFuncs[idx].custom_plugin_restore_backup = NULL;
251 }
252
253
254
255
256