d0dc4aebbd7609b632c43fc0ee91401cc6da9e07
[profile/ivi/persistence-client-library.git] / src / persistence_client_library_custom_loader.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_custom_loader.c
13  * @ingroup        Persistence client library
14  * @author         Ingo Huerner
15  * @brief          Implementation of persistence custom loadedr
16  * @see
17  */
18
19 #include "persistence_client_library_custom_loader.h"
20 #include "persistence_client_library_data_organization.h"
21
22 #include <stdio.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <sys/mman.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <dlfcn.h>
31
32
33 /// type definition of persistence custom library information
34 typedef struct sPersCustomLibInfo
35 {
36    char libname[CustLibMaxLen];
37    int valid;
38 } PersCustomLibInfo;
39
40
41 /// array with custom client library names
42 static PersCustomLibInfo gCustomLibArray[PersCustomLib_LastEntry];
43
44
45 PersistenceCustomLibs_e custom_client_name_to_id(const char* lib_name, int substring)
46 {
47    PersistenceCustomLibs_e libId = PersCustomLib_LastEntry;
48
49    if(substring == 0)
50    {
51       if(0 == strncmp(lib_name, "early", PersCustomPathSize) )
52       {
53          libId = PersCustomLib_early;
54       }
55       else if (0 == strncmp(lib_name, "secure", PersCustomPathSize) )
56       {
57          libId = PersCustomLib_secure;
58       }
59       else if (0 == strncmp(lib_name, "emergency", PersCustomPathSize) )
60       {
61          libId = PersCustomLib_emergency;
62       }
63       else if (0 == strncmp(lib_name, "hwinfo", PersCustomPathSize) )
64       {
65          libId = PersCustomLib_HWinfo;
66       }
67       else if (0 == strncmp(lib_name, "custom1", PersCustomPathSize) )
68       {
69          libId = PersCustomLib_Custom1;
70       }
71       else if (0 == strncmp(lib_name, "custom2", PersCustomPathSize) )
72       {
73          libId = PersCustomLib_Custom2;
74       }
75       else if (0 == strncmp(lib_name, "custom3", PersCustomPathSize) )
76       {
77          libId = PersCustomLib_Custom3;
78       }
79       else
80       {
81          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("custom_libname_to_id - error - id not found for lib:"), DLT_STRING(lib_name));
82       }
83    }
84    else
85    {
86       if(NULL != strstr(lib_name, "early") )
87       {
88          libId = PersCustomLib_early;
89       }
90       else if (NULL != strstr(lib_name, "secure") )
91       {
92          libId = PersCustomLib_secure;
93       }
94       else if (NULL != strstr(lib_name, "emergency") )
95       {
96          libId = PersCustomLib_emergency;
97       }
98       else if (NULL != strstr(lib_name, "hwinfo") )
99       {
100          libId = PersCustomLib_HWinfo;
101       }
102       else if (NULL != strstr(lib_name, "custom1") )
103       {
104          libId = PersCustomLib_Custom1;
105       }
106       else if (NULL != strstr(lib_name, "custom2") )
107       {
108          libId = PersCustomLib_Custom2;
109       }
110       else if (NULL != strstr(lib_name, "custom3") )
111       {
112          libId = PersCustomLib_Custom3;
113       }
114       else
115       {
116          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("custom_libname_to_id - error - id not found for lib:"), DLT_STRING(lib_name));
117       }
118
119    }
120    return libId;
121 }
122
123
124
125 int get_custom_libraries()
126 {
127    int rval = 0, fd = 0, j = 0;
128
129    struct stat buffer;
130    char* delimiters = " \n";   // search for blank and end of line
131    char* configFileMap = 0;
132    char* token = 0;
133    const char *filename = getenv("PERS_CLIENT_LIB_CUSTOM_LOAD");
134
135    if(filename == NULL)
136    {
137       filename = "/etc/pclCustomLibConfigFile.cfg";  // use default filename
138    }
139
140    for(j=0; j<PersCustomLib_LastEntry; j++)
141    {
142       // init pos to -1
143       gCustomLibArray[j].valid = -1;
144    }
145
146
147    if(stat(filename, &buffer) != -1)
148    {
149       if(buffer.st_size > 20)  // file needs to be at least bigger then 20 bytes
150       {
151          fd = open(filename, O_RDONLY);
152          if (fd != -1)
153          {
154             configFileMap = (char*)mmap(0, buffer.st_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
155
156             if(configFileMap != MAP_FAILED)
157             {
158                int libId = 0;
159
160                // get the library identifier (early, secure, emergency, ...)
161                token = strtok(configFileMap, delimiters);
162                libId = custom_client_name_to_id(token, 0);
163
164
165                if(libId < PersCustomLib_LastEntry)
166                {
167                   gCustomLibArray[libId].valid = 1;
168                }
169                else
170                {
171                   munmap(configFileMap, buffer.st_size); // @CB: Add
172                   close(fd); // @CB: Add // close file descriptor before return
173                    return EPERS_OUTOFBOUNDS; // out of array bounds
174                }
175
176                // get the library name
177                token  = strtok (NULL, delimiters);
178                strncpy(gCustomLibArray[libId].libname, token, CustLibMaxLen);
179                gCustomLibArray[libId].libname[CustLibMaxLen-1] = '\0'; // Ensures 0-Termination
180
181                while( token != NULL )
182                {
183                   // get the library identifier (early, secure, emergency, ...)
184                   token = strtok(NULL, delimiters);
185                   if(token != NULL)
186                   {
187                      libId = custom_client_name_to_id(token, 0);
188                      if(libId < PersCustomLib_LastEntry)
189                      {
190                         gCustomLibArray[libId].valid = 1;
191                      }
192                      else
193                      {
194                         rval = EPERS_OUTOFBOUNDS;
195                         break;
196                      }
197                   }
198                   else
199                   {
200                      break;
201                   }
202
203                   // get the library name
204                   token  = strtok (NULL, delimiters);
205                   if(token != NULL)
206                   {
207                      strncpy(gCustomLibArray[libId].libname, token, CustLibMaxLen);
208                      gCustomLibArray[libId].libname[CustLibMaxLen-1] = '\0'; // Ensures 0-Termination
209                   }
210                   else
211                   {
212                      break;
213                   }
214                }
215
216                munmap(configFileMap, buffer.st_size);
217
218                #if 0 // debuging
219                for(j=0; j<PersCustomLib_LastEntry; j++)
220                {
221                   printf("Custom libraries => Name: %s | valid: %d \n", gCustomLibArray[j].libname, gCustomLibArray[j].valid);
222                }
223                #endif
224             }
225             else
226             {
227                rval = EPERS_CONFIGMAPFAILED;
228                DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load config file error - mapping of file failed"));
229             }
230             close(fd);
231          }
232          else
233          {
234             rval = EPERS_CONFIGNOTAVAILABLE;
235             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load config file error - no file with plugins available:"), DLT_STRING(filename), DLT_STRING(strerror(errno)));
236          }
237       }
238       else
239       {
240          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load config file error - invalid file size"), DLT_STRING(filename), DLT_STRING(strerror(errno)));
241       }
242    }
243    else
244    {
245       rval = EPERS_CONFIGNOSTAT;
246       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("lload config file error - can't stat config file:"), DLT_STRING(filename), DLT_STRING(strerror(errno)));
247    }
248    return rval;
249 }
250
251
252
253 int load_custom_library(PersistenceCustomLibs_e customLib, Pers_custom_functs_s *customFuncts)
254 {
255    int rval = 1;
256    char *error = NULL;
257
258    if(customLib < PersCustomLib_LastEntry)
259    {
260       void* handle = dlopen(gCustomLibArray[customLib].libname, RTLD_LAZY);
261       customFuncts->handle = handle;
262
263       if(handle != NULL)
264       {
265          dlerror();    // reset error
266
267          // plugin_close
268          *(void **) (&customFuncts->custom_plugin_handle_close) = dlsym(handle, "plugin_handle_close");
269          if ((error = dlerror()) != NULL)
270          {
271               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
272          }
273          // custom_plugin_delete_data
274          *(void **) (&customFuncts->custom_plugin_delete_data) = dlsym(handle, "plugin_delete_data");
275          if ((error = dlerror()) != NULL)
276          {
277               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
278           }
279          // custom_plugin_get_data
280          *(void **) (&customFuncts->custom_plugin_handle_get_data) = dlsym(handle, "plugin_handle_get_data");
281          if ((error = dlerror()) != NULL)
282          {
283               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
284           }
285          // custom_plugin_get_data
286          *(void **) (&customFuncts->custom_plugin_get_data) = dlsym(handle, "plugin_get_data");
287          if ((error = dlerror()) != NULL)
288          {
289               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
290           }
291          // custom_plugin_init
292          *(void **) (&customFuncts->custom_plugin_init) = dlsym(handle, "plugin_init");
293          if ((error = dlerror()) != NULL)
294          {
295               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
296           }
297          // custom_plugin_deinit
298          *(void **) (&customFuncts->custom_plugin_deinit) = dlsym(handle, "plugin_deinit");
299          if ((error = dlerror()) != NULL)
300          {
301               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
302           }
303          // custom_plugin_open
304          *(void **) (&customFuncts->custom_plugin_handle_open) = dlsym(handle, "plugin_handle_open");
305          if ((error = dlerror()) != NULL)
306          {
307               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
308           }
309          // custom_plugin_set_data
310          *(void **) (&customFuncts->custom_plugin_handle_set_data) = dlsym(handle, "plugin_handle_set_data");
311          if ((error = dlerror()) != NULL)
312          {
313               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
314           }
315          // custom_plugin_set_data
316          *(void **) (&customFuncts->custom_plugin_set_data) = dlsym(handle, "plugin_set_data");
317          if ((error = dlerror()) != NULL)
318          {
319               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
320          }
321          // custom_plugin_get_size_handle
322          *(void **) (&customFuncts->custom_plugin_handle_get_size) = dlsym(handle, "plugin_handle_get_size");
323          if ((error = dlerror()) != NULL)
324          {
325             DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
326          }
327          // custom_plugin_get_size
328          *(void **) (&customFuncts->custom_plugin_get_size) = dlsym(handle, "plugin_get_size");
329          if ((error = dlerror()) != NULL)
330          {
331             DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
332          }
333           // create backup
334          *(void **) (&customFuncts->custom_plugin_create_backup) = dlsym(handle, "plugin_create_backup");
335          if ((error = dlerror()) != NULL)
336          {
337             DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
338          }
339          // restore backup
340          *(void **) (&customFuncts->custom_plugin_restore_backup) = dlsym(handle, "plugin_restore_backup");
341          if ((error = dlerror()) != NULL)
342          {
343              DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
344          }
345          // restore backup
346          *(void **) (&customFuncts->custom_plugin_get_backup) = dlsym(handle, "plugin_get_backup");
347          if ((error = dlerror()) != NULL)
348          {
349              DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
350          }
351
352          // custom_plugin_get_status_notification_clbk
353          *(void **) (&customFuncts->custom_plugin_get_status_notification_clbk) = dlsym(handle, "plugin_get_status_notification_clbk");
354          if ((error = dlerror()) != NULL)
355          {
356               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
357           }
358
359          // initialize plugin (non blocking)
360          *(void **) (&customFuncts->custom_plugin_init_async) = dlsym(handle, "plugin_init_async");
361          if ((error = dlerror()) != NULL)
362          {
363               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
364          }
365
366          // clear all data
367          *(void **) (&customFuncts->custom_plugin_clear_all_data) = dlsym(handle, "plugin_clear_all_data");
368          if ((error = dlerror()) != NULL)
369          {
370               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
371          }
372
373          // sync data
374          *(void **) (&customFuncts->custom_plugin_sync) = dlsym(handle, "plugin_sync");
375          if ((error = dlerror()) != NULL)
376          {
377               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
378          }
379       }
380       else
381       {
382          error = dlerror();
383          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
384          rval = EPERS_DLOPENERROR;
385       }
386    }
387    else
388    {
389       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load_custom_library - error: - customLib out of bounds"));
390       rval = EPERS_DLOPENERROR;
391    }
392
393    return rval;
394 }
395
396
397
398 int load_all_custom_libraries()
399 {
400    int rval = 0,
401           i = 0;
402
403    for(i=0; i<PersCustomLib_LastEntry; i++)
404    {
405       rval = load_custom_library(i, &gPersCustomFuncs[i]);
406       if( rval < 0)
407       {
408          break;
409       }
410    }
411    return rval;
412 }
413
414
415 char* get_custom_client_lib_name(int idx)
416 {
417    if(idx < PersCustomLib_LastEntry)
418    {
419       return gCustomLibArray[idx].libname;
420    }
421    else
422    {
423       return NULL;
424    }
425 }
426
427 //int get_custom_client_position_in_array(int customLibId)
428 int check_valid_idx(int idx)
429 {
430    int rval = -1;
431
432    if(idx < PersCustomLib_LastEntry)
433    {
434       rval = gCustomLibArray[idx].valid;
435    }
436
437    return rval;
438 }
439
440
441
442 void invalidate_custom_plugin(int idx)
443 {
444    gPersCustomFuncs[idx].handle  = NULL;
445    gPersCustomFuncs[idx].custom_plugin_init = NULL;
446    gPersCustomFuncs[idx].custom_plugin_deinit = NULL;
447    gPersCustomFuncs[idx].custom_plugin_handle_open = NULL;
448    gPersCustomFuncs[idx].custom_plugin_handle_close = NULL;
449    gPersCustomFuncs[idx].custom_plugin_handle_get_data = NULL;
450    gPersCustomFuncs[idx].custom_plugin_handle_set_data  = NULL;
451    gPersCustomFuncs[idx].custom_plugin_get_data = NULL;
452    gPersCustomFuncs[idx].custom_plugin_set_data = NULL;
453    gPersCustomFuncs[idx].custom_plugin_delete_data = NULL;
454    gPersCustomFuncs[idx].custom_plugin_get_status_notification_clbk = NULL;
455    gPersCustomFuncs[idx].custom_plugin_handle_get_size = NULL;
456    gPersCustomFuncs[idx].custom_plugin_get_size = NULL;
457    gPersCustomFuncs[idx].custom_plugin_create_backup = NULL;
458    gPersCustomFuncs[idx].custom_plugin_get_backup = NULL;
459    gPersCustomFuncs[idx].custom_plugin_restore_backup = NULL;
460 }