config_load_configmodule.c 7.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
/*
 * 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"

45
int load_config_sharedlib(configmodule_interface_t *cfgptr)
46 47 48 49 50 51 52
{
void *lib_handle;
char fname[128];
char libname[FILENAME_MAX]; 
int st;

   st=0;  
53
   sprintf(libname,CONFIG_SHAREDLIBFORMAT,cfgptr->cfgmode);
54 55 56 57 58 59

   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 { 
60
      sprintf (fname,"config_%s_init",cfgptr->cfgmode);
61 62 63 64
      cfgptr->init = dlsym(lib_handle,fname);

      if (cfgptr->init == NULL ) {
         printf("[CONFIG] %s %d no function %s for config mode %s\n",
65
               __FILE__, __LINE__,fname, cfgptr->cfgmode);
66
      } else {
67
         st=cfgptr->init(cfgptr->cfgP,cfgptr->num_cfgP); 
68 69 70 71
         printf("[CONFIG] function %s returned %i\n",
               fname, st);	 
      }

72
      sprintf (fname,"config_%s_get",cfgptr->cfgmode);
73 74 75
      cfgptr->get = dlsym(lib_handle,fname);
      if (cfgptr->get == NULL ) { 
         printf("[CONFIG] %s %d no function %s for config mode %s\n",
76
               __FILE__, __LINE__,fname, cfgptr->cfgmode);
77 78 79
	 st = -1;
      }
      
80
      sprintf (fname,"config_%s_getlist",cfgptr->cfgmode);
81 82 83
      cfgptr->getlist = dlsym(lib_handle,fname);
      if (cfgptr->getlist == NULL ) { 
         printf("[CONFIG] %s %d no function %s for config mode %s\n",
84
               __FILE__, __LINE__,fname, cfgptr->cfgmode);
85 86 87
	 st = -1;
      }

88
      sprintf (fname,"config_%s_end",cfgptr->cfgmode);
89 90 91
      cfgptr->end = dlsym(lib_handle,fname);
      if (cfgptr->getlist == NULL ) { 
         printf("[CONFIG] %s %d no function %s for config mode %s\n",
92
               __FILE__, __LINE__,fname, cfgptr->cfgmode);
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
      }      
   } 
   
   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;
108
char *atoken;
109
uint32_t tmpflags=0;
110
int i;
111
 
112

113 114
/* first parse the command line to look for the -O option */
  opterr=0;
115
  while ((i = getopt(argc, argv, "O:h")) != -1) {
116 117
       if ( i == 'O' ) {
          cfgparam = optarg; 
118 119 120 121
       } 
        if ( i == 'h' ) {
          tmpflags = CONFIG_HELP; 
       }            
122
   }
123 124
   optind=1;

125 126 127 128 129 130 131 132 133 134 135 136 137
/* 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));
138 139
       cfgmode=strdup("libconfig");
       modeparams = strdup("oaisoftmodem.conf");
140 141
   }
   else if ( i == 1 ) {
142 143
  /* -O argument doesn't contain ":" separator, legacy -O <conf file> option, default cfgmode to libconfig
     with one parameter, the path to the configuration file */
144 145
       modeparams=cfgmode;
       cfgmode=strdup("libconfig");
146
       tmpflags = tmpflags | CONFIG_LEGACY;/* temporary, legacy mode */
147 148 149
   }

   cfgptr = malloc(sizeof(configmodule_interface_t));
150
   memset(cfgptr,0,sizeof(configmodule_interface_t));
151 152

   cfgptr->rtflags = cfgptr->rtflags | tmpflags;
153 154 155 156 157 158 159 160 161
   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 */
162
       char *aptr;
163
       aptr=strcasestr(atoken,"dbgl");
164
       if (aptr != NULL) {
165 166 167 168 169
           cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0);

       } else {
           cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken);
           cfgptr->num_cfgP++;
170
       }
171
       atoken = strtok_r(NULL,":",&strtokctx);
172 173 174 175
   }

   
   printf("[CONFIG] get parameters from %s ",cfgmode);
176 177
   for (i=0;i<cfgptr->num_cfgP; i++) {
        printf("%s ",cfgptr->cfgP[i]); 
178 179 180 181
   }
   printf("\n");

 
182
   i=load_config_sharedlib(cfgptr);
183 184
   if (i< 0) {
      fprintf(stderr,"[CONFIG] %s %d config module %s couldn't be loaded\n", __FILE__, __LINE__,cfgmode);
185
      cfgptr->rtflags = cfgptr->rtflags | CONFIG_HELP | CONFIG_ABORT;
186 187
   } else {
      printf("[CONFIG] config module %s loaded\n",cfgmode);
188 189
      Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].uptr=&(cfgptr->rtflags);
      config_get(Config_Params,CONFIG_PARAMLENGTH(Config_Params), CONFIG_SECTIONNAME ); 
190 191
   }

192
  
193 194 195

   if (modeparams != NULL) free(modeparams);
   if (cfgmode != NULL) free(cfgmode);
196
   if (CONFIG_ISFLAGSET(CONFIG_ABORT)) config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params));
197 198 199 200 201 202
   return cfgptr;
}

void end_configmodule()
{ 
  if (cfgptr != NULL) {
203 204 205 206 207 208 209 210 211 212
      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);  
213 214 215 216 217 218
      for(int i=0; i<cfgptr->numptrs ; i++) {
          if (cfgptr->ptrs[i] != NULL) {
             free(cfgptr->ptrs[i]);
          }
          cfgptr->ptrs[i]=NULL;
      }
219

220 221 222 223 224 225 226 227
  free(cfgptr);
  cfgptr=NULL;
  }
}