mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
651 lines
24 KiB
C
651 lines
24 KiB
C
/*
|
|
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
|
*/
|
|
|
|
/*!
|
|
* \brief: implementation of telnet commands related to this linux process
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/sysinfo.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 TELNETSERVERCODE
|
|
#include "telnetsrv.h"
|
|
#define TELNETSRV_PROCCMD_MAIN
|
|
#include "common/utils/LOG/log.h"
|
|
#include "common/config/config_userapi.h"
|
|
#include "openair1/PHY/phy_extern.h"
|
|
#include "telnetsrv_proccmd.h"
|
|
|
|
void decode_procstat(char *record, int debug, telnet_printfunc_t prnt, webdatadef_t *tdata)
|
|
{
|
|
UNUSED(debug);
|
|
char prntline[160];
|
|
char *procfile_fields;
|
|
char *strtokptr;
|
|
char *lptr;
|
|
int fieldcnt;
|
|
char toksep[2];
|
|
|
|
fieldcnt = 0;
|
|
procfile_fields = strtok_r(record, " ", &strtokptr);
|
|
lptr = prntline;
|
|
/*http://man7.org/linux/man-pages/man5/proc.5.html gives the structure of the stat file */
|
|
int priority = 0;
|
|
int nice = 0;
|
|
while (procfile_fields != NULL && fieldcnt < 42) {
|
|
long int policy;
|
|
if (strlen(procfile_fields) == 0)
|
|
continue;
|
|
fieldcnt++;
|
|
sprintf(toksep, " ");
|
|
switch (fieldcnt) {
|
|
case 1: /* id */
|
|
if (tdata != NULL) {
|
|
tdata->lines[tdata->numlines].val[0] = strdup(procfile_fields);
|
|
}
|
|
lptr += sprintf(lptr, "%9.9s ", procfile_fields);
|
|
sprintf(toksep, ")");
|
|
break;
|
|
case 2: /* name */
|
|
if (tdata != NULL) {
|
|
tdata->lines[tdata->numlines].val[1] = strdup(procfile_fields);
|
|
}
|
|
lptr += sprintf(lptr, "%20.20s ", procfile_fields + 1);
|
|
break;
|
|
case 3: // thread state
|
|
lptr += sprintf(lptr, " %c ", procfile_fields[0]);
|
|
break;
|
|
case 14: // time in user mode
|
|
case 15: // time in kernel mode
|
|
lptr += sprintf(lptr, "%9.9s ", procfile_fields);
|
|
break;
|
|
case 18: // priority column index 2 in tdata, -2 to -100 (1, min to 99, highest prio)
|
|
priority = strtol(procfile_fields, NULL, 0);
|
|
case 19: // nice column index 3 in tdata 0 to 39 (-20, highest prio, to 19)
|
|
if (tdata != NULL) {
|
|
tdata->lines[tdata->numlines].val[fieldcnt - 16] = strdup(procfile_fields);
|
|
}
|
|
lptr += sprintf(lptr, "%3.3s ", procfile_fields);
|
|
nice = strtol(procfile_fields, NULL, 0);
|
|
break;
|
|
case 23: // vsize
|
|
lptr += sprintf(lptr, "%9.9s ", procfile_fields);
|
|
break;
|
|
case 39: // processor
|
|
if (tdata != NULL) {
|
|
tdata->lines[tdata->numlines].val[4] = strdup(procfile_fields);
|
|
}
|
|
lptr += sprintf(lptr, " %2.2s ", procfile_fields);
|
|
break;
|
|
case 41: // policy
|
|
lptr += sprintf(lptr, "%3.3s ", procfile_fields);
|
|
policy = strtol(procfile_fields, NULL, 0);
|
|
char strschedp[64];
|
|
switch (policy) {
|
|
case SCHED_FIFO:
|
|
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:fifo");
|
|
priority = priority + 1; // in /proc file system priority 1 to 99 mapped to -2 to -100
|
|
break;
|
|
case SCHED_OTHER:
|
|
snprintf(strschedp, sizeof(strschedp), "%s ", "other");
|
|
priority = nice - NICE_MIN; // linux nice is -20 to 19
|
|
break;
|
|
case SCHED_IDLE:
|
|
snprintf(strschedp, sizeof(strschedp), "%s ", "idle");
|
|
priority = 2 * (NICE_MAX - NICE_MIN + 1);
|
|
break;
|
|
case SCHED_BATCH:
|
|
snprintf(strschedp, sizeof(strschedp), "%s ", "batch");
|
|
priority = (NICE_MAX - NICE_MIN + 1) + nice - NICE_MIN;
|
|
break;
|
|
case SCHED_RR:
|
|
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:rr");
|
|
priority = priority - 99;
|
|
break;
|
|
#ifdef SCHED_DEADLINE
|
|
case SCHED_DEADLINE:
|
|
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:deadline");
|
|
break;
|
|
#endif
|
|
default:
|
|
snprintf(strschedp, sizeof(strschedp), "%s ", "????");
|
|
break;
|
|
}
|
|
lptr += sprintf(lptr, "%s ", strschedp);
|
|
if (tdata != NULL) {
|
|
tdata->lines[tdata->numlines].val[5] = strdup(strschedp);
|
|
tdata->lines[tdata->numlines].val[6] = malloc(10);
|
|
snprintf(tdata->lines[tdata->numlines].val[6], 9, "%i", priority);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
} /* switch on fieldcnr */
|
|
procfile_fields = strtok_r(NULL, toksep, &strtokptr);
|
|
} /* while on proc_fields != NULL */
|
|
prnt("%s\n", prntline);
|
|
if (tdata != NULL) {
|
|
tdata->numlines++;
|
|
}
|
|
} /*decode_procstat */
|
|
|
|
void read_statfile(char *fname, int debug, telnet_printfunc_t prnt, webdatadef_t *tdata)
|
|
{
|
|
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, tdata);
|
|
}
|
|
|
|
int nullprnt(char *fmt, ...)
|
|
{
|
|
UNUSED(fmt);
|
|
return 0;
|
|
}
|
|
|
|
void proccmd_get_threaddata(int debug, telnet_printfunc_t fprnt, webdatadef_t *tdata)
|
|
{
|
|
char aname[256];
|
|
|
|
DIR *proc_dir;
|
|
struct dirent *entry;
|
|
telnet_printfunc_t prnt = (fprnt != NULL) ? fprnt : (telnet_printfunc_t)nullprnt;
|
|
if (tdata != NULL) {
|
|
tdata->numcols = 7;
|
|
snprintf(tdata->columns[0].coltitle, sizeof(tdata->columns[0].coltitle), "thread id");
|
|
tdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
|
snprintf(tdata->columns[1].coltitle, sizeof(tdata->columns[1].coltitle), "thread name");
|
|
tdata->columns[1].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
|
snprintf(tdata->columns[2].coltitle, sizeof(tdata->columns[2].coltitle), "priority");
|
|
tdata->columns[2].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
|
snprintf(tdata->columns[3].coltitle, sizeof(tdata->columns[3].coltitle), "nice");
|
|
tdata->columns[3].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
|
snprintf(tdata->columns[4].coltitle, sizeof(tdata->columns[4].coltitle), "core");
|
|
tdata->columns[4].coltype = TELNET_VARTYPE_STRING | TELNET_VAR_NEEDFREE;
|
|
snprintf(tdata->columns[5].coltitle, sizeof(tdata->columns[5].coltitle), "sched policy");
|
|
tdata->columns[5].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
|
snprintf(tdata->columns[5].coltitle, sizeof(tdata->columns[5].coltitle), "sched policy");
|
|
tdata->columns[6].coltype = TELNET_VARTYPE_STRING | TELNET_VAR_NEEDFREE;
|
|
snprintf(tdata->columns[6].coltitle, sizeof(tdata->columns[6].coltitle), "oai priority");
|
|
tdata->numlines = 0;
|
|
}
|
|
|
|
int nprocs = get_nprocs();
|
|
prnt("System has %d cores", nprocs);
|
|
|
|
prnt("\n 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, NULL);
|
|
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] != '.') {
|
|
snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(), (int)(sizeof(aname) - 24), entry->d_name);
|
|
read_statfile(aname, debug, prnt, tdata);
|
|
}
|
|
} /* while entry != NULL */
|
|
closedir(proc_dir);
|
|
} /* proccmd_get_threaddata */
|
|
|
|
void print_threads(int debug, telnet_printfunc_t prnt)
|
|
{
|
|
proccmd_get_threaddata(debug, prnt, NULL);
|
|
}
|
|
|
|
#define FLAG_PRINT_DEBUG_DUMP(flag) \
|
|
logsdata->lines[i].val[0] = (char *)flag_name[i]; \
|
|
logsdata->lines[i].val[1] = g_log->debug_mask.DEBUG_##flag ? "true" : "false"; \
|
|
logsdata->lines[i].val[1] = g_log->dump_mask.DEBUG_##flag ? "true" : "false"; \
|
|
i++;
|
|
|
|
int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt)
|
|
{
|
|
webdatadef_t *logsdata = (webdatadef_t *)data;
|
|
const mapping *const log_level_names = log_level_names_ptr();
|
|
const mapping *const log_options = log_option_names_ptr();
|
|
if (strncmp(cmdbuff, "set", 3) == 0) {
|
|
telnet_printfunc_t printfunc = (prnt != NULL) ? prnt : (telnet_printfunc_t)printf;
|
|
if (strcasestr(cmdbuff, "loglvl") != NULL) {
|
|
int level = map_str_to_int(log_level_names, logsdata->lines[0].val[1]);
|
|
int enabled = (strcmp(logsdata->lines[0].val[2], "true") == 0) ? 1 : 0;
|
|
int loginfile = (strcmp(logsdata->lines[0].val[3], "true") == 0) ? 1 : 0;
|
|
set_log(logsdata->numlines, level);
|
|
if (enabled == 0)
|
|
set_log(logsdata->numlines, OAILOG_DISABLE);
|
|
if (loginfile == 1) {
|
|
set_component_filelog(logsdata->numlines);
|
|
} else {
|
|
close_component_filelog(logsdata->numlines);
|
|
}
|
|
printfunc("%s log level %s is %s, output to %s\n",
|
|
logsdata->lines[0].val[0],
|
|
logsdata->lines[0].val[1],
|
|
enabled ? "enabled" : "disabled",
|
|
loginfile ? g_log->log_rarely_used[logsdata->numlines].filelog_name : "stdout");
|
|
}
|
|
if (strcasestr(cmdbuff, "logopt") != NULL) {
|
|
int optbit = map_str_to_int(log_options, logsdata->lines[0].val[0]);
|
|
if (optbit < 0) {
|
|
printfunc("option %s unknown\n", logsdata->lines[0].val[0]);
|
|
} else {
|
|
if (strcmp(logsdata->lines[0].val[1], "true") == 0) {
|
|
SET_LOG_OPTION(optbit);
|
|
} else {
|
|
CLEAR_LOG_OPTION(optbit);
|
|
}
|
|
printfunc("%s log option %s\n", logsdata->lines[0].val[0], (strcmp(logsdata->lines[0].val[1], "true") == 0) ? "enabled" : "disabled");
|
|
}
|
|
}
|
|
if (strcasestr(cmdbuff, "dbgopt") != NULL) {
|
|
if (strcmp(logsdata->lines[0].val[1], "true") == 0)
|
|
if (!set_log_debug(logsdata->lines[0].val[0], strcmp(logsdata->lines[0].val[2], "true") == 0))
|
|
printfunc("debug option %s unknown\n", logsdata->lines[0].val[0]);
|
|
if (strcmp(logsdata->lines[0].val[2], "true") == 0)
|
|
if (!set_log_dump(logsdata->lines[0].val[0], strcmp(logsdata->lines[0].val[2], "true") == 0))
|
|
printfunc("debug option %s unknown\n", logsdata->lines[0].val[0]);
|
|
printfunc("%s debug %s dump %s\n",
|
|
logsdata->lines[0].val[0],
|
|
(strcmp(logsdata->lines[0].val[1], "true") == 0) ? "enabled" : "disabled",
|
|
(strcmp(logsdata->lines[0].val[2], "true") == 0) ? "enabled" : "disabled");
|
|
}
|
|
if (strcasestr(cmdbuff, "threadsched") != NULL) {
|
|
unsigned int tid = strtoll(logsdata->lines[0].val[0], NULL, 0);
|
|
unsigned int core = strtoll(logsdata->lines[0].val[4], NULL, 0);
|
|
int priority = strtoll(logsdata->lines[0].val[6], NULL, 0);
|
|
printfunc("Thread %s id %u set affinity to core %u\n", logsdata->lines[0].val[0], tid, core);
|
|
set_affinity(0, (pid_t)tid, core);
|
|
set_sched(0, (pid_t)tid, priority);
|
|
}
|
|
} else { /* end of set, => show */
|
|
if (strcasestr(cmdbuff, "loglvl") != NULL) {
|
|
logsdata->numcols = 4;
|
|
logsdata->numlines = 0;
|
|
snprintf(logsdata->columns[0].coltitle, TELNET_CMD_MAXSIZE, "component");
|
|
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
|
|
snprintf(logsdata->columns[1].coltitle, TELNET_CMD_MAXSIZE, "level");
|
|
logsdata->columns[1].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_LOGLVL;
|
|
snprintf(logsdata->columns[2].coltitle, TELNET_CMD_MAXSIZE, "enabled");
|
|
logsdata->columns[2].coltype = TELNET_CHECKVAL_BOOL;
|
|
snprintf(logsdata->columns[3].coltitle, TELNET_CMD_MAXSIZE, "in file");
|
|
logsdata->columns[3].coltype = TELNET_CHECKVAL_BOOL;
|
|
|
|
for (int i = 0; i < MAX_LOG_COMPONENTS; i++) {
|
|
if (g_log->log_component[i].name != NULL) {
|
|
logsdata->numlines++;
|
|
logsdata->lines[i].val[0] = (char *)(g_log->log_component[i].name);
|
|
|
|
logsdata->lines[i].val[1] = map_int_to_str(
|
|
log_level_names,
|
|
(g_log->log_component[i].level >= 0) ? g_log->log_component[i].level : g_log->log_rarely_used[i].savedlevel);
|
|
logsdata->lines[i].val[2] = (g_log->log_component[i].level >= 0) ? "true" : "false";
|
|
logsdata->lines[i].val[3] = (g_log->log_component[i].filelog > 0) ? "true" : "false";
|
|
}
|
|
}
|
|
}
|
|
if (strcasestr(cmdbuff, "dbgopt") != NULL) {
|
|
webdatadef_t *logsdata = (webdatadef_t *)data;
|
|
logsdata->numcols = 3;
|
|
logsdata->numlines = 0;
|
|
snprintf(logsdata->columns[0].coltitle, TELNET_CMD_MAXSIZE, "module");
|
|
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
|
|
snprintf(logsdata->columns[1].coltitle, TELNET_CMD_MAXSIZE, "debug");
|
|
logsdata->columns[1].coltype = TELNET_CHECKVAL_BOOL;
|
|
snprintf(logsdata->columns[2].coltitle, TELNET_CMD_MAXSIZE, "dump");
|
|
logsdata->columns[2].coltype = TELNET_CHECKVAL_BOOL;
|
|
|
|
int i = 0;
|
|
FOREACH_FLAG(FLAG_PRINT_DEBUG_DUMP);
|
|
logsdata->numlines += i;
|
|
}
|
|
|
|
if (strcasestr(cmdbuff, "logopt") != NULL) {
|
|
webdatadef_t *logsdata = (webdatadef_t *)data;
|
|
logsdata->numcols = 2;
|
|
logsdata->numlines = 0;
|
|
snprintf(logsdata->columns[0].coltitle, TELNET_CMD_MAXSIZE, "option");
|
|
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
|
|
snprintf(logsdata->columns[1].coltitle, TELNET_CMD_MAXSIZE, "enabled");
|
|
logsdata->columns[1].coltype = TELNET_CHECKVAL_BOOL;
|
|
|
|
for (int i = 0; log_options[i].name != NULL; i++) {
|
|
logsdata->numlines++;
|
|
logsdata->lines[i].val[0] = (char *)log_options[i].name;
|
|
logsdata->lines[i].val[1] = (g_log->flag & log_options[i].value) ? "true" : "false";
|
|
}
|
|
}
|
|
if (strcasestr(cmdbuff, "threadsched") != NULL) {
|
|
proccmd_get_threaddata(debug, prnt, (webdatadef_t *)data);
|
|
}
|
|
} // show
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define FLAG_PRINT2_DEBUG_DUMP(flag) \
|
|
prnt("%02i %17.17s %5.5s %5.5s\n", \
|
|
i, \
|
|
flag_name[i], \
|
|
g_log->debug_mask.DEBUG_##flag ? "Y" : "N", \
|
|
g_log->dump_mask.DEBUG_##flag ? "Y" : "N"); \
|
|
i++;
|
|
|
|
int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt)
|
|
{
|
|
if (buf == NULL) {
|
|
prnt("ERROR wrong softmodem SHOW command...\n");
|
|
return 0;
|
|
}
|
|
if (debug > 0)
|
|
prnt(" proccmd_show received %s\n",buf);
|
|
if (strcasestr(buf,"thread") != NULL) {
|
|
print_threads(debug, prnt);
|
|
}
|
|
if (strcasestr(buf,"loglvl") != NULL) {
|
|
prnt("\n component level enabled output\n");
|
|
const mapping *const log_level_names = log_level_names_ptr();
|
|
for (int i = 0; i < MAX_LOG_COMPONENTS; i++) {
|
|
if (g_log->log_component[i].name != NULL) {
|
|
prnt("%02i %17.17s:%10.10s %s %s\n",
|
|
i,
|
|
g_log->log_component[i].name,
|
|
map_int_to_str(
|
|
log_level_names,
|
|
(g_log->log_component[i].level >= 0) ? g_log->log_component[i].level : g_log->log_rarely_used[i].savedlevel),
|
|
((g_log->log_component[i].level >= 0) ? "Y" : "N"),
|
|
((g_log->log_component[i].filelog > 0) ? g_log->log_rarely_used[i].filelog_name : "stdout"));
|
|
}
|
|
}
|
|
}
|
|
if (strcasestr(buf,"logopt") != NULL) {
|
|
prnt("\n option enabled\n");
|
|
const mapping *const log_options = log_option_names_ptr();
|
|
for (int i=0; log_options[i].name != NULL; i++) {
|
|
prnt("%02i %17.17s %10.10s \n",i ,log_options[i].name,
|
|
((g_log->flag & log_options[i].value)?"Y":"N") );
|
|
}
|
|
}
|
|
if (strcasestr(buf,"dbgopt") != NULL) {
|
|
prnt("\n module debug dumpfile\n");
|
|
int i = 0;
|
|
FOREACH_FLAG(FLAG_PRINT2_DEBUG_DUMP);
|
|
}
|
|
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;
|
|
}
|
|
|
|
int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt)
|
|
{
|
|
int bv1,bv2;
|
|
int res;
|
|
char sv1[64];
|
|
|
|
if (buf == NULL) {
|
|
prnt("ERROR wrong thread command...\n");
|
|
return 0;
|
|
}
|
|
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);
|
|
if(res != 3)
|
|
{
|
|
print_threads(debug, prnt);
|
|
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)
|
|
{
|
|
if (debug > 0)
|
|
prnt("process module received %s\n",buf);
|
|
exit_fun("telnet server received exit command\n");
|
|
return 0;
|
|
}
|
|
|
|
int proccmd_restart(char *buf, int debug, telnet_printfunc_t prnt)
|
|
{
|
|
if (debug > 0)
|
|
prnt("process module received %s\n", buf);
|
|
configmodule_interface_t *cfg = config_get_if();
|
|
end_configmodule(cfg);
|
|
execvpe(cfg->argv[0], cfg->argv, environ);
|
|
return 0;
|
|
}
|
|
|
|
int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt)
|
|
{
|
|
int idx1=0;
|
|
int idx2=NUM_LOG_LEVEL-1;
|
|
char *logsubcmd=NULL;
|
|
|
|
int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
|
|
|
if (debug > 0)
|
|
prnt( "proccmd_log received %s\n s=%i sub command %s\n",buf,s,((logsubcmd==NULL)?"":logsubcmd));
|
|
const mapping *const log_level_names = log_level_names_ptr();
|
|
const mapping *const log_options = log_option_names_ptr();
|
|
const mapping *log_maskmap = log_maskmap_ptr();
|
|
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("\n\n");
|
|
prnt("Available display options: \n ");
|
|
for (int i = 0; log_options[i].name != NULL; i++)
|
|
prnt("%s ", log_options[i].name);
|
|
prnt("\n\n");
|
|
prnt("Available debug and dump options: \n ");
|
|
for (int i = 0; log_maskmap[i].name != NULL; i++)
|
|
prnt("%s ", log_maskmap[i].name);
|
|
prnt("\n\n");
|
|
proccmd_show("loglvl", debug, prnt);
|
|
proccmd_show("logopt", debug, prnt);
|
|
proccmd_show("dbgopt", debug, prnt);
|
|
}
|
|
else if (strcasestr(logsubcmd,"help") != NULL) {
|
|
prnt(PROCCMD_LOG_HELP_STRING);
|
|
} else {
|
|
prnt("%s: wrong log command...\n",logsubcmd);
|
|
}
|
|
} else if ( s == 2 && logsubcmd != NULL) {
|
|
char *opt=NULL;
|
|
char *logparam=NULL;
|
|
int l;
|
|
int optbit;
|
|
|
|
l=sscanf(logsubcmd,"%m[^'_']_%ms",&logparam,&opt);
|
|
if (l == 2 && strcmp(logparam,"print") == 0){
|
|
optbit = map_str_to_int(log_options, opt);
|
|
if (optbit < 0) {
|
|
prnt("option %s unknown\n", opt);
|
|
} else {
|
|
if (idx1 > 0)
|
|
SET_LOG_OPTION(optbit);
|
|
else
|
|
CLEAR_LOG_OPTION(optbit);
|
|
proccmd_show("logopt", debug, prnt);
|
|
}
|
|
}
|
|
else if (l == 2 && strcmp(logparam,"debug") == 0){
|
|
int ret = set_log_debug(opt, idx1 > 0);
|
|
if (!ret)
|
|
prnt("module %s unknown\n", opt);
|
|
proccmd_show("dbgopt", debug, prnt);
|
|
}
|
|
else if (l == 2 && strcmp(logparam,"dump") == 0){
|
|
int ret = set_log_dump(opt, idx1 > 0);
|
|
if (!ret)
|
|
prnt("module %s unknown\n", opt);
|
|
proccmd_show("dump", debug, prnt);
|
|
}
|
|
if (logparam != NULL) free(logparam);
|
|
if (opt != NULL) free(opt);
|
|
} else if ( s == 3 && logsubcmd != NULL) {
|
|
int level, enable,filelog;
|
|
char *tmpstr=NULL;
|
|
char *logparam=NULL;
|
|
int l;
|
|
|
|
level = OAILOG_DISABLE - 1;
|
|
filelog = -1;
|
|
enable=-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);
|
|
level = OAILOG_DISABLE - 1;
|
|
}
|
|
} else {
|
|
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
|
|
}
|
|
} else if (l ==1 ) {
|
|
if (strcmp(logparam,"enable") == 0) {
|
|
enable=1;
|
|
} else if (strcmp(logparam,"disable") == 0) {
|
|
level=OAILOG_DISABLE;
|
|
} else if (strcmp(logparam,"file") == 0) {
|
|
filelog = 1 ;
|
|
} else if (strcmp(logparam,"nofile") == 0) {
|
|
filelog = 0 ;
|
|
} else {
|
|
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
|
|
}
|
|
} else {
|
|
level = map_str_to_int(log_level_names, tmpstr);
|
|
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++) {
|
|
if (level >= OAILOG_DISABLE)
|
|
set_log(i, level);
|
|
else if ( enable == 1)
|
|
set_log(i, g_log->log_rarely_used[i].savedlevel);
|
|
else if ( filelog == 1 ) {
|
|
set_component_filelog(i);
|
|
} else if ( filelog == 0 ) {
|
|
close_component_filelog(i);
|
|
}
|
|
|
|
}
|
|
proccmd_show("loglvl",debug,prnt);
|
|
} else {
|
|
prnt("%s: wrong log command...\n",buf);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
/*-------------------------------------------------------------------------------------*/
|
|
|
|
void add_softmodem_cmds(void)
|
|
{
|
|
add_telnetcmd("softmodem",proc_vardef,proc_cmdarray);
|
|
}
|