Commit 17d5bcd3 authored by laurent's avatar laurent

dev continue

parent 7653b79f
......@@ -28,13 +28,23 @@
* separate process solves this problem.
*/
#define _GNU_SOURCE
#include "system.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <common/utils/assertions.h>
#include <common/utils/LOG/log.h>
#define MAX_COMMAND 4096
static int command_pipe_read;
......@@ -50,37 +60,37 @@ static int module_initialized = 0;
/* util functions */
/********************************************************************/
static void lock_system(void)
{
static void lock_system(void) {
if (pthread_mutex_lock(&lock) != 0) {
printf("pthread_mutex_lock fails\n");
abort();
}
}
static void unlock_system(void)
{
static void unlock_system(void) {
if (pthread_mutex_unlock(&lock) != 0) {
printf("pthread_mutex_unlock fails\n");
abort();
}
}
static void write_pipe(int p, char *b, int size)
{
static void write_pipe(int p, char *b, int size) {
while (size) {
int ret = write(p, b, size);
if (ret <= 0) exit(0);
b += ret;
size -= ret;
}
}
static void read_pipe(int p, char *b, int size)
{
static void read_pipe(int p, char *b, int size) {
while (size) {
int ret = read(p, b, size);
if (ret <= 0) exit(0);
b += ret;
size -= ret;
}
......@@ -95,14 +105,13 @@ static void read_pipe(int p, char *b, int size)
* when the main process exits, because then a "read" on the pipe
* will return 0, in which case "read_pipe" exits.
*/
static void background_system_process(void)
{
static void background_system_process(void) {
int len;
int ret;
char command[MAX_COMMAND+1];
while (1) {
read_pipe(command_pipe_read, (char*)&len, sizeof(int));
read_pipe(command_pipe_read, (char *)&len, sizeof(int));
read_pipe(command_pipe_read, command, len);
ret = system(command);
write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
......@@ -114,8 +123,7 @@ static void background_system_process(void)
/* return -1 on error, 0 on success */
/********************************************************************/
int background_system(char *command)
{
int background_system(char *command) {
int res;
int len;
......@@ -125,18 +133,22 @@ int background_system(char *command)
}
len = strlen(command)+1;
if (len > MAX_COMMAND) {
printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
printf("command was: '%s'\n", command);
abort();
}
/* only one command can run at a time, so let's lock/unlock */
lock_system();
write_pipe(command_pipe_write, (char*)&len, sizeof(int));
write_pipe(command_pipe_write, (char *)&len, sizeof(int));
write_pipe(command_pipe_write, command, len);
read_pipe(result_pipe_read, (char*)&res, sizeof(int));
read_pipe(result_pipe_read, (char *)&res, sizeof(int));
unlock_system();
if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
return 0;
}
......@@ -146,17 +158,16 @@ int background_system(char *command)
/* to be called very early by the main processing */
/********************************************************************/
void start_background_system(void)
{
void start_background_system(void) {
int p[2];
pid_t son;
module_initialized = 1;
if (pipe(p) == -1) {
perror("pipe");
exit(1);
}
command_pipe_read = p[0];
command_pipe_write = p[1];
......@@ -164,10 +175,11 @@ void start_background_system(void)
perror("pipe");
exit(1);
}
result_pipe_read = p[0];
result_pipe_write = p[1];
son = fork();
if (son == -1) {
perror("fork");
exit(1);
......@@ -181,6 +193,56 @@ void start_background_system(void)
close(result_pipe_read);
close(command_pipe_write);
background_system_process();
}
void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
struct sched_param sparam={0};
sparam.sched_priority = priority;
pthread_attr_setschedparam(&attr, &sparam);
pthread_create(t, &attr, func, param);
pthread_setname_np(*t, name);
if (affinity != -1 ) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(affinity, &cpuset);
AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
}
pthread_attr_destroy(&attr);
}
// Block CPU C-states deep sleep
void configure_linux(void) {
int ret;
static int latency_target_fd=-1;
uint32_t latency_target_value=10; // in microseconds
if (latency_target_fd == -1) {
if ( (latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR)) != -1 ) {
ret = write(latency_target_fd, &latency_target_value, sizeof(latency_target_value));
if (ret == 0) {
printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno));
close(latency_target_fd);
latency_target_fd=-1;
return;
}
}
}
if (latency_target_fd != -1)
LOG_I(HW,"# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
else
LOG_E(HW,"Can't set /dev/cpu_dma_latency to %dus\n", latency_target_value);
// Set CPU frequency to it's maximum
if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
LOG_W(HW,"Can't set cpu frequency\n");
}
......@@ -21,6 +21,12 @@
#ifndef _SYSTEM_H_OAI_
#define _SYSTEM_H_OAI_
#include <stdint.h>
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************
* send a command to the background process
......@@ -36,4 +42,23 @@ int background_system(char *command);
void start_background_system(void);
void set_latency_target(void);
void configure_linux(void);
void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10
#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO)
void thread_top_init(char *thread_name,
int affinity,
uint64_t runtime,
uint64_t deadline,
uint64_t period);
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_H_OAI_ */
#define MTU 65536
#define UDP_TIMEOUT 100000L // in nano second
receiveSubFrame(int sock) {
//read all subframe data from the control unit
char * buf[MTU];
int ret=recv(sock, buf, sizeof(buf), 0);
if ( ret==-1) {
if ( errno == EWOULDBLOCK || errno== EINTR ) {
finishSubframeRecv();
} else {
LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno));
return;
}
} else {
}
#include <split_headers.h>
}
void pdsch_procedures(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
......@@ -206,21 +190,6 @@ DL_thread_fs6() {
ru->fh_south_out(ru);
}
int createListner (port) {
int sock;
AssertFatal((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0, "");
struct sockaddr_in addr = {
sin_family:
AF_INET,
sin_port:
htons(port),
sin_addr:
{ s_addr: INADDR_ANY }
};
AssertFatal(bind(sock, const struct sockaddr *addr, socklen_t addrlen)==0,"");
struct timeval tv={0,UDP_TIMEOUT};
AssertFatal(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,"");
}
DL_thread_frequency() {
......
#ifndef __SPLIT_HEADERS_H
#define __SPLIT_HEADERS_H
struct frequency_s {
#define MTU 65536
#define UDP_TIMEOUT 100000L // in nano second
#define MAX_BLOCKS 16
#define blockAlign 32 //bytes
typedef struct commonUDP_s {
uint64_t timestamp; // id of the group (subframe for LTE)
uint16_t nbBlocks; // total number of blocks for this timestamp
uint16_t blockID; // id: 0..nbBocks-1
uint16_t contentType; // defines the content format
uint16_t contentBytes; // will be sent in a UDP packet, so must be < 2^16 bytes
} commonUDP_t;
typedef struct frequency_s {
int frame;
int subframe;
int timestamp;
int sampleSize;
int nbAnt
int nbSamples;
} frequency_t;
int createListner (port);
int receiveSubFrame(int sock, uint64_t expectedTS, void* bufferZone, int bufferSize);
int sendSubFrame(int sock, void* bufferZone, int nbBlocks);}
#endif
#include <split_headers.h>
int createListner (port) {
int sock;
AssertFatal((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0, "");
struct sockaddr_in addr = {
sin_family:
AF_INET,
sin_port:
htons(port),
sin_addr:
{ s_addr: INADDR_ANY }
};
int enable=1;
AssertFatal(setsockopt(eth->sockfdc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,"");
AssertFatal(bind(sock, const struct sockaddr *addr, socklen_t addrlen)==0,"");
struct timeval tv={0,UDP_TIMEOUT};
AssertFatal(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,"");
// Make a send/recv buffer larger than a a couple of subframe
// so the kernel will store for us in and out paquets
int buff=1000*1000*10;
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, "");
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, "");
}
// sock: udp socket
// expectedTS: the expected timestamp, 0 if unknown
// bufferZone: a reception area of bufferSize
int receiveSubFrame(int sock, uint64_t expectedTS, void* bufferZone, int bufferSize) {
int rcved=0;
do {
//read all subframe data from the control unit
int ret=recv(sock, bufferZone, bufferSize, 0);
if ( ret==-1) {
if ( errno == EWOULDBLOCK || errno== EINTR ) {
return rcved; // Timeout, subframe incomplete
} else {
LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno));
return -1;
}
} else {
commonUDP_t * tmp=(commonUDP_t *)bufferZone;
if ( expectedTS && tmp->timestamp != expectedTS) {
LOG_W(HW,"Received a paquet in mixed subframes, dropping it\n");
} else {
rcved++;
bufferZone+=ret;
}
}
} while ( !recved || recved < tmp->nbBlocks);
return recv;
}
int sendSubFrame(int sock, void* bufferZone, int nbBlocks) {
do {
int sz=alignedSize(bufferZone);
int ret=send(sock, bufferZone, sz, 0);
if ( ret != sz )
LOG_W(HW,"Wrote socket doesn't return size %d (val: %d, errno:%d)\n",
sz, ret, errno);
bufferZone+=sz;
nbBlocks--;
} while (nbBlocks);
return 0;
}
......@@ -1204,6 +1204,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
return(chan_desc);
}
void free_channel_desc_scm(channel_desc_t * ch) {
// Must be made cleanly, a lot of leaks...
free(ch);
}
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
......
......@@ -108,10 +108,6 @@ pthread_mutex_t sync_mutex;
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
int config_sync_var=-1;
uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
volatile int oai_exit = 0;
uint32_t downlink_frequency[MAX_NUM_CCs][4];
......@@ -150,20 +146,12 @@ char ref[128] = "internal";
char channels[128] = "0";
int rx_input_level_dBm;
int otg_enabled;
uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
extern void init_eNB_afterRU(void);
extern void phy_free_RU(RU_t *);
int transmission_mode=1;
int emulate_rf = 0;
......@@ -172,73 +160,11 @@ int numerology = 0;
THREAD_STRUCT thread_struct;
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params;
double cpuf;
/* forward declarations */
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
/*---------------------BMC: timespec helpers -----------------------------*/
struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec clock_difftime(struct timespec start, struct timespec end) {
struct timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
void print_difftimes(void) {
#ifdef DEBUG
printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#else
LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#endif
}
void update_difftimes(struct timespec start, struct timespec end) {
struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
int changed = 0;
diff_time = clock_difftime(start, end);
if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) {
min_diff_time.tv_nsec = diff_time.tv_nsec;
changed = 1;
}
if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) {
max_diff_time.tv_nsec = diff_time.tv_nsec;
changed = 1;
}
#if 1
if (changed) print_difftimes();
#endif
}
/*------------------------------------------------------------------------*/
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) {
return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
}
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) {
return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
}
void signal_handler(int sig) {
void *array[10];
size_t size;
......@@ -256,7 +182,6 @@ void signal_handler(int sig) {
}
}
void exit_function(const char *file, const char *function, const int line, const char *s) {
int ru_id;
......@@ -285,8 +210,6 @@ void exit_function(const char *file, const char *function, const int line, const
exit(1);
}
static void get_options(void) {
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
get_common_options();
......@@ -297,11 +220,11 @@ static void get_options(void) {
/* Read RC configuration file */
RCConfig();
NB_eNB_INST = RC.nb_inst;
printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,RC.nb_RU);
LOG_I(ENB_APP,"Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,RC.nb_RU);
if (!IS_SOFTMODEM_NONBIOT) {
load_NB_IoT();
printf(" nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n",
LOG_I(ENB_APP," nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n",
RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst);
} else {
printf("All Nb-IoT instances disabled\n");
......@@ -310,10 +233,6 @@ static void get_options(void) {
}
}
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
int CC_id;
......@@ -528,60 +447,44 @@ int main( int argc, char **argv ) {
int CC_id = 0;
int ru_id;
if ( load_configmodule(argc,argv,0) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
AssertFatal(load_configmodule(argc,argv,0) != NULL,
"[SOFTMODEM] Error, configuration module init failed\n");
mode = normal_txrx;
set_latency_target();
logInit();
printf("Reading in command-line options\n");
get_options ();
AssertFatal(!CONFIG_ISFLAGSET(CONFIG_ABORT),"Getting configuration failed\n");
configure_linux();
// to make a graceful exit when ctrl-c is pressed
signal(SIGSEGV, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGABRT, signal_handler);
cpuf=get_cpu_freq_GHz();
#ifndef PACKAGE_VERSION
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif
LOG_I(HW, "OAI Version: %s\n", PACKAGE_VERSION);
if (is_nos1exec(argv[0]) )
set_softmodem_optmask(SOFTMODEM_NOS1_BIT);
EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) {
fprintf(stderr,"Getting configuration failed\n");
exit(-1);
}
#if T_TRACER
T_Config_Init();
#endif
//randominit (0);
set_taus_seed (0);
printf("configuring for RAU/RRU\n");
if (opp_enabled ==1) {
if (opp_enabled ==1)
reset_opp_meas();
}
cpuf=get_cpu_freq_GHz();
printf("ITTI init, useMME: %i\n",EPC_MODE_ENABLED);
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
// initialize mscgen log after ITTI
if (get_softmodem_params()->start_msc) {
load_module_shlib("msc",NULL,0,&msc_interface);
}
MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
// allows to forward in wireshark L2 protocol for decoding
init_opt();
// to make a graceful exit when ctrl-c is pressed
signal(SIGSEGV, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGABRT, signal_handler);
check_clock();
#ifndef PACKAGE_VERSION
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
printf("Runtime table\n");
fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
/* Read configuration */
if (RC.nb_inst > 0) {
......@@ -589,9 +492,8 @@ int main( int argc, char **argv ) {
/* Start the agent. If it is turned off in the configuration, it won't start */
RCconfig_flexran();
for (i = 0; i < RC.nb_inst; i++) {
for (i = 0; i < RC.nb_inst; i++)
flexran_agent_start(i);
}
/* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks
* for monolithic/F1 modes */
......@@ -685,14 +587,10 @@ int main( int argc, char **argv ) {
}
printf("wait RUs\n");
// CI -- Flushing the std outputs for the previous marker to show on the eNB / RRU log file
fflush(stdout);
fflush(stderr);
// end of CI modifications
wait_RUs();
LOG_I(ENB_APP,"RC.nb_RU:%d\n", RC.nb_RU);
// once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration)
printf("ALL RUs ready - init eNBs\n");
if (NFAPI_MODE!=NFAPI_MODE_PNF && NFAPI_MODE!=NFAPI_MODE_VNF) {
LOG_I(ENB_APP,"Not NFAPI mode - call init_eNB_afterRU()\n");
......@@ -738,7 +636,6 @@ int main( int argc, char **argv ) {
* threads have been stopped (they partially use the same memory) */
for (int inst = 0; inst < NB_eNB_INST; inst++) {
for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) {
free_transport(RC.eNB[inst][cc_id]);
phy_free_lte_eNB(RC.eNB[inst][cc_id]);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment