config module fix and extensions for Nb-IoT, shared lib loader and telnet server implementation
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <dlfcn.h>
|
||||
#include "openair1/PHY/defs.h"
|
||||
@@ -44,55 +45,114 @@
|
||||
void loader_init(void) {
|
||||
paramdef_t LoaderParams[] = LOADER_PARAMS_DESC;
|
||||
|
||||
|
||||
loader_data.mainexec_buildversion = PACKAGE_VERSION;
|
||||
int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),LOADER_CONFIG_PREFIX);
|
||||
if (ret <0) {
|
||||
fprintf(stderr,"[LOADER] configuration couldn't be performed");
|
||||
fprintf(stderr,"[LOADER] %s %d configuration couldn't be performed",__FILE__, __LINE__);
|
||||
if (loader_data.shlibpath == NULL) {
|
||||
loader_data.shlibpath=DEFAULT_PATH;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
loader_data.shlibs = malloc(loader_data.maxshlibs * sizeof(loader_shlibdesc_t));
|
||||
if(loader_data.shlibs == NULL) {
|
||||
fprintf(stderr,"[LOADER] %s %d memory allocation error %s\n",__FILE__, __LINE__,strerror(errno));
|
||||
exit_fun("[LOADER] unrecoverable error");
|
||||
}
|
||||
memset(loader_data.shlibs,0,loader_data.maxshlibs * sizeof(loader_shlibdesc_t));
|
||||
}
|
||||
|
||||
/* build the full shared lib name from the module name */
|
||||
char *loader_format_shlibpath(char *modname)
|
||||
{
|
||||
|
||||
char *tmpstr;
|
||||
char *shlibpath =NULL;
|
||||
char *shlibversion=NULL;
|
||||
char *cfgprefix;
|
||||
paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0},
|
||||
{"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0}};
|
||||
|
||||
int ret;
|
||||
|
||||
|
||||
|
||||
|
||||
/* looks for specific path for this module in the config file */
|
||||
/* specific value for a module path and version is located in a modname subsection of the loader section */
|
||||
/* shared lib name is formatted as lib<module name><module version>.so */
|
||||
cfgprefix = malloc(sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16);
|
||||
if (cfgprefix == NULL) {
|
||||
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
|
||||
exit_fun("[LOADER] unrecoverable error");
|
||||
} else {
|
||||
sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname);
|
||||
int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix);
|
||||
if (ret <0) {
|
||||
fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix);
|
||||
}
|
||||
}
|
||||
/* no specific path, use loader default shared lib path */
|
||||
if (shlibpath == NULL) {
|
||||
shlibpath = loader_data.shlibpath ;
|
||||
}
|
||||
|
||||
/* alloc memory for full module shared lib file name */
|
||||
tmpstr = malloc(strlen(shlibpath)+strlen(modname)+strlen(shlibversion)+16);
|
||||
if (tmpstr == NULL) {
|
||||
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
|
||||
exit_fun("[LOADER] unrecoverable error");
|
||||
}
|
||||
if(shlibpath[0] != 0) {
|
||||
ret=sprintf(tmpstr,"%s/",shlibpath);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
sprintf(tmpstr+ret,"lib%s%s.so",modname,shlibversion);
|
||||
|
||||
|
||||
return tmpstr;
|
||||
}
|
||||
|
||||
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
|
||||
{
|
||||
void *lib_handle;
|
||||
initfunc_t fpi;
|
||||
char *tmpstr;
|
||||
checkverfunc_t fpc;
|
||||
char *shlib_path;
|
||||
char *afname=NULL;
|
||||
int ret=0;
|
||||
|
||||
if (loader_data.shlibpath == NULL) {
|
||||
loader_init();
|
||||
}
|
||||
tmpstr = malloc(strlen(loader_data.shlibpath)+strlen(modname)+16);
|
||||
if (tmpstr == NULL) {
|
||||
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(loader_data.shlibpath[0] != 0) {
|
||||
ret=sprintf(tmpstr,"%s/",loader_data.shlibpath);
|
||||
}
|
||||
if(strstr(modname,".so") == NULL) {
|
||||
sprintf(tmpstr+ret,"lib%s.so",modname);
|
||||
} else {
|
||||
sprintf(tmpstr+ret,"%s",modname);
|
||||
}
|
||||
shlib_path = loader_format_shlibpath(modname);
|
||||
|
||||
ret = 0;
|
||||
lib_handle = dlopen(tmpstr, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL);
|
||||
lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL);
|
||||
if (!lib_handle) {
|
||||
fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", tmpstr,dlerror());
|
||||
fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror());
|
||||
ret = -1;
|
||||
} else {
|
||||
printf("[LOADER] library %s uccessfully loaded loaded\n", tmpstr);
|
||||
sprintf(tmpstr,"%s_autoinit",modname);
|
||||
fpi = dlsym(lib_handle,tmpstr);
|
||||
printf("[LOADER] library %s successfully loaded\n", shlib_path);
|
||||
afname=malloc(strlen(modname)+15);
|
||||
sprintf(afname,"%s_checkbuildver",modname);
|
||||
fpc = dlsym(lib_handle,afname);
|
||||
if (fpc != NULL ){
|
||||
int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion));
|
||||
if (chkver_ret < 0) {
|
||||
fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname);
|
||||
exit_fun("[LOADER] unrecoverable error");
|
||||
}
|
||||
}
|
||||
sprintf(afname,"%s_autoinit",modname);
|
||||
fpi = dlsym(lib_handle,afname);
|
||||
|
||||
if (fpi != NULL )
|
||||
{
|
||||
if (fpi != NULL ) {
|
||||
fpi();
|
||||
}
|
||||
}
|
||||
|
||||
if (farray != NULL) {
|
||||
for (int i=0; i<numf; i++) {
|
||||
@@ -103,9 +163,22 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
|
||||
}
|
||||
} /* for int i... */
|
||||
} /* farray ! NULL */
|
||||
}
|
||||
loader_data.shlibs[loader_data.numshlibs].name=strdup(modname);
|
||||
loader_data.shlibs[loader_data.numshlibs].thisshlib_path=strdup(shlib_path);
|
||||
loader_data.shlibs[loader_data.numshlibs].funcarray=malloc(numf*sizeof(loader_shlibfunc_t));
|
||||
loader_data.shlibs[loader_data.numshlibs].numfunc=0;
|
||||
for (int i=0; i<numf;i++) {
|
||||
if (farray[i].fptr != NULL) {
|
||||
loader_data.shlibs[loader_data.numshlibs].funcarray[i].fname=strdup(farray[i].fname);
|
||||
loader_data.shlibs[loader_data.numshlibs].funcarray[i].fptr = farray[i].fptr;
|
||||
loader_data.shlibs[loader_data.numshlibs].numfunc++;
|
||||
}
|
||||
}
|
||||
(loader_data.numshlibs)++;
|
||||
} /* lib_handle != NULL */
|
||||
|
||||
if (tmpstr != NULL) free(tmpstr);
|
||||
if ( shlib_path!= NULL) free(shlib_path);
|
||||
if ( afname!= NULL) free(afname);
|
||||
if (lib_handle != NULL) dlclose(lib_handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -34,32 +34,49 @@
|
||||
|
||||
|
||||
typedef int(*initfunc_t)(void);
|
||||
|
||||
typedef struct {
|
||||
char *shlibpath;
|
||||
}loader_data_t;
|
||||
typedef int(*checkverfunc_t)(char * mainexec_version, char ** shlib_version);
|
||||
|
||||
typedef struct {
|
||||
char *fname;
|
||||
int (*fptr)(void);
|
||||
}loader_shlibfunc_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *shlib_version; //
|
||||
char *shlib_buildversion;
|
||||
char *thisshlib_path;
|
||||
uint32_t numfunc;
|
||||
loader_shlibfunc_t *funcarray;
|
||||
}loader_shlibdesc_t;
|
||||
|
||||
typedef struct {
|
||||
char *mainexec_buildversion;
|
||||
char *shlibpath;
|
||||
uint32_t maxshlibs;
|
||||
uint32_t numshlibs;
|
||||
loader_shlibdesc_t *shlibs;
|
||||
}loader_data_t;
|
||||
|
||||
#ifdef LOAD_MODULE_SHLIB_MAIN
|
||||
#define LOADER_CONFIG_PREFIX "loader"
|
||||
#define DEFAULT_PATH ""
|
||||
loader_data_t loader_data;
|
||||
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* LOADER parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* LOADER parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define LOADER_PARAMS_DESC { \
|
||||
{"shlibpath", NULL, 0, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0} \
|
||||
{"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0}, \
|
||||
{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs), defintval:10, TYPE_UINT32, 0}, \
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------*/
|
||||
#else
|
||||
#else /* LOAD_MODULE_SHLIB_MAIN */
|
||||
extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf);
|
||||
#endif
|
||||
extern loader_data_t loader_data;
|
||||
#endif /* LOAD_MODULE_SHLIB_MAIN */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
|
||||
IF(DEFINED ENV{OPENAIR_DIR})
|
||||
message("...using oai source files in $ENV{OPENAIR_DIR}")
|
||||
ELSE()
|
||||
message("OPENAIR_DIR is not defined. You must run \"source oaienv\" from the oai root dir")
|
||||
# exit early
|
||||
return()
|
||||
ENDIF()
|
||||
|
||||
|
||||
|
||||
set(OPENAIR_DIR $ENV{OPENAIR_DIR})
|
||||
set(APPROOT ${OPENAIR_DIR}/common/utils/telnetsrv )
|
||||
set(OPENAIR_BUILD_DIR $ENV{OPENAIR_DIR}/cmake_targets)
|
||||
set(OPENAIR1_DIR $ENV{OPENAIR1_DIR})
|
||||
set(OPENAIR2_DIR $ENV{OPENAIR2_DIR})
|
||||
set(OPENAIR3_DIR $ENV{OPENAIR3_DIR})
|
||||
set(OPENAIR_PHY_DIR $ENV{OPENAIR1_DIR}/PHY)
|
||||
set(OPENAIR_TARGET_DIR $ENV{OPENAIR_DIR}/targets)
|
||||
set(OPENAIR_COMMONUTILS_DIR $ENV{OPENAIR_DIR}/common/utils)
|
||||
set(OPENAIR2_COMMON_DIR $ENV{OPENAIR_DIR}/openair2/COMMON)
|
||||
set(OPENAIR_ASN1INC ${OPENAIR_BUILD_DIR}/lte_build_oai/build/CMakeFiles/Rel14)
|
||||
set(OPENAIR_NFAPIINC $ENV{NFAPI_DIR} )
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX $ENV{OPENAIR_TARGETS})
|
||||
|
||||
add_definitions (-DRel14 -DCMAKER -DENABLE_ITTI -DENABLE_NAS_UE_LOGGING -DENABLE_SECURITY -DENABLE_USE_CPU_EXECUTION_TIME -DENABLE_USE_MME -DENABLE_VCD -DENB_AGENT -DENB_MODE -DETHERNET=1 -DEXMIMO_IOT -DJUMBO_FRAME -DLINK_ENB_PDCP_TO_GTPV1U -DLOG_NO_THREAD -DMAC_CONTEXT -DMAX_NUM_CCs=1 -DNAS_BUILT_IN_UE -DNAS_UE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DNO_RRM -DNone=1 -DOAI_NW_DRIVER_USE_NETLINK -DOPENAIR2 -DOPENAIR_LTE -DPHYSIM -DPHY_CONTEXT -DRel10=1 -DS1AP_VERSION=R10 -DTRACE_RLC_MUTEX -DX2AP_VERSION=R11 -DXFORMS -mavx2 -msse4.1 -mssse3)
|
||||
add_compile_options( -fPIC -march=native -Ofast)
|
||||
|
||||
include_directories( ./ ${OPENAIR_COMMON_DIR} ${OPENAIR_DIR} ${OPENAIR1_DIR} ${OPENAIR2_DIR} ${OPENAIR2_COMMON_DIR} ${OPENAIR2_DIR}/UTIL/LOG
|
||||
${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC}
|
||||
${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0 ${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC}
|
||||
${OPENAIR2_DIR}/LAYER2/RLC ${OPENAIR2_DIR}/UTIL/LISTS ${OPENAIR2_DIR}/UTIL/MEM ${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0
|
||||
${OPENAIR2_DIR}/LAYER2/RLC/TM_v9.3.0 ${OPENAIR2_DIR}/RRC/LITE ${OPENAIR_TARGET_DIR}/COMMON ${OPENAIR_TARGET_DIR}/ARCH/COMMON
|
||||
${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK ${OPENAIR3_DIR}/NAS/COMMON/EMM/MSG/ ${OPENAIR3_DIR}/NAS/COMMON/IES/ ${OPENAIR3_DIR}/NAS/COMMON/UTIL
|
||||
${OPENAIR3_DIR}/NAS/COMMON/ESM/MSG/ ${OPENAIR3_DIR}/GTPV1-U ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/shared ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/include
|
||||
${OPENAIR3_DIR}/UTILS ${OPENAIR_NFAPIINC})
|
||||
|
||||
set(TELNETSRV_SOURCE
|
||||
${APPROOT}/telnetsrv.c
|
||||
${APPROOT}/telnetsrv_phycmd.c
|
||||
${APPROOT}/telnetsrv_proccmd.c
|
||||
)
|
||||
|
||||
#set(TELNETSRV_ETHDEVCMD_SOURCE
|
||||
# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c
|
||||
# )
|
||||
|
||||
|
||||
|
||||
add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} )
|
||||
#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} )
|
||||
|
||||
|
||||
install(TARGETS telnetsrv DESTINATION bin)
|
||||
|
||||
if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
|
||||
install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build)
|
||||
endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
|
||||
@@ -3,7 +3,7 @@
|
||||
* 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
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
@@ -43,7 +43,7 @@
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <telnetsrv.h>
|
||||
#include "telnetsrv.h"
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
@@ -53,18 +53,25 @@
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "common/config/config_userapi.h"
|
||||
#include <readline/history.h>
|
||||
|
||||
|
||||
#include "telnetsrv_phycmd.h"
|
||||
#include "telnetsrv_proccmd.h"
|
||||
static char* telnet_defstatmod[] = {"softmodem","phy"};
|
||||
static char* telnet_defstatmod[] = {"softmodem","phy","loader"};
|
||||
static telnetsrv_params_t telnetparams;
|
||||
#define TELNETSRV_LISTENADDR 0
|
||||
#define TELNETSRV_LISTENPORT 1
|
||||
#define TELNETSRV_PRIORITY 2
|
||||
#define TELNETSRV_DEBUG 3
|
||||
#define TELNETSRV_STATICMOD 7
|
||||
#define TELNETSRV_SHRMOD 8
|
||||
#define TELNETSRV_LOOPC 4
|
||||
#define TELNETSRV_LOOPD 5
|
||||
#define TELNETSRV_HISFILE 6
|
||||
#define TELNETSRV_HISSIZE 7
|
||||
#define TELNETSRV_PHYBSIZE 8
|
||||
#define TELNETSRV_STATICMOD 9
|
||||
#define TELNETSRV_SHRMOD 10
|
||||
|
||||
paramdef_t telnetoptions[] = {
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* configuration parameters for telnet utility */
|
||||
@@ -72,19 +79,22 @@ paramdef_t telnetoptions[] = {
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{"listenaddr", "<listen ip address>", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 },
|
||||
{"listenport", "<local port>", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 },
|
||||
{"priority", "<scheduling policy (0-99)", 0, uptr:&telnetparams.priority, defuintval:0, TYPE_INT, 0 },
|
||||
{"priority", "<scheduling policy (0-99)", 0, iptr:&telnetparams.priority, defuintval:0, TYPE_INT, 0 },
|
||||
{"debug", "<debug level>", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 },
|
||||
{"loopcount", "<loop command iterations>", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 },
|
||||
{"loopdelay", "<loop command delay (ms)>", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 },
|
||||
{"histfile", "<history file name>", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 },
|
||||
{"histsize", "<history sizes>", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 },
|
||||
{"phypbsize", "<phy dump buff size (bytes)>",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 },
|
||||
{"staticmod", "<static modules selection>", 0, NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,1},
|
||||
{"shrmod", "<static modules selection>", 0, NULL, NULL,TYPE_STRINGLIST,0 },
|
||||
{"staticmod", "<static modules selection>", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))},
|
||||
{"shrmod", "<dynamic modules selection>", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 }
|
||||
};
|
||||
|
||||
int get_phybsize() {return telnetparams.phyprntbuff_size; };
|
||||
int get_phybsize(void) {return telnetparams.phyprntbuff_size; };
|
||||
int add_telnetcmd(char *modulename,telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd );
|
||||
int setoutput(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
int setparam(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
int history_cmd(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
|
||||
telnetshell_vardef_t telnet_vardef[] = {
|
||||
{"debug",TELNET_VARTYPE_INT32,&telnetparams.telnetdbg},
|
||||
@@ -92,12 +102,15 @@ telnetshell_vardef_t telnet_vardef[] = {
|
||||
{"loopc",TELNET_VARTYPE_INT32,&telnetparams.loopcount},
|
||||
{"loopd",TELNET_VARTYPE_INT32,&telnetparams.loopdelay},
|
||||
{"phypb",TELNET_VARTYPE_INT32,&telnetparams.phyprntbuff_size},
|
||||
{"hsize",TELNET_VARTYPE_INT32,&telnetparams.histsize},
|
||||
{"hfile",TELNET_VARTYPE_STRING,&telnetparams.histfile},
|
||||
{"",0,NULL}
|
||||
};
|
||||
|
||||
telnetshell_cmddef_t telnet_cmdarray[] = {
|
||||
{"redirlog","[here,file,off]",setoutput},
|
||||
{"param","[prio]",setparam},
|
||||
{"history","[list,reset]",history_cmd},
|
||||
{"","",NULL},
|
||||
};
|
||||
|
||||
@@ -131,41 +144,54 @@ char strpolicy[10];
|
||||
|
||||
|
||||
//sched_get_priority_max(SCHED_FIFO)
|
||||
if (priority < NICE_MIN)
|
||||
{
|
||||
if (priority < NICE_MIN) {
|
||||
policy=SCHED_FIFO;
|
||||
sprintf(strpolicy,"%s","fifo");
|
||||
schedp.sched_priority= NICE_MIN - priority ;
|
||||
schedp.sched_priority= NICE_MIN - priority ;
|
||||
if ( (schedp.sched_priority < sched_get_priority_min(SCHED_FIFO)) ||
|
||||
(schedp.sched_priority > sched_get_priority_max(SCHED_FIFO)) ) {
|
||||
client_printf("Error: %i invalid prio, should be %i to %i, \n",
|
||||
priority, NICE_MIN -sched_get_priority_min(SCHED_FIFO),
|
||||
NICE_MIN - sched_get_priority_max(SCHED_FIFO) );
|
||||
}
|
||||
else if (priority > NICE_MAX)
|
||||
{
|
||||
} else if (priority > NICE_MAX) {
|
||||
policy=SCHED_IDLE;
|
||||
sprintf(strpolicy,"%s","idle");
|
||||
schedp.sched_priority=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
policy=SCHED_OTHER;
|
||||
sprintf(strpolicy,"%s","other");
|
||||
schedp.sched_priority=0;
|
||||
}
|
||||
if( tid != 0)
|
||||
{
|
||||
}
|
||||
|
||||
if( tid != 0) {
|
||||
rt = pthread_setschedparam(tid, policy, &schedp);
|
||||
}
|
||||
else if(pid > 0)
|
||||
{
|
||||
} else if(pid > 0) {
|
||||
rt = sched_setscheduler( pid, policy,&schedp);
|
||||
}
|
||||
if (rt != 0)
|
||||
{
|
||||
} else {
|
||||
rt= -1;
|
||||
client_printf("Error: no pid or tid specified\n");
|
||||
}
|
||||
|
||||
if (rt != 0) {
|
||||
client_printf("Error %i: %s modifying sched param to %s:%i, \n",
|
||||
errno,strerror(errno),strpolicy,schedp.sched_priority);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority);
|
||||
if ( policy==SCHED_OTHER) {
|
||||
rt = getpriority(PRIO_PROCESS,tid);
|
||||
if (rt != -1) {
|
||||
rt = setpriority(PRIO_PROCESS,tid,priority);
|
||||
if (rt < 0) {
|
||||
client_printf("Error %i: %s trying to set nice value of thread %u to %i\n",
|
||||
errno,strerror(errno),tid,priority);
|
||||
}
|
||||
} else {
|
||||
client_printf("Error %i: %s trying to get nice value of thread %u \n",
|
||||
errno,strerror(errno),tid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -198,14 +224,13 @@ int rt;
|
||||
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(coreid, &cpuset);
|
||||
if (tid > 0)
|
||||
{
|
||||
if (tid > 0) {
|
||||
rt = pthread_setaffinity_np((pthread_t)tid, sizeof(cpu_set_t), &cpuset);
|
||||
}
|
||||
else if (pid > 0)
|
||||
{
|
||||
} else if (pid > 0){
|
||||
rt = sched_setaffinity((pid_t)pid, sizeof(cpu_set_t), &cpuset);
|
||||
}
|
||||
} else {
|
||||
rt= -1;
|
||||
}
|
||||
if (rt != 0)
|
||||
{
|
||||
client_printf("Error %i: %s calling , xxx_setaffinity...\n",errno,strerror(errno));
|
||||
@@ -284,7 +309,6 @@ memset(cmds,0,sizeof(cmds));
|
||||
sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] );
|
||||
if (strncasecmp(cmds[0],"prio",4) == 0)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
int prio;
|
||||
prio=(int)strtol(cmds[1],NULL,0);
|
||||
if (errno == ERANGE)
|
||||
@@ -305,6 +329,35 @@ if (strncasecmp(cmds[0],"aff",3) == 0)
|
||||
|
||||
return CMDSTATUS_NOTFOUND;
|
||||
} /* setparam */
|
||||
|
||||
int history_cmd(char *buff, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
|
||||
|
||||
|
||||
memset(cmds,0,sizeof(cmds));
|
||||
sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] );
|
||||
if (cmds[0] == NULL)
|
||||
return CMDSTATUS_VARNOTFOUND;
|
||||
if (strncasecmp(cmds[0],"list",4) == 0)
|
||||
{
|
||||
HIST_ENTRY **hist = history_list();
|
||||
if (hist) {
|
||||
for (int i = 0; hist[i]; i++) {
|
||||
prnt ("%d: %s\n", i + history_base, hist[i]->line);
|
||||
}
|
||||
}
|
||||
return CMDSTATUS_FOUND;
|
||||
}
|
||||
if (strncasecmp(cmds[0],"reset",5) == 0)
|
||||
{
|
||||
clear_history();
|
||||
write_history(telnetparams.histfile);
|
||||
return CMDSTATUS_FOUND;
|
||||
}
|
||||
|
||||
return CMDSTATUS_NOTFOUND;
|
||||
} /* history_cmd */
|
||||
/*-------------------------------------------------------------------------------------------------------*/
|
||||
/*
|
||||
generic commands available for all modules loaded by the server
|
||||
@@ -314,11 +367,11 @@ int setgetvar(int moduleindex,char getorset,char *params)
|
||||
{
|
||||
int n,i;
|
||||
char varname[TELNET_CMD_MAXSIZE];
|
||||
char varval[TELNET_CMD_MAXSIZE];
|
||||
char *varval=NULL;
|
||||
|
||||
memset(varname,0,sizeof(varname));
|
||||
memset(varval,0,sizeof(varval));
|
||||
n = sscanf(params,"%s %s",varname,varval);
|
||||
|
||||
n = sscanf(params,"%s %ms",varname,&varval);
|
||||
for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++)
|
||||
{
|
||||
if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0)
|
||||
@@ -330,7 +383,10 @@ char varval[TELNET_CMD_MAXSIZE];
|
||||
switch(telnetparams.CmdParsers[moduleindex].var[i].vartype)
|
||||
{
|
||||
case TELNET_VARTYPE_INT32:
|
||||
client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
client_printf("%i\n",*(int32_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
case TELNET_VARTYPE_INT64:
|
||||
client_printf("%lli\n",*(int64_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
case TELNET_VARTYPE_INT16:
|
||||
client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
@@ -338,8 +394,8 @@ char varval[TELNET_CMD_MAXSIZE];
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
case TELNET_VARTYPE_PTR:
|
||||
client_printf("0x%08x\n",*((unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)));
|
||||
case TELNET_VARTYPE_STRING:
|
||||
client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
default:
|
||||
client_printf("unknown type\n");
|
||||
@@ -364,6 +420,10 @@ char varval[TELNET_CMD_MAXSIZE];
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL);
|
||||
client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
case TELNET_VARTYPE_STRING:
|
||||
sprintf(*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr),"%s", varval);
|
||||
client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
default:
|
||||
client_printf("unknown type\n");
|
||||
@@ -372,6 +432,9 @@ char varval[TELNET_CMD_MAXSIZE];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n>1 && varval != NULL) {
|
||||
free(varval);
|
||||
}
|
||||
return CMDSTATUS_VARNOTFOUND;
|
||||
}
|
||||
/*----------------------------------------------------------------------------------------------------*/
|
||||
@@ -515,13 +578,14 @@ if(listen(sock, 1) == -1)
|
||||
fprintf(stderr,"[TELNETSRV] Error %s on listen call\n",strerror(errno));
|
||||
|
||||
|
||||
using_history();
|
||||
|
||||
printf("\nInitializing telnet server...\n");
|
||||
while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) )
|
||||
{
|
||||
printf("[TELNETSRV] Telnet client connected....\n");
|
||||
|
||||
|
||||
read_history(telnetparams.histfile);
|
||||
stifle_history(telnetparams.histsize);
|
||||
if(telnetparams.new_socket < 0)
|
||||
fprintf(stderr,"[TELNETSRV] Error %s on accept call\n",strerror(errno));
|
||||
|
||||
@@ -548,31 +612,43 @@ while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) )
|
||||
break;
|
||||
}
|
||||
if (telnetparams.telnetdbg > 0)
|
||||
printf("[TELNETSRV] Command received: readc %i filled %i %s\n", readc, filled ,buf);
|
||||
if (strlen(buf) >= 2 )
|
||||
printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled ,buf);
|
||||
if (buf[0] == '!') {
|
||||
if (buf[1] == '!') {
|
||||
sprintf(buf,"%s","telnet history list");
|
||||
} else {
|
||||
HIST_ENTRY *hisentry = history_get(strtol(buf+1,NULL,0));
|
||||
if (hisentry) {
|
||||
char msg[TELNET_MAX_MSGLENGTH + sizeof(TELNET_PROMPT) +10];
|
||||
sprintf(buf,"%s",hisentry->line);
|
||||
sprintf(msg,"%s %s\n",TELNET_PROMPT, hisentry->line);
|
||||
send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strlen(buf) > 2 )
|
||||
{
|
||||
status=process_command(buf);
|
||||
}
|
||||
else
|
||||
status=CMDSTATUS_NOCMD;
|
||||
|
||||
if (status != CMDSTATUS_EXIT)
|
||||
{
|
||||
if (status == CMDSTATUS_NOTFOUND)
|
||||
{
|
||||
if (status != CMDSTATUS_EXIT) {
|
||||
if (status == CMDSTATUS_NOTFOUND) {
|
||||
char msg[TELNET_MAX_MSGLENGTH + 50];
|
||||
sprintf(msg,"Error: \n %s\n is not a softmodem command\n",buf);
|
||||
send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL);
|
||||
}
|
||||
} else if (status == CMDSTATUS_FOUND) {
|
||||
add_history(buf);
|
||||
}
|
||||
send(telnetparams.new_socket, TELNET_PROMPT, sizeof(TELNET_PROMPT), MSG_NOSIGNAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
printf ("[TELNETSRV] Closing telnet connection...\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write_history(telnetparams.histfile);
|
||||
clear_history();
|
||||
close(telnetparams.new_socket);
|
||||
printf ("[TELNETSRV] Telnet server waitting for connection...\n");
|
||||
}
|
||||
@@ -588,7 +664,7 @@ return;
|
||||
*/
|
||||
void exec_moduleinit(char *modname)
|
||||
{
|
||||
void (*fptr)();
|
||||
void (*fptr)(void);
|
||||
char initfunc[TELNET_CMD_MAXSIZE+9];
|
||||
|
||||
if (strlen(modname) > TELNET_CMD_MAXSIZE)
|
||||
@@ -609,23 +685,26 @@ char initfunc[TELNET_CMD_MAXSIZE+9];
|
||||
}
|
||||
}
|
||||
|
||||
int add_embeddedmodules()
|
||||
int add_embeddedmodules(void)
|
||||
{
|
||||
|
||||
int ret=0;
|
||||
|
||||
|
||||
|
||||
for(int i=0; i<telnetoptions[TELNETSRV_STATICMOD].numelt;i++)
|
||||
{
|
||||
ret++;
|
||||
exec_moduleinit(telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int add_sharedmodules()
|
||||
int add_sharedmodules(void)
|
||||
{
|
||||
char initfunc[TELNET_CMD_MAXSIZE+9];
|
||||
void (*fptr)();
|
||||
|
||||
void (*fptr)(void);
|
||||
int ret=0;
|
||||
|
||||
for(int i=0; i<telnetoptions[TELNETSRV_SHRMOD].numelt;i++)
|
||||
{
|
||||
@@ -634,22 +713,23 @@ void (*fptr)();
|
||||
if ( fptr != NULL)
|
||||
{
|
||||
fptr();
|
||||
ret++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"[TELNETSRV] couldn't find %s for module %s \n",initfunc,telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int init_telnetsrv(char *cfgfile)
|
||||
int telnetsrv_autoinit(void)
|
||||
{
|
||||
void *lib_handle;
|
||||
char** moduleslist;
|
||||
|
||||
|
||||
memset(&telnetparams,0,sizeof(telnetparams));
|
||||
|
||||
config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),NULL);
|
||||
config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),"telnetsrv");
|
||||
|
||||
|
||||
if(pthread_create(&telnetparams.telnet_pthread,NULL, (void *(*)(void *))run_telnetsrv, NULL) != 0)
|
||||
@@ -691,6 +771,20 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* function which will be called by the shared lib loader, to check shared lib version
|
||||
against main exec version. version mismatch no considered as fatal (interfaces not supposed to change)
|
||||
*/
|
||||
int telnetsrv_checkbuildver(char * mainexec_buildversion, char ** shlib_buildversion)
|
||||
{
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__
|
||||
#endif
|
||||
*shlib_buildversion = PACKAGE_VERSION;
|
||||
if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) {
|
||||
fprintf(stderr,"[TELNETSRV] shared lib version %s, doesn't match main version %s, compatibility should be checked\n",
|
||||
mainexec_buildversion,*shlib_buildversion);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* 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
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
@@ -18,7 +18,6 @@
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file common/utils/telnetsrv/telnetsrv.h
|
||||
* \brief: include file for telnet server implementation
|
||||
* \author Francois TABURET
|
||||
@@ -38,7 +37,7 @@
|
||||
#define TELNET_MAX_MSGLENGTH 2048
|
||||
#define TELNET_PROMPT "softmodem> "
|
||||
#define TELNET_MAXCMD 20
|
||||
#define TELNET_CMD_MAXSIZE 10
|
||||
#define TELNET_CMD_MAXSIZE 20
|
||||
#define TELNET_HELPSTR_SIZE 80
|
||||
|
||||
/* status return by the command parser after it analysed user input */
|
||||
@@ -70,7 +69,7 @@ typedef struct cmddef {
|
||||
#define TELNET_VARTYPE_INT64 3
|
||||
#define TELNET_VARTYPE_STRING 4
|
||||
#define TELNET_VARTYPE_DOUBLE 5
|
||||
#define TELNET_VARTYPE_PTR 6
|
||||
//#define TELNET_VARTYPE_PTR 6
|
||||
typedef struct variabledef {
|
||||
char varname[TELNET_CMD_MAXSIZE];
|
||||
char vartype;
|
||||
@@ -96,6 +95,8 @@ typedef struct {
|
||||
pthread_t telnet_pthread; // thread id of the telnet server
|
||||
int telnetdbg; // debug level of the server
|
||||
int priority; // server running priority
|
||||
char *histfile; // command history
|
||||
int histsize; // command history length
|
||||
int new_socket; // socket of the client connection
|
||||
int logfilefd; // file id of the log file when log output is redirected to a file
|
||||
int saved_stdout; // file id of the previous stdout, used to be able to restore original stdout
|
||||
@@ -134,6 +135,6 @@ VT escape sequence definition, for smarter display....
|
||||
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd);
|
||||
void set_sched(pthread_t tid, int pid,int priority);
|
||||
void set_affinity(pthread_t tid, int pid, int coreid);
|
||||
extern int get_phybsize();
|
||||
extern int get_phybsize(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
|
||||
set(TELNETROOT ${OPENAIR_DIR}/common/utils/telnetsrv )
|
||||
|
||||
|
||||
|
||||
set(TELNETSRV_SOURCE
|
||||
${TELNETROOT}/telnetsrv.c
|
||||
${TELNETROOT}/telnetsrv_phycmd.c
|
||||
${TELNETROOT}/telnetsrv_proccmd.c
|
||||
${TELNETROOT}/telnetsrv_loader.c
|
||||
)
|
||||
|
||||
#set(TELNETSRV_ETHDEVCMD_SOURCE
|
||||
# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c
|
||||
# )
|
||||
|
||||
|
||||
|
||||
add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} )
|
||||
#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} )
|
||||
target_link_libraries(telnetsrv PRIVATE history)
|
||||
|
||||
install(TARGETS telnetsrv DESTINATION bin)
|
||||
|
||||
if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
|
||||
install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build)
|
||||
endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.1 (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/utils/telnetsrv/telnetsrv_loader.c
|
||||
* \brief: implementation of telnet commands related to softmodem linux process
|
||||
* \author Francois TABURET
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company NOKIA BellLabs France
|
||||
* \email: francois.taburet@nokia-bell-labs.com
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
#define TELNETSERVERCODE
|
||||
#include "telnetsrv.h"
|
||||
#define TELNETSRV_LOADER_MAIN
|
||||
#include "telnetsrv_loader.h"
|
||||
|
||||
|
||||
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
telnetshell_cmddef_t loader_cmdarray[] = {
|
||||
{"show","[params,modules]",loader_show_cmd},
|
||||
{"","",NULL},
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (debug > 0)
|
||||
prnt( "loader_show_cmd received %s\n",buff);
|
||||
|
||||
if (strcasestr(buff,"params") != NULL) {
|
||||
prnt( "loader parameters:\n");
|
||||
prnt( " Main executable build version: \"%s\"\n", loader_data.mainexec_buildversion);
|
||||
prnt( " Default shared lib path: \"%s\"\n", loader_data.shlibpath);
|
||||
prnt( " Max number of shared lib : %i\n", loader_data.maxshlibs);
|
||||
}
|
||||
else if (strcasestr(buff,"modules") != NULL) {
|
||||
prnt( "%i shared lib have been dynamicaly loaded by the oai loader\n", loader_data.numshlibs);
|
||||
for (int i=0 ; i<loader_data.numshlibs ; i++) {
|
||||
prnt( " Module %i: %s\n", i,loader_data.shlibs[i].name);
|
||||
prnt( " Shared library build version: \"%s\"\n",((loader_data.shlibs[i].shlib_buildversion == NULL )?"":loader_data.shlibs[i].shlib_buildversion));
|
||||
prnt( " Shared library path: \"%s\"\n", loader_data.shlibs[i].thisshlib_path);
|
||||
prnt( " %i function pointers registered:\n", loader_data.shlibs[i].numfunc);
|
||||
for(int j=0 ; j<loader_data.shlibs[i].numfunc;j++) {
|
||||
prnt( " function %i %s at %p\n",j,
|
||||
loader_data.shlibs[i].funcarray[j].fname, loader_data.shlibs[i].funcarray[j].fptr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
prnt("%s: wrong loader command...\n",buff);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void add_loader_cmds(void)
|
||||
{
|
||||
|
||||
add_telnetcmd("loader", loader_globalvardef, loader_cmdarray);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.1 (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/utils/telnetsrv_proccmd.h
|
||||
* \brief: Include file defining telnet commands related to softmodem linux process
|
||||
* \author Francois TABURET
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company NOKIA BellLabs France
|
||||
* \email: francois.taburet@nokia-bell-labs.com
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifdef TELNETSRV_LOADER_MAIN
|
||||
|
||||
#include "UTIL/LOG/log.h"
|
||||
|
||||
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
|
||||
|
||||
telnetshell_vardef_t loader_globalvardef[] = {
|
||||
{"mainversion",TELNET_VARTYPE_STRING,&(loader_data.mainexec_buildversion)},
|
||||
{"defpath",TELNET_VARTYPE_STRING,&(loader_data.shlibpath)},
|
||||
{"maxshlibs",TELNET_VARTYPE_INT32,&(loader_data.maxshlibs)},
|
||||
{"numshlibs",TELNET_VARTYPE_INT32,&(loader_data.numshlibs)},
|
||||
{"",0,NULL}
|
||||
};
|
||||
telnetshell_vardef_t *loader_modulesvardef;
|
||||
|
||||
extern void add_loader_cmds(void);
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
char *prnbuff;
|
||||
extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length);
|
||||
|
||||
void init_phytelnet()
|
||||
void init_phytelnet(void)
|
||||
{
|
||||
prnbuff=malloc(get_phybsize() );
|
||||
if (prnbuff == NULL)
|
||||
@@ -134,7 +134,7 @@ telnetshell_cmddef_t phy_cmdarray[] = {
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
void add_phy_cmds()
|
||||
void add_phy_cmds(void)
|
||||
{
|
||||
|
||||
init_phytelnet();
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
#define TELNETVAR_PHYCC1 1
|
||||
|
||||
telnetshell_vardef_t phy_vardef[] = {
|
||||
{"phycc1",TELNET_VARTYPE_PTR,NULL},
|
||||
{"phycc2",TELNET_VARTYPE_PTR,NULL},
|
||||
//{"iqmax",TELNET_VARTYPE_INT16,NULL},
|
||||
//{"iqmin",TELNET_VARTYPE_INT16,NULL},
|
||||
//{"loglvl",TELNET_VARTYPE_INT32,NULL},
|
||||
@@ -57,7 +55,7 @@ telnetshell_vardef_t phy_vardef[] = {
|
||||
|
||||
#else
|
||||
|
||||
extern void add_phy_cmds();
|
||||
extern void add_phy_cmds(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* 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
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
@@ -54,6 +54,8 @@
|
||||
#define TELNETSRV_PROCCMD_MAIN
|
||||
#include "log.h"
|
||||
#include "log_extern.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "openair1/PHY/extern.h"
|
||||
#include "telnetsrv_proccmd.h"
|
||||
|
||||
void decode_procstat(char *record, int debug, telnet_printfunc_t prnt)
|
||||
@@ -70,14 +72,13 @@ char toksep[2];
|
||||
lptr= prntline;
|
||||
/*http://man7.org/linux/man-pages/man5/proc.5.html gives the structure of the stat file */
|
||||
|
||||
while( procfile_fiels != NULL && fieldcnt < 42)
|
||||
{
|
||||
while( procfile_fiels != NULL && fieldcnt < 42) {
|
||||
long int policy;
|
||||
if (strlen(procfile_fiels) == 0)
|
||||
continue;
|
||||
fieldcnt++;
|
||||
sprintf(toksep," ");
|
||||
switch(fieldcnt)
|
||||
{
|
||||
switch(fieldcnt) {
|
||||
case 1: /* id */
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
|
||||
sprintf(toksep,")");
|
||||
@@ -104,12 +105,36 @@ char toksep[2];
|
||||
break;
|
||||
case 41: //policy
|
||||
lptr+=sprintf(lptr,"%3.3s ",procfile_fiels);
|
||||
policy=strtol(procfile_fiels,NULL,0);
|
||||
switch(policy) {
|
||||
case SCHED_FIFO:
|
||||
lptr+=sprintf(lptr,"%s ","rt: fifo");
|
||||
break;
|
||||
case SCHED_OTHER:
|
||||
lptr+=sprintf(lptr,"%s ","other");
|
||||
break;
|
||||
case SCHED_IDLE:
|
||||
lptr+=sprintf(lptr,"%s ","idle");
|
||||
break;
|
||||
case SCHED_BATCH:
|
||||
lptr+=sprintf(lptr,"%s ","batch");
|
||||
break;
|
||||
case SCHED_RR:
|
||||
lptr+=sprintf(lptr,"%s ","rt: rr");
|
||||
break;
|
||||
case SCHED_DEADLINE:
|
||||
lptr+=sprintf(lptr,"%s ","rt: deadline");
|
||||
break;
|
||||
default:
|
||||
lptr+=sprintf(lptr,"%s ","????");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}/* switch on fieldcnr */
|
||||
}/* switch on fieldcnr */
|
||||
procfile_fiels =strtok_r(NULL,toksep,&strtokptr);
|
||||
} /* while on proc_fields != NULL */
|
||||
} /* while on proc_fields != NULL */
|
||||
prnt("%s\n",prntline);
|
||||
} /*decode_procstat */
|
||||
|
||||
@@ -141,7 +166,7 @@ char aname[256];
|
||||
DIR *proc_dir;
|
||||
struct dirent *entry;
|
||||
|
||||
int rt;
|
||||
|
||||
|
||||
prnt(" id name state USRmod KRNmod prio nice vsize proc pol \n\n");
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/stat", getpid());
|
||||
@@ -172,14 +197,51 @@ extern log_t *g_log;
|
||||
|
||||
if (debug > 0)
|
||||
prnt(" proccmd_show received %s\n",buf);
|
||||
if (strcasestr(buf,"thread") != NULL)
|
||||
{
|
||||
if (strcasestr(buf,"thread") != NULL) {
|
||||
print_threads(buf,debug,prnt);
|
||||
}
|
||||
}
|
||||
if (strcasestr(buf,"loglvl") != NULL) {
|
||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++){
|
||||
prnt("\t%s:\t%s\t%s\n",g_log->log_component[i].name, map_int_to_str(log_verbosity_names,g_log->log_component[i].flag),
|
||||
map_int_to_str(log_level_names,g_log->log_component[i].level));
|
||||
prnt("component verbosity level enabled\n");
|
||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
prnt("%02i %17.17s:%10.10s%10.10s %s\n",i ,g_log->log_component[i].name,
|
||||
map_int_to_str(log_verbosity_names,g_log->log_component[i].flag),
|
||||
map_int_to_str(log_level_names,g_log->log_component[i].level),
|
||||
((g_log->log_component[i].interval>0)?"Y":"N") );
|
||||
}
|
||||
}
|
||||
if (strcasestr(buf,"config") != NULL) {
|
||||
prnt("Command line arguments:\n");
|
||||
for (int i=0; i < config_get_if()->argc; i++) {
|
||||
prnt(" %02i %s\n",i ,config_get_if()->argv[i]);
|
||||
}
|
||||
prnt("Config module flags ( -O <cfg source>:<xxx>:dbgl<flags>): 0x%08x\n", config_get_if()->rtflags);
|
||||
|
||||
prnt(" Print config debug msg, params values (flag %u): %s\n",CONFIG_PRINTPARAMS,
|
||||
((config_get_if()->rtflags & CONFIG_PRINTPARAMS) ? "Y" : "N") );
|
||||
prnt(" Print config debug msg, memory management(flag %u): %s\n",CONFIG_DEBUGPTR,
|
||||
((config_get_if()->rtflags & CONFIG_DEBUGPTR) ? "Y" : "N") );
|
||||
prnt(" Print config debug msg, command line processing (flag %u): %s\n",CONFIG_DEBUGCMDLINE,
|
||||
((config_get_if()->rtflags & CONFIG_DEBUGCMDLINE) ? "Y" : "N") );
|
||||
prnt(" Don't exit if param check fails (flag %u): %s\n",CONFIG_NOABORTONCHKF,
|
||||
((config_get_if()->rtflags & CONFIG_NOABORTONCHKF) ? "Y" : "N") );
|
||||
prnt("Config source: %s, parameters:\n",CONFIG_GETSOURCE );
|
||||
for (int i=0; i < config_get_if()->num_cfgP; i++) {
|
||||
prnt(" %02i %s\n",i ,config_get_if()->cfgP[i]);
|
||||
}
|
||||
prnt("Softmodem components:\n");
|
||||
prnt(" %02i Ru(s)\n", RC.nb_RU);
|
||||
prnt(" %02i lte RRc(s), %02i NbIoT RRC(s)\n", RC.nb_inst, RC.nb_nb_iot_rrc_inst);
|
||||
prnt(" %02i lte MACRLC(s), %02i NbIoT MACRLC(s)\n", RC.nb_macrlc_inst, RC.nb_nb_iot_macrlc_inst);
|
||||
prnt(" %02i lte L1, %02i NbIoT L1\n", RC.nb_L1_inst, RC.nb_nb_iot_L1_inst);
|
||||
|
||||
for(int i=0; i<RC.nb_inst; i++) {
|
||||
prnt(" lte RRC %i: %02i CC(s) \n",i,((RC.nb_CC == NULL)?0:RC.nb_CC[i]));
|
||||
}
|
||||
for(int i=0; i<RC.nb_L1_inst; i++) {
|
||||
prnt(" lte L1 %i: %02i CC(s)\n",i,((RC.nb_L1_CC == NULL)?0:RC.nb_L1_CC[i]));
|
||||
}
|
||||
for(int i=0; i<RC.nb_macrlc_inst; i++) {
|
||||
prnt(" lte macrlc %i: %02i CC(s)\n",i,((RC.nb_mac_CC == NULL)?0:RC.nb_mac_CC[i]));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -190,12 +252,16 @@ int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
int bv1,bv2;
|
||||
int res;
|
||||
char sv1[64];
|
||||
char tname[32];
|
||||
|
||||
bv1=0;
|
||||
bv2=0;
|
||||
sv1[0]=0;
|
||||
if (debug > 0)
|
||||
prnt("proccmd_thread received %s\n",buf);
|
||||
if (strcasestr(buf,"help") != NULL) {
|
||||
prnt(PROCCMD_THREAD_HELP_STRING);
|
||||
return 0;
|
||||
}
|
||||
res=sscanf(buf,"%i %9s %i",&bv1,sv1,&bv2);
|
||||
if (debug > 0)
|
||||
prnt(" proccmd_thread: %i params = %i,%s,%i\n",res,bv1,sv1,bv2);
|
||||
@@ -231,32 +297,95 @@ extern void exit_fun(const char* s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
int idx1=0;
|
||||
int idx2=NUM_LOG_LEVEL-1;
|
||||
int s = sscanf(buf,"%*s %i-%i",&idx1,&idx2);
|
||||
char *logsubcmd=NULL;
|
||||
|
||||
int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
|
||||
if (debug > 0)
|
||||
prnt("process module received %s\n",buf);
|
||||
prnt( "proccmd_log received %s\n s=%i sub command %s\n",buf,s,((logsubcmd==NULL)?"":logsubcmd));
|
||||
|
||||
if (s == 1 && logsubcmd != NULL) {
|
||||
if (strcasestr(logsubcmd,"online") != NULL) {
|
||||
if (strcasestr(buf,"noonline") != NULL) {
|
||||
set_glog_onlinelog(0);
|
||||
prnt("online logging disabled\n",buf);
|
||||
} else {
|
||||
set_glog_onlinelog(1);
|
||||
prnt("online logging enabled\n",buf);
|
||||
}
|
||||
}
|
||||
else if (strcasestr(logsubcmd,"show") != NULL) {
|
||||
prnt("Available log levels: \n ");
|
||||
for (int i=0; log_level_names[i].name != NULL; i++)
|
||||
prnt("%s ",log_level_names[i].name);
|
||||
prnt("\nAvailable verbosity: \n ");
|
||||
for (int i=0; log_verbosity_names[i].name != NULL; i++)
|
||||
prnt("%s ",log_verbosity_names[i].name);
|
||||
prnt("\n");
|
||||
proccmd_show("loglvl",debug,prnt);
|
||||
}
|
||||
else if (strcasestr(logsubcmd,"help") != NULL) {
|
||||
prnt(PROCCMD_LOG_HELP_STRING);
|
||||
} else {
|
||||
prnt("%s: wrong log command...\n",logsubcmd);
|
||||
}
|
||||
} else if ( s == 3 && logsubcmd != NULL) {
|
||||
int level, verbosity, interval;
|
||||
char *tmpstr=NULL;
|
||||
char *logparam=NULL;
|
||||
int l;
|
||||
|
||||
level = verbosity = interval = -1;
|
||||
l=sscanf(logsubcmd,"%m[^'_']_%m[^'_']",&logparam,&tmpstr);
|
||||
if (debug > 0)
|
||||
prnt("l=%i, %s %s\n",l,((logparam==NULL)?"\"\"":logparam), ((tmpstr==NULL)?"\"\"":tmpstr));
|
||||
if (l ==2 ) {
|
||||
if (strcmp(logparam,"level") == 0) {
|
||||
level=map_str_to_int(log_level_names,tmpstr);
|
||||
if (level < 0) prnt("level %s unknown\n",tmpstr);
|
||||
} else if (strcmp(logparam,"verbos") == 0) {
|
||||
verbosity=map_str_to_int(log_verbosity_names,tmpstr);
|
||||
if (verbosity < 0) prnt("verbosity %s unknown\n",tmpstr);
|
||||
} else {
|
||||
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
|
||||
}
|
||||
} else if (l ==1 ) {
|
||||
if (strcmp(logparam,"enable") == 0) {
|
||||
interval = 1;
|
||||
} else if (strcmp(logparam,"disable") == 0) {
|
||||
interval = 0;
|
||||
} else {
|
||||
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
|
||||
}
|
||||
} else {
|
||||
prnt("%s unknown log sub command \n",logsubcmd);
|
||||
}
|
||||
if (logparam != NULL) free(logparam);
|
||||
if (tmpstr != NULL) free(tmpstr);
|
||||
for (int i=idx1; i<=idx2 ; i++) {
|
||||
set_comp_log(i, level, verbosity, interval);
|
||||
prnt("log level/verbosity comp %i %s set to %s / %s (%s)\n",
|
||||
i,((g_log->log_component[i].name==NULL)?"":g_log->log_component[i].name),
|
||||
map_int_to_str(log_level_names,g_log->log_component[i].level),
|
||||
map_int_to_str(log_verbosity_names,g_log->log_component[i].flag),
|
||||
((g_log->log_component[i].interval>0)?"enabled":"disabled"));
|
||||
|
||||
|
||||
}
|
||||
} else {
|
||||
prnt("%s: wrong log command...\n",buf);
|
||||
}
|
||||
|
||||
if (strcasestr(buf,"enable") != NULL)
|
||||
{
|
||||
set_glog_onlinelog(1);
|
||||
}
|
||||
if (strcasestr(buf,"disable") != NULL)
|
||||
{
|
||||
set_glog_onlinelog(0);
|
||||
}
|
||||
if (strcasestr(buf,"show") != NULL)
|
||||
{
|
||||
proccmd_show("loglvl",debug,prnt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
|
||||
void add_softmodem_cmds()
|
||||
void add_softmodem_cmds(void)
|
||||
{
|
||||
add_telnetcmd("softmodem",proc_vardef,proc_cmdarray);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* 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
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
@@ -19,6 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
|
||||
/*! \file common/utils/telnetsrv/telnetsrv_proccmd.h
|
||||
* \brief: Include file defining telnet commands related to this linux process
|
||||
* \author Francois TABURET
|
||||
@@ -43,15 +44,33 @@ extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
telnetshell_vardef_t proc_vardef[] = {
|
||||
{"",0,NULL}
|
||||
};
|
||||
#define PROCCMD_LOG_HELP_STRING " log sub commands: \n\
|
||||
show: display current log configuration \n\
|
||||
online, noonline: enable or disable console logs \n\
|
||||
enable, disable id1-id2: enable or disable logs for components index id1 to id2 \n\
|
||||
level_<level> id1-id2: set log level to <level> for components index id1 to id2 \n\
|
||||
level_<verbosity> id1-id2: set log verbosity to <verbosity> for components index id1 to id2 \n\
|
||||
use the show command to get the values for <level>, <verbosity> and the list of component indexes \
|
||||
that can be used for id1 and id2 \n"
|
||||
|
||||
#define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\
|
||||
<thread id> aff <core> : set affinity of thread <thread id> to core <core> \n\
|
||||
<thread id> prio <prio> : set scheduling parameters for thread <thread id> \n\
|
||||
if prio < -20: linux scheduling policy set to FIFO, \n\
|
||||
with priority = -20 - prio \n\
|
||||
if prio > 19: linux scheduling policy set to OTHER, \n\
|
||||
with priority (nice value) = prio \n\
|
||||
use \"softmodem show thread\" to get <thread id> \n"
|
||||
|
||||
|
||||
telnetshell_cmddef_t proc_cmdarray[] = {
|
||||
{"show","loglvl|thread", proccmd_show},
|
||||
{"log","[enable,disable]", proccmd_log},
|
||||
{"thread","<id> aff|prio <aff|prio>", proccmd_thread},
|
||||
{"show","loglvl|thread|config", proccmd_show},
|
||||
{"log","(enter help for details)", proccmd_log},
|
||||
{"thread","(enter help for details)", proccmd_thread},
|
||||
{"exit","", proccmd_exit},
|
||||
{"","",NULL},
|
||||
};
|
||||
#else
|
||||
extern void add_proccmd_cmds();
|
||||
extern void add_proccmd_cmds(void);
|
||||
#endif /* TELNETSRV_PROCCMD_MAIN */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user