/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.0 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ /*! \file common/config/config_load_configmodule.c * \brief configuration module, load the shared library implementing the configuration module * \author Francois TABURET * \date 2017 * \version 0.1 * \company NOKIA BellLabs France * \email: francois.taburet@nokia-bell-labs.com * \note * \warning */ #define _GNU_SOURCE #include <string.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <dlfcn.h> #define CONFIG_LOADCONFIG_MAIN #include "config_load_configmodule.h" #include "config_userapi.h" #define CONFIG_SHAREDLIBFORMAT "libparams_%s.so" int load_config_sharedlib(configmodule_interface_t *cfgptr) { void *lib_handle; char fname[128]; char libname[FILENAME_MAX]; int st; st=0; sprintf(libname,CONFIG_SHAREDLIBFORMAT,cfgptr->cfgmode); lib_handle = dlopen(libname,RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); if (!lib_handle) { fprintf(stderr,"[CONFIG] %s %d Error calling dlopen(%s): %s\n",__FILE__, __LINE__, libname,dlerror()); st = -1; } else { sprintf (fname,"config_%s_init",cfgptr->cfgmode); cfgptr->init = dlsym(lib_handle,fname); if (cfgptr->init == NULL ) { printf("[CONFIG] %s %d no function %s for config mode %s\n", __FILE__, __LINE__,fname, cfgptr->cfgmode); } else { st=cfgptr->init(cfgptr->cfgP,cfgptr->num_cfgP); printf("[CONFIG] function %s returned %i\n", fname, st); } sprintf (fname,"config_%s_get",cfgptr->cfgmode); cfgptr->get = dlsym(lib_handle,fname); if (cfgptr->get == NULL ) { printf("[CONFIG] %s %d no function %s for config mode %s\n", __FILE__, __LINE__,fname, cfgptr->cfgmode); st = -1; } sprintf (fname,"config_%s_getlist",cfgptr->cfgmode); cfgptr->getlist = dlsym(lib_handle,fname); if (cfgptr->getlist == NULL ) { printf("[CONFIG] %s %d no function %s for config mode %s\n", __FILE__, __LINE__,fname, cfgptr->cfgmode); st = -1; } sprintf (fname,"config_%s_end",cfgptr->cfgmode); cfgptr->end = dlsym(lib_handle,fname); if (cfgptr->getlist == NULL ) { printf("[CONFIG] %s %d no function %s for config mode %s\n", __FILE__, __LINE__,fname, cfgptr->cfgmode); } } return st; } /*-----------------------------------------------------------------------------------*/ /* from here: interface implementtion of the configuration module */ configmodule_interface_t *load_configmodule(int argc, char **argv) { char *cfgparam=NULL; char *modeparams=NULL; char *cfgmode=NULL; char *strtokctx=NULL; char *atoken; uint32_t tmpflags=0; int i; /* first parse the command line to look for the -O option */ opterr=0; for (i = 0;i<argc;i++) { if (strlen(argv[i]) < 2) continue; if ( argv[i][1] == 'O' && i < (argc -1)) { cfgparam = argv[i+1]; } if ( argv[i][1] == 'h' ) { tmpflags = CONFIG_HELP; } } optind=1; /* look for the OAI_CONFIGMODULE environement variable */ if ( cfgparam == NULL ) { cfgparam = getenv("OAI_CONFIGMODULE"); } /* default */ if (cfgparam == NULL) { cfgparam = "libconfig:oaisoftmodem.conf"; } /* parse the config parameters to set the config source */ i = sscanf(cfgparam,"%m[^':']:%ms",&cfgmode,&modeparams); if (i< 0) { fprintf(stderr,"[CONFIG] %s, %d, sscanf error parsing config source %s: %s\n", __FILE__, __LINE__,cfgparam, strerror(errno)); cfgmode=strdup("libconfig"); modeparams = strdup("oaisoftmodem.conf"); } else if ( i == 1 ) { /* -O argument doesn't contain ":" separator, assume -O <conf file> option, default cfgmode to libconfig with one parameter, the path to the configuration file */ modeparams=cfgmode; cfgmode=strdup("libconfig"); } cfgptr = malloc(sizeof(configmodule_interface_t)); memset(cfgptr,0,sizeof(configmodule_interface_t)); cfgptr->rtflags = cfgptr->rtflags | tmpflags; cfgptr->argc = argc; cfgptr->argv = argv; cfgptr->cfgmode=strdup(cfgmode); cfgptr->num_cfgP=0; atoken=strtok_r(modeparams,":",&strtokctx); while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) { /* look for debug level in the config parameters, it is commom to all config mode and will be removed frome the parameter array passed to the shared module */ char *aptr; aptr=strcasestr(atoken,"dbgl"); if (aptr != NULL) { cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0); } else { cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken); cfgptr->num_cfgP++; } atoken = strtok_r(NULL,":",&strtokctx); } printf("[CONFIG] get parameters from %s ",cfgmode); for (i=0;i<cfgptr->num_cfgP; i++) { printf("%s ",cfgptr->cfgP[i]); } printf("\n"); i=load_config_sharedlib(cfgptr); if (i< 0) { fprintf(stderr,"[CONFIG] %s %d config module %s couldn't be loaded\n", __FILE__, __LINE__,cfgmode); cfgptr->rtflags = cfgptr->rtflags | CONFIG_HELP | CONFIG_ABORT; } else { printf("[CONFIG] config module %s loaded\n",cfgmode); Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].uptr=&(cfgptr->rtflags); config_get(Config_Params,CONFIG_PARAMLENGTH(Config_Params), CONFIG_SECTIONNAME ); } if (modeparams != NULL) free(modeparams); if (cfgmode != NULL) free(cfgmode); if (CONFIG_ISFLAGSET(CONFIG_ABORT)) config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params)); return cfgptr; } void end_configmodule() { if (cfgptr != NULL) { if (cfgptr->end != NULL) { printf ("[CONFIG] calling config module end function...\n"); cfgptr->end(); } if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP); for (int i=0; i<cfgptr->num_cfgP; i++) { if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); } printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); for(int i=0; i<cfgptr->numptrs ; i++) { if (cfgptr->ptrs[i] != NULL) { free(cfgptr->ptrs[i]); } cfgptr->ptrs[i]=NULL; } free(cfgptr); cfgptr=NULL; } }