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

Signed-off-by: Raphael Defosseux <raphael.defosseux@eurecom.fr>
This commit is contained in:
Raphael Defosseux
2019-01-16 11:21:27 +01:00
191 changed files with 24354 additions and 20258 deletions
+138
View File
@@ -0,0 +1,138 @@
BladeRF documentation
=====================
As of 2018-11-06, the bladeRF support is not fully automatic and requires
some manual settings before use. This documentation is the ultimate source
of information. If something described in this file does not work or does
not correspond to the reality, then contact us so we can fix the problems
and update this documentation.
1. Install bladeRF 2.0 libraries.
As of now, it's better to install from source.
So, do not run: ./build_oai -I -w BLADERF
(That is: do not include '-w BLADERF'.)
Instead, follow the instructions at: https://github.com/Nuand/bladeRF
If you already had some bladeRF software installed using automatic
methods, first remove it by hand ('apt-get purge bladeRF' or something
similar, you can get the list of installed bladeRF packages by running
'dpkg -l|grep -i blade', remove them all).
2. Update the device.
Download the latest FX3 firmware and FPGA images from Nuand's website.
As of writing, this is:
https://github.com/Nuand/bladeRF/wiki
That points to the following pages.
For FX3:
http://www.nuand.com/fx3_images/
For FPGA:
http://www.nuand.com/fpga_images/
Install FX3 firmware:
sudo bladeRF-cli -f bladeRF_fw_latest.img
Install FPGA image (this is for BladeRF x40):
sudo bladeRF-cli -L hostedx40-latest.rbf
Retrieve calibration information:
sudo bladeRF-cli -i
info
That outputs the serial number of your device.
Go to:
https://www.nuand.com/calibration
And enter your serial number.
The website tells you to run something like:
sudo bladeRF-cli -i
flash_init_cal 40 0x9271
Actual values depend on your device and serial number.
3. Calibrate the bladeRF device.
We will work with band 7 on 2.68GHz with a bandwidth of 5 MHz (25 RBs).
Plug the bladeRF device, then run:
sudo bladeRF-cli -i
set frequency tx 2680000000
set frequency rx 2560000000
set gain rx 60
set gain tx 60
set bandwidth 5000000
set samplerate 7680000
cal lms
cal lms
cal lms
cal dc rxtx
cal dc rxtx
cal dc rxtx
4. Tune the RX gain using the enb tracer.
Run the softmodem and the 'enb' tracer. For instructions, see:
https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/T/basic
In the enb window, check the 'input signal'. You should see some blue
signal as seen at:
https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/T/enb
(the 'Time signal power' plot).
The level should be around 30.
If it's not around 30 then edit your configuration file and modify
the value 'max_rxgain' in the section 'RUs'.
The configuration file to use is:
configuration/bladeRF/enb-band7-5mhz.conf
In the configuration file, you also need to set the correct values for:
- tracking_area_code
- plmn_list: mcc, mnc, mnc_length
- mme_ip_address: this is the IP address used by the computer running
the softmodem to connect to the EPC
- NETWORK_INTERFACES: all the ENB*ADDRESS* variables have to point
to the IP address of the EPC machine
5. You're good to go.
You can now connect a UE and pass some traffic. If everything is well
configured you can expect more than 16 Mb/s of throughput in the downlink
using iperf and more than 8 Mb/s in the uplink. Looking at the logs, you
should find lines containing 'PHR 40' and 'CQI 15'. If your values are
lower then your setup may need some adjustments.
6. In case of problems.
If the performance of the softmodem is very bad, you can stop it and
run the calibration again, without setting the parameters (frequencies,
gains, etc.). Just run:
sudo bladeRF-cli -i
cal lms
cal dc rxtx
That may help.
Be sure to use proper radio equipment (duplexer, antennas, clean
environment without interferences).
@@ -116,15 +116,6 @@ int trx_brf_start(openair0_device *device) {
abort();
}
if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_TX)) != 0) {
fprintf(stderr,"Failed to calibrate TX DC: %s\n", bladerf_strerror(status));
abort();
}
if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_RX)) != 0) {
fprintf(stderr,"Failed to calibrate RX DC: %s\n", bladerf_strerror(status));
abort();
}
return 0;
}
@@ -235,8 +226,6 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
* \param device the hardware to use
*/
void trx_brf_end(openair0_device *device) {
abort();
int status;
brf_state_t *brf = (brf_state_t*)device->priv;
// Disable RX module, shutting down our underlying RX stream
@@ -247,6 +236,7 @@ abort();
fprintf(stderr, "Failed to disable TX module: %s\n", bladerf_strerror(status));
}
bladerf_close(brf->dev);
exit(1);
}
/*! \brief print the BladeRF statistics
@@ -362,6 +352,8 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) {
*/
void calibrate_rf(openair0_device *device) {
/* TODO: this function does not seem to work. Disabled until fixed. */
return;
brf_state_t *brf = (brf_state_t *)device->priv;
openair0_timestamp ptimestamp;
@@ -1005,6 +997,12 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
// RX
// Example of CLI output: RX Frequency: 2539999999Hz
if ((status=bladerf_set_gain_mode(brf->dev, BLADERF_MODULE_RX, BLADERF_GAIN_MGC))) {
fprintf(stderr, "[BRF] Failed to disable AGC\n");
brf_error(status);
}
if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0){
fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status));
brf_error(status);
@@ -1096,17 +1094,14 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
// calibrate
if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_TX)) != 0) {
fprintf(stderr,"Failed to calibrate TX DC: %s\n", bladerf_strerror(status));
if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_LPF_TUNING)) != 0 ||
(status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_TX_LPF)) != 0 ||
(status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RX_LPF)) != 0 ||
(status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RXVGA2)) != 0) {
fprintf(stderr, "[BRF] error calibrating\n");
brf_error(status);
} else
printf("[BRF] TX module calibrated DC \n");
if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_RX)) != 0) {
fprintf(stderr,"Failed to calibrate RX DC: %s\n", bladerf_strerror(status));
brf_error(status);
}else
printf("[BRF] RX module calibrated DC \n");
} else
printf("[BRF] calibration OK\n");
bladerf_log_set_verbosity(get_brf_log_level(openair0_cfg->log_level));
@@ -1146,8 +1141,8 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
* \returns 0 on success
*/
int brf_error(int status) {
//exit(-1);
fprintf(stderr, "[BRF] brf_error: %s\n", bladerf_strerror(status));
exit(-1);
return status; // or status error code
}
@@ -1190,7 +1185,7 @@ struct bladerf * open_bladerf_from_serial(const char *serial) {
int get_brf_log_level(int log_level){
int level=BLADERF_LOG_LEVEL_INFO;
return BLADERF_LOG_LEVEL_DEBUG; // BLADERF_LOG_LEVEL_VERBOSE;// BLADERF_LOG_LEVEL_DEBUG; //
return BLADERF_LOG_LEVEL_INFO;
switch(log_level) {
case LOG_DEBUG:
level=BLADERF_LOG_LEVEL_DEBUG;
+4 -1
View File
@@ -48,7 +48,7 @@ int set_device(openair0_device *device) {
case USRP_B200_DEV:
printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case USRP_X300_DEV:
case USRP_X300_DEV:
printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case BLADERF_DEV:
@@ -57,6 +57,9 @@ case USRP_X300_DEV:
case LMSSDR_DEV:
printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case IRIS_DEV:
printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case NONE_DEV:
printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
+2
View File
@@ -95,6 +95,8 @@ typedef enum {
BLADERF_DEV,
/*!\brief device is LMSSDR (SoDeRa)*/
LMSSDR_DEV,
/*!\brief device is Iris */
IRIS_DEV,
/*!\brief device is NONE*/
NONE_DEV,
MAX_RF_DEV_TYPE
@@ -0,0 +1,4 @@
IRIS_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.o
IRIS_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
IRIS_CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON
@@ -0,0 +1,852 @@
/** iris_lib.cpp
*
* \authors: Rahman Doost-Mohammady : doost@rice.edu
* Clay Shepard : cws@rice.edu
*/
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <SoapySDR/Device.hpp>
#include <SoapySDR/Formats.hpp>
#include <SoapySDR/Time.hpp>
//#include <boost/format.hpp>
#include <iostream>
#include <complex>
#include <fstream>
#include <cmath>
#include <time.h>
#include <limits>
#include "common/utils/LOG/log_extern.h"
#include "common_lib.h"
#include <chrono>
#ifdef __SSE4_1__
# include <smmintrin.h>
#endif
#ifdef __AVX2__
# include <immintrin.h>
#endif
#define MOVE_DC
#define SAMPLE_RATE_DOWN 1
/*! \brief Iris Configuration */
typedef struct {
// --------------------------------
// variables for Iris configuration
// --------------------------------
//! Iris device pointer
std::vector<SoapySDR::Device *> iris;
int device_num;
int rx_num_channels;
int tx_num_channels;
//create a send streamer and a receive streamer
//! Iris TX Stream
std::vector<SoapySDR::Stream *> txStream;
//! Iris RX Stream
std::vector<SoapySDR::Stream *> rxStream;
//! Sampling rate
double sample_rate;
//! time offset between transmiter timestamp and receiver timestamp;
double tdiff;
//! TX forward samples.
int tx_forward_nsamps; //166 for 20Mhz
// --------------------------------
// Debug and output control
// --------------------------------
//! Number of underflows
int num_underflows;
//! Number of overflows
int num_overflows;
//! Number of sequential errors
int num_seq_errors;
//! tx count
int64_t tx_count;
//! rx count
int64_t rx_count;
//! timestamp of RX packet
openair0_timestamp rx_timestamp;
} iris_state_t;
/*! \brief Called to start the Iris lime transceiver. Return 0 if OK, < 0 if error
@param device pointer to the device structure specific to the RF hardware target
*/
static int trx_iris_start(openair0_device *device) {
iris_state_t *s = (iris_state_t *) device->priv;
long long timeNs = s->iris[0]->getHardwareTime("") + 500000;
int flags = 0;
//flags |= SOAPY_SDR_HAS_TIME;
int r;
for (r = 0; r < s->device_num; r++) {
int ret = s->iris[r]->activateStream(s->rxStream[r], flags, timeNs, 0);
int ret2 = s->iris[r]->activateStream(s->txStream[r]);
if (ret < 0 | ret2 < 0)
return -1;
}
return 0;
}
/*! \brief Stop Iris
* \param card refers to the hardware index to use
*/
int trx_iris_stop(openair0_device *device) {
iris_state_t *s = (iris_state_t *) device->priv;
int r;
for (r = 0; r < s->device_num; r++) {
s->iris[r]->deactivateStream(s->txStream[r]);
s->iris[r]->deactivateStream(s->rxStream[r]);
}
return (0);
}
/*! \brief Terminate operation of the Iris lime transceiver -- free all associated resources
* \param device the hardware to use
*/
static void trx_iris_end(openair0_device *device) {
LOG_I(HW, "Closing Iris device.\n");
trx_iris_stop(device);
iris_state_t *s = (iris_state_t *) device->priv;
int r;
for (r = 0; r < s->device_num; r++) {
s->iris[r]->closeStream(s->txStream[r]);
s->iris[r]->closeStream(s->rxStream[r]);
SoapySDR::Device::unmake(s->iris[r]);
}
}
/*! \brief Called to send samples to the Iris RF target
@param device pointer to the device structure specific to the RF hardware target
@param timestamp The timestamp at whicch the first sample MUST be sent
@param buff Buffer which holds the samples
@param nsamps number of samples to be sent
@param antenna_id index of the antenna if the device has multiple anteannas
@param flags flags must be set to TRUE if timestamp parameter needs to be applied
*/
static int
trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
using namespace std::chrono;
static long long int loop = 0;
static long time_min = 0, time_max = 0, time_avg = 0;
struct timespec tp_start, tp_end;
long time_diff;
int ret = 0, ret_i = 0;
int flag = 0;
iris_state_t *s = (iris_state_t *) device->priv;
int nsamps2; // aligned to upper 32 or 16 byte boundary
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
nsamps2 = (nsamps+7)>>3;
__m256i buff_tx[2][nsamps2];
#else
nsamps2 = (nsamps+3)>>2;
__m128i buff_tx[2][nsamps2];
#endif
#endif
// bring RX data into 12 LSBs for softmodem RX
for (int i=0; i<cc; i++) {
for (int j=0; j<nsamps2; j++) {
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
buff_tx[i][j] = _mm256_slli_epi16(((__m256i *)buff[i])[j],4);
#else
buff_tx[i][j] = _mm_slli_epi16(((__m128i *)buff[i])[j],4);
#endif
#endif
}
}
clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start);
// This hack was added by cws to help keep packets flowing
if (flags)
flag |= SOAPY_SDR_HAS_TIME;
else {
long long tempHack = s->iris[0]->getHardwareTime("");
return nsamps;
}
if (flags == 2 || flags == 1) { // start of burst
} else if (flags == 3 | flags == 4) {
flag |= SOAPY_SDR_END_BURST;
}
long long timeNs = SoapySDR::ticksToTimeNs(timestamp, s->sample_rate / SAMPLE_RATE_DOWN);
uint32_t *samps[2]; //= (uint32_t **)buff;
int r;
int m = s->tx_num_channels;
for (r = 0; r < s->device_num; r++) {
int samples_sent = 0;
samps[0] = (uint32_t *) buff_tx[m * r];
if (cc % 2 == 0)
samps[1] = (uint32_t *) buff_tx[m * r + 1]; //cws: it seems another thread can clobber these, so we need to save them locally.
#ifdef IRIS_DEBUG
int i;
for (i = 200; i < 216; i++)
printf("%d, ",((int16_t)(samps[0][i]>>16))>>4);
printf("\n");
//printf("\nHardware time before write: %lld, tx_time_stamp: %lld\n", s->iris[0]->getHardwareTime(""), timeNs);
#endif
ret = s->iris[r]->writeStream(s->txStream[r], (void **) samps, (size_t)(nsamps), flag, timeNs, 1000000);
if (ret < 0)
printf("Unable to write stream!\n");
else
samples_sent = ret;
if (samples_sent != nsamps)
printf("[xmit] tx samples %d != %d\n", samples_sent, nsamps);
}
return nsamps;
}
/*! \brief Receive samples from hardware.
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
* the first channel. *ptimestamp is the time at which the first sample
* was received.
* \param device the hardware to use
* \param[out] ptimestamp the time at which the first sample was received.
* \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
* \param antenna_id Index of antenna for which to receive samples
* \returns the number of sample read
*/
static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
int ret = 0;
static long long nextTime;
static bool nextTimeValid = false;
iris_state_t *s = (iris_state_t *) device->priv;
bool time_set = false;
long long timeNs = 0;
int flags;
int samples_received;
uint32_t *samps[2]; //= (uint32_t **)buff;
int r;
int m = s->rx_num_channels;
int nsamps2; // aligned to upper 32 or 16 byte boundary
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
nsamps2 = (nsamps+7)>>3;
__m256i buff_tmp[2][nsamps2];
#else
nsamps2 = (nsamps+3)>>2;
__m128i buff_tmp[2][nsamps2];
#endif
#endif
for (r = 0; r < s->device_num; r++) {
flags = 0;
samples_received = 0;
samps[0] = (uint32_t *) buff_tmp[m * r];
if (cc % 2 == 0)
samps[1] = (uint32_t *) buff_tmp[m * r + 1];
flags = 0;
ret = s->iris[r]->readStream(s->rxStream[r], (void **) samps, (size_t)(nsamps), flags,
timeNs, 1000000);
if (ret < 0) {
if (ret == SOAPY_SDR_TIME_ERROR)
printf("[recv] Time Error in tx stream!\n");
else if (ret == SOAPY_SDR_OVERFLOW | (flags & SOAPY_SDR_END_ABRUPT))
printf("[recv] Overflow occured!\n");
else if (ret == SOAPY_SDR_TIMEOUT)
printf("[recv] Timeout occured!\n");
else if (ret == SOAPY_SDR_STREAM_ERROR)
printf("[recv] Stream (tx) error occured!\n");
else if (ret == SOAPY_SDR_CORRUPTION)
printf("[recv] Bad packet occured!\n");
break;
} else
samples_received = ret;
if (r == 0) {
if (samples_received == ret) // first batch
{
if (flags & SOAPY_SDR_HAS_TIME) {
s->rx_timestamp = SoapySDR::timeNsToTicks(timeNs, s->sample_rate / SAMPLE_RATE_DOWN);
*ptimestamp = s->rx_timestamp;
nextTime = timeNs;
nextTimeValid = true;
time_set = true;
//printf("1) time set %llu \n", *ptimestamp);
}
}
}
if (r == 0) {
if (samples_received == nsamps) {
if (flags & SOAPY_SDR_HAS_TIME) {
s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate / SAMPLE_RATE_DOWN);
*ptimestamp = s->rx_timestamp;
nextTime = timeNs;
nextTimeValid = true;
time_set = true;
}
} else if (samples_received < nsamps)
printf("[recv] received %d samples out of %d\n", samples_received, nsamps);
s->rx_count += samples_received;
if (s->sample_rate != 0 && nextTimeValid) {
if (!time_set) {
s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate / SAMPLE_RATE_DOWN);
*ptimestamp = s->rx_timestamp;
//printf("2) time set %llu, nextTime will be %llu \n", *ptimestamp, nextTime);
}
nextTime += SoapySDR::ticksToTimeNs(samples_received, s->sample_rate / SAMPLE_RATE_DOWN);
}
}
// bring RX data into 12 LSBs for softmodem RX
for (int i=0; i<cc; i++) {
for (int j=0; j<nsamps2; j++) {
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4);
#else
((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4);
#endif
#endif
}
}
}
return samples_received;
}
/*! \brief Get current timestamp of Iris
* \param device the hardware to use
*/
openair0_timestamp get_iris_time(openair0_device *device) {
iris_state_t *s = (iris_state_t *) device->priv;
return SoapySDR::timeNsToTicks(s->iris[0]->getHardwareTime(""), s->sample_rate);
}
/*! \brief Compares two variables within precision
* \param a first variable
* \param b second variable
*/
static bool is_equal(double a, double b) {
return std::fabs(a - b) < std::numeric_limits<double>::epsilon();
}
void *set_freq_thread(void *arg) {
openair0_device *device = (openair0_device *) arg;
iris_state_t *s = (iris_state_t *) device->priv;
int r, i;
printf("Setting Iris TX Freq %f, RX Freq %f\n", device->openair0_cfg[0].tx_freq[0],
device->openair0_cfg[0].rx_freq[0]);
// add check for the number of channels in the cfg
for (r = 0; r < s->device_num; r++) {
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels)
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", device->openair0_cfg[0].rx_freq[i]);
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels)
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", device->openair0_cfg[0].tx_freq[i]);
}
}
}
/*! \brief Set frequencies (TX/RX)
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \param dummy dummy variable not used
* \returns 0 in success
*/
int trx_iris_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dont_block) {
iris_state_t *s = (iris_state_t *) device->priv;
pthread_t f_thread;
if (dont_block)
pthread_create(&f_thread, NULL, set_freq_thread, (void *) device);
else {
int r, i;
for (r = 0; r < s->device_num; r++) {
printf("Setting Iris TX Freq %f, RX Freq %f\n", openair0_cfg[0].tx_freq[0], openair0_cfg[0].rx_freq[0]);
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) {
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]);
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) {
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]);
}
}
}
}
return (0);
}
/*! \brief Set Gains (TX/RX)
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
*/
int trx_iris_set_gains(openair0_device *device,
openair0_config_t *openair0_cfg) {
iris_state_t *s = (iris_state_t *) device->priv;
int r;
for (r = 0; r < s->device_num; r++) {
s->iris[r]->setGain(SOAPY_SDR_RX, 0, openair0_cfg[0].rx_gain[0]);
s->iris[r]->setGain(SOAPY_SDR_TX, 0, openair0_cfg[0].tx_gain[0]);
s->iris[r]->setGain(SOAPY_SDR_RX, 1, openair0_cfg[0].rx_gain[1]);
s->iris[r]->setGain(SOAPY_SDR_TX, 1, openair0_cfg[0].tx_gain[1]);
}
return (0);
}
/*! \brief Iris RX calibration table */
rx_gain_calib_table_t calib_table_iris[] = {
{3500000000.0, 83},
{2660000000.0, 83},
{2580000000.0, 83},
{2300000000.0, 83},
{1880000000.0, 83},
{816000000.0, 83},
{-1, 0}};
/*! \brief Set RX gain offset
* \param openair0_cfg RF frontend parameters set by application
* \param chain_index RF chain to apply settings to
* \returns 0 in success
*/
void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index, int bw_gain_adjust) {
int i = 0;
// loop through calibration table to find best adjustment factor for RX frequency
double min_diff = 6e9, diff, gain_adj = 0.0;
if (bw_gain_adjust == 1) {
switch ((int) openair0_cfg[0].sample_rate) {
case 30720000:
break;
case 23040000:
gain_adj = 1.25;
break;
case 15360000:
gain_adj = 3.0;
break;
case 7680000:
gain_adj = 6.0;
break;
case 3840000:
gain_adj = 9.0;
break;
case 1920000:
gain_adj = 12.0;
break;
default:
printf("unknown sampling rate %d\n", (int) openair0_cfg[0].sample_rate);
exit(-1);
break;
}
}
while (openair0_cfg->rx_gain_calib_table[i].freq > 0) {
diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq);
printf("cal %d: freq %f, offset %f, diff %f\n",
i,
openair0_cfg->rx_gain_calib_table[i].freq,
openair0_cfg->rx_gain_calib_table[i].offset, diff);
if (min_diff > diff) {
min_diff = diff;
openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset + gain_adj;
}
i++;
}
}
/*! \brief print the Iris statistics
* \param device the hardware to use
* \returns 0 on success
*/
int trx_iris_get_stats(openair0_device *device) {
return (0);
}
/*! \brief Reset the Iris statistics
* \param device the hardware to use
* \returns 0 on success
*/
int trx_iris_reset_stats(openair0_device *device) {
return (0);
}
extern "C" {
/*! \brief Initialize Openair Iris target. It returns 0 if OK
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
size_t i, r, card;
int bw_gain_adjust = 0;
openair0_cfg[0].rx_gain_calib_table = calib_table_iris;
iris_state_t *s = (iris_state_t *) malloc(sizeof(iris_state_t));
memset(s, 0, sizeof(iris_state_t));
std::string devFE("DEV");
std::string cbrsFE("CBRS");
std::string wireFormat("WIRE");
// Initialize Iris device
device->openair0_cfg = openair0_cfg;
SoapySDR::Kwargs args;
args["driver"] = "iris";
char *iris_addrs = device->openair0_cfg[0].sdr_addrs;
if (iris_addrs == NULL)
{
s->iris.push_back(SoapySDR::Device::make(args));
}
else
{
char *serial = strtok(iris_addrs, ",");
while (serial != NULL) {
LOG_I(HW, "Attempting to open Iris device %s\n", serial);
args["serial"] = serial;
s->iris.push_back(SoapySDR::Device::make(args));
serial = strtok(NULL, ",");
}
}
s->device_num = s->iris.size();
device->type = IRIS_DEV;
switch ((int) openair0_cfg[0].sample_rate) {
case 30720000:
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 115;
openair0_cfg[0].tx_bw = 20e6;
openair0_cfg[0].rx_bw = 20e6;
break;
case 23040000:
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 113;
openair0_cfg[0].tx_bw = 15e6;
openair0_cfg[0].rx_bw = 15e6;
break;
case 15360000:
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 60;
openair0_cfg[0].tx_bw = 10e6;
openair0_cfg[0].rx_bw = 10e6;
break;
case 7680000:
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 30;
openair0_cfg[0].tx_bw = 5e6;
openair0_cfg[0].rx_bw = 5e6;
break;
case 1920000:
//openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 20;
openair0_cfg[0].tx_bw = 1.4e6;
openair0_cfg[0].rx_bw = 1.4e6;
break;
default:
printf("Error: unknown sampling rate %f\n", openair0_cfg[0].sample_rate);
exit(-1);
break;
}
printf("tx_sample_advance %d\n", openair0_cfg[0].tx_sample_advance);
s->rx_num_channels = openair0_cfg[0].rx_num_channels;
s->tx_num_channels = openair0_cfg[0].tx_num_channels;
if ((s->rx_num_channels == 1 || s->rx_num_channels == 2) && (s->tx_num_channels == 1 || s->tx_num_channels == 2))
printf("Enabling %d rx and %d tx channel(s) on each device...\n", s->rx_num_channels, s->tx_num_channels);
else {
printf("Invalid rx or tx number of channels (%d, %d)\n", s->rx_num_channels, s->tx_num_channels);
exit(-1);
}
for (r = 0; r < s->device_num; r++) {
//this is unnecessary -- it will set the correct master clock based on sample rate
/*switch ((int) openair0_cfg[0].sample_rate) {
case 1920000:
s->iris[r]->setMasterClockRate(256 * openair0_cfg[0].sample_rate);
break;
case 3840000:
s->iris[r]->setMasterClockRate(128 * openair0_cfg[0].sample_rate);
break;
case 7680000:
s->iris[r]->setMasterClockRate(64 * openair0_cfg[0].sample_rate);
break;
case 15360000:
s->iris[r]->setMasterClockRate(32 * openair0_cfg[0].sample_rate);
break;
case 30720000:
s->iris[r]->setMasterClockRate(16 * openair0_cfg[0].sample_rate);
break;
default:
printf("Error: unknown sampling rate %f\n", openair0_cfg[0].sample_rate);
exit(-1);
break;
}*/
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) {
s->iris[r]->setSampleRate(SOAPY_SDR_RX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN);
#ifdef MOVE_DC
printf("Moving DC out of main carrier for rx...\n");
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]-.75*openair0_cfg[0].sample_rate);
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "BB", .75*openair0_cfg[0].sample_rate);
#else
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]);
#endif
set_rx_gain_offset(&openair0_cfg[0], i, bw_gain_adjust);
//s->iris[r]->setGain(SOAPY_SDR_RX, i, openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]);
printf("rx gain offset: %f, rx_gain: %f, tx_tgain: %f\n", openair0_cfg[0].rx_gain_offset[i], openair0_cfg[0].rx_gain[i], openair0_cfg[0].tx_gain[i]);
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]);
//s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", 0);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA1", 30);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA2", 17);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 7);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 18);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "ATTN", 0);
} else {
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]); // [0,30]
s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 7); // [0,12,6]
s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 18); // [-12,19,1]
//s->iris[r]->setGain(SOAPY_SDR_RX, i, 50); // [-12,19,1]
}
s->iris[r]->setDCOffsetMode(SOAPY_SDR_RX, i, true); // move somewhere else
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) {
s->iris[r]->setSampleRate(SOAPY_SDR_TX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN);
#ifdef MOVE_DC
printf("Moving DC out of main carrier for tx...\n");
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]-.75*openair0_cfg[0].sample_rate);
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "BB", .75*openair0_cfg[0].sample_rate);
#else
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]);
#endif
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) == 0) {
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]);
//s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 50);
s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 12);
//s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0");
//s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100");
} else {
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]);
s->iris[r]->setGain(SOAPY_SDR_TX, i, "ATTN", 0); // [-18, 0, 6] dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 6); // [-12, 12, 1] dB
//s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 44); //openair0_cfg[0].tx_gain[i]);
//s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 35); // [0, 52, 1] dB
//s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA1", 17); // 17 ??? dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA2", 0); // [0, 17, 17] dB
//s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA3", 20); // 33 ??? dB
s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0");
s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100");
}
// if (openair0_cfg[0].duplex_mode == 0) {
// printf("\nFDD: Enable TX antenna override\n");
// s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "TX_ENB_OVERRIDE",
// "true"); // From Josh: forces tx switching to be on always transmit regardless of bursts
// }
}
}
printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate() / 1e6));
int tx_filt_bw = openair0_cfg[0].tx_bw;
int rx_filt_bw = openair0_cfg[0].rx_bw;
#ifdef MOVE_DC //the filter is centered around the carrier, so we have to expand it if we have moved the DC tone.
tx_filt_bw *= 3;
rx_filt_bw *= 3;
#endif
/* Setting TX/RX BW */
for (i = 0; i < s->tx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) {
s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, tx_filt_bw);
printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n", i,
s->iris[r]->getNumChannels(SOAPY_SDR_TX), tx_filt_bw / 1e6,
s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6);
}
}
for (i = 0; i < s->rx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) {
s->iris[r]->setBandwidth(SOAPY_SDR_RX, i, rx_filt_bw);
printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n", i,
s->iris[r]->getNumChannels(SOAPY_SDR_RX), rx_filt_bw / 1e6,
s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6);
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) {
printf("\nUsing SKLK calibration...\n");
s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", "SKLK");
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) {
printf("\nUsing SKLK calibration...\n");
s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", "SKLK");
}
}
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) == 0) {
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (openair0_cfg[0].duplex_mode == 0) {
printf("\nFDD: Setting receive antenna to %s\n", s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[1].c_str());
if (i < s->rx_num_channels)
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "RX");
} else {
printf("\nTDD: Setting receive antenna to %s\n", s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[0].c_str());
if (i < s->rx_num_channels)
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "TRX");
}
}
}
//s->iris[r]->writeSetting("TX_SW_DELAY", std::to_string(
// -openair0_cfg[0].tx_sample_advance)); //should offset switching to compensate for RF path (Lime) delay -- this will eventually be automated
// create tx & rx streamer
//const SoapySDR::Kwargs &arg = SoapySDR::Kwargs();
std::map <std::string, std::string> rxStreamArgs;
rxStreamArgs["WIRE"] = SOAPY_SDR_CS16;
std::vector <size_t> channels;
for (i = 0; i < s->rx_num_channels; i++)
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX))
channels.push_back(i);
s->rxStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, channels));//, rxStreamArgs));
std::vector <size_t> tx_channels = {};
for (i = 0; i < s->tx_num_channels; i++)
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX))
tx_channels.push_back(i);
s->txStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_TX, SOAPY_SDR_CS16, tx_channels)); //, arg));
//s->iris[r]->setHardwareTime(0, "");
std::cout << "Front end detected: " << s->iris[r]->getHardwareInfo()["frontend"] << "\n";
for (i = 0; i < s->rx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) {
printf("RX Channel %lu\n", i);
printf("Actual RX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_RX, i) / 1e6));
printf("Actual RX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_RX, i) / 1e9));
printf("Actual RX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i)));
printf("Actual RX LNA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA")));
printf("Actual RX PGA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "PGA")));
printf("Actual RX TIA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "TIA")));
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("Actual RX LNA1 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA1")));
printf("Actual RX LNA2 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA2")));
}
printf("Actual RX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6));
printf("Actual RX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_RX, i).c_str()));
}
}
for (i = 0; i < s->tx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) {
printf("TX Channel %lu\n", i);
printf("Actual TX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_TX, i) / 1e6));
printf("Actual TX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_TX, i) / 1e9));
printf("Actual TX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i)));
printf("Actual TX PAD gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PAD")));
printf("Actual TX IAMP gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "IAMP")));
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("Actual TX PA1 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA1")));
printf("Actual TX PA2 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA2")));
printf("Actual TX PA3 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA3")));
}
printf("Actual TX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6));
printf("Actual TX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_TX, i).c_str()));
}
}
}
s->iris[0]->writeSetting("SYNC_DELAYS", "");
for (r = 0; r < s->device_num; r++)
s->iris[r]->setHardwareTime(0, "TRIGGER");
s->iris[0]->writeSetting("TRIGGER_GEN", "");
for (r = 0; r < s->device_num; r++)
printf("Device timestamp: %f...\n", (s->iris[r]->getHardwareTime("TRIGGER") / 1e9));
device->priv = s;
device->trx_start_func = trx_iris_start;
device->trx_write_func = trx_iris_write;
device->trx_read_func = trx_iris_read;
device->trx_get_stats_func = trx_iris_get_stats;
device->trx_reset_stats_func = trx_iris_reset_stats;
device->trx_end_func = trx_iris_end;
device->trx_stop_func = trx_iris_stop;
device->trx_set_freq_func = trx_iris_set_freq;
device->trx_set_gains_func = trx_iris_set_gains;
device->openair0_cfg = openair0_cfg;
s->sample_rate = openair0_cfg[0].sample_rate;
// TODO:
// init tx_forward_nsamps based iris_time_offset ex
if (is_equal(s->sample_rate, (double) 30.72e6))
s->tx_forward_nsamps = 176;
if (is_equal(s->sample_rate, (double) 15.36e6))
s->tx_forward_nsamps = 90;
if (is_equal(s->sample_rate, (double) 7.68e6))
s->tx_forward_nsamps = 50;
LOG_I(HW, "Finished initializing %d Iris device(s).\n", s->device_num);
fflush(stdout);
return 0;
}
}
/*@}*/
@@ -193,7 +193,7 @@ int trx_lms_start(openair0_device *device){
LMS_EnableChannel(lms_device,LMS_CH_RX,1,true);
LMS_EnableChannel(lms_device,LMS_CH_TX,1,true);
} */
LMS_VCTCXOWrite(lms_device,129);
LMS_VCTCXOWrite(lms_device,129, true);
if (LMS_SetSampleRate(lms_device,device->openair0_cfg->sample_rate,2)!=0)
{
+7 -2
View File
@@ -23,6 +23,7 @@
# include "intertask_interface.h"
# include "create_tasks.h"
# include "common/utils/LOG/log.h"
# include "targets/RT/USER/lte-softmodem.h"
# ifdef OPENAIR2
# if defined(ENABLE_USE_MME)
@@ -32,7 +33,12 @@
# include "nas_ue_task.h"
# include "udp_eNB_task.h"
# include "gtpv1u_eNB_task.h"
/* temporary warning removale while implementing noS1 */
/* as config option */
# else
# ifdef EPC_MODE_ENABLED
# undef EPC_MODE_ENABLED
# endif
# define EPC_MODE_ENABLED 0
# endif
# if ENABLE_RAL
@@ -43,7 +49,6 @@
# endif
# include "enb_app.h"
extern int emulate_rf;
int create_tasks(uint32_t enb_nb)
{
@@ -79,7 +84,7 @@ int create_tasks(uint32_t enb_nb)
LOG_E(S1AP, "Create task for S1AP failed\n");
return -1;
}
if(!emulate_rf){
if(!(get_softmodem_params()->emulate_rf)){
if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
LOG_E(UDP_, "Create task for UDP failed\n");
return -1;
-95
View File
@@ -1,95 +0,0 @@
<ICIC_API>
<SRUCTURE>
<STRUCTNAME>SBMAP_CONF</STRUCTNAME>
<PATH>openair2/LAYER2/MAC/defs.h</PATH>
<FIELD>
<FIELDNAME>sbmap[13]</FIELDNAME>
<FIELDTYPE>unsigned char</FIELDTYPE>
<DESC>subband map indicates to scheduler allowed SB for eNB</DESC>
</FIELD>
<FIELD>
<FIELDNAME>periodicity</FIELDNAME>
<FIELDTYPE>unsigned char</FIELDTYPE>
<DESC>in millisecond indicate update instant</DESC>
</FIELD>
<FIELD>
<FIELDNAME>first_subframe</FIELDNAME>
<FIELDTYPE>unsigned char</FIELDTYPE>
<DESC>...</DESC>
</FIELD>
<FIELD>
<FIELDNAME>sb_size</FIELDNAME>
<FIELDTYPE>unsigned char</FIELDTYPE>
<DESC>number of PRB in this subband</DESC>
</FIELD>
<FIELD>
<FIELDNAME>nb_active_sb</FIELDNAME>
<FIELDTYPE>unsigned char</FIELDTYPE>
<DESC>indicates the number of set subbands</DESC>
</FIELD>
</SRUCTURE>
<SRUCTURE>
<STRUCTNAME>eNB_MAC_INST</STRUCTNAME>
<PATH>openair2/LAYER2/MAC/defs.h</PATH>
<FIELD>
...
</FIELD>
<FIELD>
<FIELDNAME>sbmap_conf</FIELDNAME>
<FIELDTYPE>SBMAP_CONF</FIELDTYPE>
<DESC>subband map configuration for each eNB</DESC>
</FIELD>
<INITPATH>openair2/LAYER2/MAC/main.c</INITPATH>
<INITFUNC>mac_top_init</INITFUNC>
</SRUCTURE>
<SRUCTURE>
<STRUCTNAME>MAC_xface</STRUCTNAME>
<PATH>openair2/PHY_INTERFACE/defs.h</PATH>
<FIELD>
...
</FIELD>
<FIELD>
<FIELDNAME>(*get_SB_size)(unsigned char)</FIELDNAME>
<FIELDTYPE>function pointer n</FIELDTYPE>
<DESC>return the number of PRB supported in a subband configuration</DESC>
</FIELD>
<INITPATH>openair2/LAYER2/MAC/main.c</INITPATH>
<INITFUNC>l2_init</INITFUNC>
</SRUCTURE>
<FUNCTION>
<FUNCNAME>Get_Cell_SBMap</FUNCNAME>
<PARAMS>unsigned char Mod_id</PARAMS>
<RETURN>void</RETURN>
<PROTOPATH>openair2/LAYER2/MAC/defs.h</PROTOPATH>
<IMPLPATH>openair2/LAYER2/MAC/eNB_scheduler.c</IMPLPATH>
<DESC>imlements ICIC algo</DESC>
</FUNCTION>
<FUNCTION>
<FUNCNAME>Get_SB_size</FUNCNAME>
<PARAMS>unsigned char n_rb_dl</PARAMS>
<RETURN>unsigned char </RETURN>
<PROTOPATH>openair1/PHY/LTE_TRANSPORT/proto.h</PROTOPATH>
<IMPLPATH>openair1/PHY/LTE_TRANSPORT/lte_mcs.c</IMPLPATH>
<DESC>return the number of PRB supported in a subband configuration.</DESC>
</FUNCTION>
</ICIC_API>
Binary file not shown.
Binary file not shown.
-47
View File
@@ -1,47 +0,0 @@
\documentclass[a4paper]{book}
\usepackage{a4wide}
\usepackage{makeidx}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{multicol}
\usepackage{float}
\usepackage{textcomp}
\usepackage{alltt}
\usepackage{amsmath}
\usepackage{amssymb}
\ifx\pdfoutput\undefined
\usepackage[ps2pdf,
pagebackref=true,
colorlinks=true,
linkcolor=blue
]{hyperref}
\usepackage{pspicture}
\else
\usepackage[pdftex,
pagebackref=true,
colorlinks=true,
linkcolor=blue
]{hyperref}
\fi
\usepackage{doxygen}
\usepackage{times}
\makeindex
\setcounter{tocdepth}{1}
\renewcommand{\footrulewidth}{0.4pt}
\begin{document}
\begin{titlepage}
\vspace*{7cm}
\begin{center}
{\Large openair Specifications }\\
Phyiscal, Medium-Access, Radio-link Control, Packet Data Convergence Protocol and Radio Resource Control Layers\\
\vspace*{1cm}
{\large Generated by Doxygen 1.3.8}\\
\vspace*{0.5cm}
{\small Sun Oct 31 19:27:37 2004}\\
\end{center}
\end{titlepage}
\clearemptydoublepage
\pagenumbering{roman}
\tableofcontents
\clearemptydoublepage
\pagenumbering{arabic}
Binary file not shown.
@@ -0,0 +1,264 @@
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "TDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 38;
downlink_frequency = 2580000000L;
uplink_frequency_offset = 0;
Nid_cell = 10;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 52; # [~50 for DEV-FE, ~30 for CBRS-FE]
rx_gain = 115; # [115 for DEV-FE, 90 for CBRS-FE]
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -30;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -70;
pusch_alpha = "AL1";
pucch_p0_Nominal = -96;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -96;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
//Parameters for SIB18
rxPool_sc_CP_Len = "normal";
rxPool_sc_Period = "sf40";
rxPool_data_CP_Len = "normal";
rxPool_ResourceConfig_prb_Num = 20;
rxPool_ResourceConfig_prb_Start = 5;
rxPool_ResourceConfig_prb_End = 44;
rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
rxPool_ResourceConfig_offsetIndicator_choice = 0;
rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
/* rxPool_dataHoppingConfig_hoppingParameter = 0;
rxPool_dataHoppingConfig_numSubbands = "ns1";
rxPool_dataHoppingConfig_rbOffset = 0;
rxPool_commTxResourceUC-ReqAllowed = "TRUE";
*/
// Parameters for SIB19
discRxPool_cp_Len = "normal"
discRxPool_discPeriod = "rf32"
discRxPool_numRetx = 1;
discRxPool_numRepetition = 2;
discRxPool_ResourceConfig_prb_Num = 5;
discRxPool_ResourceConfig_prb_Start = 3;
discRxPool_ResourceConfig_prb_End = 21;
discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
discRxPool_ResourceConfig_offsetIndicator_choice = 0;
discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "fe80::d65d:dfff:fe1d:f4d4";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eno1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "enp5s0";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.10/8";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 200;
puCch10xSnr = 200;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 125;
eNB_instances = [0];
#sdr_addrs = "RF3C000025";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
@@ -0,0 +1,264 @@
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "TDD";
tdd_config = 1;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 42;
downlink_frequency = 3500000000L;
uplink_frequency_offset = 0;
Nid_cell = 10;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 48; # [~50 for DEV-FE, ~30 for CBRS-FE]
rx_gain = 80; # [115 for DEV-FE, 90 for CBRS-FE]
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -30;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -70;
pusch_alpha = "AL1";
pucch_p0_Nominal = -96;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -96;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
//Parameters for SIB18
rxPool_sc_CP_Len = "normal";
rxPool_sc_Period = "sf40";
rxPool_data_CP_Len = "normal";
rxPool_ResourceConfig_prb_Num = 20;
rxPool_ResourceConfig_prb_Start = 5;
rxPool_ResourceConfig_prb_End = 44;
rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
rxPool_ResourceConfig_offsetIndicator_choice = 0;
rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
/* rxPool_dataHoppingConfig_hoppingParameter = 0;
rxPool_dataHoppingConfig_numSubbands = "ns1";
rxPool_dataHoppingConfig_rbOffset = 0;
rxPool_commTxResourceUC-ReqAllowed = "TRUE";
*/
// Parameters for SIB19
discRxPool_cp_Len = "normal"
discRxPool_discPeriod = "rf32"
discRxPool_numRetx = 1;
discRxPool_numRepetition = 2;
discRxPool_ResourceConfig_prb_Num = 5;
discRxPool_ResourceConfig_prb_Start = 3;
discRxPool_ResourceConfig_prb_End = 21;
discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
discRxPool_ResourceConfig_offsetIndicator_choice = 0;
discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "fe80::d65d:dfff:fe1d:f4d4";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eno1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "enp5s0";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.10/8";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 200;
puCch10xSnr = 200;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1;
nb_rx = 1;
att_tx = 44; #apparently this is being used as tx_gain...
att_rx = 0; #apparently max_rxgain - att_rx -83 is what is used for rx_gain (at least for 5 MHz)
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 107;
eNB_instances = [0];
#sdr_addrs = "RF3E000025";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
@@ -15,7 +15,7 @@ eNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
@@ -138,7 +138,7 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.26";
mme_ip_address = ( { ipv4 = "192.168.12.148";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
@@ -187,7 +187,7 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 116;
eNB_instances = [0];
sdr_addrs = "type=x300";
}
);
@@ -0,0 +1,264 @@
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 10;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 52; # [~50 for DEV-FE, ~30 for CBRS-FE]
rx_gain = 115; # [115 for DEV-FE, 90 for CBRS-FE]
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -30;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -70;
pusch_alpha = "AL1";
pucch_p0_Nominal = -96;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -96;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
//Parameters for SIB18
rxPool_sc_CP_Len = "normal";
rxPool_sc_Period = "sf40";
rxPool_data_CP_Len = "normal";
rxPool_ResourceConfig_prb_Num = 20;
rxPool_ResourceConfig_prb_Start = 5;
rxPool_ResourceConfig_prb_End = 44;
rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
rxPool_ResourceConfig_offsetIndicator_choice = 0;
rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
/* rxPool_dataHoppingConfig_hoppingParameter = 0;
rxPool_dataHoppingConfig_numSubbands = "ns1";
rxPool_dataHoppingConfig_rbOffset = 0;
rxPool_commTxResourceUC-ReqAllowed = "TRUE";
*/
// Parameters for SIB19
discRxPool_cp_Len = "normal"
discRxPool_discPeriod = "rf32"
discRxPool_numRetx = 1;
discRxPool_numRepetition = 2;
discRxPool_ResourceConfig_prb_Num = 5;
discRxPool_ResourceConfig_prb_Start = 3;
discRxPool_ResourceConfig_prb_End = 21;
discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
discRxPool_ResourceConfig_offsetIndicator_choice = 0;
discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "fe80::d65d:dfff:fe1d:f4d4";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.10/8";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 200;
puCch10xSnr = 200;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 125;
eNB_instances = [0];
sdr_addrs = "RF3E000028";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
@@ -31,9 +31,9 @@ log_config = {
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="debug";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="debug";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
+397 -476
View File
File diff suppressed because it is too large Load Diff
+62 -37
View File
@@ -90,6 +90,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
#include "targets/RT/USER/lte-softmodem.h"
//#include "PHY/TOOLS/time_meas.h"
/* these variables have to be defined before including ENB_APP/enb_paramdef.h */
@@ -122,12 +123,13 @@ extern int numerology;
extern clock_source_t clock_source;
extern uint8_t dlsch_ue_select_tbl_in_use;
extern uint8_t nfapi_mode;
extern PARALLEL_CONF_t get_thread_parallel_conf(void);
extern WORKER_CONF_t get_thread_worker_conf(void);
extern void phy_init_RU(RU_t*);
extern void phy_free_RU(RU_t*);
void init_RU(char*);
void stop_RU(int nb_ru);
void do_ru_sync(RU_t *ru);
@@ -705,6 +707,7 @@ static void* emulatedRF_thread(void* param) {
RU_proc_t *proc = (RU_proc_t *) param;
int microsec = 500; // length of time to sleep, in miliseconds
struct timespec req = {0};
int numerology = get_softmodem_params()->numerology;
req.tv_sec = 0;
req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2;
cpu_set_t cpuset;
@@ -749,7 +752,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
old_ts = proc->timestamp_rx;
if(emulate_rf){
if(get_softmodem_params()->emulate_rf){
wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
rxs = fp->samples_per_tti;
@@ -767,9 +770,9 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
proc->timestamp_rx = ts-ru->ts_offset;
// AssertFatal(rxs == fp->samples_per_tti,
// "rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
// "rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs);
if(rxs != fp->samples_per_tti){
LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs);
late_control=STATE_BURST_TERMINATE;
}
@@ -962,7 +965,7 @@ void tx_rf(RU_t *ru) {
/*!
* \brief The Asynchronous RX/TX FH thread of RAU/RCC/eNB/RRU.
* This handles the RX FH for an asynchronous RRU/UE
* \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \param param is a \ref L1_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
static void* ru_thread_asynch_rxtx( void* param ) {
@@ -1255,12 +1258,12 @@ void do_ru_synch(RU_t *ru) {
void wakeup_eNBs(RU_t *ru) {
void wakeup_L1s(RU_t *ru) {
int i;
PHY_VARS_eNB **eNB_list = ru->eNB_list;
LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top);
LOG_D(PHY,"wakeup_L1s (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top);
if (ru->num_eNB==1 && ru->eNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
@@ -1279,7 +1282,6 @@ void wakeup_eNBs(RU_t *ru) {
for (i=0;i<ru->num_eNB;i++)
{
LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx);
eNB_list[i]->proc.ru_proc = &ru->proc;
if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0)
{
LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx);
@@ -1358,7 +1360,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
openair0_config_t *cfg = &ru->openair0_cfg;
//printf("////////////////numerology in config = %d\n",numerology);
int numerology = get_softmodem_params()->numerology;
if(fp->N_RB_DL == 100) {
if(numerology == 0){
if (fp->threequarter_fs) {
@@ -1417,7 +1419,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
cfg->num_rb_dl=fp->N_RB_DL;
cfg->tx_num_channels=ru->nb_tx;
cfg->rx_num_channels=ru->nb_rx;
cfg->clock_source=clock_source;
cfg->clock_source=get_softmodem_params()->clock_source;
for (i=0; i<ru->nb_tx; i++) {
@@ -1535,8 +1537,12 @@ volatile int16_t phy_tx_end;
#endif
static void* ru_thread_tx( void* param ) {
RU_t *ru = (RU_t*)param;
RU_proc_t *proc = &ru->proc;
RU_t *ru = (RU_t*)param;
RU_proc_t *proc = &ru->proc;
PHY_VARS_eNB *eNB;
L1_proc_t *eNB_proc;
L1_rxtx_proc_t *L1_proc;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
@@ -1557,8 +1563,8 @@ static void* ru_thread_tx( void* param ) {
if (oai_exit) break;
LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n");
// wait until eNBs are finished subframe RX n and TX n+4
LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n");
// wait until eNBs are finished subframe RX n and TX n+4
wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
if (oai_exit) break;
@@ -1567,22 +1573,44 @@ static void* ru_thread_tx( void* param ) {
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
if(!emulate_rf){
if(!(get_softmodem_params()->emulate_rf)){
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
if (ru->fh_north_out) ru->fh_north_out(ru);
}
release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
pthread_mutex_lock( &proc->mutex_eNBs );
proc->ru_tx_ready++;
// the thread can now be woken up
if (pthread_cond_signal(&proc->cond_eNBs) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
for(int i = 0; i<ru->num_eNB; i++)
{
eNB = ru->eNB_list[i];
eNB_proc = &eNB->proc;
L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &eNB_proc->L1_proc_tx : &eNB_proc->L1_proc;
pthread_mutex_lock(&eNB_proc->mutex_RU_tx);
for (int j=0;j<eNB->num_RU;j++) {
if (ru == eNB->RU_list[j]) {
if ((eNB_proc->RU_mask_tx&(1<<j)) > 0)
LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n",
eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx);
eNB_proc->RU_mask_tx |= (1<<j);
}
}
if (eNB_proc->RU_mask_tx != (1<<eNB->num_RU)-1) { // not all RUs have provided their information so return
pthread_mutex_unlock(&eNB_proc->mutex_RU_tx);
}
else { // all RUs TX are finished so send the ready signal to eNB processing
eNB_proc->RU_mask_tx = 0;
pthread_mutex_unlock(&eNB_proc->mutex_RU_tx);
pthread_mutex_lock( &L1_proc->mutex_RUs);
L1_proc->instance_cnt_RUs = 0;
// the thread can now be woken up
if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
}
pthread_mutex_unlock( &L1_proc->mutex_RUs );
}
}
pthread_mutex_unlock( &proc->mutex_eNBs );
}
release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
return 0;
@@ -1619,7 +1647,7 @@ static void* ru_thread( void* param ) {
LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]);
if(emulate_rf){
if(get_softmodem_params()->emulate_rf){
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(&ru->frame_parms,1);
phy_init_RU(ru);
@@ -1665,7 +1693,7 @@ static void* ru_thread( void* param ) {
wait_sync("ru_thread");
if(!emulate_rf){
if(!(get_softmodem_params()->emulate_rf)){
// Start RF device if any
if (ru->start_rf) {
if (ru->start_rf(ru) != 0)
@@ -1791,7 +1819,7 @@ static void* ru_thread( void* param ) {
#endif
// wakeup all eNB processes waiting for this RU
if (ru->num_eNB>0) wakeup_eNBs(ru);
if (ru->num_eNB>0) wakeup_L1s(ru);
#ifndef PHY_TX_THREAD
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0){
@@ -1800,7 +1828,7 @@ static void* ru_thread( void* param ) {
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
if(!emulate_rf){
if(!(get_softmodem_params()->emulate_rf)){
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
@@ -1823,7 +1851,7 @@ static void* ru_thread( void* param ) {
printf( "Exiting ru_thread \n");
if (!emulate_rf){
if (!(get_softmodem_params()->emulate_rf)){
if (ru->stop_rf != NULL) {
if (ru->stop_rf(ru) != 0)
LOG_E(HW,"Could not stop the RF device\n");
@@ -1974,7 +2002,7 @@ void* pre_scd_thread( void* param ){
#ifdef PHY_TX_THREAD
/*!
* \brief The phy tx thread of eNB.
* \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \param param is a \ref L1_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
static void* eNB_thread_phy_tx( void* param ) {
@@ -1985,7 +2013,7 @@ static void* eNB_thread_phy_tx( void* param ) {
RU_proc_t *proc = &ru->proc;
PHY_VARS_eNB **eNB_list = ru->eNB_list;
eNB_rxtx_proc_t proc_rxtx;
L1_rxtx_proc_t L1_proc;
// set default return value
eNB_thread_phy_tx_status = 0;
@@ -2002,9 +2030,9 @@ static void* eNB_thread_phy_tx( void* param ) {
LOG_D(PHY,"Running eNB phy tx procedures\n");
if(ru->num_eNB == 1){
proc_rxtx.subframe_tx = proc->subframe_phy_tx;
proc_rxtx.frame_tx = proc->frame_phy_tx;
phy_procedures_eNB_TX(eNB_list[0], &proc_rxtx, 1);
L1_proc.subframe_tx = proc->subframe_phy_tx;
L1_proc.frame_tx = proc->frame_phy_tx;
phy_procedures_eNB_TX(eNB_list[0], &L1_proc, 1);
phy_tx_txdataF_end = 1;
if(pthread_mutex_lock(&ru->proc.mutex_rf_tx) != 0){
LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for rf tx thread (IC %d)\n", ru->proc.instance_cnt_rf_tx);
@@ -2136,8 +2164,6 @@ void init_RU_proc(RU_t *ru) {
proc->frame_offset = 0;
proc->num_slaves = 0;
proc->frame_tx_unwrap = 0;
proc->ru_rx_ready = 0;
proc->ru_tx_ready = 0;
for (i=0;i<10;i++) proc->symbol_mask[i]=0;
@@ -2209,7 +2235,7 @@ void init_RU_proc(RU_t *ru) {
pthread_create( &proc->pthread_rf_tx, NULL, rf_tx, (void*)ru );
#endif
if(emulate_rf)
if(get_softmodem_params()->emulate_rf)
pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc );
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)
@@ -2312,7 +2338,6 @@ void kill_RU_proc(RU_t *ru)
pthread_mutex_unlock(&proc->mutex_synch);
pthread_mutex_lock(&proc->mutex_eNBs);
proc->ru_tx_ready = 0;
proc->instance_cnt_eNBs = 1;
// cond_eNBs is used by both ru_thread and ru_thread_tx, so we need to send
// a broadcast to wake up both threads
+105
View File
@@ -0,0 +1,105 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file lte-softmodem-common.c
* \brief Top-level threads for eNodeB
* \author Nokia BellLabs France, francois Taburet
* \date 2012
* \version 0.1
* \company Eurecom
* \email: francois.taburet@nokia-bell-labs.com
* \note
* \warning
*/
#include "lte-softmodem.h"
#include "UTIL/OPT/opt.h"
#include "common/config/config_userapi.h"
#include "common/utils/load_module_shlib.h"
static softmodem_params_t softmodem_params;
char *parallel_config=NULL;
char *worker_config=NULL;
uint64_t get_softmodem_optmask(void) {
return softmodem_params.optmask;
}
uint64_t set_softmodem_optmask(uint64_t bitmask) {
softmodem_params.optmask = softmodem_params.optmask | bitmask;
return softmodem_params.optmask;
}
softmodem_params_t* get_softmodem_params(void) {
return &softmodem_params;
}
void get_common_options(void)
{
uint32_t online_log_messages;
uint32_t glog_level ;
uint32_t start_telnetsrv;
uint32_t noS1;
uint32_t nokrnmod;
uint32_t nonbiot;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
if (strlen(in_path) > 0) {
opt_type = OPT_PCAP;
opt_enabled=1;
printf("Enabling OPT for PCAP with the following file %s \n",in_path);
}
if (strlen(in_ip) > 0) {
opt_enabled=1;
opt_type = OPT_WIRESHARK;
printf("Enabling OPT for wireshark for local interface");
}
config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) {
set_glog_onlinelog(online_log_messages);
}
if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
set_glog(glog_level);
}
if (start_telnetsrv) {
load_module_shlib("telnetsrv",NULL,0,NULL);
}
if (noS1) {
set_softmodem_optmask(SOFTMODEM_NOS1_BIT);
}
if (nokrnmod) {
set_softmodem_optmask(SOFTMODEM_NOKRNMOD_BIT);
}
if (nonbiot) {
set_softmodem_optmask(SOFTMODEM_NONBIOT_BIT);
}
if(parallel_config != NULL) set_parallel_conf(parallel_config);
if(worker_config != NULL) set_worker_conf(worker_config);
}
File diff suppressed because it is too large Load Diff
+104 -53
View File
@@ -95,7 +95,8 @@
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
#define CONFIG_HLP_NOS1 "Disable s1 interface\n"
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n"
@@ -130,30 +131,49 @@
#define CMDLINE_DUMPMEMORY_IDX 7
/*------------------------------------------------------------------------------------------------------------------------------------------*/
#define START_MSC softmodem_params.start_msc
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters specific to UE */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters specific to UE */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_UEPARAMS_DESC { \
{"siml1", CONFIG_HLP_SIML1, PARAMFLAG_BOOL, iptr:&simL1flag, defintval:0, TYPE_INT, 0}, \
{"U", CONFIG_HLP_NUMUE, 0, u8ptr:&NB_UE_INST, defuintval:1, TYPE_UINT, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:130, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:23, TYPE_INT, 0}, \
{"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \
{"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \
{"num-ues", NULL, 0, u16ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT16, 0}, \
{"nums_ue_thread" , NULL, 0, u16ptr:&(NB_THREAD_INST), defuintval:1, TYPE_UINT16, 0}, \
{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0} \
}
{"siml1", CONFIG_HLP_SIML1, PARAMFLAG_BOOL, iptr:&simL1flag, defintval:0, TYPE_INT, 0}, \
{"U", CONFIG_HLP_NUMUE, 0, u8ptr:&NB_UE_INST, defuintval:1, TYPE_UINT, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:130, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:23, TYPE_INT, 0}, \
{"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \
{"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \
{"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \
{"nums_ue_thread", NULL, 0, u16ptr:&(NB_THREAD_INST), defuintval:1, TYPE_UINT16, 0}, \
{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200",TYPE_STRING, 0}, \
{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0}, \
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
{"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \
{"s" , CONFIG_HLP_SNR, 0, iptr:&snr_dB, defintval:25, TYPE_INT, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0} \
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters specific to UE threads */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_UETHREADSPARAMS_DESC { \
{"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \
{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \
{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \
{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \
}
#define DEFAULT_DLF 2680000000
@@ -161,40 +181,38 @@
/* command line parameters common to eNodeB and UE */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define RF_CONFIG_FILE softmodem_params.rf_config_file
#define PHY_TEST softmodem_params.phy_test
#define WAIT_FOR_SYNC softmodem_params.wait_for_sync
#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag
#define CHAIN_OFFSET softmodem_params.chain_offset
#define DO_FORMS softmodem_params.do_forms
#define NUMEROLOGY softmodem_params.numerology
#define EMULATE_RF softmodem_params.emulate_rf
#define CLOCK_SOURCE softmodem_params.clock_source
#define USIM_TEST softmodem_params.usim_test
#define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)}, \
{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
{"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:0, TYPE_INT, 0}, \
{"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \
{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \
{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \
{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&EMULATE_RF, defintval:0, TYPE_INT, 0}, \
{"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \
{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&DO_FORMS, defintval:0, TYPE_INT8, 0}, \
{"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \
{"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"s" , CONFIG_HLP_SNR, 0, iptr:&snr_dB, defintval:25, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
{"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
}
#define CONFIG_HLP_FLOG "Enable online log \n"
@@ -205,11 +223,12 @@
/* command line parameters for LOG utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define START_MSC softmodem_params.start_msc
#define CMDLINE_LOGPARAMS_DESC { \
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
{"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:start_msc, defintval:0, TYPE_UINT, 0}, \
{"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \
}
#define CMDLINE_ONLINELOG_IDX 0
#define CMDLINE_GLOGLEVEL_IDX 1
@@ -218,6 +237,38 @@
/***************************************************************************************************************************************/
/* */
#include "threads_t.h"
#define SOFTMODEM_NOS1_BIT (1<<0)
#define SOFTMODEM_NOKRNMOD_BIT (1<<1)
#define SOFTMODEM_NONBIOT_BIT (1<<2)
typedef struct {
uint64_t optmask;
THREAD_STRUCT thread_struct;
char rf_config_file[1024];
int phy_test;
uint8_t usim_test;
int emulate_rf;
int wait_for_sync; //eNodeB only
int single_thread_flag; //eNodeB only
int chain_offset;
uint32_t do_forms;
int numerology;
unsigned int start_msc;
int nonbiotflag;
uint32_t clock_source;
int hw_timing_advance;
} softmodem_params_t;
#define SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT)
#define SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT)
#define SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT)
extern uint64_t get_softmodem_optmask(void);
extern uint64_t set_softmodem_optmask(uint64_t bitmask);
extern void get_common_options(void);
extern softmodem_params_t* get_softmodem_params(void);
uint64_t get_pdcp_optmask(void);
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
@@ -245,8 +296,8 @@ extern volatile int start_eNB;
extern volatile int start_UE;
#endif
#include "threads_t.h"
extern threads_t threads;
// In lte-enb.c
extern void init_eNB(int single_thread_flag,int wait_for_sync);
@@ -254,7 +305,7 @@ extern void stop_eNB(int);
extern void kill_eNB_proc(int inst);
// In lte-ru.c
extern void init_RU(const char*);
extern void init_RU(char*);
extern void stop_ru(RU_t *ru);
extern void init_ru_vnf(void);
extern void init_RU_proc(RU_t *ru);
@@ -272,7 +323,7 @@ extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, c
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_td_thread(PHY_VARS_eNB *);
extern void init_te_thread(PHY_VARS_eNB *);
extern void kill_td_thread(PHY_VARS_eNB *);
+13 -4
View File
@@ -58,8 +58,8 @@
#include "UTIL/MATH/oml.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "lte-softmodem.h"
#include "common/config/config_userapi.h"
#include "T.h"
extern double cpuf;
@@ -160,12 +160,21 @@ static const eutra_band_t eutra_bands[] = {
};
threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
pthread_t main_ue_thread;
pthread_attr_t attr_UE_thread;
struct sched_param sched_param_UE_thread;
void get_uethreads_params(void) {
paramdef_t cmdline_threadsparams[] =CMDLINE_UETHREADSPARAMS_DESC;
config_process_cmdline( cmdline_threadsparams,sizeof(cmdline_threadsparams)/sizeof(paramdef_t),NULL);
}
void phy_init_lte_ue_transport(PHY_VARS_UE *ue,int absraction_flag);
PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
@@ -181,7 +190,7 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
memcpy(&(ue->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS));
}
ue->hw_timing_advance=get_softmodem_params()->hw_timing_advance;
ue->Mod_id = UE_id;
ue->mac_enabled = 1;
File diff suppressed because it is too large Load Diff
-1
View File
@@ -62,7 +62,6 @@ sim_t sim;
void init_ru_devices(void);
void init_RU(const char*);
void *rfsim_top(void *n_frames);
void wait_RUs(void)