mirror of https://github.com/PentHertz/srsLTE.git
Merge branch 'next' of github.com:softwareradiosystems/srsLTE into next
This commit is contained in:
commit
4068ad0064
|
@ -122,7 +122,7 @@ public:
|
|||
}
|
||||
|
||||
void clear() { // remove all items
|
||||
myobj item;
|
||||
myobj *item = NULL;
|
||||
while (try_pop(item));
|
||||
}
|
||||
|
||||
|
|
|
@ -166,8 +166,13 @@ static inline void srslte_mat_2x2_mmse_csi_simd(simd_cf_t y0,
|
|||
simd_cf_t _noise_estimate;
|
||||
simd_f_t _norm = srslte_simd_f_set1(norm);
|
||||
|
||||
#if HAVE_NEON
|
||||
_noise_estimate.val[0] = srslte_simd_f_set1(noise_estimate);
|
||||
_noise_estimate.val[1] = srslte_simd_f_zero();
|
||||
#else /* HAVE_NEON */
|
||||
_noise_estimate.re = srslte_simd_f_set1(noise_estimate);
|
||||
_noise_estimate.im = srslte_simd_f_zero();
|
||||
#endif /* HAVE_NEON */
|
||||
|
||||
/* 1. A = H' x H + No*/
|
||||
simd_cf_t a00 =
|
||||
|
|
|
@ -139,7 +139,7 @@
|
|||
#define SRSLTE_SIMD_S_SIZE 8
|
||||
#define SRSLTE_SIMD_C16_SIZE 8
|
||||
|
||||
#else /* LV_HAVE_NEON */
|
||||
#else /* HAVE_NEON */
|
||||
#define SRSLTE_SIMD_F_SIZE 0
|
||||
#define SRSLTE_SIMD_CF_SIZE 0
|
||||
|
||||
|
@ -514,7 +514,7 @@ static inline simd_f_t srslte_simd_f_abs(simd_f_t a) {
|
|||
return _mm_andnot_ps(_mm_set1_ps(-0.0f), a);
|
||||
#else /* LV_HAVE_SSE */
|
||||
#ifdef HAVE_NEON
|
||||
return vqabsq_s32(a);
|
||||
return vabsq_f32(a);
|
||||
#endif /* HAVE_NEON */
|
||||
#endif /* LV_HAVE_SSE */
|
||||
#endif /* LV_HAVE_AVX2 */
|
||||
|
@ -990,13 +990,13 @@ static inline simd_cf_t srslte_simd_cf_rcp (simd_cf_t a) {
|
|||
|
||||
static inline simd_cf_t srslte_simd_cf_neg (simd_cf_t a) {
|
||||
simd_cf_t ret;
|
||||
#if LV_HAVE_NEON
|
||||
#if HAVE_NEON
|
||||
ret.val[0] = srslte_simd_f_neg(a.val[0]);
|
||||
ret.val[1] = srslte_simd_f_neg(a.val[1]);
|
||||
#else /* LV_HAVE_NEON */
|
||||
#else /* HAVE_NEON */
|
||||
ret.re = srslte_simd_f_neg(a.re);
|
||||
ret.im = srslte_simd_f_neg(a.im);
|
||||
#endif /* LV_HAVE_NEON */
|
||||
#endif /* HAVE_NEON */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1007,37 +1007,37 @@ static inline simd_cf_t srslte_simd_cf_neg_mask (simd_cf_t a, simd_f_t mask) {
|
|||
mask = _mm256_permutevar8x32_ps(mask, _mm256_setr_epi32(0,4,1,5,2,6,3,7));
|
||||
#endif /* LV_HAVE_AVX2 */
|
||||
#endif /* LV_HAVE_AVX512 */
|
||||
#if LV_HAVE_NEON
|
||||
#if HAVE_NEON
|
||||
ret.val[0] = srslte_simd_f_neg_mask(a.val[0], mask);
|
||||
ret.val[1] = srslte_simd_f_neg_mask(a.val[1], mask);
|
||||
#else /* LV_HAVE_NEON */
|
||||
#else /* HAVE_NEON */
|
||||
ret.re = srslte_simd_f_neg_mask(a.re, mask);
|
||||
ret.im = srslte_simd_f_neg_mask(a.im, mask);
|
||||
#endif /* LV_HAVE_NEON */
|
||||
#endif /* HAVE_NEON */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_conj (simd_cf_t a) {
|
||||
simd_cf_t ret;
|
||||
#if LV_HAVE_NEON
|
||||
#if HAVE_NEON
|
||||
ret.val[0] = a.val[0];
|
||||
ret.val[1] = srslte_simd_f_neg(a.val[1]);
|
||||
#else /* LV_HAVE_NEON */
|
||||
#else /* HAVE_NEON */
|
||||
ret.re = a.re;
|
||||
ret.im = srslte_simd_f_neg(a.im);
|
||||
#endif /* LV_HAVE_NEON */
|
||||
#endif /* HAVE_NEON */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline simd_cf_t srslte_simd_cf_mulj (simd_cf_t a) {
|
||||
simd_cf_t ret;
|
||||
#if LV_HAVE_NEON
|
||||
#if HAVE_NEON
|
||||
ret.val[0] = srslte_simd_f_neg(a.val[1]);
|
||||
ret.val[1] = a.val[0];
|
||||
#else /* LV_HAVE_NEON */
|
||||
#else /* HAVE_NEON */
|
||||
ret.re = srslte_simd_f_neg(a.im);
|
||||
ret.im = a.re;
|
||||
#endif /* LV_HAVE_NEON */
|
||||
#endif /* HAVE_NEON */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,13 +27,15 @@
|
|||
#ifndef SRSLTE_RLC_METRICS_H
|
||||
#define SRSLTE_RLC_METRICS_H
|
||||
|
||||
#include "srslte/common/common.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
struct rlc_metrics_t
|
||||
{
|
||||
float dl_tput_mbps;
|
||||
float ul_tput_mbps;
|
||||
float dl_tput_mbps[SRSLTE_N_RADIO_BEARERS];
|
||||
float ul_tput_mbps[SRSLTE_N_RADIO_BEARERS];
|
||||
float dl_tput_mrb_mbps[SRSLTE_N_MCH_LCIDS];
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
|
|
@ -404,16 +404,16 @@ double rf_blade_set_tx_freq(void *h, double freq)
|
|||
|
||||
void rf_blade_set_tx_cal(void *h, srslte_rf_cal_t *cal) {
|
||||
rf_blade_handler_t *handler = (rf_blade_handler_t*) h;
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_PHASE, cal->dc_gain);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_GAIN, cal->dc_phase);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_PHASE, cal->dc_phase);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_GAIN, cal->dc_gain);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_I, cal->iq_i);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_Q, cal->iq_q);
|
||||
}
|
||||
|
||||
void rf_blade_set_rx_cal(void *h, srslte_rf_cal_t *cal) {
|
||||
rf_blade_handler_t *handler = (rf_blade_handler_t*) h;
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_PHASE, cal->dc_gain);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_GAIN, cal->dc_phase);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_PHASE, cal->dc_phase);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_GAIN, cal->dc_gain);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_LMS_DCOFF_I, cal->iq_i);
|
||||
bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_LMS_DCOFF_Q, cal->iq_q);
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ int rf_soapy_start_rx_stream(void *h, bool now)
|
|||
{
|
||||
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
|
||||
if(handler->rx_stream_active == false){
|
||||
if(SoapySDRDevice_activateStream(handler->device, handler->rxStream, 0, 0, 0) != 0)
|
||||
if(SoapySDRDevice_activateStream(handler->device, handler->rxStream, SOAPY_SDR_HAS_TIME | SOAPY_SDR_END_BURST, 0, 0) != 0)
|
||||
return SRSLTE_ERROR;
|
||||
handler->rx_stream_active = true;
|
||||
}
|
||||
|
@ -339,9 +339,19 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
|
|||
rf_soapy_set_rx_srate(handler, 1.92e6);
|
||||
rf_soapy_set_tx_srate(handler, 1.92e6);
|
||||
|
||||
if(SoapySDRDevice_getNumChannels(handler->device, SOAPY_SDR_RX) > 0){
|
||||
size_t channels = SoapySDRDevice_getNumChannels(handler->device, SOAPY_SDR_RX);
|
||||
|
||||
if((channels > 0) && (nof_rx_antennas > 0)){
|
||||
printf("Setting up RX stream\n");
|
||||
if(SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) {
|
||||
size_t numChannels = channels;
|
||||
if (channels > nof_rx_antennas) {
|
||||
numChannels = nof_rx_antennas;
|
||||
}
|
||||
size_t rx_channels[numChannels];
|
||||
for(int i = 0 ; i < numChannels ; i++) {
|
||||
rx_channels[i] = i;
|
||||
}
|
||||
if(SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, rx_channels, numChannels, NULL) != 0) {
|
||||
printf("Rx setupStream fail: %s\n", SoapySDRDevice_lastError());
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
@ -439,9 +449,11 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
|
|||
|
||||
#if HAVE_ASYNC_THREAD
|
||||
bool start_async_thread = true;
|
||||
if (strstr(args, "silent")) {
|
||||
REMOVE_SUBSTRING_WITHCOMAS(args, "silent");
|
||||
start_async_thread = false;
|
||||
if (args) {
|
||||
if (strstr(args, "silent")) {
|
||||
REMOVE_SUBSTRING_WITHCOMAS(args, "silent");
|
||||
start_async_thread = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -839,7 +851,7 @@ int rf_soapy_send_timed_multi(void *h,
|
|||
|
||||
// Convert initial tx time
|
||||
if (has_time_spec) {
|
||||
timeNs = secs * 1000000000;
|
||||
timeNs = (long long)secs * 1000000000;
|
||||
timeNs = timeNs + (frac_secs * 1000000000);
|
||||
}
|
||||
|
||||
|
|
|
@ -788,17 +788,17 @@ int rf_uhd_recv_with_time_multi(void *h,
|
|||
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
|
||||
uhd_rx_metadata_handle *md = &handler->rx_md_first;
|
||||
size_t rxd_samples = 0;
|
||||
size_t rxd_samples_total = 0;
|
||||
int trials = 0;
|
||||
if (blocking) {
|
||||
int n = 0;
|
||||
while (n < nsamples && trials < 100) {
|
||||
while (rxd_samples_total < nsamples && trials < 100) {
|
||||
void *buffs_ptr[4];
|
||||
for (int i=0;i<handler->nof_rx_channels;i++) {
|
||||
cf_t *data_c = (cf_t*) data[i];
|
||||
buffs_ptr[i] = &data_c[n];
|
||||
buffs_ptr[i] = &data_c[rxd_samples_total];
|
||||
}
|
||||
|
||||
size_t num_samps_left = nsamples - n;
|
||||
size_t num_samps_left = nsamples - rxd_samples_total;
|
||||
size_t num_rx_samples = (num_samps_left > handler->rx_nof_samples) ? handler->rx_nof_samples : num_samps_left;
|
||||
|
||||
rxd_samples = 0;
|
||||
|
@ -814,7 +814,7 @@ int rf_uhd_recv_with_time_multi(void *h,
|
|||
uhd_rx_metadata_error_code(*md, &error_code);
|
||||
|
||||
md = &handler->rx_md;
|
||||
n += rxd_samples;
|
||||
rxd_samples_total += rxd_samples;
|
||||
trials++;
|
||||
|
||||
if (error_code == UHD_RX_METADATA_ERROR_CODE_OVERFLOW) {
|
||||
|
@ -830,6 +830,7 @@ int rf_uhd_recv_with_time_multi(void *h,
|
|||
}
|
||||
} else {
|
||||
uhd_error error = uhd_rx_streamer_recv(handler->rx_stream, data, nsamples, md, 0.0, false, &rxd_samples);
|
||||
rxd_samples_total = rxd_samples;
|
||||
if (error) {
|
||||
fprintf(stderr, "Error receiving from UHD: %d\n", error);
|
||||
log_rx_error(handler);
|
||||
|
@ -839,7 +840,7 @@ int rf_uhd_recv_with_time_multi(void *h,
|
|||
if (secs && frac_secs) {
|
||||
uhd_rx_metadata_time_spec(handler->rx_md_first, secs, frac_secs);
|
||||
}
|
||||
return nsamples;
|
||||
return rxd_samples_total;
|
||||
}
|
||||
|
||||
int rf_uhd_send_timed(void *h,
|
||||
|
|
|
@ -117,13 +117,10 @@ void rlc::get_metrics(rlc_metrics_t &m)
|
|||
gettimeofday(&metrics_time[2], NULL);
|
||||
get_time_interval(metrics_time);
|
||||
double secs = (double)metrics_time[0].tv_sec + metrics_time[0].tv_usec*1e-6;
|
||||
|
||||
m.dl_tput_mbps = 0;
|
||||
m.ul_tput_mbps = 0;
|
||||
|
||||
for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) {
|
||||
m.dl_tput_mbps += (it->second->get_num_rx_bytes()*8/(double)1e6)/secs;
|
||||
m.ul_tput_mbps += (it->second->get_num_tx_bytes()*8/(double)1e6)/secs;
|
||||
m.dl_tput_mbps[it->first] = (it->second->get_num_rx_bytes()*8/static_cast<double>(1e6))/secs;
|
||||
m.ul_tput_mbps[it->first] = (it->second->get_num_tx_bytes()*8/static_cast<double>(1e6))/secs;
|
||||
rlc_log->info("LCID=%d, RX throughput: %4.6f Mbps. TX throughput: %4.6f Mbps.\n",
|
||||
it->first,
|
||||
(it->second->get_num_rx_bytes()*8/(double)1e6)/secs,
|
||||
|
@ -132,10 +129,10 @@ void rlc::get_metrics(rlc_metrics_t &m)
|
|||
|
||||
// Add multicast metrics
|
||||
for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) {
|
||||
m.dl_tput_mbps += (it->second->get_num_rx_bytes()*8/(double)1e6)/secs;
|
||||
m.dl_tput_mbps[it->first] = (it->second->get_num_rx_bytes()*8/static_cast<double>(1e6))/secs;
|
||||
rlc_log->info("MCH_LCID=%d, RX throughput: %4.6f Mbps\n",
|
||||
it->first,
|
||||
(it->second->get_num_rx_bytes()*8/(double)1e6)/secs);
|
||||
(it->second->get_num_rx_bytes()*8/static_cast<double>(1e6))/secs);
|
||||
}
|
||||
|
||||
memcpy(&metrics_time[1], &metrics_time[2], sizeof(struct timeval));
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
#include "srslte/upper/rlc_um.h"
|
||||
#include <sstream>
|
||||
#include <srslte/upper/rlc_interface.h>
|
||||
#include <srslte/upper/rlc_common.h>
|
||||
|
||||
#define RX_MOD_BASE(x) (x-vr_uh-cfg.rx_window_size)%cfg.rx_mod
|
||||
#define RX_MOD_BASE(x) (((x)-vr_uh-cfg.rx_window_size)%cfg.rx_mod)
|
||||
|
||||
namespace srslte {
|
||||
|
||||
|
@ -95,6 +96,11 @@ bool rlc_um::rlc_um_rx::configure(srslte_rlc_config_t cnfg_, std::string rb_name
|
|||
return false;
|
||||
}
|
||||
|
||||
// set reordering timer
|
||||
if (reordering_timer != NULL) {
|
||||
reordering_timer->set(this, cfg.t_reordering);
|
||||
}
|
||||
|
||||
rb_name = rb_name_;
|
||||
|
||||
rx_enabled = true;
|
||||
|
@ -464,12 +470,11 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
|
|||
vt_us = (vt_us + 1)%cfg.tx_mod;
|
||||
|
||||
// Add header and TX
|
||||
log->debug("%s packing PDU with length %d\n", get_rb_name(), pdu->N_bytes);
|
||||
rlc_um_write_data_pdu_header(&header, pdu);
|
||||
memcpy(payload, pdu->msg, pdu->N_bytes);
|
||||
uint32_t ret = pdu->N_bytes;
|
||||
|
||||
log->debug("%s returning length %d\n", get_rb_name(), pdu->N_bytes);
|
||||
log->info("%s Transmitting PDU SN=%d (%d B)\n", get_rb_name(), header.sn, pdu->N_bytes);
|
||||
pool->deallocate(pdu);
|
||||
|
||||
debug_state();
|
||||
|
@ -545,9 +550,7 @@ void rlc_um::rlc_um_rx::reestablish()
|
|||
void rlc_um::rlc_um_rx::stop()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
if(reordering_timer) {
|
||||
reordering_timer->stop();
|
||||
}
|
||||
|
||||
vr_ur = 0;
|
||||
vr_ux = 0;
|
||||
vr_uh = 0;
|
||||
|
@ -559,7 +562,8 @@ void rlc_um::rlc_um_rx::stop()
|
|||
rx_sdu = NULL;
|
||||
}
|
||||
|
||||
if (mac_timers && reordering_timer) {
|
||||
if (mac_timers != NULL && reordering_timer != NULL) {
|
||||
reordering_timer->stop();
|
||||
mac_timers->timer_release_id(reordering_timer_id);
|
||||
reordering_timer = NULL;
|
||||
}
|
||||
|
@ -642,7 +646,7 @@ void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
|
|||
}
|
||||
if(!reordering_timer->is_running()) {
|
||||
if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) {
|
||||
reordering_timer->set(this, cfg.t_reordering);
|
||||
reordering_timer->reset();
|
||||
reordering_timer->run();
|
||||
vr_ux = vr_uh;
|
||||
}
|
||||
|
@ -714,7 +718,7 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
|
|||
|
||||
// Handle last segment
|
||||
if (rx_sdu->N_bytes > 0 || rlc_um_start_aligned(rx_window[vr_ur].header.fi)) {
|
||||
log->debug("Writing last segment in SDU buffer. Lower edge vr_ur=%d, Buffer size=%d, segment size=%d\n",
|
||||
log->info("Writing last segment in SDU buffer. Lower edge vr_ur=%d, Buffer size=%d, segment size=%d\n",
|
||||
vr_ur, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes);
|
||||
|
||||
memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes);
|
||||
|
@ -753,18 +757,36 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
|
|||
|
||||
// Now update vr_ur until we reach an SN we haven't yet received
|
||||
while(rx_window.end() != rx_window.find(vr_ur)) {
|
||||
log->debug("Reassemble loop for vr_ur=%d\n", vr_ur);
|
||||
if ((vr_ur_in_rx_sdu+1)%cfg.rx_mod != vr_ur) {
|
||||
log->warning("PDU SN=%d lost, dropping remainder of %d\n", vr_ur_in_rx_sdu+1, vr_ur);
|
||||
rx_sdu->reset();
|
||||
}
|
||||
|
||||
// Handle any SDU segments
|
||||
for(uint32_t i=0; i<rx_window[vr_ur].header.N_li; i++) {
|
||||
int len = rx_window[vr_ur].header.li[i];
|
||||
|
||||
// Check if the first part of the PDU is a middle or end segment
|
||||
if (rx_sdu->N_bytes == 0 && i == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) {
|
||||
log->warning("Dropping PDU %d due to lost start segment\n", vr_ur);
|
||||
log->warning_hex(rx_window[vr_ur].buf->msg, len, "Dropping first part of SN %d due to lost start segment\n", vr_ur);
|
||||
|
||||
// Advance data pointers and continue with next segment
|
||||
rx_window[vr_ur].buf->msg += len;
|
||||
rx_window[vr_ur].buf->N_bytes -= len;
|
||||
rx_sdu->reset();
|
||||
break;
|
||||
|
||||
// beginning of next SDU?
|
||||
if (rx_window[vr_ur].header.fi == RLC_FI_FIELD_NOT_START_OR_END_ALIGNED) {
|
||||
len = rx_window[vr_ur].buf->N_bytes;
|
||||
log->info_hex(rx_window[vr_ur].buf->msg, len, "Copying first %d bytes of new SDU\n", len);
|
||||
memcpy(rx_sdu->msg, rx_window[vr_ur].buf->msg, len);
|
||||
rx_sdu->N_bytes = len;
|
||||
rx_window[vr_ur].buf->msg += len;
|
||||
rx_window[vr_ur].buf->N_bytes -= len;
|
||||
log->info("Updating vr_ur_in_rx_sdu. old=%d, new=%d\n", vr_ur_in_rx_sdu, vr_ur);
|
||||
vr_ur_in_rx_sdu = vr_ur;
|
||||
goto clean_up_rx_window;
|
||||
}
|
||||
}
|
||||
|
||||
// Check available space in SDU
|
||||
|
@ -774,7 +796,7 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
|
|||
goto clean_up_rx_window;
|
||||
}
|
||||
|
||||
log->debug("Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d\n",
|
||||
log->info_hex(rx_window[vr_ur].buf->msg, len, "Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d\n",
|
||||
len, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur_in_rx_sdu, vr_ur, cfg.rx_mod, (vr_ur_in_rx_sdu+1)%cfg.rx_mod);
|
||||
memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, len);
|
||||
rx_sdu->N_bytes += len;
|
||||
|
@ -811,11 +833,10 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
|
|||
rx_window[vr_ur].buf->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BYTES &&
|
||||
rx_window[vr_ur].buf->N_bytes + rx_sdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BYTES)
|
||||
{
|
||||
|
||||
log->info_hex(rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes, "Writing last segment in SDU buffer. Updating vr_ur=%d, Buffer size=%d, segment size=%d\n",
|
||||
vr_ur, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes);
|
||||
memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes);
|
||||
rx_sdu->N_bytes += rx_window[vr_ur].buf->N_bytes;
|
||||
log->debug("Writing last segment in SDU buffer. Updating vr_ur=%d, Buffer size=%d, segment size=%d\n",
|
||||
vr_ur, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes);
|
||||
} else {
|
||||
log->error("Out of bounds while reassembling SDU buffer in UM: sdu_len=%d, window_buffer_len=%d, vr_ur=%d\n",
|
||||
rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur);
|
||||
|
@ -842,8 +863,7 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
|
|||
pdu_lost = false;
|
||||
}
|
||||
|
||||
clean_up_rx_window:
|
||||
|
||||
clean_up_rx_window:
|
||||
// Clean up rx_window
|
||||
pool->deallocate(rx_window[vr_ur].buf);
|
||||
rx_window.erase(vr_ur);
|
||||
|
@ -853,16 +873,15 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
|
|||
}
|
||||
|
||||
// Only called when lock is hold
|
||||
// 36.322 Section 5.1.2.2.1
|
||||
bool rlc_um::rlc_um_rx::inside_reordering_window(uint16_t sn)
|
||||
{
|
||||
if(cfg.rx_window_size == 0) {
|
||||
if (cfg.rx_window_size == 0 || rx_window.empty()) {
|
||||
return true;
|
||||
}
|
||||
if(RX_MOD_BASE(sn) >= RX_MOD_BASE(vr_uh-cfg.rx_window_size) &&
|
||||
RX_MOD_BASE(sn) < RX_MOD_BASE(vr_uh))
|
||||
{
|
||||
if (RX_MOD_BASE(vr_uh-cfg.rx_window_size) <= RX_MOD_BASE(sn) && RX_MOD_BASE(sn) < RX_MOD_BASE(vr_uh)) {
|
||||
return true;
|
||||
}else{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -888,8 +907,7 @@ void rlc_um::rlc_um_rx::reset_metrics()
|
|||
|
||||
void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id)
|
||||
{
|
||||
if(reordering_timer_id == timeout_id)
|
||||
{
|
||||
if (reordering_timer_id == timeout_id) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
||||
// 36.322 v10 Section 5.1.2.2.4
|
||||
|
@ -897,19 +915,19 @@ void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id)
|
|||
get_rb_name());
|
||||
|
||||
log->warning("Lost PDU SN: %d\n", vr_ur);
|
||||
|
||||
pdu_lost = true;
|
||||
rx_sdu->reset();
|
||||
while(RX_MOD_BASE(vr_ur) < RX_MOD_BASE(vr_ux))
|
||||
{
|
||||
|
||||
while(RX_MOD_BASE(vr_ur) < RX_MOD_BASE(vr_ux)) {
|
||||
vr_ur = (vr_ur + 1)%cfg.rx_mod;
|
||||
log->debug("Entering Reassemble from timeout id=%d\n", timeout_id);
|
||||
reassemble_rx_sdus();
|
||||
log->debug("Finished reassemble from timeout id=%d\n", timeout_id);
|
||||
}
|
||||
reordering_timer->stop();
|
||||
if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur))
|
||||
{
|
||||
reordering_timer->set(this, cfg.t_reordering);
|
||||
if (RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) {
|
||||
reordering_timer->reset();
|
||||
reordering_timer->run();
|
||||
vr_ux = vr_uh;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
#include <assert.h>
|
||||
#include <srslte/upper/rlc_interface.h>
|
||||
|
||||
#define SDU_SIZE 1500
|
||||
#define SDU_SIZE (1500)
|
||||
#define LOG_HEX_LIMIT (-1)
|
||||
|
||||
using namespace std;
|
||||
using namespace srsue;
|
||||
|
@ -55,6 +56,7 @@ typedef struct {
|
|||
bool single_tx;
|
||||
bool write_pcap;
|
||||
float opp_sdu_ratio;
|
||||
bool zero_seed;
|
||||
} stress_test_args_t;
|
||||
|
||||
void parse_args(stress_test_args_t *args, int argc, char *argv[]) {
|
||||
|
@ -78,7 +80,8 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) {
|
|||
("reestablish", bpo::value<bool>(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution")
|
||||
("loglevel", bpo::value<uint32_t>(&args->log_level)->default_value(srslte::LOG_LEVEL_DEBUG), "Log level (1=Error,2=Warning,3=Info,4=Debug)")
|
||||
("singletx", bpo::value<bool>(&args->single_tx)->default_value(false), "If set to true, only one node is generating data")
|
||||
("pcap", bpo::value<bool>(&args->write_pcap)->default_value(false), "Whether to write all RLC PDU to PCAP file");
|
||||
("pcap", bpo::value<bool>(&args->write_pcap)->default_value(false), "Whether to write all RLC PDU to PCAP file")
|
||||
("zeroseed", bpo::value<bool>(&args->zero_seed)->default_value(false), "Whether to initialize random seed to zero");
|
||||
|
||||
// these options are allowed on the command line
|
||||
bpo::options_description cmdline_options;
|
||||
|
@ -102,21 +105,25 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
class mac_reader
|
||||
:public thread
|
||||
class mac_dummy
|
||||
:public srslte::mac_interface_timers
|
||||
,public thread
|
||||
{
|
||||
public:
|
||||
mac_reader(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, float opp_sdu_ratio_, uint32_t pdu_tx_delay_usec_, rlc_pcap *pcap_, uint32_t lcid_, bool is_dl_ = true)
|
||||
mac_dummy(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, float opp_sdu_ratio_, int32_t pdu_tx_delay_usec_, uint32_t lcid_, rlc_pcap* pcap_ = NULL)
|
||||
:timers(8)
|
||||
,run_enable(true)
|
||||
,rlc1(rlc1_)
|
||||
,rlc2(rlc2_)
|
||||
,fail_rate(fail_rate_)
|
||||
,opp_sdu_ratio(opp_sdu_ratio_)
|
||||
,pdu_tx_delay_usec(pdu_tx_delay_usec_)
|
||||
,pcap(pcap_)
|
||||
,lcid(lcid_)
|
||||
,log("MAC ")
|
||||
{
|
||||
rlc1 = rlc1_;
|
||||
rlc2 = rlc2_;
|
||||
fail_rate = fail_rate_;
|
||||
opp_sdu_ratio = opp_sdu_ratio_;
|
||||
run_enable = true;
|
||||
pdu_tx_delay_usec = pdu_tx_delay_usec_;
|
||||
pcap = pcap_;
|
||||
is_dl = is_dl_;
|
||||
lcid = lcid_;
|
||||
log.set_level(srslte::LOG_LEVEL_ERROR);
|
||||
log.set_hex_limit(LOG_HEX_LIMIT);
|
||||
}
|
||||
|
||||
void stop()
|
||||
|
@ -125,85 +132,76 @@ public:
|
|||
wait_thread_finish();
|
||||
}
|
||||
|
||||
private:
|
||||
void run_thread()
|
||||
srslte::timers::timer* timer_get(uint32_t timer_id)
|
||||
{
|
||||
byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate("mac_reader::run_thread");
|
||||
return timers.get(timer_id);
|
||||
}
|
||||
uint32_t timer_get_unique_id() {
|
||||
return timers.get_unique_id();
|
||||
}
|
||||
void timer_release_id(uint32_t timer_id) {
|
||||
timers.release_id(timer_id);
|
||||
}
|
||||
void step_timer() {
|
||||
timers.step_all();
|
||||
}
|
||||
|
||||
private:
|
||||
void run_tti(rlc_interface_mac *tx_rlc, rlc_interface_mac *rx_rlc, bool is_dl)
|
||||
{
|
||||
byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate(__PRETTY_FUNCTION__);
|
||||
if (!pdu) {
|
||||
printf("Fatal Error: Could not allocate PDU in mac_reader::run_thread\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
while(run_enable) {
|
||||
// generate MAC opportunities of random size or with fixed ratio
|
||||
float r = opp_sdu_ratio ? opp_sdu_ratio : (float)rand()/RAND_MAX;
|
||||
int opp_size = r*SDU_SIZE;
|
||||
uint32_t buf_state = rlc1->get_buffer_state(lcid);
|
||||
if (buf_state) {
|
||||
int read = rlc1->read_pdu(lcid, pdu->msg, opp_size);
|
||||
if (pdu_tx_delay_usec) usleep(pdu_tx_delay_usec);
|
||||
if(((float)rand()/RAND_MAX > fail_rate) && read>0) {
|
||||
pdu->N_bytes = read;
|
||||
rlc2->write_pdu(lcid, pdu->msg, pdu->N_bytes);
|
||||
if (is_dl) {
|
||||
pcap->write_dl_am_ccch(pdu->msg, pdu->N_bytes);
|
||||
} else {
|
||||
pcap->write_ul_am_ccch(pdu->msg, pdu->N_bytes);
|
||||
}
|
||||
float r = opp_sdu_ratio ? opp_sdu_ratio : (float)rand()/RAND_MAX;
|
||||
int opp_size = r*SDU_SIZE;
|
||||
uint32_t buf_state = tx_rlc->get_buffer_state(lcid);
|
||||
if (buf_state) {
|
||||
int read = tx_rlc->read_pdu(lcid, pdu->msg, opp_size);
|
||||
pdu->N_bytes = read;
|
||||
if (pdu_tx_delay_usec) usleep(pdu_tx_delay_usec);
|
||||
if(((float)rand()/RAND_MAX > fail_rate) && read>0) {
|
||||
rx_rlc->write_pdu(lcid, pdu->msg, pdu->N_bytes);
|
||||
if (is_dl) {
|
||||
pcap->write_dl_am_ccch(pdu->msg, pdu->N_bytes);
|
||||
} else {
|
||||
pcap->write_ul_am_ccch(pdu->msg, pdu->N_bytes);
|
||||
}
|
||||
} else {
|
||||
log.info_hex(pdu->msg, pdu->N_bytes, "Dropping RLC PDU (%d B)\n", pdu->N_bytes);
|
||||
}
|
||||
}
|
||||
byte_buffer_pool::get_instance()->deallocate(pdu);
|
||||
}
|
||||
|
||||
void run_thread()
|
||||
{
|
||||
while (run_enable) {
|
||||
// Downlink direction first (RLC1->RLC2)
|
||||
run_tti(rlc1, rlc2, true);
|
||||
|
||||
// UL direction (RLC2->RLC1)
|
||||
run_tti(rlc2, rlc1, false);
|
||||
|
||||
// step timer
|
||||
step_timer();
|
||||
}
|
||||
}
|
||||
|
||||
rlc_interface_mac *rlc1;
|
||||
rlc_interface_mac *rlc2;
|
||||
srslte::timers timers;
|
||||
bool run_enable;
|
||||
float fail_rate;
|
||||
float opp_sdu_ratio;
|
||||
uint32_t pdu_tx_delay_usec;
|
||||
rlc_pcap *pcap;
|
||||
uint32_t lcid;
|
||||
bool is_dl;
|
||||
bool run_enable;
|
||||
srslte::log_filter log;
|
||||
};
|
||||
|
||||
class mac_dummy
|
||||
:public srslte::mac_interface_timers
|
||||
{
|
||||
public:
|
||||
mac_dummy(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, float opp_sdu_ratio_, int32_t pdu_tx_delay, uint32_t lcid, rlc_pcap* pcap = NULL)
|
||||
:r1(rlc1_, rlc2_, fail_rate_, opp_sdu_ratio_, pdu_tx_delay, pcap, lcid, true)
|
||||
,r2(rlc2_, rlc1_, fail_rate_, opp_sdu_ratio_, pdu_tx_delay, pcap, lcid, false)
|
||||
{
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
r1.start(7);
|
||||
r2.start(7);
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
r1.stop();
|
||||
r2.stop();
|
||||
}
|
||||
|
||||
srslte::timers::timer* timer_get(uint32_t timer_id)
|
||||
{
|
||||
return &t;
|
||||
}
|
||||
uint32_t timer_get_unique_id(){return 0;}
|
||||
void timer_release_id(uint32_t id){}
|
||||
|
||||
private:
|
||||
srslte::timers::timer t;
|
||||
|
||||
mac_reader r1;
|
||||
mac_reader r2;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class rlc_tester
|
||||
:public pdcp_interface_rlc
|
||||
|
@ -231,10 +229,12 @@ public:
|
|||
{
|
||||
assert(rx_lcid == lcid);
|
||||
if (sdu->N_bytes != SDU_SIZE) {
|
||||
printf("Received PDU with size %d, expected %d. Exiting.\n", sdu->N_bytes, SDU_SIZE);
|
||||
srslte::log_filter log1("Testr");;
|
||||
log1.set_level(srslte::LOG_LEVEL_ERROR);
|
||||
log1.set_hex_limit(sdu->N_bytes);
|
||||
log1.error_hex(sdu->msg, sdu->N_bytes, "Received PDU with size %d, expected %d. Exiting.\n", sdu->N_bytes, SDU_SIZE);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
byte_buffer_pool::get_instance()->deallocate(sdu);
|
||||
rx_pdus++;
|
||||
}
|
||||
|
@ -245,13 +245,12 @@ public:
|
|||
|
||||
// RRC interface
|
||||
void max_retx_attempted(){}
|
||||
std::string get_rb_name(uint32_t rx_lcid) { return std::string(""); }
|
||||
std::string get_rb_name(uint32_t rx_lcid) { return std::string("DRB1"); }
|
||||
|
||||
int get_nof_rx_pdus() { return rx_pdus; }
|
||||
|
||||
private:
|
||||
void run_thread()
|
||||
{
|
||||
void run_thread() {
|
||||
uint8_t sn = 0;
|
||||
while(run_enable) {
|
||||
byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate("rlc_tester::run_thread");
|
||||
|
@ -288,8 +287,8 @@ void stress_test(stress_test_args_t args)
|
|||
srslte::log_filter log2("RLC_2");
|
||||
log1.set_level((LOG_LEVEL_ENUM)args.log_level);
|
||||
log2.set_level((LOG_LEVEL_ENUM)args.log_level);
|
||||
log1.set_hex_limit(-1);
|
||||
log2.set_hex_limit(-1);
|
||||
log1.set_hex_limit(LOG_HEX_LIMIT);
|
||||
log2.set_hex_limit(LOG_HEX_LIMIT);
|
||||
rlc_pcap pcap;
|
||||
uint32_t lcid = 1;
|
||||
|
||||
|
@ -374,16 +373,16 @@ void stress_test(stress_test_args_t args)
|
|||
tester1.get_nof_rx_pdus(),
|
||||
args.test_duration_sec,
|
||||
(float)tester1.get_nof_rx_pdus()/args.test_duration_sec,
|
||||
metrics.dl_tput_mbps,
|
||||
metrics.ul_tput_mbps);
|
||||
metrics.dl_tput_mbps[lcid],
|
||||
metrics.ul_tput_mbps[lcid]);
|
||||
|
||||
rlc2.get_metrics(metrics);
|
||||
printf("RLC2 received %d SDUs in %ds (%.2f PDU/s), Throughput: DL=%4.2f Mbps, UL=%4.2f Mbps\n",
|
||||
tester2.get_nof_rx_pdus(),
|
||||
args.test_duration_sec,
|
||||
(float)tester2.get_nof_rx_pdus()/args.test_duration_sec,
|
||||
metrics.dl_tput_mbps,
|
||||
metrics.ul_tput_mbps);
|
||||
metrics.dl_tput_mbps[lcid],
|
||||
metrics.ul_tput_mbps[lcid]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -391,6 +390,12 @@ int main(int argc, char **argv) {
|
|||
stress_test_args_t args;
|
||||
parse_args(&args, argc, argv);
|
||||
|
||||
if (args.zero_seed) {
|
||||
srand(0);
|
||||
} else {
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
stress_test(args);
|
||||
byte_buffer_pool::get_instance()->cleanup();
|
||||
|
||||
|
|
|
@ -1073,7 +1073,7 @@ void phch_worker::ue::metrics_ul(uint32_t mcs, float rssi, float sinr, uint32_t
|
|||
{
|
||||
metrics.ul.mcs = SRSLTE_VEC_CMA((float) mcs, metrics.ul.mcs, metrics.ul.n_samples);
|
||||
metrics.ul.sinr = SRSLTE_VEC_CMA((float) sinr, metrics.ul.sinr, metrics.ul.n_samples);
|
||||
metrics.ul.rssi = SRSLTE_VEC_CMA((float) sinr, metrics.ul.rssi, metrics.ul.n_samples);
|
||||
metrics.ul.rssi = SRSLTE_VEC_CMA((float) rssi, metrics.ul.rssi, metrics.ul.n_samples);
|
||||
metrics.ul.turbo_iters = SRSLTE_VEC_CMA((float) turbo_iters, metrics.ul.turbo_iters, metrics.ul.n_samples);
|
||||
metrics.ul.n_samples++;
|
||||
}
|
||||
|
|
|
@ -594,6 +594,10 @@ hss::resync_sqn_milenage(uint64_t imsi, uint8_t *auts)
|
|||
|
||||
uint8_t mac_s_tmp[8];
|
||||
|
||||
for(int i=0; i<2; i++){
|
||||
amf[i] = 0;
|
||||
}
|
||||
|
||||
security_milenage_f1_star(k, opc, last_rand, sqn_ms, amf, mac_s_tmp);
|
||||
|
||||
m_hss_log->debug_hex(mac_s_tmp, 8, "MAC calc : ");
|
||||
|
|
|
@ -39,6 +39,8 @@ struct mac_metrics_t
|
|||
int rx_errors;
|
||||
int rx_brate;
|
||||
int ul_buffer;
|
||||
float dl_retx_avg;
|
||||
float ul_retx_avg;
|
||||
};
|
||||
|
||||
} // namespace srsue
|
||||
|
|
|
@ -477,6 +477,8 @@ void mac::get_metrics(mac_metrics_t &m)
|
|||
ul_harq.get_average_retx());
|
||||
|
||||
metrics.ul_buffer = (int) bsr_procedure.get_buffer_state();
|
||||
metrics.dl_retx_avg = dl_harq.get_average_retx();
|
||||
metrics.ul_retx_avg = ul_harq.get_average_retx();
|
||||
m = metrics;
|
||||
bzero(&metrics, sizeof(mac_metrics_t));
|
||||
}
|
||||
|
|
|
@ -237,7 +237,8 @@ void ra_proc::step_resource_selection() {
|
|||
}
|
||||
if (sel_group == RA_GROUP_A) {
|
||||
if (nof_groupA_preambles) {
|
||||
sel_preamble = preambleTransmissionCounter%nof_groupA_preambles;
|
||||
// randomly choose preamble from [0 nof_groupA_preambles)
|
||||
sel_preamble = rand() % nof_groupA_preambles;
|
||||
} else {
|
||||
rError("Selected group preamble A but nof_groupA_preambles=0\n");
|
||||
state = RA_PROBLEM;
|
||||
|
@ -245,7 +246,8 @@ void ra_proc::step_resource_selection() {
|
|||
}
|
||||
} else {
|
||||
if (nof_groupB_preambles) {
|
||||
sel_preamble = nof_groupA_preambles + rand()%nof_groupB_preambles;
|
||||
// randomly choose preamble from [nof_groupA_preambles nof_groupB_preambles)
|
||||
sel_preamble = nof_groupA_preambles + rand() % nof_groupB_preambles;
|
||||
} else {
|
||||
rError("Selected group preamble B but nof_groupA_preambles=0\n");
|
||||
state = RA_PROBLEM;
|
||||
|
@ -254,7 +256,7 @@ void ra_proc::step_resource_selection() {
|
|||
}
|
||||
sel_maskIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
rDebug("Selected preambleIndex=%d maskIndex=%d GroupA=%d, GroupB=%d\n",
|
||||
sel_preamble, sel_maskIndex,nof_groupA_preambles, nof_groupB_preambles);
|
||||
state = PREAMBLE_TRANSMISSION;
|
||||
|
|
Loading…
Reference in New Issue