Merge remote-tracking branch 'origin/develop' into if5_ECPRI_rework

This commit is contained in:
Raymond Knopp
2022-05-01 14:51:27 +02:00
531 changed files with 15637 additions and 21668 deletions
+19 -7
View File
@@ -43,16 +43,31 @@
//#include "targets/RT/USER/lte-softmodem.h"
#include "executables/softmodem-common.h"
char *get_devname(int devtype) {
char *devnames[MAX_RF_DEV_TYPE]=DEVTYPE_NAMES;
const char* devtype_names[MAX_RF_DEV_TYPE] = {
"",
"EXMIMO",
"USRP B200",
"USRP X300",
"USRP N300",
"USRP X400",
"BLADERF",
"LMSSDR",
"IRIS",
"No HW",
"ADRV9371_ZC706",
"UEDv2",
"RFSIMULATOR"
};
const char *get_devname(int devtype) {
if (devtype < MAX_RF_DEV_TYPE && devtype !=MIN_RF_DEV_TYPE )
return devnames[devtype];
return devtype_names[devtype];
return "none";
}
int set_device(openair0_device *device)
{
char *devname = get_devname(device->type);
const char *devname = get_devname(device->type);
if (strcmp(devname,"none") != 0) {
LOG_I(HW,"[%s] has loaded %s device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),devname);
} else {
@@ -101,9 +116,6 @@ int load_lib(openair0_device *device,
deflibname=OAI_IQPLAYER_LIBNAME;
shlib_fdesc[0].fname="device_init";
set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT); // softmodem has to know we use the iqplayer to workaround randomized algorithms
} else if ( IS_SOFTMODEM_BASICSIM ) {
deflibname=OAI_BASICSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else if (IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) {
deflibname=OAI_RFSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
+6 -4
View File
@@ -46,8 +46,6 @@
#define OAI_THIRDPARTY_TP_LIBNAME "thirdparty_transpro"
/* name of shared library implementing the rf simulator */
#define OAI_RFSIM_LIBNAME "rfsimulator"
/* name of shared library implementing the basic simulator */
#define OAI_BASICSIM_LIBNAME "tcp_bridge_oai"
/* name of shared library implementing the iq player */
#define OAI_IQPLAYER_LIBNAME "oai_iqplayer"
@@ -92,6 +90,8 @@ typedef enum {
USRP_X300_DEV,
/*!\brief device is USRP N300/N310*/
USRP_N300_DEV,
/*!\brief device is USRP X400/X410*/
USRP_X400_DEV,
/*!\brief device is BLADE RF*/
BLADERF_DEV,
/*!\brief device is LMSSDR (SoDeRa)*/
@@ -107,7 +107,9 @@ typedef enum {
RFSIMULATOR,
MAX_RF_DEV_TYPE
} dev_type_t;
#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2", "RFSIMULATOR"}
/* list of names of devices, needs to match dev_type_t */
extern const char* devtype_names[MAX_RF_DEV_TYPE];
/*!\brief transport protocol types
*/
typedef enum {
@@ -575,7 +577,7 @@ extern "C"
/*! \brief get device name from device type */
char *get_devname(int devtype);
const char *get_devname(int devtype);
/*! \brief Initialize openair RF target. It returns 0 if OK */
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);
/*! \brief Initialize transport protocol . It returns 0 if OK */
+41 -15
View File
@@ -273,18 +273,20 @@ static int sync_to_gps(openair0_device *device) {
static int trx_usrp_start(openair0_device *device) {
usrp_state_t *s = (usrp_state_t *)device->priv;
// setup GPIO for TDD, GPIO(4) = ATR_RX
//set data direction register (DDR) to output
s->usrp->set_gpio_attr("FP0", "DDR", 0xfff, 0xfff);
//set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually)
s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0xfff);
//set pins 4 (RX_TX_Switch) and 6 (Shutdown PA) to 1 when the radio is only receiving (ATR_RX)
s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f);
// set pin 5 (Shutdown LNA) to 1 when the radio is transmitting and receiveing (ATR_XX)
// (we use full duplex here, because our RX is on all the time - this might need to change later)
s->usrp->set_gpio_attr("FP0", "ATR_XX", (1<<5), 0x7f);
// set the output pins to 1
s->usrp->set_gpio_attr("FP0", "OUT", 7<<7, 0xf80);
if (device->type != USRP_X400_DEV) {
// setup GPIO for TDD, GPIO(4) = ATR_RX
//set data direction register (DDR) to output
s->usrp->set_gpio_attr("FP0", "DDR", 0xfff, 0xfff);
//set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually)
s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0xfff);
//set pins 4 (RX_TX_Switch) and 6 (Shutdown PA) to 1 when the radio is only receiving (ATR_RX)
s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f);
// set pin 5 (Shutdown LNA) to 1 when the radio is transmitting and receiveing (ATR_XX)
// (we use full duplex here, because our RX is on all the time - this might need to change later)
s->usrp->set_gpio_attr("FP0", "ATR_XX", (1<<5), 0x7f);
// set the output pins to 1
s->usrp->set_gpio_attr("FP0", "OUT", 7<<7, 0xf80);
}
s->wait_for_first_pps = 1;
s->rx_count = 0;
@@ -847,7 +849,7 @@ rx_gain_calib_table_t calib_table_x310[] = {
{-1,0}
};
/*! \brief USRPB210 RX calibration table */
/*! \brief USRPn3xf RX calibration table */
rx_gain_calib_table_t calib_table_n310[] = {
{3500000000.0,0.0},
{2660000000.0,0.0},
@@ -857,6 +859,16 @@ rx_gain_calib_table_t calib_table_n310[] = {
{-1,0}
};
/*! \brief Empty RX calibration table */
rx_gain_calib_table_t calib_table_none[] = {
{3500000000.0,0.0},
{2660000000.0,0.0},
{2300000000.0,0.0},
{1880000000.0,0.0},
{816000000.0, 0.0},
{-1,0}
};
/*! \brief Set RX gain offset
* \param openair0_cfg RF frontend parameters set by application
@@ -1011,7 +1023,9 @@ extern "C" {
device->type=USRP_N300_DEV;
usrp_master_clock = 122.88e6;
args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
//args += ", send_buff_size=33554432";
if ( 0 != system("sysctl -w net.core.rmem_max=62500000 net.core.wmem_max=62500000") )
LOG_W(HW,"Can't set kernel parameters for N3x0\n");
}
if (device_adds[0].get("type") == "x300") {
@@ -1025,6 +1039,13 @@ extern "C" {
LOG_W(HW,"Can't set kernel parameters for X3xx\n");
}
if (device_adds[0].get("type") == "x4xx") {
printf("Found USRP x400\n");
device->type = USRP_X400_DEV;
usrp_master_clock = 245.76e6;
args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
}
s->usrp = uhd::usrp::multi_usrp::make(args);
if (args.find("clock_source")==std::string::npos) {
@@ -1102,8 +1123,13 @@ extern "C" {
std::cerr << "-- Using calibration table: calib_table_n310" << std::endl;
}
if (device->type == USRP_X400_DEV) {
openair0_cfg[0].rx_gain_calib_table = calib_table_none;
std::cerr << "-- Using calibration table: calib_table_none" << std::endl;
}
if (device->type==USRP_N300_DEV || device->type==USRP_X300_DEV) {
if (device->type==USRP_N300_DEV || device->type==USRP_X300_DEV || device->type==USRP_X400_DEV) {
LOG_I(HW,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate);
switch ((int)openair0_cfg[0].sample_rate) {
+4 -3
View File
@@ -52,7 +52,8 @@
either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
legacy: we regenerate each sub frame in UL, and each frame only in DL
*/
void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
void rxAddInput( const c16_t *input_sig,
c16_t *after_channel_sig,
int rxAnt,
channel_desc_t *channelDesc,
int nbSamples,
@@ -73,7 +74,7 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
const int nbTx=channelDesc->nb_tx;
for (int i=0; i<((int)nbSamples-dd); i++) {
struct complex16 *out_ptr=after_channel_sig+dd+i;
c16_t *out_ptr=after_channel_sig+dd+i;
struct complexd rx_tmp= {0};
for (int txAnt=0; txAnt < nbTx; txAnt++) {
@@ -87,7 +88,7 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
// but it is not very usefull
// it would be better to split out each antenna in a separate flow
// that will allow to mix ru antennas freely
struct complex16 tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
c16_t tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
rx_tmp.r += tx16.r * channelModel[l].r - tx16.i * channelModel[l].i;
rx_tmp.i += tx16.i * channelModel[l].r + tx16.r * channelModel[l].i;
} //l
+2 -2
View File
@@ -25,8 +25,8 @@
#define __RFSIMULATOR_H
double gaussZiggurat(double mean, double variance);
void tableNor(unsigned long seed);
void rxAddInput( struct complex16 *input_sig,
struct complex16 *after_channel_sig,
void rxAddInput( const c16_t *input_sig,
c16_t *after_channel_sig,
int rxAnt,
channel_desc_t *channelDesc,
int nbSamples,
+26 -60
View File
@@ -100,7 +100,7 @@ static telnetshell_vardef_t rfsimu_vardef[] = {
};
pthread_mutex_t Sockmutex;
typedef struct complex16 sample_t; // 2*16 bits complex number
typedef c16_t sample_t; // 2*16 bits complex number
typedef struct buffer_s {
int conn_sock;
@@ -117,7 +117,7 @@ typedef struct buffer_s {
typedef struct {
int listen_sock, epollfd;
openair0_timestamp nextTimestamp;
openair0_timestamp nextRxTstamp;
openair0_timestamp lastWroteTS;
uint64_t typeStamp;
char *ip;
@@ -196,7 +196,7 @@ static void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
free(bridge->buf[sock].circularBuf);
// Fixme: no free_channel_desc_scm(bridge->buf[sock].channel_model) implemented
// a lot of mem leaks
free(bridge->buf[sock].channel_model);
//free(bridge->buf[sock].channel_model);
memset(&bridge->buf[sock], 0, sizeof(buffer_t));
bridge->buf[sock].conn_sock=-1;
}
@@ -429,8 +429,6 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
if (!alreadyLocked)
pthread_mutex_lock(&Sockmutex);
LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
for (int i=0; i<FD_SETSIZE; i++) {
buffer_t *b=&t->buf[i];
@@ -495,7 +493,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
setblocking(conn_sock, notBlocking);
allocCirBuf(t, conn_sock);
LOG_I(HW,"A client connected, sending the current time\n");
struct complex16 v= {0};
c16_t v= {0};
void *samplesVoid[t->tx_num_channels];
for ( int i=0; i < t->tx_num_channels; i++)
@@ -549,14 +547,14 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
(t->typeStamp == ENB_MAGICDL && b->th.magic==UE_MAGICDL), "Socket Error in protocol");
b->headerMode=false;
if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS
t->nextTimestamp=b->th.timestamp> nsamps_for_initial ?
if ( t->nextRxTstamp == 0 ) { // First block in UE, resync with the eNB current TS
t->nextRxTstamp=b->th.timestamp> nsamps_for_initial ?
b->th.timestamp - nsamps_for_initial :
0;
b->lastReceivedTS=b->th.timestamp> nsamps_for_initial ?
b->th.timestamp :
nsamps_for_initial;
LOG_W(HW,"UE got first timestamp: starting at %lu\n", t->nextTimestamp);
LOG_W(HW,"UE got first timestamp: starting at %lu\n", t->nextRxTstamp);
b->trashingPacket=true;
} else if ( b->lastReceivedTS < b->th.timestamp) {
int nbAnt= b->th.nbAnt;
@@ -623,7 +621,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
}
rfsimulator_state_t *t = device->priv;
LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextRxTstamp+nsamps);
// deliver data from received data
// check if a UE is connected
int first_sock;
@@ -634,54 +632,22 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
if ( first_sock == FD_SETSIZE ) {
// no connected device (we are eNB, no UE is connected)
if ( t->nextTimestamp == 0)
if ( t->nextRxTstamp == 0)
LOG_W(HW,"No connected device, generating void samples...\n");
if (!flushInput(t, 10, nsamps)) {
for (int x=0; x < nbAnt; x++)
memset(samplesVoid[x],0,sampleToByte(nsamps,1));
t->nextTimestamp+=nsamps;
t->nextRxTstamp+=nsamps;
if ( ((t->nextTimestamp/nsamps)%100) == 0)
LOG_D(HW,"No UE, Generated void samples for Rx: %ld\n", t->nextTimestamp);
if ( ((t->nextRxTstamp/nsamps)%100) == 0)
LOG_D(HW,"No UE, Generated void samples for Rx: %ld\n", t->nextRxTstamp);
*ptimestamp = t->nextTimestamp-nsamps;
*ptimestamp = t->nextRxTstamp-nsamps;
return nsamps;
}
} else {
pthread_mutex_lock(&Sockmutex);
if ( t->nextTimestamp > 0 && t->lastWroteTS < t->nextTimestamp) {
pthread_mutex_unlock(&Sockmutex);
usleep(10000);
pthread_mutex_lock(&Sockmutex);
if ( t->lastWroteTS < t->nextTimestamp ) {
// Assuming Tx is not done fully in another thread
// We can never write is the past from the received time
// So, the node perform receive but will never write these symbols
// let's tell this to the opposite node
// We send timestamp for nb samples required
// assuming this should have been done earlier if a Tx would exist
pthread_mutex_unlock(&Sockmutex);
struct complex16 v= {0};
void *dummyS[t->tx_num_channels];
for ( int i=0; i < t->tx_num_channels; i++)
dummyS[i]=(void *)&v;
LOG_I(HW, "No samples Tx occured, so we send 1 sample to notify it: Tx:%lu, Rx:%lu\n",
t->lastWroteTS, t->nextTimestamp);
rfsimulator_write_internal(t, t->nextTimestamp,
dummyS, 1,
t->tx_num_channels, 1, true);
} else {
pthread_mutex_unlock(&Sockmutex);
LOG_W(HW, "trx_write came from another thread\n");
}
} else
pthread_mutex_unlock(&Sockmutex);
bool have_to_wait;
@@ -692,7 +658,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
buffer_t *b=&t->buf[sock];
if ( b->circularBuf )
if ( t->nextTimestamp+nsamps > b->lastReceivedTS ) {
if ( t->nextRxTstamp+nsamps > b->lastReceivedTS ) {
have_to_wait=true;
break;
}
@@ -701,7 +667,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
if (have_to_wait)
/*printf("Waiting on socket, current last ts: %ld, expected at least : %ld\n",
ptr->lastReceivedTS,
t->nextTimestamp+nsamps);
t->nextRxTstamp+nsamps);
*/
flushInput(t, 3, nsamps);
} while (have_to_wait);
@@ -728,18 +694,18 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
for (int a=0; a<nbAnt; a++) {//loop over number of Rx antennas
if ( ptr->channel_model != NULL ) // apply a channel model
rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a],
rxAddInput( ptr->circularBuf, (c16_t *) samplesVoid[a],
a,
ptr->channel_model,
nsamps,
t->nextTimestamp,
t->nextRxTstamp,
CirSize
);
else { // no channel modeling
double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0
{0.5, 1.0, 0.5, 0.25}, //rx 1
{0.25, 0.5, 1.0, 0.5}, //rx 2
{0.125, 0.25, 0.5, 1.0}};//rx 3
double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0
{0.2, 1.0, 0.2, 0.1}, //rx 1
{0.1, 0.2, 1.0, 0.2}, //rx 2
{0.05, 0.1, 0.2, 1.0}};//rx 3
sample_t *out=(sample_t *)samplesVoid[a];
int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas
@@ -747,8 +713,8 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
//LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx);
for (int i=0; i < nsamps; i++) {//loop over nsamps
for (int a_tx=0; a_tx<nbAnt_tx; a_tx++) { //sum up signals from nbAnt_tx antennas
out[i].r += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r*H_awgn_mimo[a][a_tx]);
out[i].i += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i*H_awgn_mimo[a][a_tx]);
out[i].r += (short)(ptr->circularBuf[((t->nextRxTstamp+i)*nbAnt_tx+a_tx)%CirSize].r*H_awgn_mimo[a][a_tx]);
out[i].i += (short)(ptr->circularBuf[((t->nextRxTstamp+i)*nbAnt_tx+a_tx)%CirSize].i*H_awgn_mimo[a][a_tx]);
} // end for a_tx
} // end for i (number of samps)
} // end of no channel modeling
@@ -756,11 +722,11 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
}
}
*ptimestamp = t->nextTimestamp; // return the time of the first sample
t->nextTimestamp+=nsamps;
*ptimestamp = t->nextRxTstamp; // return the time of the first sample
t->nextRxTstamp+=nsamps;
LOG_D(HW,"Rx to upper layer: %d from %ld to %ld, energy in first antenna %d\n",
nsamps,
*ptimestamp, t->nextTimestamp,
*ptimestamp, t->nextRxTstamp,
signal_energy(samplesVoid[0], nsamps));
return nsamps;
}
-4
View File
@@ -1,4 +0,0 @@
This is sort of a "TCP driver" to ease debugging. This is mostly internal
to EURECOM. You probably don't want to use it.
Same license as the rest.
@@ -1,42 +0,0 @@
The driver tcp_bridge_oai.c is to be used with the basic simulator.
To build the basic simulator:
cd [openair top directory]
. oaienv
cd cmake_targets
./build_oai -I -w USRP
./build_oai --basic-simulator
cd ../common/utils/T/tracer
make
To use it, you need to run the eNB and the UE.
The eNB requires the T tracer.
Open two terminals.
In one terminal, run:
cd [openair top directory]
cd common/utils/T/tracer
./enb -d ../T_messages.txt
In the other terminal, run:
cd [openair top directory]
cd cmake_targets/basic_simulator/enb
export ENODEB=1
sudo -E ./lte-softmodem -O [configuration file] --T_stdout 0
[configuration file] is just a regular configuration file.
The eNB needs an EPC.
To run the UE, open a terminal and run:
cd [openair top directory]
cd cmake_targets/basic_simulator/ue
sudo ./lte-uesoftmodem -C 2680000000 -r 25 --ue-rxgain 140
Adapt the value of -r, it has to match the value N_RB_DL in the configuration
file of the eNB. (Same for -C which should match the value downlink_frequency
in the configuration file.)
The UE configuration (security keys) is generated from the file
openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf. You need to configure
your EPC to know about the UE. If you change the file
openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf then you need to
regenerate the configuration files using the program targets/bin/conf2uedata.
You run it as:
$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o $OPENAIR_DIR/cmake_targets/basic_simulator/ue
-292
View File
@@ -1,292 +0,0 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int fullread(int fd, void *_buf, int count)
{
char *buf = _buf;
int ret = 0;
int l;
while (count) {
l = read(fd, buf, count);
if (l <= 0) return -1;
count -= l;
buf += l;
ret += l;
}
return ret;
}
int fullwrite(int fd, void *_buf, int count)
{
char *buf = _buf;
int ret = 0;
int l;
while (count) {
l = write(fd, buf, count);
if (l <= 0) return -1;
count -= l;
buf += l;
ret += l;
}
return ret;
}
#include "common_lib.h"
typedef struct {
int32_t data[30720]; /* max 20MHz */
unsigned long timestamp;
int size;
} input_buffer;
#define BSIZE 16
typedef struct {
int sock;
int samples_per_subframe;
input_buffer b[BSIZE];
int bstart;
int blen;
unsigned long read_timestamp;
} tcp_bridge_state_t;
/****************************************************************************/
/* buffer management */
/* (could be simpler, we are synchronous) */
/* maybe we should lock */
/****************************************************************************/
void put_buffer(tcp_bridge_state_t *t, void *data, int size, unsigned long timestamp)
{
int nextpos;
if (t->blen == BSIZE) { printf("tcp_bridge: buffer full\n"); exit(1); }
if (size > 30720*4) abort();
if (t->blen) {
int lastpos = (t->bstart+t->blen-1) % BSIZE;
if (timestamp != t->b[lastpos].timestamp + t->samples_per_subframe)
{ printf("tcp_bridge: discontinuity\n"); exit(1); }
}
nextpos = (t->bstart+t->blen) % BSIZE;
t->b[nextpos].timestamp = timestamp;
t->b[nextpos].size = size;
memcpy(t->b[nextpos].data, data, size);
t->blen++;
}
void get_buffer(tcp_bridge_state_t *t, void *data, int size, unsigned long timestamp)
{
int pos;
if (t->blen == 0) { printf("tcp_bridge: buffer empty\n"); exit(1); }
if (size >30720*4) abort();
pos = t->bstart;
if (size != t->b[pos].size) { printf("tcp_bridge: bad size\n"); exit(1); }
memcpy(data, t->b[pos].data, size);
t->bstart = (t->bstart + 1) % BSIZE;
t->blen--;
}
/****************************************************************************/
/* end of buffer management */
/****************************************************************************/
/****************************************************************************/
/* network management (read/write) */
/****************************************************************************/
void read_data_from_network(int sock, input_buffer *b)
{
if (fullread(sock, &b->timestamp, sizeof(b->timestamp)) != sizeof(b->timestamp)) goto err;
if (fullread(sock, &b->size, sizeof(b->size)) != sizeof(b->size)) goto err;
if (fullread(sock, b->data, b->size) != b->size) goto err;
return;
err:
printf("tcp_bridge: read_data_from_network fails\n");
exit(1);
}
void write_data_to_network(int sock, input_buffer *b)
{
if (fullwrite(sock, &b->timestamp, sizeof(b->timestamp)) != sizeof(b->timestamp)) goto err;
if (fullwrite(sock, &b->size, sizeof(b->size)) != sizeof(b->size)) goto err;
if (fullwrite(sock, b->data, b->size) != b->size) goto err;
return;
err:
printf("tcp_bridge: write_data_to_network fails\n");
exit(1);
}
/****************************************************************************/
/* end of network management */
/****************************************************************************/
int tcp_bridge_start(openair0_device *device)
{
int i;
int port = 4042;
tcp_bridge_state_t *tcp_bridge = device->priv;
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) { perror("tcp_bridge: socket"); exit(1); }
int enable = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)))
{ perror("tcp_bridge: SO_REUSEADDR"); exit(1); }
struct sockaddr_in addr = {
sin_family: AF_INET,
sin_port: htons(port),
sin_addr: { s_addr: INADDR_ANY }
};
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)))
{ perror("tcp_bridge: bind"); exit(1); }
if (listen(sock, 5))
{ perror("tcp_bridge: listen"); exit(1); }
printf("tcp_bridge: wait for connection on port %d\n", port);
socklen_t len = sizeof(addr);
int sock2 = accept(sock, (struct sockaddr *)&addr, &len);
if (sock2 == -1)
{ perror("tcp_bridge: accept"); exit(1); }
close(sock);
tcp_bridge->sock = sock2;
/* the other end has to send 10 subframes at startup */
for (i = 0; i < 10; i++)
read_data_from_network(sock2, &tcp_bridge->b[i]);
tcp_bridge->bstart = 0;
tcp_bridge->blen = 10;
printf("tcp_bridge: connection established\n");
return 0;
}
int tcp_bridge_request(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; }
int tcp_bridge_reply(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; }
int tcp_bridge_get_stats(openair0_device* device) { return 0; }
int tcp_bridge_reset_stats(openair0_device* device) { return 0; }
void tcp_bridge_end(openair0_device *device) {}
int tcp_bridge_stop(openair0_device *device) { return 0; }
int tcp_bridge_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { return 0; }
int tcp_bridge_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) { return 0; }
int tcp_bridge_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags)
{
tcp_bridge_state_t *t = device->priv;
input_buffer out;
int i;
//printf("write ts %ld nsamps %d\n", timestamp, nsamps);
if (nsamps > 30720) abort();
/* read buffer timestamped with 'timestamp' if not already here */
for (i = 0; i < t->blen; i++) {
input_buffer *b = &t->b[(t->bstart + i) % BSIZE];
if (b->timestamp == timestamp) break;
}
if (i == t->blen) {
int nextpos = (t->bstart + t->blen) % BSIZE;
if (t->blen == BSIZE) abort();
read_data_from_network(t->sock, &t->b[nextpos]);
t->blen++;
if (t->b[nextpos].timestamp != timestamp) abort();
}
memcpy(out.data, buff[0], nsamps * 4);
out.timestamp = timestamp;
out.size = nsamps * 4;
write_data_to_network(t->sock, &out);
return nsamps;
}
int tcp_bridge_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc)
{
tcp_bridge_state_t *t = device->priv;
input_buffer *b;
if (cc != 1) abort();
if (t->blen == 0) abort();
b = &t->b[t->bstart];
if (b->timestamp != t->read_timestamp) abort();
if (b->size != nsamps * 4) abort();
*timestamp = b->timestamp;
memcpy(buff[0], b->data, b->size);
t->read_timestamp += nsamps;
t->bstart = (t->bstart + 1) % BSIZE;
t->blen--;
static unsigned long ts = 0;
//printf("read ts %ld nsamps %d\n", ts, nsamps);
*timestamp = ts;
ts += nsamps;
return nsamps;
}
int tcp_bridge_write_init(openair0_device *device)
{
return 0;
}
__attribute__((__visibility__("default")))
int device_init(openair0_device* device, openair0_config_t *openair0_cfg)
{
tcp_bridge_state_t *tcp_bridge = (tcp_bridge_state_t*)malloc(sizeof(tcp_bridge_state_t));
memset(tcp_bridge, 0, sizeof(tcp_bridge_state_t));
/* only 25 or 50 PRBs handled for the moment */
if (openair0_cfg[0].sample_rate != 61440000 &&
openair0_cfg[0].sample_rate != 30720000 &&
openair0_cfg[0].sample_rate != 15360000 &&
openair0_cfg[0].sample_rate != 7680000) {
printf("tcp_bridge: ERROR: only sample rate 61.44, 30.72, 15.36, and 7.68 Msps supported\n");
exit(1);
}
device->trx_start_func = tcp_bridge_start;
device->trx_get_stats_func = tcp_bridge_get_stats;
device->trx_reset_stats_func = tcp_bridge_reset_stats;
device->trx_end_func = tcp_bridge_end;
device->trx_stop_func = tcp_bridge_stop;
device->trx_set_freq_func = tcp_bridge_set_freq;
device->trx_set_gains_func = tcp_bridge_set_gains;
device->trx_write_func = tcp_bridge_write;
device->trx_read_func = tcp_bridge_read;
device->trx_write_init = tcp_bridge_write_init;
device->priv = tcp_bridge;
switch ((int)openair0_cfg[0].sample_rate) {
case 61440000: tcp_bridge->samples_per_subframe = 61440; break;
case 30720000: tcp_bridge->samples_per_subframe = 30720; break;
case 15360000: tcp_bridge->samples_per_subframe = 15360; break;
case 7680000: tcp_bridge->samples_per_subframe = 7680; break;
}
/* let's pretend to be a b2x0 */
device->type = USRP_B200_DEV;
device->openair0_cfg=&openair0_cfg[0];
return 0;
}
-443
View File
@@ -1,443 +0,0 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
const int port = 4043;
#define helpTxt "\
\x1b[31m\
tcp_bridge: error: you have to run one UE and one eNB\n\
For this, export TCPBRIDGE=enb (eNB case) or \n\
TCPBRIDGE=<an ip address> (UE case)\n\
\x1b[m"
int fullread(int fd, void *_buf, int count) {
char *buf = _buf;
int ret = 0;
int l;
while (count) {
l = read(fd, buf, count);
if (l <= 0) return -1;
count -= l;
buf += l;
ret += l;
}
return ret;
}
int fullwrite(int fd, void *_buf, int count) {
char *buf = _buf;
int ret = 0;
int l;
while (count) {
l = write(fd, buf, count);
if (l <= 0) return -1;
count -= l;
buf += l;
ret += l;
}
return ret;
}
#include "common_lib.h"
typedef struct {
int sock;
int samples_per_subframe;
uint64_t timestamp;
uint64_t next_tx_timestamp;
int is_enb;
char *ip;
} tcp_bridge_state_t;
void verify_connection(int fd, int is_enb) {
char c = is_enb;
if (fullwrite(fd, &c, 1) != 1) exit(1);
if (fullread(fd, &c, 1) != 1) exit(1);
if (c == is_enb) {
printf(helpTxt);
exit(1);
}
}
int start_enb(tcp_bridge_state_t *tcp_bridge) {
struct sockaddr_in addr = {
sin_family:
AF_INET,
sin_port:
htons(port),
sin_addr:
{ s_addr: INADDR_ANY }
};
if (bind(tcp_bridge->sock, (struct sockaddr *)&addr, sizeof(addr))) {
perror("tcp_bridge: bind");
exit(1);
}
if (listen(tcp_bridge->sock, 5)) {
perror("tcp_bridge: listen");
exit(1);
}
printf("tcp_bridge: wait for connection on port %d\n", port);
socklen_t len = sizeof(addr);
int sockServ = accept(tcp_bridge->sock, (struct sockaddr *)&addr, &len);
if ( sockServ == -1) {
perror("tcp_bridge: accept");
exit(1);
}
verify_connection(sockServ, tcp_bridge->is_enb);
printf("tcp_bridge: connection established\n");
close(tcp_bridge->sock);
tcp_bridge->sock=sockServ;
return 0;
}
int start_ue(tcp_bridge_state_t *tcp_bridge) {
struct sockaddr_in addr = {sin_family:
AF_INET,
sin_port:
htons(port),
sin_addr:
{ s_addr: INADDR_ANY }
};
addr.sin_addr.s_addr = inet_addr(tcp_bridge->ip);
while(1) {
printf("tcp_bridge: trying to connect to %s:%d\n", tcp_bridge->ip, port);
if (connect(tcp_bridge->sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
verify_connection(tcp_bridge->sock, tcp_bridge->is_enb);
printf("tcp_bridge: connection established\n");
return 0;
}
perror("tcp_bridge");
sleep(1);
}
return 0;
}
int tcp_bridge_start(openair0_device *device) {
tcp_bridge_state_t *tcp_bridge = device->priv;
tcp_bridge->sock = socket(AF_INET, SOCK_STREAM, 0);
if (tcp_bridge->sock == -1) {
perror("tcp_bridge: socket");
exit(1);
}
int enable = 1;
if (setsockopt(tcp_bridge->sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) {
perror("tcp_bridge: SO_REUSEADDR");
exit(1);
}
if ( tcp_bridge->is_enb )
return start_enb(tcp_bridge);
else
return start_ue(tcp_bridge);
}
int tcp_bridge_request(openair0_device *device, void *msg, ssize_t msg_len) {
abort();
return 0;
}
int tcp_bridge_reply(openair0_device *device, void *msg, ssize_t msg_len) {
abort();
return 0;
}
int tcp_bridge_get_stats(openair0_device *device) {
return 0;
}
int tcp_bridge_reset_stats(openair0_device *device) {
return 0;
}
void tcp_bridge_end(openair0_device *device) {}
int tcp_bridge_stop(openair0_device *device) {
return 0;
}
int tcp_bridge_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
return 0;
}
int tcp_bridge_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
return 0;
}
int tcp_bridge_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
if (cc != 1) {
printf("tcp_bridge: only 1 antenna supported\n");
exit(1);
}
tcp_bridge_state_t *t = device->priv;
/* deal with discontinuities in output (think: eNB in TDD mode) */
if (t->next_tx_timestamp && timestamp != t->next_tx_timestamp) {
uint32_t b[4096];
uint64_t to_send = timestamp - t->next_tx_timestamp;
memset(b, 0, 4096 * sizeof(uint32_t));
while (to_send) {
int len = to_send > 4096 ? 4096 : to_send;
int n = fullwrite(t->sock, b, len * 4);
if (n != len * 4) {
printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno));
abort();
}
to_send -= len;
}
}
int n = fullwrite(t->sock, buff[0], nsamps * 4);
if (n != nsamps * 4) {
printf("tcp_bridge: write error ret %d (wanted %d) error %s\n", n, nsamps*4, strerror(errno));
abort();
}
t->next_tx_timestamp = timestamp + nsamps;
return nsamps;
}
int tcp_bridge_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
if (cc != 1) {
printf("tcp_bridge: only 1 antenna supported\n");
exit(1);
}
tcp_bridge_state_t *t = device->priv;
int n = fullread(t->sock, buff[0], nsamps * 4);
if (n != nsamps * 4) {
printf("tcp_bridge: read error ret %d nsamps*4 %d error %s\n", n, nsamps * 4, strerror(errno));
abort();
}
*timestamp = t->timestamp;
t->timestamp += nsamps;
return nsamps;
}
int tcp_bridge_read_ue(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
if (cc != 1) {
printf("tcp_bridge: only 1 antenna supported\n");
exit(1);
}
tcp_bridge_state_t *t = device->priv;
int n;
/* In synch mode, UE does not write, but we need to
send something to the eNodeB.
We know that UE is in synch mode when it reads
10 subframes at a time.
*/
if (nsamps == t->samples_per_subframe * 10) {
uint32_t b[nsamps];
memset(b, 0, nsamps * 4);
n = fullwrite(t->sock, b, nsamps * 4);
if (n != nsamps * 4) {
printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno));
abort();
}
}
return tcp_bridge_read(device, timestamp, buff, nsamps, cc);
}
/* To startup proper communcation between eNB and UE,
we need to understand that:
- eNodeB starts reading subframe 0
- then eNodeB starts sending subframe 4
and then repeats read/write for each subframe.
The UE:
- reads 10 subframes at a time until it is synchronized
- then reads subframe n and writes subframe n+2
We also want to enforce that the subframe 0 is read
at the beginning of the UE RX buffer, not in the middle
of it.
So it means:
- for the eNodeB: let it run as in normal mode (as with a B210)
- for the UE, on its very first read:
- we want this read to get data from subframe 0
but the first write of eNodeB is subframe 4
so we first need to read and ignore 6 subframes
- the UE will start its TX only at the subframe 2
corresponding to the subframe 0 it just read,
so we need to write 12 subframes before anything
(the function tcp_bridge_read_ue takes care to
insert dummy TX data during the synch phase)
Here is a drawing of the beginning of things to make
this logic clearer.
We see that eNB starts RX at subframe 0, starts TX at subfram 4,
and that UE starts RX at subframe 10 and TX at subframe 12.
We understand that the UE has to transmit 12 empty
subframes for the eNodeB to start its processing.
And because the eNodeB starts its TX at subframe 4 and we
want the UE to start its RX at subframe 10, we need to
read and ignore 6 subframes in the UE.
-------------------------------------------------------------------------
eNB RX: | *0* | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 ...
-------------------------------------------------------------------------
-------------------------------------------------------------------------
eNB TX: | 0 | 1 | 2 | 3 | *4* | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 ...
-------------------------------------------------------------------------
-------------------------------------------------------------------------
UE RX: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *10* | 11 | 12 | 13 | 14 ...
-------------------------------------------------------------------------
-------------------------------------------------------------------------
UE TX: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | *12* | 13 | 14 ...
-------------------------------------------------------------------------
As a final note, we do TX before RX to ensure that the eNB will
get some data and send us something so there is no deadlock
at the beginning of things. Hopefully the kernel buffers for
the sockets are big enough so that the first (big) TX can
return to user mode before the buffers are full. If this
is wrong in some environment, we will need to work by smaller
units of data at a time.
*/
int tcp_bridge_ue_first_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
if (cc != 1) {
printf("tcp_bridge: only 1 antenna supported\n");
exit(1);
}
tcp_bridge_state_t *t = device->priv;
uint32_t b[t->samples_per_subframe * 12];
memset(b, 0, t->samples_per_subframe * 12 * 4);
int n = fullwrite(t->sock, b, t->samples_per_subframe * 12 * 4);
if (n != t->samples_per_subframe * 12 * 4) {
printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno));
abort();
}
n = fullread(t->sock, b, t->samples_per_subframe * 6 * 4);
if (n != t->samples_per_subframe * 6 * 4) {
printf("tcp_bridge: read error ret %d error %s\n", n, strerror(errno));
abort();
}
/* Due to some unknown bug in the eNB (or UE, or both), the first frames
* are not correctly generated (or handled), which leads to a bad behavior
* of the simulator in some cases (seen with 100 RBs: the UE reads a bad
* MIB and switches to 25 RBs, which results in a deadlock in this driver).
* Let's skip 10 frames to avoid this issue.
*/
for (int i = 0; i < 10 * 10; i++) {
memset(b, 0, t->samples_per_subframe * 4);
n = fullwrite(t->sock, b, t->samples_per_subframe * 4);
if (n != t->samples_per_subframe * 4) {
printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno));
abort();
}
n = fullread(t->sock, b, t->samples_per_subframe * 4);
if (n != t->samples_per_subframe * 4) {
printf("tcp_bridge: read error ret %d error %s\n", n, strerror(errno));
abort();
}
}
device->trx_read_func = tcp_bridge_read_ue;
return tcp_bridge_read_ue(device, timestamp, buff, nsamps, cc);
}
__attribute__((__visibility__("default")))
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
tcp_bridge_state_t *tcp_bridge = (tcp_bridge_state_t *)calloc(sizeof(tcp_bridge_state_t),1);
if ((tcp_bridge->ip=getenv("TCPBRIDGE")) == NULL ) {
/* for compatibility, we test the ENB environment variable */
if ((tcp_bridge->ip=getenv("ENODEB")) != NULL ) {
tcp_bridge->ip=strdup("enb");
} else {
tcp_bridge->ip=strdup("127.0.0.1");
}
}
tcp_bridge->is_enb = strncasecmp(tcp_bridge->ip,"enb",3) == 0;
printf("tcp_bridge: running as %s\n", tcp_bridge->is_enb ? "eNB" : "UE");
if (openair0_cfg[0].sample_rate != 61440000 &&
openair0_cfg[0].sample_rate != 30720000 &&
openair0_cfg[0].sample_rate != 15360000 &&
openair0_cfg[0].sample_rate != 7680000) {
printf("tcp_bridge: ERROR: only sample rate 61.44, 30.72, 15.36, and 7.68 Msps supported\n");
exit(1);
}
device->trx_start_func = tcp_bridge_start;
device->trx_get_stats_func = tcp_bridge_get_stats;
device->trx_reset_stats_func = tcp_bridge_reset_stats;
device->trx_end_func = tcp_bridge_end;
device->trx_stop_func = tcp_bridge_stop;
device->trx_set_freq_func = tcp_bridge_set_freq;
device->trx_set_gains_func = tcp_bridge_set_gains;
device->trx_write_func = tcp_bridge_write;
if (tcp_bridge->is_enb) {
device->trx_read_func = tcp_bridge_read;
} else {
device->trx_read_func = tcp_bridge_ue_first_read;
}
device->priv = tcp_bridge;
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000:
tcp_bridge->samples_per_subframe = 30720;
break;
case 15360000:
tcp_bridge->samples_per_subframe = 15360;
break;
case 7680000:
tcp_bridge->samples_per_subframe = 7680;
break;
}
/* let's pretend to be a b2x0 */
device->type = USRP_B200_DEV;
device->openair0_cfg=&openair0_cfg[0];
return 0;
}
@@ -23,8 +23,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,9 +22,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,9 +22,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,9 +22,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -203,7 +201,7 @@ L1s = (
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_tx = 4
nb_rx = 1
att_tx = 0
att_rx = 0;
@@ -217,8 +215,10 @@ RUs = (
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
## beamforming 2x2 matrix:
#bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
## beamforming 4x4 matrix:
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
## beamforming 2x4 matrix:
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000];
#beamforming 4x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
clock_src = "external";
}
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,9 +22,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -22,9 +22,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -22,9 +22,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -22,8 +22,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
@@ -13,7 +13,6 @@ gNBs =
gNB_name = "gNB-Eurecom-CU";
// Tracking area code, 0x0000 and 0xfffe are reserved values
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({
@@ -27,14 +26,14 @@ gNBs =
},
{
sst = 1;
sd = 0x1; #112233; // 0 false, else true
sd = 0x112233; // 0 false, else true
}
);
});
nr_cellid = 12345678L
nr_cellid = 12345678L;
tr_s_preference = "f1";
@@ -43,9 +42,148 @@ gNBs =
remote_s_address = "127.0.0.3";
local_s_portc = 501;
local_s_portd = 2152;
remote_s_portc = 501;
remote_s_portc = 500;
remote_s_portd = 2152;
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
min_rxtxtime = 6;
sib1_tda = 0;
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 12;
searchSpaceZero = 0;
}
);
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641280;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640008;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
@@ -56,7 +194,7 @@ gNBs =
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.69.131";
amf_ip_address = ( { ipv4 = "192.168.69.131";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
@@ -66,15 +204,31 @@ gNBs =
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "bond0";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.18.207/24";
GNB_INTERFACE_NAME_FOR_NGU = "bond0";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.18.207/24";
GNB_INTERFACE_NAME_FOR_NG_AMF = "eth0";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.18.207";
GNB_INTERFACE_NAME_FOR_NGU = "eth0";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.18.207";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
@@ -12,7 +12,6 @@ gNBs =
gNB_name = "gNB-Eurecom-DU";
// Tracking area code, 0x0000 and 0xfffe are reserved values
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({
@@ -26,25 +25,21 @@ gNBs =
},
{
sst = 1;
sd = 0x1; #112233; // 0 false, else true
sd = 0x112233; // 0 false, else true
}
);
});
nr_cellid = 12345678L
# tr_s_preference = "local_mac"
nr_cellid = 12345678L;
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
min_rxtxtime = 6;
sib1_tda = 0;
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 12;
@@ -74,15 +69,14 @@ gNBs =
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 12952;
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
@@ -95,7 +89,7 @@ gNBs =
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 12952;
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
@@ -107,7 +101,7 @@ gNBs =
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -118;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
@@ -118,9 +112,9 @@ gNBs =
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
@@ -136,7 +130,6 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
@@ -177,7 +170,7 @@ gNBs =
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
ssPBCH_BlockPower = -25;
}
);
@@ -201,9 +194,9 @@ MACRLCs = (
local_n_if_name = "lo";
local_n_address = "127.0.0.3";
remote_n_address = "127.0.0.4";
local_n_portc = 601;
local_n_portc = 500;
local_n_portd = 2152;
remote_n_portc = 600;
remote_n_portc = 501;
remote_n_portd = 2152;
}
@@ -214,6 +207,9 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
thread_pool_size = 8;
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 150;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -224,21 +220,13 @@ RUs = (
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
max_rxgain = 114;
eNB_instances = [0];
##beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000];
##beamforming 1x4 matrix: 1 layer x 4 antennas
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
## beamforming 2x2 matrix:
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
## beamforming 4x4 matrix:
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
clock_src = "external";
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
clock_src = "internal";
}
);
@@ -250,6 +238,13 @@ THREAD_STRUCT = (
worker_config = "WORKER_ENABLE";
}
);
rfsimulator: {
serveraddr = "server";
serverport = "4043";
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"
}
log_config :
{
@@ -257,7 +252,7 @@ THREAD_STRUCT = (
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="debug";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
f1ap_log_level ="debug";
@@ -37,8 +37,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
sib1_tda = 0;
servingCellConfigCommon = (
{
@@ -33,8 +33,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
min_rxtxtime = 6;
sib1_tda = 0;
do_SRS = 1;
@@ -33,7 +33,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pdsch_AntennaPorts_N1 = 2;
pusch_AntennaPorts = 2;
sib1_tda = 0;
do_SRS = 1;
@@ -100,7 +100,7 @@ gNBs =
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -104;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
@@ -33,8 +33,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
min_rxtxtime = 6;
sib1_tda = 0;
@@ -31,8 +31,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
pdcch_ConfigSIB1 = (
{
@@ -33,10 +33,8 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pdsch_AntennaPorts_N1 = 2;
pusch_AntennaPorts = 2;
# do_CSIRS = 1;
min_rxtxtime_pdsch = 2;
ul_prbblacklist = "79,80,81,82"
pdcch_ConfigSIB1 = (
{
@@ -66,7 +64,7 @@ gNBs =
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
initialDLBWPlocationAndBandwidth = 31899;
initialDLBWPlocationAndBandwidth = 31624;
#
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
@@ -100,7 +98,7 @@ gNBs =
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 31899;
initialULBWPlocationAndBandwidth = 31624;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
@@ -112,7 +110,7 @@ gNBs =
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -104;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
+18 -7
View File
@@ -732,7 +732,7 @@ void tx_rf(RU_t *ru,
int sf_extension = 0;
if ((SF_type == SF_DL) ||
(SF_type == SF_S)) {
(SF_type == SF_S) ) {
int siglen=fp->samples_per_tti,flags=1;
if (SF_type == SF_S) {
@@ -830,6 +830,23 @@ void tx_rf(RU_t *ru,
late_control=STATE_BURST_TERMINATE;
LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs, siglen,late_control);
}
} else if (IS_SOFTMODEM_RFSIM ) {
// in case of rfsim, we always enable tx because we need to feed rx of the opposite side
// we write 1 single I/Q sample to trigger Rx (rfsim will fill gaps with 0 I/Q)
void *dummy_tx[ru->frame_parms->nb_antennas_tx];
int16_t dummy_tx_data[ru->frame_parms->nb_antennas_tx][2]; // 2 because the function we call use pairs of int16_t implicitly as complex numbers
memset(dummy_tx_data,0,sizeof(dummy_tx_data));
for (int i=0; i<ru->frame_parms->nb_antennas_tx; i++)
dummy_tx[i]= dummy_tx_data[i];
AssertFatal( 1 ==
ru->rfdevice.trx_write_func(&ru->rfdevice,
timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
dummy_tx,
1,
ru->frame_parms->nb_antennas_tx,
4),"");
}
}
@@ -1386,12 +1403,6 @@ int setup_RU_buffers(RU_t *ru) {
else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2;
else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4;
if(IS_SOFTMODEM_BASICSIM)
/* this is required for the basic simulator in TDD mode
* TODO: find a proper cleaner solution
*/
ru->N_TA_offset = 0;
if (frame_parms->N_RB_DL == 100) /* no scaling to do */;
else if (frame_parms->N_RB_DL == 50) {
ru->sf_extension /= 2;
-1
View File
@@ -49,7 +49,6 @@
{"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \
{"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
}
#define CMDLINE_CALIBUERX_IDX 0
+395 -448
View File
File diff suppressed because it is too large Load Diff
+1 -10
View File
@@ -276,7 +276,6 @@ uint16_t node_number;
static void get_options(void) {
int CC_id=0;
int tddflag=0;
char *loopfile=NULL;
int dumpframe=0;
int timingadv=0;
uint8_t nfapi_mode = NFAPI_MONOLITHIC;
@@ -293,14 +292,6 @@ static void get_options(void) {
config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
nfapi_setmode(nfapi_mode);
if (loopfile != NULL) {
printf("Input file for hardware emulation: %s",loopfile);
mode=loop_through_memory;
input_fd = fopen(loopfile,"r");
AssertFatal(input_fd != NULL,"Please provide a valid input file\n");
}
get_softmodem_params()->hw_timing_advance = timingadv;
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
@@ -519,7 +510,7 @@ int restart_L1L2(module_id_t enb_id) {
static void init_pdcp(int ue_id) {
uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT);
if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) {
if (IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) {
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
}