diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index c22ecf964a0e99d6734cd7c97c3b20e6bcd8cde5..170f8963cf032ea20ce87ba30918a114760a0277 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -54,7 +54,7 @@ char defbool[2]="1"; } else { /* boolean value */ tmpval = defbool; } - printf("cc 0x%08x, %i\n",tmpval,argok); + switch(cfgoptions->type) { case TYPE_STRING: diff --git a/common/utils/telnetsrv/CMakeLists.txt b/common/utils/telnetsrv/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..6e6c21c2dbad61cfe6c699a10dfe90aebfa643da --- /dev/null +++ b/common/utils/telnetsrv/CMakeLists.txt @@ -0,0 +1,52 @@ +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(APPROOT . ) +set(OPENAIR_DIR $ENV{OPENAIR_DIR}) +set(OPENAIR_BUILD_DIR $ENV{OPENAIR_DIR}/cmake_targets) +set(OPENAIR1_DIR $ENV{OPENAIR1_DIR}) +set(OPENAIR2_DIR $ENV{OPENAIR2_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_FXP -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 -DNB_ANTENNAS_TXRX=2 -DNEW_FFT -DNO_RRM -DNone=1 -DOAI_NW_DRIVER_USE_NETLINK -DOPENAIR1 -DOPENAIR2 -DOPENAIR_LTE -DPC_DSP -DPC_TARGET -DPHYSIM -DPHY_CONTEXT -DPUCCH -DRel10=1 -DS1AP_VERSION=R10 -DTRACE_RLC_MUTEX -DUSER_MODE -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_ASN1INC} ${OPENAIR_TARGET_DIR}/COMMON ${OPENAIR_TARGET_DIR}/ARCH/COMMON + ${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") diff --git a/common/utils/telnetsrv/load_telnet.c b/common/utils/telnetsrv/load_telnet.c new file mode 100644 index 0000000000000000000000000000000000000000..850c02531317672ef542da56018bdf1647042ae3 --- /dev/null +++ b/common/utils/telnetsrv/load_telnet.c @@ -0,0 +1,45 @@ + +/* FT NOKBLF: + * this source is to be linked with the program using the telnet server, it looks for + * the telnet server dynamic library, possibly loads it and calls the telnet server + * init functions +*/ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/ioctl.h> +#include <dlfcn.h> +#include "telnetsrv.h" +#include "openair1/PHY/defs.h" + +int load_telnet(void) +{ + void *lib_handle; + initfunc_t fpi; + + + lib_handle = dlopen(TELNETSRV_SHAREDLIB, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); + if (!lib_handle) + { + printf("[TELNETSRV] telnet server is not loaded: %s\n", dlerror()); + return -1; + } + + fpi = dlsym(lib_handle,"init_telnetsrv"); + + if (fpi != NULL ) + { + fpi(cfgfile); + } + else + { + fprintf(stderr,"[TELNETSRV] %s %d Telnet server init function not found %s\n",__FILE__, __LINE__, dlerror()); + return -1; + } + + + dlclose(lib_handle); + return 0; +} diff --git a/common/utils/telnetsrv/load_telnet.h b/common/utils/telnetsrv/load_telnet.h new file mode 100644 index 0000000000000000000000000000000000000000..73543fe38ad14439884214ee6aaeca46097f83b8 --- /dev/null +++ b/common/utils/telnetsrv/load_telnet.h @@ -0,0 +1,5 @@ +#ifndef TELNET_LOAD_H +#define TELNET_LOAD_H +#include "telnetsrv.h" +extern int load_telnet(void); +#endif diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c new file mode 100644 index 0000000000000000000000000000000000000000..6d6b84f5684f209f20b2b4cf2504f16dc7e140b1 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv.c @@ -0,0 +1,696 @@ +/* + * 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/utils/telnetsrv.c + * \brief: implementation of a telnet server + * \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 <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <pthread.h> +#include <telnetsrv.h> +#include <string.h> +#include <stdarg.h> +#include <unistd.h> +#include <fcntl.h> +#include <dlfcn.h> +#include <sys/time.h> +#include <sys/resource.h> + +#include "common/config/config_userapi.h" + + +#include "telnetsrv_phycmd.h" +#include "telnetsrv_proccmd.h" +static char* telnet_defstatmod[] = {"softmodem","phy"}; +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 +paramdef_t telnetoptions[] = { +/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* configuration parameters for telnet utility */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + {"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 }, + {"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 }, + {"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 }, +}; + +int get_phybsize() {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); + +telnetshell_vardef_t telnet_vardef[] = { +{"debug",TELNET_VARTYPE_INT32,&telnetparams.telnetdbg}, +{"prio",TELNET_VARTYPE_INT32,&telnetparams.priority}, +{"loopc",TELNET_VARTYPE_INT32,&telnetparams.loopcount}, +{"loopd",TELNET_VARTYPE_INT32,&telnetparams.loopdelay}, +{"phypb",TELNET_VARTYPE_INT32,&telnetparams.phyprntbuff_size}, +{"",0,NULL} +}; + +telnetshell_cmddef_t telnet_cmdarray[] = { + {"redirlog","[here,file,off]",setoutput}, + {"param","[prio]",setparam}, + {"","",NULL}, +}; + + +void client_printf(const char *message, ...) +{ + va_list va_args; + + va_start(va_args, message); + if (telnetparams.new_socket > 0) + { + vsnprintf(telnetparams.msgbuff,sizeof(telnetparams.msgbuff)-1,message, va_args); + send(telnetparams.new_socket,telnetparams.msgbuff , strlen(telnetparams.msgbuff), MSG_NOSIGNAL); + } + else + { + vprintf(message, va_args); + } + va_end(va_args); + return ; +} + +#define NICE_MAX 19 +#define NICE_MIN -20 +void set_sched(pthread_t tid, int pid, int priority) +{ +int rt; +struct sched_param schedp; +int policy; +char strpolicy[10]; + + +//sched_get_priority_max(SCHED_FIFO) +if (priority < NICE_MIN) + { + policy=SCHED_FIFO; + sprintf(strpolicy,"%s","fifo"); + schedp.sched_priority= NICE_MIN - priority ; + } +else if (priority > NICE_MAX) + { + policy=SCHED_IDLE; + sprintf(strpolicy,"%s","idle"); + schedp.sched_priority=0; + } +else + { + policy=SCHED_OTHER; + sprintf(strpolicy,"%s","other"); + schedp.sched_priority=0; + } +if( tid != 0) + { + rt = pthread_setschedparam(tid, policy, &schedp); + } +else if(pid > 0) + { + rt = sched_setscheduler( pid, policy,&schedp); + } +if (rt != 0) + { + client_printf("Error %i: %s modifying sched param to %s:%i, \n", + errno,strerror(errno),strpolicy,schedp.sched_priority); + } +else + { + client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority); + } + + + +if ( policy == SCHED_OTHER) + { + if ( tid > 0 && tid != pthread_self()) + { + client_printf("setting nice value using a thread id not implemented....\n"); + } + else if (pid > 0) + { + errno=0; + rt = setpriority(PRIO_PROCESS,pid,priority); + if (rt != 0) + { + client_printf("Error %i: %s calling setpriority, \n",errno,strerror(errno)); + } + else + { + client_printf("nice value set to %i\n",priority); + } + } + } +} + +void set_affinity(pthread_t tid, int pid, int coreid) +{ +cpu_set_t cpuset; +int rt; + + CPU_ZERO(&cpuset); + CPU_SET(coreid, &cpuset); + if (tid > 0) + { + rt = pthread_setaffinity_np((pthread_t)tid, sizeof(cpu_set_t), &cpuset); + } + else if (pid > 0) + { + rt = sched_setaffinity((pid_t)pid, sizeof(cpu_set_t), &cpuset); + } + if (rt != 0) + { + client_printf("Error %i: %s calling , xxx_setaffinity...\n",errno,strerror(errno)); + } + else + { + client_printf("thread %i affinity set to %i\n",(pid==0)?(int)tid:pid,coreid); + } +} +/*------------------------------------------------------------------------------------*/ +/* +function implementing telnet server specific commands, parameters of the +telnet_cmdarray table +*/ + +void redirstd(char *newfname,telnet_printfunc_t prnt ) +{ +FILE *fd; + fd=freopen(newfname, "w", stdout); + if (fd == NULL) + { + prnt("ERROR: stdout redir to %s error %s",strerror(errno)); + } + fd=freopen(newfname, "w", stderr); + if (fd == NULL) + { + prnt("ERROR: stderr redir to %s error %s",strerror(errno)); + } +} +int setoutput(char *buff, int debug, telnet_printfunc_t prnt) +{ + +char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE]; +char *logfname; +char stdout_str[64]; + + +#define LOGFILE "logfile.log" +memset(cmds,0,sizeof(cmds)); +sscanf(buff,"%9s %32s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] ); +if (strncasecmp(cmds[0],"here",4) == 0) + { + fflush(stdout); + sprintf(stdout_str,"/proc/%i/fd/%i",getpid(),telnetparams.new_socket); + dup2(telnetparams.new_socket,fileno(stdout)); +// freopen(stdout_str, "w", stdout); +// freopen(stdout_str, "w", stderr); + dup2(telnetparams.new_socket,fileno(stderr)); + prnt("Log output redirected to this terminal (%s)\n",stdout_str); + } +if (strncasecmp(cmds[0],"file",4) == 0) + { + if (cmds[1][0] == 0) + logfname=LOGFILE; + else + logfname=cmds[1]; + fflush(stdout); + redirstd(logfname,prnt); + + } +if (strncasecmp(cmds[0],"off",3) == 0) + { + fflush(stdout); + redirstd("/dev/tty",prnt); + } + +return CMDSTATUS_FOUND; +} /* setoutput */ + +int setparam(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 (strncasecmp(cmds[0],"prio",4) == 0) + { + pthread_attr_t attr; + int prio; + prio=(int)strtol(cmds[1],NULL,0); + if (errno == ERANGE) + return CMDSTATUS_VARNOTFOUND; + telnetparams.priority = prio; + set_sched(pthread_self(),0,prio); + return CMDSTATUS_FOUND; + } +if (strncasecmp(cmds[0],"aff",3) == 0) + { + int aff; + aff=(int)strtol(cmds[1],NULL,0); + if (errno == ERANGE) + return CMDSTATUS_VARNOTFOUND; + set_affinity(pthread_self(),0,aff); + return CMDSTATUS_FOUND; + } + +return CMDSTATUS_NOTFOUND; +} /* setparam */ +/*-------------------------------------------------------------------------------------------------------*/ +/* +generic commands available for all modules loaded by the server +*/ + +int setgetvar(int moduleindex,char getorset,char *params) +{ +int n,i; +char varname[TELNET_CMD_MAXSIZE]; +char varval[TELNET_CMD_MAXSIZE]; + + memset(varname,0,sizeof(varname)); + memset(varval,0,sizeof(varval)); + n = sscanf(params,"%s %s",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) + { + if (n > 0 && (getorset == 'g' || getorset == 'G')) + { + client_printf("%s, %s = ", telnetparams.CmdParsers[moduleindex].module, + telnetparams.CmdParsers[moduleindex].var[i].varname ); + switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) + { + case TELNET_VARTYPE_INT32: + client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_INT16: + client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + 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))); + break; + default: + client_printf("unknown type\n"); + break; + } + } + if (n > 1 && (getorset == 's' || getorset == 'S')) + { + client_printf("%s, %s set to \n", telnetparams.CmdParsers[moduleindex].module, + telnetparams.CmdParsers[moduleindex].var[i].varname); + + switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) + { + case TELNET_VARTYPE_INT32: + *(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (int)strtol(varval,NULL,0); + client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_INT16: + *(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (short)strtol(varval,NULL,0); + client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + 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; + default: + client_printf("unknown type\n"); + break; + } + } + } + } +return CMDSTATUS_VARNOTFOUND; +} +/*----------------------------------------------------------------------------------------------------*/ +char *get_time(char *buff,int bufflen) +{ + +struct tm tmstruct; +time_t now = time (0); +strftime (buff, bufflen, "%Y-%m-%d %H:%M:%S.000", localtime_r(&now,&tmstruct)); +return buff; +} + +int process_command(char *buf) +{ +int i,j,k; +char modulename[TELNET_CMD_MAXSIZE]; +char cmd[TELNET_CMD_MAXSIZE]; +char cmdb[TELNET_MAX_MSGLENGTH]; +char *bufbck; +int rt; + +memset(modulename,0,sizeof(modulename)); +memset(cmd,0,sizeof(cmd)); +memset(cmdb,0,sizeof(cmdb)); +if (strncasecmp(buf,"ex",2) == 0) + return CMDSTATUS_EXIT; + +if (strncasecmp(buf,"help",4) == 0) + { + for (i=0; telnetparams.CmdParsers[i].var != NULL && telnetparams.CmdParsers[i].cmd != NULL; i++) + { + client_printf(" module %i = %s:\n",i,telnetparams.CmdParsers[i].module); + for(j=0; telnetparams.CmdParsers[i].var[j].varvalptr != NULL ; j++) + { + client_printf(" %s [get set] %s <value>\n", + telnetparams.CmdParsers[i].module, telnetparams.CmdParsers[i].var[j].varname); + } + for(j=0; telnetparams.CmdParsers[i].cmd[j].cmdfunc != NULL ; j++) + { + client_printf(" %s %s %s\n", + telnetparams.CmdParsers[i].module,telnetparams.CmdParsers[i].cmd[j].cmdname, + telnetparams.CmdParsers[i].cmd[j].helpstr); + } + } + return CMDSTATUS_FOUND; + } + +memset(modulename,0,sizeof(modulename)); +memset(cmd,0,sizeof(cmd)); +memset(cmdb,0,sizeof(cmdb)); +bufbck=strdup(buf); +rt=CMDSTATUS_NOTFOUND; +j = sscanf(buf,"%9s %9s %[^\t\n]",modulename,cmd,cmdb); +if (telnetparams.telnetdbg > 0) + printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb); +for (i=0; j>=2 && telnetparams.CmdParsers[i].var != NULL && telnetparams.CmdParsers[i].cmd != NULL; i++) + { + if ( (strncasecmp(telnetparams.CmdParsers[i].module,modulename,strlen(telnetparams.CmdParsers[i].module)) == 0)) + { + if (strncasecmp(cmd,"getall",7) == 0 ) + { + for(j=0; telnetparams.CmdParsers[i].var[j].varvalptr != NULL ; j++) + { + setgetvar(i,'g',telnetparams.CmdParsers[i].var[j].varname); + } + rt= CMDSTATUS_FOUND; + } + else if (strncasecmp(cmd,"get",3) == 0 || strncasecmp(cmd,"set",3) == 0) + { + rt= setgetvar(i,cmd[0],cmdb); + } + else + { + for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++) + { + if (strncasecmp(cmd, telnetparams.CmdParsers[i].cmd[k].cmdname,sizeof(telnetparams.CmdParsers[i].cmd[k].cmdname)) == 0) + { + telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf); + rt= CMDSTATUS_FOUND; + } + } /* for k */ + }/* else */ + }/* strncmp: module name test */ + else if (strncasecmp(modulename,"loop",4) == 0 ) + { + int lc; + int f = fcntl(telnetparams.new_socket,F_GETFL); + fcntl (telnetparams.new_socket, F_SETFL, O_NONBLOCK | f); + for(lc=0; lc<telnetparams.loopcount; lc++) + { + char dummybuff[20]; + char tbuff[64]; + int rs; + client_printf(CSI "1J" CSI "1;10H " STDFMT "%s %i/%i\n", + get_time(tbuff,sizeof(tbuff)),lc,telnetparams.loopcount ); + process_command(bufbck+strlen("loop")+1); + usleep(telnetparams.loopdelay * 1000); + rs = read(telnetparams.new_socket,dummybuff,sizeof(dummybuff)); + if ( rs > 0 ) + { + break; + } + } + fcntl (telnetparams.new_socket, F_SETFL, f); + rt= CMDSTATUS_FOUND; + } /* loop */ + } /* for i */ +free(bufbck); +return rt; +} + +void run_telnetsrv(void) +{ +int sock; +struct sockaddr_in name; +char buf[TELNET_MAX_MSGLENGTH]; +struct sockaddr cli_addr; +unsigned int cli_len = sizeof(cli_addr); +int readc , filled; + +int status; +int optval = 1; + +pthread_setname_np(pthread_self(), "telnet"); +set_sched(pthread_self(),0,telnetparams.priority); +sock = socket(AF_INET, SOCK_STREAM, 0); +if (sock < 0) + fprintf(stderr,"[TELNETSRV] Error %s on socket call\n",strerror(errno)); + +setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval); +name.sin_family = AF_INET; +if (telnetparams.listenaddr == 0) + name.sin_addr.s_addr = INADDR_ANY; +else + name.sin_addr.s_addr = telnetparams.listenaddr; +name.sin_port = htons((unsigned short)(telnetparams.listenport)); + +if(bind(sock, (void*) &name, sizeof(name))) + fprintf(stderr,"[TELNETSRV] Error %s on bind call\n",strerror(errno)); +if(listen(sock, 1) == -1) + fprintf(stderr,"[TELNETSRV] Error %s on listen call\n",strerror(errno)); + + + +printf("\nInitializing telnet server...\n"); +while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) + { + printf("[TELNETSRV] Telnet client connected....\n"); + + + if(telnetparams.new_socket < 0) + fprintf(stderr,"[TELNETSRV] Error %s on accept call\n",strerror(errno)); + + while(telnetparams.new_socket>0) + { + filled = 0; + memset(buf,0,sizeof(buf)); + while(filled < ( TELNET_MAX_MSGLENGTH-1)) + { + readc = recv(telnetparams.new_socket, buf+filled, TELNET_MAX_MSGLENGTH-filled-1, 0); + if(!readc) + break; + filled += readc; + if(buf[filled-1] == '\n') + { + buf[filled-1] = 0; + + break; + } + } + if(!readc) + { + printf ("[TELNETSRV] Telnet Client disconnected.\n"); + break; + } + if (telnetparams.telnetdbg > 0) + printf("[TELNETSRV] Command received: readc %i filled %i %s\n", readc, filled ,buf); + if (strlen(buf) >= 2 ) + { + status=process_command(buf); + } + else + status=CMDSTATUS_NOCMD; + + 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); + } + send(telnetparams.new_socket, TELNET_PROMPT, sizeof(TELNET_PROMPT), MSG_NOSIGNAL); + } + else + { + printf ("[TELNETSRV] Closing telnet connection...\n"); + break; + } + } + + close(telnetparams.new_socket); + printf ("[TELNETSRV] Telnet server waitting for connection...\n"); + } +close(sock); +return; +} + +/*------------------------------------------------------------------------------------------------*/ +/* set_telnetmodule loads the commands delivered with the telnet server + * + * + * +*/ +void exec_moduleinit(char *modname) +{ +void (*fptr)(); +char initfunc[TELNET_CMD_MAXSIZE+9]; + + if (strlen(modname) > TELNET_CMD_MAXSIZE) + { + fprintf(stderr,"[TELNETSRV] module %s not loaded, name exceeds the %i size limit\n", + modname, TELNET_CMD_MAXSIZE); + return; + } + sprintf(initfunc,"add_%s_cmds",modname); + fptr = dlsym(RTLD_DEFAULT,initfunc); + if ( fptr != NULL) + { + fptr(); + } + else + { + fprintf(stderr,"[TELNETSRV] couldn't find %s for module %s \n",initfunc,modname); + } +} + +int add_embeddedmodules() +{ + + + + + for(int i=0; i<telnetoptions[TELNETSRV_STATICMOD].numelt;i++) + { + exec_moduleinit(telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]); + } +} + +int add_sharedmodules() +{ +char initfunc[TELNET_CMD_MAXSIZE+9]; +void (*fptr)(); + + + for(int i=0; i<telnetoptions[TELNETSRV_SHRMOD].numelt;i++) + { + sprintf(initfunc,"add_%s_cmds",telnetoptions[TELNETSRV_SHRMOD].strlistptr[i]); + fptr = dlsym(RTLD_DEFAULT,initfunc); + if ( fptr != NULL) + { + fptr(); + } + else + { + fprintf(stderr,"[TELNETSRV] couldn't find %s for module %s \n",initfunc,telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]); + } + } +} + +int init_telnetsrv(char *cfgfile) + { + void *lib_handle; + char** moduleslist; + + memset(&telnetparams,0,sizeof(telnetparams)); + + config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),NULL); + + + if(pthread_create(&telnetparams.telnet_pthread,NULL, (void *(*)(void *))run_telnetsrv, NULL) != 0) + { + fprintf(stderr,"[TELNETSRV] Error %s on pthread_create call\n",strerror(errno)); + return -1; + } + add_telnetcmd("telnet", telnet_vardef, telnet_cmdarray); + add_embeddedmodules(); + return 0; + } + +/*---------------------------------------------------------------------------------------------*/ +/* add_telnetcmd is used to add a set of commands to the telnet server. A module calls this + * function at init time. the telnet server is delivered with a set of commands which + * will be loaded or not depending on the telnet section of the config file +*/ +int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd) + { + int i; + if( modulename == NULL || var == NULL || cmd == NULL) + { + fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n"); + return -1; + } + for (i=0; i<TELNET_MAXCMD ; i++) + { + if (telnetparams.CmdParsers[i].var == NULL) + { + strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1); + telnetparams.CmdParsers[i].cmd = cmd; + telnetparams.CmdParsers[i].var = var; + printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n", + i,telnetparams.CmdParsers[i].module); + break; + } + } + return 0; + } + + + + + diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h new file mode 100644 index 0000000000000000000000000000000000000000..5663b44d67ea438d52526d924632dbb38c4d5631 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv.h @@ -0,0 +1,108 @@ +#ifndef TELNETSRV_H +#define TELNETSRV_H + +#define TELNETSRV_SHAREDLIB "libtelnetsrv.so" + +#define TELNET_PORT 9090 +#define TELNET_MAX_MSGLENGTH 2048 +#define TELNET_PROMPT "softmodem> " +#define TELNET_MAXCMD 20 +#define TELNET_CMD_MAXSIZE 10 +#define TELNET_HELPSTR_SIZE 80 + +/* status return by the command parser after it analysed user input */ +#define CMDSTATUS_NOCMD 0 +#define CMDSTATUS_EXIT 1 +#define CMDSTATUS_FOUND 2 +#define CMDSTATUS_VARNOTFOUND 3 +#define CMDSTATUS_NOTFOUND 4 + +/*----------------------------------------------------------------------------*/ +/* structure to be used when adding a module to the telnet server */ +/* This is the second parameter of the add_telnetcmd function, which can be used */ +/* to add a set of new command to the telnet server shell */ +typedef void(*telnet_printfunc_t)(const char* format, ...); +typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt); + +typedef struct cmddef { + char cmdname[TELNET_CMD_MAXSIZE]; + char helpstr[TELNET_HELPSTR_SIZE]; + cmdfunc_t cmdfunc; +} telnetshell_cmddef_t; + +/*----------------------------------------------------------------------------*/ +/*structure to be used when adding a module to the telnet server */ +/* This is the first parameter of the add_telnetcmd function, which can be used */ +/* to add a set of new variables which can be got/set from the telnet server shell */ +#define TELNET_VARTYPE_INT32 1 +#define TELNET_VARTYPE_INT16 2 +#define TELNET_VARTYPE_INT64 3 +#define TELNET_VARTYPE_STRING 4 +#define TELNET_VARTYPE_DOUBLE 5 +#define TELNET_VARTYPE_PTR 6 +typedef struct variabledef { + char varname[TELNET_CMD_MAXSIZE]; + char vartype; + void *varvalptr; +} telnetshell_vardef_t; + + + +/*----------------------------------------------------------------------------*/ +/* internal structure definitions */ +/* cmdparser_t is used to store all modules which have been added to the telnet server. */ +/* Each time the add_telnetcmd function is used, the internal array cmdparser_t[] of the */ +/* telnet server is populated with the new commands and variables */ +typedef struct cmdparser { + char module[TELNET_CMD_MAXSIZE]; // module name = first token of the telnet shell command + telnetshell_cmddef_t *cmd; // array of functions added to the shell + telnetshell_vardef_t *var; // array of variables added to the shell +} cmdparser_t; + +/* telnetsrv_params_t is an internal structure storing all the current parameters and */ +/* global variables used by the telnet server */ +typedef struct { + pthread_t telnet_pthread; // thread id of the telnet server + int telnetdbg; // debug level of the server + int priority; // server running priority + 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 + cmdparser_t CmdParsers[TELNET_MAXCMD]; // array of registered modules. + char msgbuff[TELNET_MAX_MSGLENGTH]; // internal buffer of the client_printf function which is used to print to the client terminal */ + unsigned int listenport; // ip port the telnet server is listening on + unsigned int listenaddr; // ip address the telnet server is listening on + unsigned int loopcount; // loop command param: number of loop iteration + unsigned int loopdelay; // loop command param: delay in ms between 2 iterations + unsigned int phyprntbuff_size; // for phy module, dump_eNB_stats function buffer size +} telnetsrv_params_t; + + + +typedef int(*addcmdfunc_t)(char*, telnetshell_vardef_t*, telnetshell_cmddef_t*); +typedef int(*initfunc_t)(char *cfgfile); +typedef void(*settelnetmodule_t)(char *name, void *ptr); + +/*-------------------------------------------------------------------------------------------*/ +/* +VT escape sequence definition, for smarter display.... +*/ + +#define ESC "\x1b" +#define CSI "\x1b[" +#define BOLD "\x1b[1m" +#define RED "\x1b[31m" +#define GREEN "\x1b[32m" +#define BLUE "\x1b[34m" +#define MAGENTA "\x1b[35m" +#define CYAN "\x1b[36m" +#define STDFMT "\x1b[0m" + +/*---------------------------------------------------------------------------------------------*/ +#ifdef TELNETSERVERCODE +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(); +#endif +#endif diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.c b/common/utils/telnetsrv/telnetsrv_phycmd.c new file mode 100644 index 0000000000000000000000000000000000000000..692238f68d5928267f4d0093cb0c5be53d99397e --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_phycmd.c @@ -0,0 +1,134 @@ +#define _GNU_SOURCE +#include <string.h> +#include <pthread.h> + + +#define TELNETSERVERCODE +#include "telnetsrv.h" +#define TELNETSRV_PHYCMD_MAIN +#include "telnetsrv_phycmd.h" +char *prnbuff; +extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length); + +void init_phytelnet() +{ + if (PHY_vars_eNB_g != NULL) + printf("init_phytelnet: phy var at 0x%08lx\n",(unsigned long int)PHY_vars_eNB_g); + else + fprintf(stderr,"init_phytelnet: phy var not found...\n"); + + + +phy_vardef[TELNETVAR_PHYCC0].varvalptr = &(PHY_vars_eNB_g[0][0]); +phy_vardef[TELNETVAR_PHYCC1].varvalptr = &(PHY_vars_eNB_g[0][1]); +prnbuff=malloc(get_phybsize() ); +if (prnbuff == NULL) + { + fprintf(stderr,"Error %s on malloc in init_phytelnet()\n",strerror(errno)); + } +} + +void display_uestatshead( telnet_printfunc_t prnt) +{ +prnt("cc ue rnti Dmcs Umcs tao tau Dbr Dtb \n"); +} + +void dump_uestats(int debug, telnet_printfunc_t prnt, uint8_t prntflag) +{ + +int p; + + p=dump_eNB_stats(PHY_vars_eNB_g[0][0], prnbuff, 0); + if(prntflag>=1) + prnt("%s\n",prnbuff); + if(debug>=1) + prnt("%i bytes printed\n",p); + + +} + +void display_uestats(int debug, telnet_printfunc_t prnt, int ue) +{ + for (int cc=0; cc<1 ; cc++) + { + + if ((PHY_vars_eNB_g[0][cc]->dlsch[ue][0]->rnti>0)&& + (PHY_vars_eNB_g[0][cc]->UE_stats[ue].mode == PUSCH)) + { + prnt("%02i %04i %04hx %04i %04i %04i %-04i %04i %06i\n",cc, ue, + PHY_vars_eNB_g[0][cc]->UE_stats[ue].crnti, + PHY_vars_eNB_g[0][cc]->dlsch[ue][0]->harq_processes[0]->mcs,0, +// PHY_vars_eNB_g[0][cc]->ulsch[ue]->harq_processes[0]->mcs, + PHY_vars_eNB_g[0][cc]->UE_stats[ue].UE_timing_offset, + PHY_vars_eNB_g[0][cc]->UE_stats[ue].timing_advance_update, + PHY_vars_eNB_g[0][cc]->UE_stats[ue].dlsch_bitrate/1000, + PHY_vars_eNB_g[0][cc]->UE_stats[ue].total_TBS/1000 + ); + } + } +} + +void display_phycounters(char *buf, int debug, telnet_printfunc_t prnt) +{ + prnt(" DLSCH kb DLSCH kb/s\n"); + + dump_uestats(debug, prnt,0); + prnt(" %09i %06i\n", + PHY_vars_eNB_g[0][0]->total_transmitted_bits/1000, + PHY_vars_eNB_g[0][0]->total_dlsch_bitrate/1000); +} + +int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt) +{ + + + + if (debug > 0) + prnt("phy interface module received %s\n",buf); + if (strcasestr(buf,"phycnt") != NULL) + { + display_phycounters(buf, debug, prnt); + } + if (strcasestr(buf,"uestat") != NULL) + { + char *cptr=strcasestr(buf+sizeof("uestat"),"UE"); + display_uestatshead(prnt); + if (cptr != NULL) + { + int ueidx = strtol( cptr+sizeof("UE"), NULL, 10); + if (ueidx < NUMBER_OF_UE_MAX && ueidx >= 0) + { + display_uestats(debug, prnt,ueidx); + } + } /* if cptr != NULL */ + else + { + for (int ue=0; ue<NUMBER_OF_UE_MAX ; ue++) + { + display_uestats(debug, prnt,ue); + } + } /* else cptr != NULL */ + } /* uestat */ + if (strcasestr(buf,"uedump") != NULL) + { + dump_uestats(debug, prnt,1); + } + return 0; +} + + + +telnetshell_cmddef_t phy_cmdarray[] = { + {"disp","[phycnt,uedump,uestat UE<x>]", dump_phyvars}, + + {"","",NULL}, +}; + + +/*-------------------------------------------------------------------------------------*/ +void add_phy_cmds() +{ + + init_phytelnet(); + add_telnetcmd("phy", phy_vardef, phy_cmdarray); +} diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.h b/common/utils/telnetsrv/telnetsrv_phycmd.h new file mode 100644 index 0000000000000000000000000000000000000000..9fb13efb8d25420536dfb3da0342976a84c26d0c --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_phycmd.h @@ -0,0 +1,34 @@ + + +#ifdef TELNETSRV_PHYCMD_MAIN + +#include "UTIL/LOG/log.h" + +#include "openair1/PHY/defs.h" + + +#define TELNETVAR_PHYCC0 0 +#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}, +//{"sndslp",TELNET_VARTYPE_INT32,NULL}, +//{"rxrescale",TELNET_VARTYPE_INT32,NULL}, +//{"txshift",TELNET_VARTYPE_INT32,NULL}, +//{"rachemin",TELNET_VARTYPE_INT32,NULL}, +//{"rachdmax",TELNET_VARTYPE_INT32,NULL}, +{"",0,NULL} +}; +extern PHY_VARS_eNB ***PHY_vars_eNB_g; +#else + +extern void add_phy_cmds(); + +#endif + +/*-------------------------------------------------------------------------------------*/ + diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c new file mode 100644 index 0000000000000000000000000000000000000000..d8ae2bfc6e529118bec3bc3f02d98d5f38a3f966 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -0,0 +1,226 @@ +#define _GNU_SOURCE +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <pthread.h> +#include <string.h> +#include <stdarg.h> +#include <dirent.h> + +#define READCFG_DYNLOAD + +#define TELNETSERVERCODE +#include "telnetsrv.h" +#define TELNETSRV_PROCCMD_MAIN +#include "log.h" +#include "telnetsrv_proccmd.h" + +void decode_procstat(char *record, int debug, telnet_printfunc_t prnt) +{ +char prntline[160]; +char *procfile_fiels; +char *strtokptr; +char *lptr; +int fieldcnt; +char toksep[2]; + + fieldcnt=0; + procfile_fiels =strtok_r(record," ",&strtokptr); + 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) + { + if (strlen(procfile_fiels) == 0) + continue; + fieldcnt++; + sprintf(toksep," "); + switch(fieldcnt) + { + case 1: /* id */ + lptr+=sprintf(lptr,"%9.9s ",procfile_fiels); + sprintf(toksep,")"); + break; + case 2: /* name */ + lptr+=sprintf(lptr,"%20.20s ",procfile_fiels+1); + break; + case 3: //thread state + lptr+=sprintf(lptr," %c ",procfile_fiels[0]); + break; + case 14: //time in user mode + case 15: //time in kernel mode + lptr+=sprintf(lptr,"%9.9s ",procfile_fiels); + break; + case 18: //priority + case 19: //nice + lptr+=sprintf(lptr,"%3.3s ",procfile_fiels); + break; + case 23: //vsize + lptr+=sprintf(lptr,"%9.9s ",procfile_fiels); + break; + case 39: //processor + lptr+=sprintf(lptr," %2.2s ",procfile_fiels); + break; + case 41: //policy + lptr+=sprintf(lptr,"%3.3s ",procfile_fiels); + break; + default: + break; + }/* switch on fieldcnr */ + procfile_fiels =strtok_r(NULL,toksep,&strtokptr); + } /* while on proc_fields != NULL */ + prnt("%s\n",prntline); +} /*decode_procstat */ + +void read_statfile(char *fname,int debug, telnet_printfunc_t prnt) +{ +FILE *procfile; +char arecord[1024]; + + procfile=fopen(fname,"r"); + if (procfile == NULL) + { + prnt("Error: Couldn't open %s %i %s\n",fname,errno,strerror(errno)); + return; + } + if ( fgets(arecord,sizeof(arecord),procfile) == NULL) + { + prnt("Error: Nothing read from %s %i %s\n",fname,errno,strerror(errno)); + fclose(procfile); + return; + } + fclose(procfile); + decode_procstat(arecord, debug, prnt); +} + +void print_threads(char *buf, int debug, telnet_printfunc_t prnt) +{ +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()); + read_statfile(aname,debug,prnt); + prnt("\n"); + snprintf(aname, sizeof(aname), "/proc/%d/task", getpid()); + proc_dir = opendir(aname); + if (proc_dir == NULL) + { + prnt("Error: Couldn't open %s %i %s\n",aname,errno,strerror(errno)); + return; + } + + while ((entry = readdir(proc_dir)) != NULL) + { + if(entry->d_name[0] == '.') + continue; + snprintf(aname, sizeof(aname), "/proc/%d/task/%s/stat", getpid(),entry->d_name); + read_statfile(aname,debug,prnt); + } /* while entry != NULL */ + closedir(proc_dir); +} /* print_threads */ + + +int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt) +{ +extern log_t *g_log; + + if (debug > 0) + prnt(" proccmd_show received %s\n",buf); + 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)); + } + } + return 0; +} + +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); + 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); + if(res != 3) + { + prnt("softmodem thread needs 3 params, %i received\n",res); + return 0; + } + + + if (strcasestr(sv1,"prio") != NULL) + { + set_sched(0,bv1, bv2); + } + else if (strcasestr(sv1,"aff") != NULL) + { + set_affinity(0,bv1, bv2); + } + else + { + prnt("%s is not a valid thread command\n",sv1); + } + return 0; +} +int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt) +{ +extern void exit_fun(const char* s); + + if (debug > 0) + prnt("process module received %s\n",buf); + + exit_fun("telnet server received exit command\n"); + 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); + + if (debug > 0) + prnt("process module received %s\n",buf); + + if (strcasestr(buf,"enable") != NULL) + { + set_glog_onlinelog(1); + } + if (strcasestr(buf,"disable") != NULL) + { + set_glog_onlinelog(0); + } + return 0; +} +/*-------------------------------------------------------------------------------------*/ + +void add_softmodem_cmds() +{ + add_telnetcmd("softmodem",NULL,proc_cmdarray); +} diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.h b/common/utils/telnetsrv/telnetsrv_proccmd.h new file mode 100644 index 0000000000000000000000000000000000000000..8a3173e3d1cb75182d15910c1909f3f08553c614 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_proccmd.h @@ -0,0 +1,56 @@ +/* + * 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/utils/telnetsrv_proccmd.h + * \brief: Include file defining telnet commands related to this linux process + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#include <dlfcn.h> +#include "telnetsrv.h" + + +#ifdef TELNETSRV_PROCCMD_MAIN +/* global variable from log.c */ +extern mapping *log_level_names; +extern mapping *log_verbosity_names; + +extern int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt); +extern int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt); +extern int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt); +extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt); + +telnetshell_cmddef_t proc_cmdarray[] = { + {"show","loglvl|thread", proccmd_show}, + {"log","[enable,disable]", proccmd_log}, + {"thread","<id> aff|prio <aff|prio>", proccmd_thread}, + {"exit","", proccmd_exit}, + {"","",NULL}, +}; +#else +extern void add_proccmd_cmds(); +#endif /* TELNETSRV_PROCCMD_MAIN */ + diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 2afb201d7b57ec4a72e3c173fbb58f142125c003..c076c3d9b7d5d503eee419b0fe5662d84ce7b768 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -50,7 +50,7 @@ #include "PHY/defs.h" #include "common/ran_context.h" #include "common/config/config_userapi.h" - +#include "common/utils/telnetsrv/load_telnet.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all