API change: new arguments to time_manager_start()
This commit is contained in:
@@ -41,12 +41,6 @@ void exit_function(const char *file, const char *function, const int line, const
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_x2ap_enabled(void)
|
|
||||||
{
|
|
||||||
/* we want x2ap ticks */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rlc_tick_count = 0;
|
static int rlc_tick_count = 0;
|
||||||
static int pdcp_tick_count = 0;
|
static int pdcp_tick_count = 0;
|
||||||
static int x2ap_tick_count = 0;
|
static int x2ap_tick_count = 0;
|
||||||
@@ -69,7 +63,13 @@ void x2ap_ms_tick(void)
|
|||||||
/* return 1 if ok, 0 if error */
|
/* return 1 if ok, 0 if error */
|
||||||
static int standalone_realtime(void)
|
static int standalone_realtime(void)
|
||||||
{
|
{
|
||||||
time_manager_start(TIME_MANAGER_GNB_MONOLITHIC, TIME_MANAGER_REALTIME);
|
time_manager_tick_function_t tick_functions[] = {
|
||||||
|
nr_pdcp_ms_tick,
|
||||||
|
nr_rlc_ms_tick,
|
||||||
|
x2ap_ms_tick
|
||||||
|
};
|
||||||
|
int tick_functions_count = sizeofArray(tick_functions);
|
||||||
|
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_REALTIME);
|
||||||
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
@@ -90,7 +90,13 @@ static int standalone_realtime(void)
|
|||||||
/* return 1 if ok, 0 if error */
|
/* return 1 if ok, 0 if error */
|
||||||
static int standalone_iq_samples(void)
|
static int standalone_iq_samples(void)
|
||||||
{
|
{
|
||||||
time_manager_start(TIME_MANAGER_GNB_MONOLITHIC, TIME_MANAGER_IQ_SAMPLES);
|
time_manager_tick_function_t tick_functions[] = {
|
||||||
|
nr_pdcp_ms_tick,
|
||||||
|
nr_rlc_ms_tick,
|
||||||
|
x2ap_ms_tick
|
||||||
|
};
|
||||||
|
int tick_functions_count = sizeofArray(tick_functions);
|
||||||
|
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_IQ_SAMPLES);
|
||||||
|
|
||||||
/* let's pretend we have 2000 samples per second */
|
/* let's pretend we have 2000 samples per second */
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
@@ -168,8 +174,14 @@ static int client_server(char *program_name, bool iq_samples_time_source)
|
|||||||
/* return 1 if ok, 0 if error */
|
/* return 1 if ok, 0 if error */
|
||||||
static int run_sub_client_server(bool iq_samples_time_source)
|
static int run_sub_client_server(bool iq_samples_time_source)
|
||||||
{
|
{
|
||||||
/* second argument doesn't matter, overwritten by args of execl in client_server() */
|
time_manager_tick_function_t tick_functions[] = {
|
||||||
time_manager_start(TIME_MANAGER_GNB_MONOLITHIC, TIME_MANAGER_REALTIME);
|
nr_pdcp_ms_tick,
|
||||||
|
nr_rlc_ms_tick,
|
||||||
|
x2ap_ms_tick
|
||||||
|
};
|
||||||
|
int tick_functions_count = sizeofArray(tick_functions);
|
||||||
|
/* last argument doesn't matter, overwritten by args of execl in client_server() */
|
||||||
|
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_REALTIME);
|
||||||
|
|
||||||
if (iq_samples_time_source) {
|
if (iq_samples_time_source) {
|
||||||
/* 'iq_samples_time_source' is true only for server
|
/* 'iq_samples_time_source' is true only for server
|
||||||
|
|||||||
@@ -19,9 +19,6 @@
|
|||||||
* contact@openairinterface.org
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <dlfcn.h>
|
|
||||||
|
|
||||||
#include "time_manager.h"
|
#include "time_manager.h"
|
||||||
|
|
||||||
#include "time_source.h"
|
#include "time_source.h"
|
||||||
@@ -37,27 +34,17 @@ static time_source_t *time_source = NULL;
|
|||||||
static time_server_t *time_server = NULL;
|
static time_server_t *time_server = NULL;
|
||||||
static time_client_t *time_client = NULL;
|
static time_client_t *time_client = NULL;
|
||||||
|
|
||||||
/* available tick functions in the executable
|
/* tick functions registered at initialization of the time manager */
|
||||||
* found at startup time of the program using dlsym()
|
static time_manager_tick_function_t *tick_functions;
|
||||||
*/
|
static int tick_functions_count;
|
||||||
static void (*pdcp_tick)(void) = NULL;
|
|
||||||
static void (*rlc_tick)(void) = NULL;
|
|
||||||
static void (*x2ap_tick)(void) = NULL;
|
|
||||||
|
|
||||||
/* tick callback, called by time_source every 'millisecond' (can be
|
/* tick callback, called by time_source every 'millisecond' (can be
|
||||||
* actual millisecond or simulated millisecond)
|
* actual millisecond or simulated millisecond)
|
||||||
*/
|
*/
|
||||||
static void tick(void *unused)
|
static void tick(void *unused)
|
||||||
{
|
{
|
||||||
/* call x2ap_tick, pdcp_tick, rlc_tick (if they exist) */
|
for (int i = 0; i < tick_functions_count; i++)
|
||||||
if (pdcp_tick != NULL)
|
tick_functions[i]();
|
||||||
pdcp_tick();
|
|
||||||
|
|
||||||
if (rlc_tick != NULL)
|
|
||||||
rlc_tick();
|
|
||||||
|
|
||||||
if (x2ap_tick != NULL)
|
|
||||||
x2ap_tick();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TIME_SOURCE "time_source"
|
#define TIME_SOURCE "time_source"
|
||||||
@@ -92,10 +79,10 @@ static int get_param_int(char *name)
|
|||||||
return *config_parameters[idx].iptr;
|
return *config_parameters[idx].iptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void time_manager_start(time_manager_client_t client_type,
|
void time_manager_start(time_manager_tick_function_t *_tick_functions,
|
||||||
time_manager_mode_t running_mode)
|
int _tick_functions_count,
|
||||||
|
time_source_type_t time_source_type)
|
||||||
{
|
{
|
||||||
time_source_type_t time_source_type = -1;
|
|
||||||
bool has_time_server = false;
|
bool has_time_server = false;
|
||||||
bool has_time_client = false;
|
bool has_time_client = false;
|
||||||
char *default_server_ip = "127.0.0.1";
|
char *default_server_ip = "127.0.0.1";
|
||||||
@@ -103,47 +90,11 @@ void time_manager_start(time_manager_client_t client_type,
|
|||||||
char *server_ip = NULL;
|
char *server_ip = NULL;
|
||||||
int server_port = -1;
|
int server_port = -1;
|
||||||
|
|
||||||
/* retrieve, if applicable, available tick functions in the program */
|
tick_functions_count = _tick_functions_count;
|
||||||
if (client_type == TIME_MANAGER_GNB_MONOLITHIC
|
tick_functions = calloc_or_fail(tick_functions_count, sizeof(*tick_functions));
|
||||||
|| client_type == TIME_MANAGER_GNB_CU
|
memcpy(tick_functions, _tick_functions, tick_functions_count * sizeof(*tick_functions));
|
||||||
|| client_type == TIME_MANAGER_UE)
|
|
||||||
pdcp_tick = dlsym(RTLD_DEFAULT, "nr_pdcp_ms_tick");
|
|
||||||
|
|
||||||
if (client_type == TIME_MANAGER_GNB_MONOLITHIC
|
/* retrieve configuration */
|
||||||
|| client_type == TIME_MANAGER_GNB_DU
|
|
||||||
|| client_type == TIME_MANAGER_UE)
|
|
||||||
rlc_tick = dlsym(RTLD_DEFAULT, "nr_rlc_ms_tick");
|
|
||||||
|
|
||||||
/* let's also retrieve is_x2ap_enabled() with dlsym to not force the
|
|
||||||
* application to define it (this logic may be changed if wanted)
|
|
||||||
*/
|
|
||||||
int (*is_x2ap_enabled)(void) = dlsym(RTLD_DEFAULT, "is_x2ap_enabled");
|
|
||||||
if ((client_type == TIME_MANAGER_GNB_MONOLITHIC
|
|
||||||
|| client_type == TIME_MANAGER_GNB_CU)
|
|
||||||
&& is_x2ap_enabled != NULL && is_x2ap_enabled())
|
|
||||||
x2ap_tick = dlsym(RTLD_DEFAULT, "x2ap_ms_tick");
|
|
||||||
|
|
||||||
/* get default configuration */
|
|
||||||
switch (client_type) {
|
|
||||||
case TIME_MANAGER_GNB_MONOLITHIC:
|
|
||||||
case TIME_MANAGER_GNB_DU:
|
|
||||||
case TIME_MANAGER_UE:
|
|
||||||
switch (running_mode) {
|
|
||||||
case TIME_MANAGER_REALTIME:
|
|
||||||
time_source_type = TIME_SOURCE_REALTIME;
|
|
||||||
break;
|
|
||||||
case TIME_MANAGER_IQ_SAMPLES:
|
|
||||||
time_source_type = TIME_SOURCE_IQ_SAMPLES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TIME_MANAGER_GNB_CU:
|
|
||||||
case TIME_MANAGER_SIMULATOR:
|
|
||||||
time_source_type = TIME_SOURCE_REALTIME;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get values from configuration */
|
|
||||||
int ret = config_get(config_get_if(), config_parameters, sizeofArray(config_parameters), "time_management");
|
int ret = config_get(config_get_if(), config_parameters, sizeofArray(config_parameters), "time_management");
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
char *param;
|
char *param;
|
||||||
@@ -209,23 +160,19 @@ void time_manager_start(time_manager_client_t client_type,
|
|||||||
|
|
||||||
if (has_time_client) {
|
if (has_time_client) {
|
||||||
time_client = new_time_client(server_ip, server_port, tick, NULL);
|
time_client = new_time_client(server_ip, server_port, tick, NULL);
|
||||||
|
/* for the log below, there is no time source, we want to print 'server' as time source */
|
||||||
|
time_source_type = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_I(UTIL,
|
LOG_I(UTIL,
|
||||||
"time manager configuration: [time source: %s] [mode: %s] [server IP: %s} [server port: %d]%s\n",
|
"time manager configuration: [time source: %s] [mode: %s] [server IP: %s} [server port: %d]%s\n",
|
||||||
(char *[]){"reatime", "iq_samples"}[time_source_type],
|
(char *[]){"reatime", "iq_samples", "server"}[time_source_type],
|
||||||
has_time_server ? "server"
|
has_time_server ? "server"
|
||||||
: has_time_client ? "client"
|
: has_time_client ? "client"
|
||||||
: "standalone",
|
: "standalone",
|
||||||
server_ip,
|
server_ip,
|
||||||
server_port,
|
server_port,
|
||||||
has_time_server || has_time_client ? "" : " (server IP/port not used)");
|
has_time_server || has_time_client ? "" : " (server IP/port not used)");
|
||||||
|
|
||||||
LOG_I(UTIL,
|
|
||||||
"time manager: pdcp tick: %s, rlc tick: %s, x2ap tick: %s\n",
|
|
||||||
pdcp_tick == NULL ? "not activated" : "activated",
|
|
||||||
rlc_tick == NULL ? "not activated" : "activated",
|
|
||||||
x2ap_tick == NULL ? "not activated" : "activated");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void time_manager_iq_samples(uint64_t iq_samples_count,
|
void time_manager_iq_samples(uint64_t iq_samples_count,
|
||||||
@@ -251,4 +198,8 @@ void time_manager_finish(void)
|
|||||||
free_time_client(time_client);
|
free_time_client(time_client);
|
||||||
time_client = NULL;
|
time_client = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(tick_functions);
|
||||||
|
tick_functions = NULL;
|
||||||
|
tick_functions_count = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,21 +24,13 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef enum {
|
#include "time_source.h"
|
||||||
TIME_MANAGER_GNB_MONOLITHIC,
|
|
||||||
TIME_MANAGER_GNB_CU,
|
|
||||||
TIME_MANAGER_GNB_DU,
|
|
||||||
TIME_MANAGER_UE,
|
|
||||||
TIME_MANAGER_SIMULATOR,
|
|
||||||
} time_manager_client_t;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef void (*time_manager_tick_function_t)(void);
|
||||||
TIME_MANAGER_REALTIME,
|
|
||||||
TIME_MANAGER_IQ_SAMPLES
|
|
||||||
} time_manager_mode_t;
|
|
||||||
|
|
||||||
void time_manager_start(time_manager_client_t client_type,
|
void time_manager_start(time_manager_tick_function_t *tick_functions,
|
||||||
time_manager_mode_t running_mode);
|
int tick_functions_count,
|
||||||
|
time_source_type_t time_source);
|
||||||
void time_manager_iq_samples(uint64_t iq_samples_count,
|
void time_manager_iq_samples(uint64_t iq_samples_count,
|
||||||
uint64_t iq_samples_per_second);
|
uint64_t iq_samples_per_second);
|
||||||
void time_manager_finish(void);
|
void time_manager_finish(void);
|
||||||
|
|||||||
@@ -253,8 +253,9 @@ in `time_manager.c`, together with some global variables (so that there is no
|
|||||||
need to pass objects around, to limit risks of misuse).
|
need to pass objects around, to limit risks of misuse).
|
||||||
|
|
||||||
Each program (for example: gnb, ue, cu, du) calls the `time_manager_start()`
|
Each program (for example: gnb, ue, cu, du) calls the `time_manager_start()`
|
||||||
function, passing the kind of program it is. Based on this type and the
|
function, passing the callback functions to be called when a tick is generated
|
||||||
configuration, `time_manager_start()` initializes what is needed.
|
(several callbacks can be passed) and a default time source. Based on this,
|
||||||
|
`time_manager_start()` initializes what is needed.
|
||||||
|
|
||||||
The function `time_manager_iq_samples()` is to be called by programs that
|
The function `time_manager_iq_samples()` is to be called by programs that
|
||||||
read IQ samples. It is called unconditionally. It may do nothing if the
|
read IQ samples. It is called unconditionally. It may do nothing if the
|
||||||
@@ -268,8 +269,9 @@ Here comes the API.
|
|||||||
|
|
||||||
- init the time manager:
|
- init the time manager:
|
||||||
```
|
```
|
||||||
void time_manager_start(time_manager_client_t client_type,
|
void time_manager_start(time_manager_tick_function_t *tick_functions,
|
||||||
time_manager_mode_t running_mode)
|
int tick_functions_count,
|
||||||
|
time_source_type_t time_source);
|
||||||
```
|
```
|
||||||
(for valid values of `client_type` and `running_mode` see in
|
(for valid values of `client_type` and `running_mode` see in
|
||||||
`time_manager.h`)
|
`time_manager.h`)
|
||||||
|
|||||||
@@ -143,7 +143,12 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
// start time manager with some reasonable default for the running mode
|
// start time manager with some reasonable default for the running mode
|
||||||
// (may be overwritten in configuration file or command line)
|
// (may be overwritten in configuration file or command line)
|
||||||
time_manager_start(TIME_MANAGER_GNB_CU, TIME_MANAGER_REALTIME);
|
void nr_pdcp_ms_tick(void);
|
||||||
|
time_manager_tick_function_t tick_functions[] = {
|
||||||
|
nr_pdcp_ms_tick
|
||||||
|
};
|
||||||
|
int tick_functions_count = 1;
|
||||||
|
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_REALTIME);
|
||||||
|
|
||||||
// strdup to put the sring in the core file for post mortem identification
|
// strdup to put the sring in the core file for post mortem identification
|
||||||
LOG_I(HW, "Version: %s\n", strdup(OAI_PACKAGE_VERSION));
|
LOG_I(HW, "Version: %s\n", strdup(OAI_PACKAGE_VERSION));
|
||||||
|
|||||||
@@ -631,15 +631,35 @@ int main( int argc, char **argv ) {
|
|||||||
|
|
||||||
// start time manager with some reasonable default for the running mode
|
// start time manager with some reasonable default for the running mode
|
||||||
// (may be overwritten in configuration file or command line)
|
// (may be overwritten in configuration file or command line)
|
||||||
time_manager_start(NODE_IS_MONOLITHIC(node_type) ? TIME_MANAGER_GNB_MONOLITHIC
|
void nr_pdcp_ms_tick(void);
|
||||||
: NODE_IS_CU(node_type) ? TIME_MANAGER_GNB_CU
|
void x2ap_ms_tick();
|
||||||
: TIME_MANAGER_GNB_DU,
|
void nr_rlc_ms_tick(void);
|
||||||
|
time_manager_tick_function_t tick_functions[3];
|
||||||
|
int tick_functions_count = 0;
|
||||||
|
if (NODE_IS_MONOLITHIC(node_type)) {
|
||||||
|
/* monolithic */
|
||||||
|
tick_functions[tick_functions_count++] = nr_pdcp_ms_tick;
|
||||||
|
tick_functions[tick_functions_count++] = nr_rlc_ms_tick;
|
||||||
|
/* x2ap is enabled when in NSA mode */
|
||||||
|
if (get_softmodem_params()->nsa)
|
||||||
|
tick_functions[tick_functions_count++] = x2ap_ms_tick;
|
||||||
|
} else if (NODE_IS_CU(node_type)) {
|
||||||
|
/* CU */
|
||||||
|
tick_functions[tick_functions_count++] = nr_pdcp_ms_tick;
|
||||||
|
/* x2ap is enabled when in NSA mode */
|
||||||
|
if (get_softmodem_params()->nsa)
|
||||||
|
tick_functions[tick_functions_count++] = x2ap_ms_tick;
|
||||||
|
} else {
|
||||||
|
/* DU */
|
||||||
|
tick_functions[tick_functions_count++] = nr_rlc_ms_tick;
|
||||||
|
}
|
||||||
|
time_manager_start(tick_functions, tick_functions_count,
|
||||||
// iq_samples time source for monolithic/du with rfsim,
|
// iq_samples time source for monolithic/du with rfsim,
|
||||||
// realtime time source for other cases
|
// realtime time source for other cases
|
||||||
IS_SOFTMODEM_RFSIM
|
IS_SOFTMODEM_RFSIM
|
||||||
&& (NODE_IS_MONOLITHIC(node_type) || NODE_IS_DU(node_type))
|
&& (NODE_IS_MONOLITHIC(node_type) || NODE_IS_DU(node_type))
|
||||||
? TIME_MANAGER_IQ_SAMPLES
|
? TIME_SOURCE_IQ_SAMPLES
|
||||||
: TIME_MANAGER_REALTIME);
|
: TIME_SOURCE_REALTIME);
|
||||||
|
|
||||||
// start the main threads
|
// start the main threads
|
||||||
number_of_cards = 1;
|
number_of_cards = 1;
|
||||||
|
|||||||
@@ -464,11 +464,18 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
// start time manager with some reasonable default for the running mode
|
// start time manager with some reasonable default for the running mode
|
||||||
// (may be overwritten in configuration file or command line)
|
// (may be overwritten in configuration file or command line)
|
||||||
time_manager_start(TIME_MANAGER_UE,
|
void nr_pdcp_ms_tick(void);
|
||||||
|
void nr_rlc_ms_tick(void);
|
||||||
|
time_manager_tick_function_t tick_functions[] = {
|
||||||
|
nr_pdcp_ms_tick,
|
||||||
|
nr_rlc_ms_tick
|
||||||
|
};
|
||||||
|
int tick_functions_count = 2;
|
||||||
|
time_manager_start(tick_functions, tick_functions_count,
|
||||||
// iq_samples time source for rfsim,
|
// iq_samples time source for rfsim,
|
||||||
// realtime time source if not
|
// realtime time source if not
|
||||||
IS_SOFTMODEM_RFSIM ? TIME_MANAGER_IQ_SAMPLES
|
IS_SOFTMODEM_RFSIM ? TIME_SOURCE_IQ_SAMPLES
|
||||||
: TIME_MANAGER_REALTIME);
|
: TIME_SOURCE_REALTIME);
|
||||||
|
|
||||||
if (!get_softmodem_params()->nsa && get_softmodem_params()->emulate_l1)
|
if (!get_softmodem_params()->nsa && get_softmodem_params()->emulate_l1)
|
||||||
start_oai_nrue_threads();
|
start_oai_nrue_threads();
|
||||||
|
|||||||
Reference in New Issue
Block a user