Merge remote-tracking branch 'origin/develop' into mu_with_tdd1
The monolithic eNodeB is not fully functional in FDD. The TDD mode has not been tested. Do not consider this commit as functional. Conflicts: cmake_targets/CMakeLists.txt cmake_targets/build_oai common/utils/itti/intertask_interface.c openair1/PHY/INIT/lte_init.c openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c openair1/PHY/LTE_TRANSPORT/dci_tools.c openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c openair1/PHY/LTE_TRANSPORT/transport_eNB.h openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h openair1/PHY/defs_eNB.h openair1/PHY/impl_defs_lte.h openair1/SCHED/fapi_l1.c openair1/SCHED/phy_procedures_lte_eNb.c openair1/SCHED/pusch_pc.c openair2/COMMON/platform_types.h openair2/COMMON/rrc_messages_types.h openair2/ENB_APP/enb_config.c openair2/ENB_APP/enb_paramdef.h openair2/LAYER2/MAC/config.c openair2/LAYER2/MAC/eNB_scheduler.c openair2/LAYER2/MAC/eNB_scheduler_RA.c openair2/LAYER2/MAC/eNB_scheduler_dlsch.c openair2/LAYER2/MAC/eNB_scheduler_primitives.c openair2/LAYER2/MAC/eNB_scheduler_ulsch.c openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c openair2/LAYER2/MAC/mac.h openair2/LAYER2/MAC/mac_proto.h openair2/LAYER2/MAC/pre_processor.c openair2/LAYER2/RLC/rlc.c openair2/LAYER2/RLC/rlc_rrc.c openair2/RRC/LITE/rrc_common.c openair2/RRC/LTE/L2_interface.c openair2/RRC/LTE/MESSAGES/asn1_msg.c openair2/RRC/LTE/rrc_eNB.c openair2/UTIL/LOG/log.h targets/COMMON/openairinterface5g_limits.h targets/RT/USER/lte-enb.c targets/RT/USER/lte-ru.c targets/RT/USER/lte-softmodem.c targets/RT/USER/lte-softmodem.h
This commit is contained in:
+11
-7
@@ -88,7 +88,7 @@ static void new_thread(void *(*f)(void *), void *data)
|
||||
|
||||
/* defined in local_tracer.c */
|
||||
void T_local_tracer_main(int remote_port, int wait_for_tracer,
|
||||
int local_socket);
|
||||
int local_socket, char *shm_file);
|
||||
|
||||
/* We monitor the tracee and the local tracer processes.
|
||||
* When one dies we forcefully kill the other.
|
||||
@@ -113,6 +113,9 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
|
||||
int s;
|
||||
int T_shm_fd;
|
||||
int child1, child2;
|
||||
char shm_file[128];
|
||||
|
||||
sprintf(shm_file, "/%s%d", T_SHM_FILENAME, getpid());
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair))
|
||||
{ perror("socketpair"); abort(); }
|
||||
@@ -122,7 +125,8 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
|
||||
child1 = fork(); if (child1 == -1) abort();
|
||||
if (child1 == 0) {
|
||||
close(socket_pair[1]);
|
||||
T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0]);
|
||||
T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0],
|
||||
shm_file);
|
||||
exit(0);
|
||||
}
|
||||
close(socket_pair[0]);
|
||||
@@ -142,13 +146,13 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
|
||||
T_socket = s;
|
||||
|
||||
/* setup shared memory */
|
||||
T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR /*| O_SYNC*/, 0666);
|
||||
shm_unlink(T_SHM_FILENAME);
|
||||
if (T_shm_fd == -1) { perror(T_SHM_FILENAME); abort(); }
|
||||
T_shm_fd = shm_open(shm_file, O_RDWR /*| O_SYNC*/, 0666);
|
||||
shm_unlink(shm_file);
|
||||
if (T_shm_fd == -1) { perror(shm_file); abort(); }
|
||||
T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, T_shm_fd, 0);
|
||||
if (T_cache == NULL)
|
||||
{ perror(T_SHM_FILENAME); abort(); }
|
||||
if (T_cache == MAP_FAILED)
|
||||
{ perror(shm_file); abort(); }
|
||||
close(T_shm_fd);
|
||||
|
||||
new_thread(T_receive_thread, NULL);
|
||||
|
||||
@@ -110,6 +110,16 @@ typedef struct {
|
||||
extern volatile int *T_freelist_head;
|
||||
extern T_cache_t *T_cache;
|
||||
|
||||
/* When running the basic simulator, we may fill the T cache too fast.
|
||||
* Let's not crash if it's full, just wait.
|
||||
*/
|
||||
#if BASIC_SIMULATOR
|
||||
# define T_BASIC_SIMULATOR_WAIT \
|
||||
while (T_cache[T_LOCAL_slot].busy) usleep(100)
|
||||
#else
|
||||
# define T_BASIC_SIMULATOR_WAIT /* */
|
||||
#endif
|
||||
|
||||
/* used at header of Tn, allocates buffer */
|
||||
#define T_LOCAL_DATA \
|
||||
char *T_LOCAL_buf; \
|
||||
@@ -118,6 +128,7 @@ extern T_cache_t *T_cache;
|
||||
T_LOCAL_slot = __sync_fetch_and_add(T_freelist_head, 1) \
|
||||
& (T_CACHE_SIZE - 1); \
|
||||
(void)__sync_fetch_and_and(T_freelist_head, T_CACHE_SIZE - 1); \
|
||||
T_BASIC_SIMULATOR_WAIT; \
|
||||
if (T_cache[T_LOCAL_slot].busy) { \
|
||||
printf("%s:%d:%s: T cache is full - consider increasing its size\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__); \
|
||||
|
||||
+13
-3
@@ -8,10 +8,20 @@
|
||||
#define T_MAX_ARGS 16
|
||||
|
||||
/* maximum size of a message - increase if needed */
|
||||
#define T_BUFFER_MAX (1024*64)
|
||||
#if BASIC_SIMULATOR
|
||||
/* let's have 100 RBs functional for the basic simulator */
|
||||
# define T_BUFFER_MAX (1024*64*2)
|
||||
#else
|
||||
# define T_BUFFER_MAX (1024*64)
|
||||
#endif
|
||||
|
||||
/* size of the local cache for messages (must be pow(2,something)) */
|
||||
#define T_CACHE_SIZE (8192 * 2)
|
||||
#if BASIC_SIMULATOR
|
||||
/* we don't need much space for the basic simulator */
|
||||
# define T_CACHE_SIZE 1024
|
||||
#else
|
||||
# define T_CACHE_SIZE (8192 * 2)
|
||||
#endif
|
||||
|
||||
/* maximum number of bytes a message can contain */
|
||||
#ifdef T_SEND_TIME
|
||||
@@ -32,7 +42,7 @@ typedef struct {
|
||||
#define VCD_NUM_FUNCTIONS 187
|
||||
|
||||
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */
|
||||
#define VCD_NUM_VARIABLES 128
|
||||
#define VCD_NUM_VARIABLES 131
|
||||
|
||||
/* first VCD function (to be kept up to date! see in T_messages.txt) */
|
||||
#define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP)
|
||||
|
||||
@@ -1442,6 +1442,18 @@ ID = VCD_VARIABLE_UE0_TRX_WRITE_NS_MISSING
|
||||
DESC = VCD variable UE0_TRX_WRITE_NS_MISSING
|
||||
GROUP = ALL:VCD:UE:VCD_VARIABLE
|
||||
FORMAT = ulong,value
|
||||
ID = VCD_VARIABLE_CPUID_ENB_THREAD_RXTX
|
||||
DESC = VCD variable CPUID_ENB_THREAD_RXTX
|
||||
GROUP = ALL:VCD:ENB:VCD_VARIABLE
|
||||
FORMAT = ulong,value
|
||||
ID = VCD_VARIABLE_CPUID_RU_THREAD
|
||||
DESC = VCD variable CPUID_RU_THREAD
|
||||
GROUP = ALL:VCD:ENB:VCD_VARIABLE
|
||||
FORMAT = ulong,value
|
||||
ID = VCD_VARIABLE_CPUID_RU_THREAD_TX
|
||||
DESC = VCD variable CPUID_RU_THREAD_TX
|
||||
GROUP = ALL:VCD:ENB:VCD_VARIABLE
|
||||
FORMAT = ulong,value
|
||||
|
||||
#functions
|
||||
|
||||
|
||||
@@ -300,6 +300,20 @@ static void forward(void *_forwarder, char *buf, int size)
|
||||
if (f->tail != NULL) f->tail->next = new;
|
||||
f->tail = new;
|
||||
|
||||
#if BASIC_SIMULATOR
|
||||
/* When runnng the basic simulator, the tracer may be too slow.
|
||||
* Let's not take too much memory in the tracee and
|
||||
* wait if there is too much data to send. 200MB is
|
||||
* arbitrary.
|
||||
*/
|
||||
while (f->memusage > 200 * 1024 * 1024) {
|
||||
if (pthread_cond_signal(&f->cond)) abort();
|
||||
if (pthread_mutex_unlock(&f->lock)) abort();
|
||||
usleep(1000);
|
||||
if (pthread_mutex_lock(&f->lock)) abort();
|
||||
}
|
||||
#endif /* BASIC_SIMULATOR */
|
||||
|
||||
f->memusage += size+4;
|
||||
/* warn every 100MB */
|
||||
if (f->memusage > f->last_warning_memusage &&
|
||||
@@ -326,17 +340,17 @@ static void wait_message(void)
|
||||
while (T_local_cache[T_busylist_head].busy == 0) usleep(1000);
|
||||
}
|
||||
|
||||
static void init_shm(void)
|
||||
static void init_shm(char *shm_file)
|
||||
{
|
||||
int i;
|
||||
int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT /*| O_SYNC*/, 0666);
|
||||
if (s == -1) { perror(T_SHM_FILENAME); abort(); }
|
||||
int s = shm_open(shm_file, O_RDWR | O_CREAT /*| O_SYNC*/, 0666);
|
||||
if (s == -1) { perror(shm_file); abort(); }
|
||||
if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t)))
|
||||
{ perror(T_SHM_FILENAME); abort(); }
|
||||
{ perror(shm_file); abort(); }
|
||||
T_local_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, s, 0);
|
||||
if (T_local_cache == NULL)
|
||||
{ perror(T_SHM_FILENAME); abort(); }
|
||||
if (T_local_cache == MAP_FAILED)
|
||||
{ perror(shm_file); abort(); }
|
||||
close(s);
|
||||
|
||||
/* let's garbage the memory to catch some potential problems
|
||||
@@ -347,7 +361,7 @@ static void init_shm(void)
|
||||
}
|
||||
|
||||
void T_local_tracer_main(int remote_port, int wait_for_tracer,
|
||||
int local_socket)
|
||||
int local_socket, char *shm_file)
|
||||
{
|
||||
int s;
|
||||
int port = remote_port;
|
||||
@@ -357,7 +371,7 @@ void T_local_tracer_main(int remote_port, int wait_for_tracer,
|
||||
/* write on a socket fails if the other end is closed and we get SIGPIPE */
|
||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();
|
||||
|
||||
init_shm();
|
||||
init_shm(shm_file);
|
||||
s = local_socket;
|
||||
|
||||
if (dont_wait) {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "gui/gui.h"
|
||||
#include "filter/filter.h"
|
||||
#include "utils.h"
|
||||
#include "../T_defs.h"
|
||||
#include "event_selector.h"
|
||||
#include "openair_logo.h"
|
||||
#include "config.h"
|
||||
@@ -875,6 +874,8 @@ int main(int n, char **v)
|
||||
if (pthread_mutex_init(&enb_data.lock, NULL)) abort();
|
||||
setup_event_selector(g, database, is_on, is_on_changed, &enb_data);
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
restart:
|
||||
clear_remote_config();
|
||||
enb_data.socket = connect_to(ip, port);
|
||||
@@ -884,9 +885,8 @@ restart:
|
||||
|
||||
/* read messages */
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(enb_data.socket, v, database);
|
||||
e = get_event(enb_data.socket, &ebuf, database);
|
||||
if (e.type == -1) goto restart;
|
||||
if (pthread_mutex_lock(&enb_data.lock)) abort();
|
||||
handle_event(h, e);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
event get_event(int socket, char *event_buffer, void *database)
|
||||
event get_event(int socket, OBUF *event_buffer, void *database)
|
||||
{
|
||||
#ifdef T_SEND_TIME
|
||||
struct timespec t;
|
||||
@@ -29,17 +29,23 @@ again:
|
||||
#endif
|
||||
if (fullread(socket, &type, sizeof(int)) == -1) goto read_error;
|
||||
length -= sizeof(int);
|
||||
if (fullread(socket, event_buffer, length) == -1) goto read_error;
|
||||
if (event_buffer->omaxsize < length) {
|
||||
event_buffer->omaxsize = (length + 65535) & ~65535;
|
||||
event_buffer->obuf = realloc(event_buffer->obuf, event_buffer->omaxsize);
|
||||
if (event_buffer->obuf == NULL) { printf("out of memory\n"); exit(1); }
|
||||
}
|
||||
if (fullread(socket, event_buffer->obuf, length) == -1) goto read_error;
|
||||
event_buffer->osize = length;
|
||||
|
||||
if (type == -1) append_received_config_chunk(event_buffer, length);
|
||||
if (type == -1) append_received_config_chunk(event_buffer->obuf, length);
|
||||
if (type == -2) verify_config();
|
||||
|
||||
if (type == -1 || type == -2) goto again;
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
return new_event(t, type, length, event_buffer, database);
|
||||
return new_event(t, type, length, event_buffer->obuf, database);
|
||||
#else
|
||||
return new_event(type, length, event_buffer, database);
|
||||
return new_event(type, length, event_buffer->obuf, database);
|
||||
#endif
|
||||
|
||||
read_error:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _EVENT_H_
|
||||
#define _EVENT_H_
|
||||
|
||||
#include "utils.h"
|
||||
#include "../T_defs.h"
|
||||
#ifdef T_SEND_TIME
|
||||
#include <time.h>
|
||||
@@ -37,7 +38,7 @@ typedef struct {
|
||||
int ecount;
|
||||
} event;
|
||||
|
||||
event get_event(int s, char *v, void *d);
|
||||
event get_event(int s, OBUF *v, void *d);
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
event new_event(struct timespec sending_time, int type,
|
||||
|
||||
@@ -99,10 +99,11 @@ int main(int n, char **v)
|
||||
|
||||
found = 0;
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(fd, v, database);
|
||||
e = get_event(fd, &ebuf, database);
|
||||
if (e.type == -1) break;
|
||||
if (e.type != input_event_id) continue;
|
||||
for (i = 0; i < filter_count; i++)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "utils.h"
|
||||
#include "../T_defs.h"
|
||||
|
||||
void usage(void)
|
||||
@@ -35,14 +36,22 @@ int main(int n, char **v)
|
||||
in = fopen(input_filename, "r");
|
||||
if (in == NULL) { perror(input_filename); abort(); }
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
while (1) {
|
||||
int type;
|
||||
int32_t length;
|
||||
char v[T_BUFFER_MAX];
|
||||
char *v;
|
||||
int vpos = 0;
|
||||
|
||||
/* read event from file */
|
||||
if (fread(&length, 4, 1, in) != 1) break;
|
||||
if (ebuf.omaxsize < length) {
|
||||
ebuf.omaxsize = (length + 65535) & ~65535;
|
||||
ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize);
|
||||
if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); }
|
||||
}
|
||||
v = ebuf.obuf;
|
||||
memcpy(v+vpos, &length, 4);
|
||||
vpos += 4;
|
||||
#ifdef T_SEND_TIME
|
||||
|
||||
@@ -104,11 +104,12 @@ err:
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd == -1) { perror(file); exit(1); }
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
/* get wanted frame/subframe */
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(fd, v, database);
|
||||
e = get_event(fd, &ebuf, database);
|
||||
if (e.type == -1) break;
|
||||
if (e.type != input_event_id) continue;
|
||||
if (verbose)
|
||||
|
||||
@@ -100,10 +100,12 @@ err:
|
||||
int last_frame = -1;
|
||||
int last_subframe = -1;
|
||||
int subframe_written = 0;
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(fd, v, database);
|
||||
e = get_event(fd, &ebuf, database);
|
||||
if (e.type == -1) break;
|
||||
if (e.type != output_event_id) continue;
|
||||
if (verbose)
|
||||
|
||||
@@ -73,17 +73,22 @@ int main(int n, char **v)
|
||||
socket_send(socket, is_on, number_of_events * sizeof(int)) == -1)
|
||||
abort();
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
char dump[10][T_BUFFER_MAX];
|
||||
event dump_ev[10];
|
||||
FILE *z = fopen("/tmp/dd", "w"); if (z == NULL) abort();
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
char *v;
|
||||
event e;
|
||||
e = get_event(socket, v, database);
|
||||
e = get_event(socket, &ebuf, database);
|
||||
v = ebuf.obuf;
|
||||
if (e.type == -1) break;
|
||||
if (e.type == ev_input) {
|
||||
int sf = e.e[2].i;
|
||||
memcpy(dump[sf], v, T_BUFFER_MAX);
|
||||
if (ebuf.osize > T_BUFFER_MAX)
|
||||
{ printf("event size too big\n"); exit(1); }
|
||||
memcpy(dump[sf], ebuf.obuf, ebuf.osize);
|
||||
dump_ev[sf] = e;
|
||||
printf("input %d/%d\n", e.e[1].i, sf);
|
||||
if (fwrite(dump_ev[sf].e[4].b, dump_ev[sf].e[4].bsize, 1, z) != 1) abort();
|
||||
|
||||
@@ -84,11 +84,12 @@ int main(int n, char **v)
|
||||
socket_send(socket, is_on, number_of_events * sizeof(int)) == -1)
|
||||
abort();
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
int on_off;
|
||||
e = get_event(socket, v, database);
|
||||
e = get_event(socket, &ebuf, database);
|
||||
if (e.type == -1) break;
|
||||
if (e.type != ev_fun)
|
||||
{ printf("unhandled event %d\n", e.type); continue; }
|
||||
|
||||
@@ -246,11 +246,12 @@ int main(int n, char **v)
|
||||
|
||||
new_thread(receiver, &d);
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
/* read messages */
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(in, v, database);
|
||||
e = get_event(in, &ebuf, database);
|
||||
if (e.type == -1) break;
|
||||
if (!(e.type == ul_id || e.type == dl_id)) continue;
|
||||
handle_event(h, e);
|
||||
|
||||
@@ -123,14 +123,22 @@ int main(int n, char **v)
|
||||
if (signal(SIGINT, force_stop) == SIG_ERR) abort();
|
||||
if (signal(SIGTSTP, force_stop) == SIG_ERR) abort();
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
/* read messages */
|
||||
while (run) {
|
||||
int type;
|
||||
int32_t length;
|
||||
char v[T_BUFFER_MAX];
|
||||
char *v;
|
||||
int vpos = 0;
|
||||
|
||||
if (fullread(socket, &length, 4) == -1) goto read_error;
|
||||
if (ebuf.omaxsize < length) {
|
||||
ebuf.omaxsize = (length + 65535) & ~65535;
|
||||
ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize);
|
||||
if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); }
|
||||
}
|
||||
v = ebuf.obuf;
|
||||
memcpy(v+vpos, &length, 4);
|
||||
vpos += 4;
|
||||
#ifdef T_SEND_TIME
|
||||
|
||||
@@ -136,14 +136,22 @@ int main(int n, char **v)
|
||||
|
||||
new_thread(get_message_thread, &socket);
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
while (1) {
|
||||
int type;
|
||||
int32_t length;
|
||||
char v[T_BUFFER_MAX];
|
||||
char *v;
|
||||
int vpos = 0;
|
||||
|
||||
/* read event from file */
|
||||
if (fread(&length, 4, 1, in) != 1) break;
|
||||
if (ebuf.omaxsize < length) {
|
||||
ebuf.omaxsize = (length + 65535) & ~65535;
|
||||
ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize);
|
||||
if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); }
|
||||
}
|
||||
v = ebuf.obuf;
|
||||
memcpy(v+vpos, &length, 4);
|
||||
vpos += 4;
|
||||
#ifdef T_SEND_TIME
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "view/view.h"
|
||||
#include "gui/gui.h"
|
||||
#include "utils.h"
|
||||
#include "../T_defs.h"
|
||||
#include "event_selector.h"
|
||||
#include "config.h"
|
||||
|
||||
@@ -182,11 +181,12 @@ int main(int n, char **v)
|
||||
/* send the first message - activate selected traces */
|
||||
is_on_changed(&textlog_data);
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
/* read messages */
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(textlog_data.socket, v, database);
|
||||
e = get_event(textlog_data.socket, &ebuf, database);
|
||||
if (e.type == -1) abort();
|
||||
handle_event(h, e);
|
||||
}
|
||||
|
||||
@@ -287,11 +287,12 @@ int main(int n, char **v)
|
||||
if (signal(SIGINT, force_stop) == SIG_ERR) abort();
|
||||
if (signal(SIGTSTP, force_stop) == SIG_ERR) abort();
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
/* read messages */
|
||||
while (run) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(socket, v, database);
|
||||
e = get_event(socket, &ebuf, database);
|
||||
if (e.type == -1) { printf("disconnected? let's quit gently\n"); break; }
|
||||
handle_event(h, e);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "gui/gui.h"
|
||||
#include "filter/filter.h"
|
||||
#include "utils.h"
|
||||
#include "../T_defs.h"
|
||||
#include "event_selector.h"
|
||||
#include "openair_logo.h"
|
||||
#include "config.h"
|
||||
@@ -854,6 +853,8 @@ int main(int n, char **v)
|
||||
if (pthread_mutex_init(&ue_data.lock, NULL)) abort();
|
||||
setup_event_selector(g, database, is_on, is_on_changed, &ue_data);
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
restart:
|
||||
clear_remote_config();
|
||||
ue_data.socket = connect_to(ip, port);
|
||||
@@ -863,9 +864,8 @@ restart:
|
||||
|
||||
/* read messages */
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(ue_data.socket, v, database);
|
||||
e = get_event(ue_data.socket, &ebuf, database);
|
||||
if (e.type == -1) goto restart;
|
||||
if (pthread_mutex_lock(&ue_data.lock)) abort();
|
||||
handle_event(h, e);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "view/view.h"
|
||||
#include "gui/gui.h"
|
||||
#include "utils.h"
|
||||
#include "../T_defs.h"
|
||||
#include "event_selector.h"
|
||||
#include "config.h"
|
||||
|
||||
@@ -188,11 +187,12 @@ int main(int n, char **v)
|
||||
/* send the first message - activate selected traces */
|
||||
is_on_changed(&vcd_data);
|
||||
|
||||
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
|
||||
/* read messages */
|
||||
while (1) {
|
||||
char v[T_BUFFER_MAX];
|
||||
event e;
|
||||
e = get_event(vcd_data.socket, v, database);
|
||||
e = get_event(vcd_data.socket, &ebuf, database);
|
||||
if (e.type == -1) abort();
|
||||
handle_event(h, e);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
|
||||
#include "signals.h"
|
||||
#include "timer.h"
|
||||
#include "log.h"
|
||||
|
||||
/* ITTI DEBUG groups */
|
||||
#define ITTI_DEBUG_POLL (1<<0)
|
||||
@@ -73,6 +72,9 @@ const int itti_debug = (ITTI_DEBUG_ISSUES | ITTI_DEBUG_MP_STATISTICS);
|
||||
/* Global message size */
|
||||
#define MESSAGE_SIZE(mESSAGEiD) (sizeof(MessageHeader) + itti_desc.messages_info[mESSAGEiD].size)
|
||||
|
||||
|
||||
extern int emulate_rf;
|
||||
|
||||
typedef enum task_state_s {
|
||||
TASK_STATE_NOT_CONFIGURED, TASK_STATE_STARTING, TASK_STATE_READY, TASK_STATE_ENDED, TASK_STATE_MAX,
|
||||
} task_state_t;
|
||||
@@ -326,8 +328,112 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
|
||||
/* Increment the global message number */
|
||||
message_number = itti_increment_message_number ();
|
||||
|
||||
#if 0
|
||||
/* itti dump is disabled */
|
||||
itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name,
|
||||
sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
|
||||
#endif
|
||||
|
||||
if (destination_task_id != TASK_UNKNOWN) {
|
||||
|
||||
if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED) {
|
||||
ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), ended destination task!\n",
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_number,
|
||||
priority,
|
||||
itti_get_task_name(origin_task_id),
|
||||
destination_task_id,
|
||||
itti_get_task_name(destination_task_id));
|
||||
} else {
|
||||
if(!emulate_rf){
|
||||
/* We cannot send a message if the task is not running */
|
||||
AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY,
|
||||
"Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n",
|
||||
itti_get_task_name(origin_task_id),
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_id,
|
||||
destination_thread_id,
|
||||
itti_desc.threads[destination_thread_id].task_state);
|
||||
}
|
||||
|
||||
/* Allocate new list element */
|
||||
new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s));
|
||||
|
||||
/* Fill in members */
|
||||
new->msg = message;
|
||||
new->message_number = message_number;
|
||||
new->message_priority = priority;
|
||||
|
||||
/* Enqueue message in destination task queue */
|
||||
if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) {
|
||||
AssertFatal(0, "Error: lfds611_queue_enqueue returns 0, queue is full, exiting\n");
|
||||
}
|
||||
|
||||
{
|
||||
/* Only use event fd for tasks, subtasks will pool the queue */
|
||||
if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) {
|
||||
ssize_t write_ret;
|
||||
eventfd_t sem_counter = 1;
|
||||
|
||||
/* Call to write for an event fd must be of 8 bytes */
|
||||
write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter));
|
||||
AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n",
|
||||
destination_thread_id, (int) write_ret, (int) sizeof(sem_counter));
|
||||
}
|
||||
}
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n",
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_number,
|
||||
priority,
|
||||
itti_get_task_name(origin_task_id),
|
||||
destination_task_id,
|
||||
itti_get_task_name(destination_task_id));
|
||||
}
|
||||
} else {
|
||||
/* This is a debug message to TASK_UNKNOWN, we can release safely release it */
|
||||
int result = itti_free(origin_task_id, message);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* same as itti_send_msg_to_task but returns -1 in case of failure instead of crashing */
|
||||
/* TODO: this is a hack - the whole logic needs a proper rework. */
|
||||
/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
|
||||
int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message)
|
||||
{
|
||||
thread_id_t destination_thread_id;
|
||||
task_id_t origin_task_id;
|
||||
message_list_t *new;
|
||||
uint32_t priority;
|
||||
message_number_t message_number;
|
||||
uint32_t message_id;
|
||||
|
||||
AssertFatal (message != NULL, "Message is NULL!\n");
|
||||
AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max);
|
||||
|
||||
destination_thread_id = TASK_GET_THREAD_ID(destination_task_id);
|
||||
message->ittiMsgHeader.destinationTaskId = destination_task_id;
|
||||
message->ittiMsgHeader.instance = instance;
|
||||
message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame;
|
||||
message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot;
|
||||
message_id = message->ittiMsgHeader.messageId;
|
||||
AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max);
|
||||
|
||||
origin_task_id = ITTI_MSG_ORIGIN_ID(message);
|
||||
|
||||
priority = itti_get_message_priority (message_id);
|
||||
|
||||
/* Increment the global message number */
|
||||
message_number = itti_increment_message_number ();
|
||||
|
||||
#if 0
|
||||
/* itti dump is disabled */
|
||||
itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name,
|
||||
sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
|
||||
#endif
|
||||
|
||||
if (destination_task_id != TASK_UNKNOWN) {
|
||||
|
||||
@@ -359,18 +465,8 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
|
||||
|
||||
/* Enqueue message in destination task queue */
|
||||
if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) {
|
||||
LOG_I(UDP_, " Assertion Message %s(id:%d), number %lu with priority %d can not be sent from (%u:%s) to queue (%u:%s). discarding...\n",
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_id,
|
||||
message_number,
|
||||
priority,
|
||||
origin_task_id,
|
||||
itti_get_task_name(origin_task_id),
|
||||
destination_task_id,
|
||||
itti_get_task_name(destination_task_id));
|
||||
int result = itti_free(origin_task_id, message);
|
||||
AssertFatal( result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
return 0;
|
||||
itti_free(origin_task_id, new);
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -524,10 +620,7 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t
|
||||
|
||||
if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 0) {
|
||||
/* No element in list -> this should not happen */
|
||||
LOG_I(UDP_, "Assertion No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret);
|
||||
/* Mark that the event has been processed */
|
||||
itti_desc.threads[thread_id].events[i].events &= ~EPOLLIN;
|
||||
return;
|
||||
AssertFatal (0, "No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret);
|
||||
}
|
||||
|
||||
AssertFatal(message != NULL, "Message from message queue is NULL!\n");
|
||||
@@ -634,8 +727,11 @@ void itti_mark_task_ready(task_id_t task_id)
|
||||
|
||||
AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max);
|
||||
|
||||
#if 0
|
||||
/* itti dump is disabled */
|
||||
/* Register the thread in itti dump */
|
||||
itti_dump_thread_use_ring_buffer();
|
||||
#endif
|
||||
|
||||
/* Mark the thread as using LFDS queue */
|
||||
lfds611_queue_use(itti_desc.tasks[task_id].message_queue);
|
||||
@@ -661,6 +757,19 @@ void itti_mark_task_ready(task_id_t task_id)
|
||||
|
||||
void itti_exit_task(void)
|
||||
{
|
||||
task_id_t task_id = itti_get_current_task_id();
|
||||
thread_id_t thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
|
||||
#if defined(OAI_EMU) || defined(RTAI)
|
||||
if (task_id > TASK_UNKNOWN) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG,
|
||||
__sync_and_and_fetch (&itti_desc.vcd_receive_msg, ~(1L << task_id)));
|
||||
}
|
||||
#endif
|
||||
|
||||
itti_desc.threads[thread_id].task_state = TASK_STATE_NOT_CONFIGURED;
|
||||
itti_desc.created_tasks--;
|
||||
ITTI_DEBUG(ITTI_DEBUG_EXIT, "Thread for task %s (%d) exits\n", itti_get_task_name(task_id), task_id);
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
@@ -762,7 +871,10 @@ int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_i
|
||||
itti_desc.wait_tasks = 0;
|
||||
itti_desc.created_tasks = 0;
|
||||
itti_desc.ready_tasks = 0;
|
||||
#if 0
|
||||
/* itti dump is disabled */
|
||||
itti_dump_init (messages_definition_xml, dump_file_name);
|
||||
#endif
|
||||
|
||||
CHECK_INIT_RETURN(timer_init ());
|
||||
|
||||
@@ -829,7 +941,10 @@ void itti_wait_tasks_end(void)
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* itti dump is disabled */
|
||||
itti_dump_exit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void itti_send_terminate_message(task_id_t task_id)
|
||||
|
||||
@@ -108,6 +108,18 @@ int itti_send_broadcast_message(MessageDef *message_p);
|
||||
**/
|
||||
int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message);
|
||||
|
||||
/* TODO: this is a hack. Almost no caller of itti_send_msg_to_task checks
|
||||
* the return value so it has been changed to crash the program in case
|
||||
* of failure instead of returning -1 as the documentation above says.
|
||||
* The RLC UM code may receive too much data when doing UDP at a higher
|
||||
* throughput than the link allows and so for this specific case we need
|
||||
* a version that actually returns -1 on failure.
|
||||
*
|
||||
* This needs to be cleaned at some point.
|
||||
*/
|
||||
/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
|
||||
int itti_try_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message);
|
||||
|
||||
/** \brief Add a new fd to monitor.
|
||||
* NOTE: it is up to the user to read data associated with the fd
|
||||
* \param task_id Task ID of the receiving task
|
||||
|
||||
@@ -27,7 +27,18 @@
|
||||
#ifndef _ITTI_TYPES_H_
|
||||
#define _ITTI_TYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
/* The current file is included in the ue_ip.ko compilation.
|
||||
* For it to work we need to include linux/types.h and
|
||||
* not stdint.h.
|
||||
* A solution to this problem is to use #ifndef __KERNEL__.
|
||||
* Maybe a better solution would be to clean things up
|
||||
* so that ue_ip.ko does not include the current file.
|
||||
*/
|
||||
#ifndef __KERNEL__
|
||||
# include <stdint.h>
|
||||
#else
|
||||
# include <linux/types.h>
|
||||
#endif
|
||||
|
||||
#define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1))
|
||||
|
||||
|
||||
@@ -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
|
||||
*
|
||||
@@ -34,9 +34,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <dlfcn.h>
|
||||
#include "openair1/PHY/defs.h"
|
||||
#include "openair1/PHY/defs_common.h"
|
||||
#define LOAD_MODULE_SHLIB_MAIN
|
||||
|
||||
#include "common/config/config_userapi.h"
|
||||
@@ -44,68 +45,162 @@
|
||||
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");
|
||||
printf("[LOADER] configuration couldn't be performed via config module, parameters set to default values\n");
|
||||
if (loader_data.shlibpath == NULL) {
|
||||
loader_data.shlibpath=DEFAULT_PATH;
|
||||
}
|
||||
return;
|
||||
}
|
||||
loader_data.maxshlibs = DEFAULT_MAXSHLIBS;
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
/* no specific shared lib version */
|
||||
if (shlibversion == NULL) {
|
||||
shlibversion = "" ;
|
||||
}
|
||||
/* 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;
|
||||
getfarrayfunc_t fpg;
|
||||
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) {
|
||||
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++) {
|
||||
farray[i].fptr = dlsym(lib_handle,farray[i].fname);
|
||||
if (farray[i].fptr == NULL ) {
|
||||
fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname);
|
||||
ret= -1;
|
||||
}
|
||||
ret= -1;
|
||||
} else { /* 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++;
|
||||
}/* farray[i].fptr != NULL */
|
||||
} /* for int i... */
|
||||
} /* farray ! NULL */
|
||||
}
|
||||
} else { /* farray ! NULL */
|
||||
sprintf(afname,"%s_getfarray",modname);
|
||||
fpg = dlsym(lib_handle,afname);
|
||||
if (fpg != NULL ) {
|
||||
loader_data.shlibs[loader_data.numshlibs].numfunc = fpg(&(loader_data.shlibs[loader_data.numshlibs].funcarray));
|
||||
}
|
||||
} /* farray ! NULL */
|
||||
loader_data.shlibs[loader_data.numshlibs].name=strdup(modname);
|
||||
loader_data.shlibs[loader_data.numshlibs].thisshlib_path=strdup(shlib_path);
|
||||
|
||||
(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;
|
||||
}
|
||||
|
||||
void * get_shlibmodule_fptr(char *modname, char *fname)
|
||||
{
|
||||
for (int i=0; i<loader_data.numshlibs && loader_data.shlibs[i].name != NULL; i++) {
|
||||
if ( strcmp(loader_data.shlibs[i].name, modname) == 0) {
|
||||
for (int j =0; j<loader_data.shlibs[i].numfunc ; j++) {
|
||||
if (strcmp(loader_data.shlibs[i].funcarray[j].fname, fname) == 0) {
|
||||
return loader_data.shlibs[i].funcarray[j].fptr;
|
||||
}
|
||||
} /* for j loop on module functions*/
|
||||
}
|
||||
} /* for i loop on modules */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*
|
||||
@@ -33,33 +33,60 @@
|
||||
#define LOAD_SHLIB_H
|
||||
|
||||
|
||||
typedef int(*initfunc_t)(void);
|
||||
|
||||
typedef struct {
|
||||
char *shlibpath;
|
||||
}loader_data_t;
|
||||
|
||||
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;
|
||||
|
||||
/* function type of functions which may be implemented by a module */
|
||||
/* 1: init function, called when loading, if found in the shared lib */
|
||||
typedef int(*initfunc_t)(void);
|
||||
/* 2: version checking function, called when loading, if it returns -1, trigger main exec abort */
|
||||
typedef int(*checkverfunc_t)(char * mainexec_version, char ** shlib_version);
|
||||
/* 3: get function array function, called when loading when a module doesn't provide */
|
||||
/* the function array when calling load_module_shlib (farray param NULL) */
|
||||
typedef int(*getfarrayfunc_t)(loader_shlibfunc_t **funcarray);
|
||||
|
||||
#ifdef LOAD_MODULE_SHLIB_MAIN
|
||||
#define LOADER_CONFIG_PREFIX "loader"
|
||||
#define DEFAULT_PATH ""
|
||||
#define DEFAULT_PATH ""
|
||||
#define DEFAULT_MAXSHLIBS 10
|
||||
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:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0}, \
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------*/
|
||||
#else
|
||||
#else /* LOAD_MODULE_SHLIB_MAIN */
|
||||
extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf);
|
||||
#endif
|
||||
extern void * get_shlibmodule_fptr(char *modname, char *fname);
|
||||
extern loader_data_t loader_data;
|
||||
#endif /* LOAD_MODULE_SHLIB_MAIN */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ void *msc_task(void *args_p)
|
||||
break;
|
||||
|
||||
case TERMINATE_MESSAGE: {
|
||||
fprintf(stderr, " *** Exiting MSC thread\n");
|
||||
timer_remove(timer_id);
|
||||
msc_end();
|
||||
itti_exit_task();
|
||||
|
||||
@@ -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>
|
||||
@@ -51,20 +51,27 @@
|
||||
#include <dlfcn.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "common/utils/load_module_shlib.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,26 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int telnetsrv_getfarray(loader_shlibfunc_t **farray)
|
||||
{
|
||||
*farray=malloc(sizeof(loader_shlibfunc_t));
|
||||
(*farray)[0].fname=TELNET_ADDCMD_FNAME;
|
||||
(*farray)[0].fptr=(int (*)(void) )add_telnetcmd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -130,10 +131,12 @@ VT escape sequence definition, for smarter display....
|
||||
#define STDFMT "\x1b[0m"
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*/
|
||||
#define TELNET_ADDCMD_FNAME "add_telnetcmd"
|
||||
typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *);
|
||||
#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();
|
||||
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
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -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
|
||||
*
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
*
|
||||
@@ -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