Implemented on demand/static loading of plugins (part I); ATTENTION: pluginf config...
[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    PersInitType_e               initFunction;
39    PersLoadingType_e    loadingType;
40 } PersCustomLibInfo;
41
42
43 /// array with custom client library names
44 static PersCustomLibInfo gCustomLibArray[PersCustomLib_LastEntry];
45
46 char* gpCustomConfigFileMap = 0;
47 char* gpCustomTokenArray[TOKENARRAYSIZE];
48 int   gCustomTokenCounter = 0;
49 unsigned int gCustomConfigFileSize = 0;
50
51
52
53 void fillCustomCharTokenArray()
54 {
55    unsigned int i=0;
56    int blankCount=0;
57    char* tmpPointer = gpCustomConfigFileMap;
58
59    // set the first pointer to the start of the file
60    gpCustomTokenArray[blankCount] = tmpPointer;
61    blankCount++;
62
63    while(i < gCustomConfigFileSize)
64    {
65       if(1 != gCharLookup[(int)*tmpPointer])
66       {
67          *tmpPointer = 0;
68
69          // check if we are at the end of the token array
70          if(blankCount >= TOKENARRAYSIZE)
71          {
72             break;
73          }
74          gpCustomTokenArray[blankCount] = tmpPointer+1;
75          blankCount++;
76          gCustomTokenCounter++;
77
78       }
79       tmpPointer++;
80       i++;
81    }
82 }
83
84 PersLoadingType_e getCustomLoadingType(int i)
85 {
86         return gCustomLibArray[i].loadingType;
87 }
88
89 PersLoadingType_e getLoadingType(const char* type)
90 {
91         PersLoadingType_e persLoadingType = LoadType_Undefined;
92
93    if(0 == strcmp(type, "init") )
94    {
95         persLoadingType = LoadType_PclInit;
96    }
97    else if(0 == strcmp(type, "od") )
98    {
99         persLoadingType = LoadType_OnDemand;
100    }
101
102    return persLoadingType;
103 }
104
105 PersInitType_e getCustomInitType(int i)
106 {
107         return gCustomLibArray[i].initFunction;
108 }
109
110 PersInitType_e getInitType(const char* policy)
111 {
112         PersInitType_e persInitType = Init_Undefined;
113
114    if(0 == strcmp(policy, "sync"))
115    {
116         persInitType = Init_Synchronous;
117    }
118    else if (0 == strcmp(policy, "async"))
119    {
120         persInitType = Init_Asynchronous;
121    }
122
123    return persInitType;
124 }
125
126
127
128
129
130 PersistenceCustomLibs_e custom_client_name_to_id(const char* lib_name, int substring)
131 {
132    PersistenceCustomLibs_e libId = PersCustomLib_LastEntry;
133
134    if(substring == 0)
135    {
136       if(0 == strncmp(lib_name, "early", PersCustomPathSize) )
137       {
138          libId = PersCustomLib_early;
139       }
140       else if (0 == strncmp(lib_name, "secure", PersCustomPathSize) )
141       {
142          libId = PersCustomLib_secure;
143       }
144       else if (0 == strncmp(lib_name, "emergency", PersCustomPathSize) )
145       {
146          libId = PersCustomLib_emergency;
147       }
148       else if (0 == strncmp(lib_name, "hwinfo", PersCustomPathSize) )
149       {
150          libId = PersCustomLib_HWinfo;
151       }
152       else if (0 == strncmp(lib_name, "custom1", PersCustomPathSize) )
153       {
154          libId = PersCustomLib_Custom1;
155       }
156       else if (0 == strncmp(lib_name, "custom2", PersCustomPathSize) )
157       {
158          libId = PersCustomLib_Custom2;
159       }
160       else if (0 == strncmp(lib_name, "custom3", PersCustomPathSize) )
161       {
162          libId = PersCustomLib_Custom3;
163       }
164       else
165       {
166          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("custom_libname_to_id - error - id not found for lib:"), DLT_STRING(lib_name));
167       }
168    }
169    else
170    {
171       if(NULL != strstr(lib_name, "early") )
172       {
173          libId = PersCustomLib_early;
174       }
175       else if (NULL != strstr(lib_name, "secure") )
176       {
177          libId = PersCustomLib_secure;
178       }
179       else if (NULL != strstr(lib_name, "emergency") )
180       {
181          libId = PersCustomLib_emergency;
182       }
183       else if (NULL != strstr(lib_name, "hwinfo") )
184       {
185          libId = PersCustomLib_HWinfo;
186       }
187       else if (NULL != strstr(lib_name, "custom1") )
188       {
189          libId = PersCustomLib_Custom1;
190       }
191       else if (NULL != strstr(lib_name, "custom2") )
192       {
193          libId = PersCustomLib_Custom2;
194       }
195       else if (NULL != strstr(lib_name, "custom3") )
196       {
197          libId = PersCustomLib_Custom3;
198       }
199       else
200       {
201          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("custom_libname_to_id - error - id not found for lib:"), DLT_STRING(lib_name));
202       }
203
204    }
205    return libId;
206 }
207
208
209
210 int get_custom_libraries()
211 {
212    int rval = 0, fd = 0, j = 0, i= 0;
213    int status = 0;
214    struct stat buffer;
215
216    const char *filename = getenv("PERS_CLIENT_LIB_CUSTOM_LOAD");
217
218         if(filename == NULL)
219         {
220                 filename = "/etc/pclCustomLibConfigFile.cfg";  // use default filename
221         }
222
223    for(j=0; j<PersCustomLib_LastEntry; j++)
224    {
225       // init pos to -1
226       gCustomLibArray[j].valid = -1;
227    }
228
229    memset(&buffer, 0, sizeof(buffer));
230    status = stat(filename, &buffer);
231    if(status != -1)
232    {
233       gCustomConfigFileSize = buffer.st_size;
234    }
235
236    fd = open(filename, O_RDONLY);
237    if (fd == -1)
238    {
239       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load config file error ==> Error file open: "),
240             DLT_STRING(filename), DLT_STRING("err msg: "), DLT_STRING(strerror(errno)) );
241
242       return -1;
243    }
244
245    // check for empty file
246    if(gCustomConfigFileSize >= 0)
247    {
248                 // map the config file into memory
249                 gpCustomConfigFileMap = (char*)mmap(0, gCustomConfigFileSize, PROT_WRITE, MAP_PRIVATE, fd, 0);
250
251                 if (gpCustomConfigFileMap == MAP_FAILED)
252                 {
253                         gpCustomConfigFileMap = 0;
254                         close(fd);
255                         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load config file error ==> Error mapping the file"));
256                         return -1;
257                 }
258
259                 // reset the token counter
260                 gCustomTokenCounter = 0;
261
262                 fillCustomCharTokenArray();
263
264                 while( i < TOKENARRAYSIZE )
265                 {
266                         if(gpCustomTokenArray[i] != 0 && gpCustomTokenArray[i+1] != 0 && gpCustomTokenArray[i+2] != 0 &&gpCustomTokenArray[i+3] != 0 )
267                         {
268                                 int libId = custom_client_name_to_id(gpCustomTokenArray[i], 0); // get the custom libID
269
270                                 // assign the libraryname
271                                 strncpy(gCustomLibArray[libId].libname, gpCustomTokenArray[i+1], CustLibMaxLen);
272                                 gCustomLibArray[libId].libname[CustLibMaxLen-1] = '\0'; // Ensures 0-Termination
273
274                                 gCustomLibArray[libId].loadingType  = getLoadingType(gpCustomTokenArray[i+2]);
275                                 gCustomLibArray[libId].initFunction = getInitType(gpCustomTokenArray[i+3]);
276                                 gCustomLibArray[libId].valid        = 1;        // marks as valid;
277 #if 0
278                                 // debug
279                                 printf("     1. => %s => %d \n",   gpCustomTokenArray[i],   libId);
280                                 printf("     2. => %s => %s \n",   gpCustomTokenArray[i+1], gCustomLibArray[libId].libname);
281                                 printf("     3. => %s => %d \n",   gpCustomTokenArray[i+2], (int)gCustomLibArray[libId].initFunction);
282                                 printf("     4. => %s => %d \n\n", gpCustomTokenArray[i+3], (int)gCustomLibArray[libId].loadingType);
283 #endif
284                         }
285                         else
286                         {
287                                 break;
288                         }
289                         i+=4;       // move to the next configuration file entry
290                 }
291
292                 close(fd);
293    }
294    else
295    {
296         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load config file error ==> Error file size is 0"));
297       close(fd);
298       rval = -1;
299    }
300
301    return rval;
302 }
303
304
305
306 int load_custom_library(PersistenceCustomLibs_e customLib, Pers_custom_functs_s *customFuncts)
307 {
308    int rval = 1;
309    char *error = NULL;
310
311    if(customLib < PersCustomLib_LastEntry)
312    {
313       void* handle = dlopen(gCustomLibArray[customLib].libname, RTLD_LAZY);
314       customFuncts->handle = handle;
315
316       if(handle != NULL)
317       {
318          dlerror();    // reset error
319
320          // plugin_close
321          *(void **) (&customFuncts->custom_plugin_handle_close) = dlsym(handle, "plugin_handle_close");
322          if ((error = dlerror()) != NULL)
323          {
324               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
325          }
326          // custom_plugin_delete_data
327          *(void **) (&customFuncts->custom_plugin_delete_data) = dlsym(handle, "plugin_delete_data");
328          if ((error = dlerror()) != NULL)
329          {
330               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
331           }
332          // custom_plugin_get_data
333          *(void **) (&customFuncts->custom_plugin_handle_get_data) = dlsym(handle, "plugin_handle_get_data");
334          if ((error = dlerror()) != NULL)
335          {
336               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
337           }
338          // custom_plugin_get_data
339          *(void **) (&customFuncts->custom_plugin_get_data) = dlsym(handle, "plugin_get_data");
340          if ((error = dlerror()) != NULL)
341          {
342               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
343           }
344          // custom_plugin_init
345          *(void **) (&customFuncts->custom_plugin_init) = dlsym(handle, "plugin_init");
346          if ((error = dlerror()) != NULL)
347          {
348               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
349           }
350          // custom_plugin_deinit
351          *(void **) (&customFuncts->custom_plugin_deinit) = dlsym(handle, "plugin_deinit");
352          if ((error = dlerror()) != NULL)
353          {
354               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
355           }
356          // custom_plugin_open
357          *(void **) (&customFuncts->custom_plugin_handle_open) = dlsym(handle, "plugin_handle_open");
358          if ((error = dlerror()) != NULL)
359          {
360               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
361           }
362          // custom_plugin_set_data
363          *(void **) (&customFuncts->custom_plugin_handle_set_data) = dlsym(handle, "plugin_handle_set_data");
364          if ((error = dlerror()) != NULL)
365          {
366               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
367           }
368          // custom_plugin_set_data
369          *(void **) (&customFuncts->custom_plugin_set_data) = dlsym(handle, "plugin_set_data");
370          if ((error = dlerror()) != NULL)
371          {
372               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
373          }
374          // custom_plugin_get_size_handle
375          *(void **) (&customFuncts->custom_plugin_handle_get_size) = dlsym(handle, "plugin_handle_get_size");
376          if ((error = dlerror()) != NULL)
377          {
378             DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
379          }
380          // custom_plugin_get_size
381          *(void **) (&customFuncts->custom_plugin_get_size) = dlsym(handle, "plugin_get_size");
382          if ((error = dlerror()) != NULL)
383          {
384             DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
385          }
386           // create backup
387          *(void **) (&customFuncts->custom_plugin_create_backup) = dlsym(handle, "plugin_create_backup");
388          if ((error = dlerror()) != NULL)
389          {
390             DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
391          }
392          // restore backup
393          *(void **) (&customFuncts->custom_plugin_restore_backup) = dlsym(handle, "plugin_restore_backup");
394          if ((error = dlerror()) != NULL)
395          {
396              DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
397          }
398          // restore backup
399          *(void **) (&customFuncts->custom_plugin_get_backup) = dlsym(handle, "plugin_get_backup");
400          if ((error = dlerror()) != NULL)
401          {
402              DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
403          }
404
405          // custom_plugin_get_status_notification_clbk
406          *(void **) (&customFuncts->custom_plugin_get_status_notification_clbk) = dlsym(handle, "plugin_get_status_notification_clbk");
407          if ((error = dlerror()) != NULL)
408          {
409               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
410           }
411
412          // initialize plugin (non blocking)
413          *(void **) (&customFuncts->custom_plugin_init_async) = dlsym(handle, "plugin_init_async");
414          if ((error = dlerror()) != NULL)
415          {
416               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
417          }
418
419          // clear all data
420          *(void **) (&customFuncts->custom_plugin_clear_all_data) = dlsym(handle, "plugin_clear_all_data");
421          if ((error = dlerror()) != NULL)
422          {
423               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
424          }
425
426          // sync data
427          *(void **) (&customFuncts->custom_plugin_sync) = dlsym(handle, "plugin_sync");
428          if ((error = dlerror()) != NULL)
429          {
430               DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
431          }
432       }
433       else
434       {
435          error = dlerror();
436          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load_custom_library - error:"), DLT_STRING(error));
437          rval = EPERS_DLOPENERROR;
438       }
439    }
440    else
441    {
442       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("load_custom_library - error: - customLib out of bounds"));
443       rval = EPERS_DLOPENERROR;
444    }
445
446    return rval;
447 }
448
449
450 char* get_custom_client_lib_name(int idx)
451 {
452    if(idx < PersCustomLib_LastEntry)
453    {
454       return gCustomLibArray[idx].libname;
455    }
456    else
457    {
458       return NULL;
459    }
460 }
461
462 //int get_custom_client_position_in_array(int customLibId)
463 int check_valid_idx(int idx)
464 {
465    int rval = -1;
466
467    if(idx < PersCustomLib_LastEntry)
468    {
469       rval = gCustomLibArray[idx].valid;
470    }
471
472    return rval;
473 }
474
475
476
477 void invalidate_custom_plugin(int idx)
478 {
479    gPersCustomFuncs[idx].handle  = NULL;
480    gPersCustomFuncs[idx].custom_plugin_init = NULL;
481    gPersCustomFuncs[idx].custom_plugin_deinit = NULL;
482    gPersCustomFuncs[idx].custom_plugin_handle_open = NULL;
483    gPersCustomFuncs[idx].custom_plugin_handle_close = NULL;
484    gPersCustomFuncs[idx].custom_plugin_handle_get_data = NULL;
485    gPersCustomFuncs[idx].custom_plugin_handle_set_data  = NULL;
486    gPersCustomFuncs[idx].custom_plugin_get_data = NULL;
487    gPersCustomFuncs[idx].custom_plugin_set_data = NULL;
488    gPersCustomFuncs[idx].custom_plugin_delete_data = NULL;
489    gPersCustomFuncs[idx].custom_plugin_get_status_notification_clbk = NULL;
490    gPersCustomFuncs[idx].custom_plugin_handle_get_size = NULL;
491    gPersCustomFuncs[idx].custom_plugin_get_size = NULL;
492    gPersCustomFuncs[idx].custom_plugin_create_backup = NULL;
493    gPersCustomFuncs[idx].custom_plugin_get_backup = NULL;
494    gPersCustomFuncs[idx].custom_plugin_restore_backup = NULL;
495 }