Joseph Giovatto 7 years ago
parent e8985dbdbc
commit 1961021496

@ -239,7 +239,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
INFO("Stopping RF and flushing buffer...\n",0); INFO("Stopping RF and flushing buffer...\n");
srslte_rf_stop_rx_stream(&rf); srslte_rf_stop_rx_stream(&rf);
srslte_rf_flush_buffer(&rf); srslte_rf_flush_buffer(&rf);

@ -220,7 +220,7 @@ int main(int argc, char **argv) {
INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000); INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000);
srslte_rf_set_rx_srate(&rf, SRSLTE_CS_SAMP_FREQ); srslte_rf_set_rx_srate(&rf, SRSLTE_CS_SAMP_FREQ);
INFO("Starting receiver...\n", 0); INFO("Starting receiver...\n");
srslte_rf_start_rx_stream(&rf, false); srslte_rf_start_rx_stream(&rf, false);
n = srslte_ue_cellsearch_scan(&cs, found_cells, NULL); n = srslte_ue_cellsearch_scan(&cs, found_cells, NULL);

@ -528,9 +528,9 @@ int update_radl() {
srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb); srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
srslte_ra_dl_grant_t dummy_grant; srslte_ra_dl_grant_t dummy_grant;
srslte_ra_nbits_t dummy_nbits; srslte_ra_nbits_t dummy_nbits[SRSLTE_MAX_CODEWORDS];
srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, UE_CRNTI, &dummy_grant); srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, UE_CRNTI, &dummy_grant);
srslte_ra_dl_grant_to_nbits(&dummy_grant, cfi, cell, 0, &dummy_nbits); srslte_ra_dl_grant_to_nbits(&dummy_grant, cfi, cell, 0, dummy_nbits);
srslte_ra_dl_grant_fprint(stdout, &dummy_grant); srslte_ra_dl_grant_fprint(stdout, &dummy_grant);
dummy_grant.sf_type = SRSLTE_SF_NORM; dummy_grant.sf_type = SRSLTE_SF_NORM;
if (pdsch_cfg.mimo_type != SRSLTE_MIMO_TYPE_SINGLE_ANTENNA) { if (pdsch_cfg.mimo_type != SRSLTE_MIMO_TYPE_SINGLE_ANTENNA) {
@ -858,7 +858,7 @@ int main(int argc, char **argv) {
if (net_port > 0) { if (net_port > 0) {
send_data = net_packet_ready; send_data = net_packet_ready;
if (net_packet_ready) { if (net_packet_ready) {
INFO("Transmitting packet\n",0); INFO("Transmitting packet\n");
} }
} else { } else {
INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs); INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs);

@ -473,7 +473,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
INFO("Stopping RF and flushing buffer...\r",0); INFO("Stopping RF and flushing buffer...\r");
} }
#endif #endif
@ -606,7 +606,7 @@ int main(int argc, char **argv) {
srslte_pbch_decode_reset(&ue_mib.pbch); srslte_pbch_decode_reset(&ue_mib.pbch);
INFO("\nEntering main loop...\n\n", 0); INFO("\nEntering main loop...\n\n");
/* Main loop */ /* Main loop */
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
bool acks [SRSLTE_MAX_CODEWORDS] = {false}; bool acks [SRSLTE_MAX_CODEWORDS] = {false};
@ -803,6 +803,7 @@ int main(int argc, char **argv) {
PRINT_LINE(" nof layers: %d", ue_dl.pdsch_cfg.nof_layers); PRINT_LINE(" nof layers: %d", ue_dl.pdsch_cfg.nof_layers);
PRINT_LINE("nof codewords: %d", SRSLTE_RA_DL_GRANT_NOF_TB(&ue_dl.pdsch_cfg.grant)); PRINT_LINE("nof codewords: %d", SRSLTE_RA_DL_GRANT_NOF_TB(&ue_dl.pdsch_cfg.grant));
PRINT_LINE(" CFO: %+7.2f Hz", srslte_ue_sync_get_cfo(&ue_sync)); PRINT_LINE(" CFO: %+7.2f Hz", srslte_ue_sync_get_cfo(&ue_sync));
PRINT_LINE(" RSRP: %+5.1f dBm | %+5.1f dBm", 10 * log10(rsrp0), 10 * log10(rsrp1));
PRINT_LINE(" SNR: %+5.1f dB | %+5.1f dB", 10 * log10(rsrp0 / noise), 10 * log10(rsrp1 / noise)); PRINT_LINE(" SNR: %+5.1f dB | %+5.1f dB", 10 * log10(rsrp0 / noise), 10 * log10(rsrp1 / noise));
PRINT_LINE(" Rb: %6.2f / %6.2f / %6.2f Mbps (net/maximum/processing)", uerate, enodebrate, procrate); PRINT_LINE(" Rb: %6.2f / %6.2f / %6.2f Mbps (net/maximum/processing)", uerate, enodebrate, procrate);
PRINT_LINE(" PDCCH-Miss: %5.2f%%", 100 * (1 - (float) ue_dl.nof_detected / nof_trials)); PRINT_LINE(" PDCCH-Miss: %5.2f%%", 100 * (1 - (float) ue_dl.nof_detected / nof_trials));

@ -79,7 +79,10 @@ public:
printf("%s\n", strlen(used[i]->debug_name)?used[i]->debug_name:"Undefined"); printf("%s\n", strlen(used[i]->debug_name)?used[i]->debug_name:"Undefined");
} }
} }
bool is_almost_empty() {
return available.size() < capacity/20;
}
buffer_t* allocate(const char *debug_name = NULL) buffer_t* allocate(const char *debug_name = NULL)
{ {
@ -92,8 +95,9 @@ public:
used.push_back(b); used.push_back(b);
available.pop(); available.pop();
if (available.size() < capacity/20) { if (is_almost_empty()) {
printf("Warning buffer pool capacity is %f %%\n", (float) 100*available.size()/capacity); printf("Warning buffer pool capacity is %f %%\n", (float) 100*available.size()/capacity);
print_all_buffers();
} }
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
if (debug_name) { if (debug_name) {

@ -63,7 +63,7 @@
#define SRSLTE_MAX_BUFFER_SIZE_BYTES 12756 #define SRSLTE_MAX_BUFFER_SIZE_BYTES 12756
#define SRSLTE_BUFFER_HEADER_OFFSET 1024 #define SRSLTE_BUFFER_HEADER_OFFSET 1024
//#define SRSLTE_BUFFER_POOL_LOG_ENABLED #define SRSLTE_BUFFER_POOL_LOG_ENABLED
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
#define pool_allocate (pool->allocate(__FUNCTION__)) #define pool_allocate (pool->allocate(__FUNCTION__))

@ -10,6 +10,7 @@
#include <vector> #include <vector>
#include "srslte/common/threads.h" #include "srslte/common/threads.h"
#include "srslte/srslte.h"
namespace srslte { namespace srslte {
@ -24,7 +25,8 @@ template<typename metrics_t>
class metrics_listener class metrics_listener
{ {
public: public:
virtual void set_metrics(metrics_t &m) = 0; virtual void set_metrics(metrics_t &m, const uint32_t period_usec) = 0;
virtual void stop() = 0;
}; };
template<typename metrics_t> template<typename metrics_t>
@ -33,15 +35,19 @@ class metrics_hub : public periodic_thread
public: public:
metrics_hub() metrics_hub()
:m(NULL) :m(NULL)
,report_period_secs(1) ,sleep_period_start()
{} {}
bool init(metrics_interface<metrics_t> *m_, float report_period_secs_=1.0) { bool init(metrics_interface<metrics_t> *m_, float report_period_secs_=1.0) {
m = m_; m = m_;
report_period_secs = report_period_secs_; // Start with user-default priority
start_periodic(report_period_secs*1e6); start_periodic(report_period_secs_*1e6, -2);
return true; return true;
} }
void stop() { void stop() {
// stop all listeners
for (uint32_t i=0;i<listeners.size();i++) {
listeners[i]->stop();
}
thread_cancel(); thread_cancel();
wait_thread_finish(); wait_thread_finish();
} }
@ -51,18 +57,24 @@ public:
} }
private: private:
void run_period() { void run_period(){
// get current time and check how long we slept
gettimeofday(&sleep_period_start[2], NULL);
get_time_interval(sleep_period_start);
uint32_t period = sleep_period_start[0].tv_sec*1e6 + sleep_period_start[0].tv_usec;
if (m) { if (m) {
metrics_t metric = {}; metrics_t metric = {};
m->get_metrics(metric); m->get_metrics(metric);
for (uint32_t i=0;i<listeners.size();i++) { for (uint32_t i=0;i<listeners.size();i++) {
listeners[i]->set_metrics(metric); listeners[i]->set_metrics(metric, period);
} }
} }
// store start of sleep period
gettimeofday(&sleep_period_start[1], NULL);
} }
metrics_interface<metrics_t> *m; metrics_interface<metrics_t> *m;
std::vector<metrics_listener<metrics_t>*> listeners; std::vector<metrics_listener<metrics_t>*> listeners;
float report_period_secs; struct timeval sleep_period_start[3];
}; };
} // namespace srslte } // namespace srslte

@ -30,6 +30,9 @@
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
// Default priority for all threads below UHD threads
#define DEFAULT_PRIORITY 60
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus

@ -59,6 +59,9 @@
// cf_t definition // cf_t definition
typedef _Complex float cf_t; typedef _Complex float cf_t;
#ifdef ENABLE_C16
typedef _Complex short int c16_t; typedef _Complex short int c16_t;
#endif /* ENABLE_C16 */
#endif // CONFIG_H #endif // CONFIG_H

@ -110,7 +110,7 @@ typedef enum {SRSLTE_SF_NORM, SRSLTE_SF_MBSFN} srslte_sf_t;
#define SRSLTE_SF_LEN_MAX (SRSLTE_SF_LEN(SRSLTE_SYMBOL_SZ_MAX)) #define SRSLTE_SF_LEN_MAX (SRSLTE_SF_LEN(SRSLTE_SYMBOL_SZ_MAX))
#define SRSLTE_SLOT_LEN_PRB(nof_prb) (SRSLTE_SLOT_LEN(srslte_symbol_sz(nof_prb))) #define SRSLTE_SLOT_LEN_PRB(nof_prb) (SRSLTE_SLOT_LEN(srslte_symbol_sz(nof_prb)))
#define SRSLTE_SF_LEN_PRB(nof_prb) (SRSLTE_SF_LEN(srslte_symbol_sz(nof_prb))) #define SRSLTE_SF_LEN_PRB(nof_prb) (nof_prb > 0 ? SRSLTE_SF_LEN(srslte_symbol_sz(nof_prb)) : 0)
#define SRSLTE_SLOT_LEN_RE(nof_prb, cp) (nof_prb*SRSLTE_NRE*SRSLTE_CP_NSYMB(cp)) #define SRSLTE_SLOT_LEN_RE(nof_prb, cp) (nof_prb*SRSLTE_NRE*SRSLTE_CP_NSYMB(cp))
#define SRSLTE_SF_LEN_RE(nof_prb, cp) (2*SRSLTE_SLOT_LEN_RE(nof_prb, cp)) #define SRSLTE_SF_LEN_RE(nof_prb, cp) (2*SRSLTE_SLOT_LEN_RE(nof_prb, cp))

@ -43,6 +43,7 @@
#define SRSLTE_CQI_MAX_BITS 64 #define SRSLTE_CQI_MAX_BITS 64
#define SRSLTE_DIF_CQI_MAX_BITS 3 #define SRSLTE_DIF_CQI_MAX_BITS 3
#define SRSLTE_PMI_MAX_BITS 4 #define SRSLTE_PMI_MAX_BITS 4
#define SRSLTE_CQI_STR_MAX_CHAR 32
typedef struct { typedef struct {
bool configured; bool configured;

@ -139,7 +139,11 @@ typedef struct SRSLTE_API {
uint8_t tpc_pucch; uint8_t tpc_pucch;
bool tb_en[2]; bool tb_en[2];
bool is_ra_order;
uint32_t ra_preamble;
uint32_t ra_mask_idx;
bool dci_is_1a; bool dci_is_1a;
bool dci_is_1c; bool dci_is_1c;
} srslte_ra_dl_dci_t; } srslte_ra_dl_dci_t;

@ -150,7 +150,10 @@
#endif /* LV_HAVE_AVX2 */ #endif /* LV_HAVE_AVX2 */
#endif /* LV_HAVE_AVX512 */ #endif /* LV_HAVE_AVX512 */
#ifndef ENABLE_C16
#undef SRSLTE_SIMD_C16_SIZE
#define SRSLTE_SIMD_C16_SIZE 0
#endif /* ENABLE_C16 */
#if SRSLTE_SIMD_F_SIZE #if SRSLTE_SIMD_F_SIZE

@ -106,7 +106,9 @@ SRSLTE_API cf_t srslte_vec_dot_prod_conj_ccc_simd(const cf_t *x, const cf_t *y,
SRSLTE_API cf_t srslte_vec_dot_prod_ccc_simd(const cf_t *x, const cf_t *y, const int len); SRSLTE_API cf_t srslte_vec_dot_prod_ccc_simd(const cf_t *x, const cf_t *y, const int len);
#ifdef ENABLE_C16
SRSLTE_API c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len); SRSLTE_API c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len);
#endif /* ENABLE_C16 */
SRSLTE_API int srslte_vec_dot_prod_sss_simd(const int16_t *x, const int16_t *y, const int len); SRSLTE_API int srslte_vec_dot_prod_sss_simd(const int16_t *x, const int16_t *y, const int len);

@ -61,7 +61,6 @@ static const char pdcp_d_c_text[PDCP_D_C_N_ITEMS][20] = {"Control PDU",
* Common interface for all PDCP entities * Common interface for all PDCP entities
***************************************************************************/ ***************************************************************************/
class pdcp_entity class pdcp_entity
:public thread
{ {
public: public:
pdcp_entity(); pdcp_entity();
@ -71,7 +70,6 @@ public:
srslte::log *log_, srslte::log *log_,
uint32_t lcid_, uint32_t lcid_,
srslte_pdcp_config_t cfg_); srslte_pdcp_config_t cfg_);
void stop();
void reset(); void reset();
void reestablish(); void reestablish();
@ -97,10 +95,6 @@ private:
srsue::rrc_interface_pdcp *rrc; srsue::rrc_interface_pdcp *rrc;
srsue::gw_interface_pdcp *gw; srsue::gw_interface_pdcp *gw;
static const int PDCP_THREAD_PRIO = 7;
srslte::msg_queue rx_pdu_queue;
bool running;
bool active; bool active;
uint32_t lcid; uint32_t lcid;
srslte_pdcp_config_t cfg; srslte_pdcp_config_t cfg;
@ -134,8 +128,6 @@ private:
uint32_t ct_len, uint32_t ct_len,
uint8_t *msg); uint8_t *msg);
void run_thread();
uint8_t get_bearer_id(uint8_t lcid); uint8_t get_bearer_id(uint8_t lcid);
}; };

@ -2243,6 +2243,12 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_imsi(
if(ie != NULL && if(ie != NULL &&
ptr != NULL) ptr != NULL)
{ {
// max length of IE buffer is 32, so limit
if (ie->n_octets > 31) {
printf("Length in struct exceeds buffer (%d > 31).\n", ie->n_octets);
return LIBLTE_ERROR_ENCODE_FAIL;
}
// Dynamic octet string - IMSI // Dynamic octet string - IMSI
// Length // Length
if(ie->n_octets < 128) { if(ie->n_octets < 128) {

@ -67,6 +67,20 @@ bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void
fprintf(stderr, "Error not enough privileges to set Scheduling priority\n"); fprintf(stderr, "Error not enough privileges to set Scheduling priority\n");
} }
attr_enable = true; attr_enable = true;
} else if (prio_offset == -1) {
param.sched_priority = sched_get_priority_max(SCHED_FIFO) - DEFAULT_PRIORITY;
pthread_attr_init(&attr);
if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) {
perror("pthread_attr_setinheritsched");
}
if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
perror("pthread_attr_setschedpolicy");
}
if (pthread_attr_setschedparam(&attr, &param)) {
perror("pthread_attr_setschedparam");
fprintf(stderr, "Error not enough privileges to set Scheduling priority\n");
}
attr_enable = true;
} else if (prio_offset == -2) { } else if (prio_offset == -2) {
param.sched_priority = 0; param.sched_priority = 0;
pthread_attr_init(&attr); pthread_attr_init(&attr);

@ -66,7 +66,7 @@ bool srslte_cell_isvalid(srslte_cell_t *cell) {
} }
void srslte_cell_fprint(FILE *stream, srslte_cell_t *cell, uint32_t sfn) { void srslte_cell_fprint(FILE *stream, srslte_cell_t *cell, uint32_t sfn) {
fprintf(stream, " - Cell ID: %d\n", cell->id); fprintf(stream, " - PCI: %d\n", cell->id);
fprintf(stream, " - Nof ports: %d\n", cell->nof_ports); fprintf(stream, " - Nof ports: %d\n", cell->nof_ports);
fprintf(stream, " - CP: %s\n", srslte_cp_string(cell->cp)); fprintf(stream, " - CP: %s\n", srslte_cp_string(cell->cp));
fprintf(stream, " - PRB: %d\n", cell->nof_prb); fprintf(stream, " - PRB: %d\n", cell->nof_prb);

@ -133,7 +133,7 @@ void map_simd_dec(map_gen_t * h, int16_t * input[SRSLTE_TDEC_MAX_NPAR], int16_t
{ {
uint32_t nof_cb = 1; uint32_t nof_cb = 1;
int16_t *outptr[SRSLTE_TDEC_MAX_NPAR]; int16_t *outptr[SRSLTE_TDEC_MAX_NPAR] = { NULL, NULL };
// Compute branch metrics // Compute branch metrics
switch(cb_mask) { switch(cb_mask) {

@ -85,6 +85,10 @@ void map_sse_inter_beta(srslte_tdec_simd_inter_t * s, int16_t *input, int16_t *p
__m128i *outputPtr = (__m128i*) output; __m128i *outputPtr = (__m128i*) output;
__m128i *alphaPtr = (__m128i*) s->alpha; __m128i *alphaPtr = (__m128i*) s->alpha;
for (int i = 0; i < 8; i++) {
old[i] = _mm_set1_epi16(0);
}
for (int k = end - 1; k >= 0; k--) { for (int k = end - 1; k >= 0; k--) {
x = _mm_load_si128(inputPtr++); x = _mm_load_si128(inputPtr++);
y = _mm_load_si128(parityPtr++); y = _mm_load_si128(parityPtr++);

@ -50,7 +50,9 @@ void srslte_filesource_free(srslte_filesource_t *q) {
} }
void srslte_filesource_seek(srslte_filesource_t *q, int pos) { void srslte_filesource_seek(srslte_filesource_t *q, int pos) {
fseek(q->f, pos, SEEK_SET); if (!fseek(q->f, pos, SEEK_SET)){
perror("srslte_filesource_seek");
}
} }
int read_complex_f(FILE *f, _Complex float *y) { int read_complex_f(FILE *f, _Complex float *y) {

@ -2205,7 +2205,9 @@ int srslte_precoding_pmi_select_2l_gen(cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORT
} }
/* Divide average by noise */ /* Divide average by noise */
sinr_list[i] /= count; if (count) {
sinr_list[i] /= count;
}
if (sinr_list[i] > max_sinr) { if (sinr_list[i] > max_sinr) {
max_sinr = sinr_list[i]; max_sinr = sinr_list[i];
@ -2326,7 +2328,9 @@ int srslte_precoding_pmi_select_2l_sse(cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORT
} }
/* Divide average by noise */ /* Divide average by noise */
sinr_list[i] /= count; if (count) {
sinr_list[i] /= count;
}
if (sinr_list[i] > max_sinr) { if (sinr_list[i] > max_sinr) {
max_sinr = sinr_list[i]; max_sinr = sinr_list[i];
@ -2473,7 +2477,9 @@ int srslte_precoding_pmi_select_2l_avx(cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORT
} }
/* Divide average by noise */ /* Divide average by noise */
sinr_list[i] /= count; if (count) {
sinr_list[i] /= count;
}
if (sinr_list[i] > max_sinr) { if (sinr_list[i] > max_sinr) {
max_sinr = sinr_list[i]; max_sinr = sinr_list[i];
@ -2545,7 +2551,11 @@ float srslte_precoding_2x2_cn_gen(cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], u
count++; count++;
} }
return cn_avg/count; if (count) {
cn_avg /= count;
}
return cn_avg;
} }
/* Computes the condition number for a given number of antennas, /* Computes the condition number for a given number of antennas,

@ -124,7 +124,7 @@ int main(int argc, char **argv) {
/* Condition number */ /* Condition number */
if (srslte_precoding_cn(h, 2, 2, nof_symbols, &cn)) { if (srslte_precoding_cn(h, 2, 2, nof_symbols, &cn)) {
ERROR("Test case %d condition number returned error\n"); ERROR("Test case %d condition number returned error\n", c + 1);
goto clean; goto clean;
} }

@ -42,7 +42,7 @@ int nof_symbols = 1000;
uint32_t codebook_idx = 0; uint32_t codebook_idx = 0;
int nof_layers = 1, nof_tx_ports = 1, nof_rx_ports = 1, nof_re = 1; int nof_layers = 1, nof_tx_ports = 1, nof_rx_ports = 1, nof_re = 1;
char *mimo_type_name = NULL; char *mimo_type_name = NULL;
char decoder_type_name [16] = "zf"; char decoder_type_name [17] = "zf";
float snr_db = 100.0f; float snr_db = 100.0f;
float scaling = 0.1f; float scaling = 0.1f;
@ -56,7 +56,7 @@ void usage(char *prog) {
printf("\t-g Scaling [Default %.1f]*\n", scaling); printf("\t-g Scaling [Default %.1f]*\n", scaling);
printf("\t-d decoder type [zf|mmse] [Default %s]\n", decoder_type_name); printf("\t-d decoder type [zf|mmse] [Default %s]\n", decoder_type_name);
printf("\n"); printf("\n");
printf("* Performance test example:\n\t for snr in {0..20..1}; do ./precoding_test -m single -s $snr; done; \n\n", decoder_type_name); printf("* Performance test example:\n\t for snr in {0..20..1}; do ./precoding_test -m single -s $snr; done; \n\n");
} }
void parse_args(int argc, char **argv) { void parse_args(int argc, char **argv) {
@ -82,7 +82,8 @@ void parse_args(int argc, char **argv) {
codebook_idx = (uint32_t) atoi(argv[optind]); codebook_idx = (uint32_t) atoi(argv[optind]);
break; break;
case 'd': case 'd':
strncpy(decoder_type_name, argv[optind], 16); strncpy(decoder_type_name, argv[optind], 15);
decoder_type_name[15] = 0;
break; break;
case 's': case 's':
snr_db = (float) atof(argv[optind]); snr_db = (float) atof(argv[optind]);

@ -383,7 +383,7 @@ bool srslte_ri_send(uint32_t I_cqi_pmi, uint32_t I_ri, uint32_t tti) {
return false; return false;
} }
if (M_ri) { if (M_ri && N_p) {
if ((tti - N_offset_p + N_offset_ri) % (N_p * M_ri) == 0) { if ((tti - N_offset_p + N_offset_ri) % (N_p * M_ri) == 0) {
return true; return true;
} }
@ -456,8 +456,16 @@ int srslte_cqi_hl_get_no_subbands(int nof_prb)
void srslte_cqi_to_str(const uint8_t *cqi_value, int cqi_len, char *str, int str_len) { void srslte_cqi_to_str(const uint8_t *cqi_value, int cqi_len, char *str, int str_len) {
int i = 0; int i = 0;
for (i = 0; i < cqi_len && i < (str_len - 1); i++) {
for (i = 0; i < cqi_len && i < (str_len - 5); i++) {
str[i] = (cqi_value[i] == 0)?(char)'0':(char)'1'; str[i] = (cqi_value[i] == 0)?(char)'0':(char)'1';
} }
if (i == (str_len - 5)) {
str[i++] = '.';
str[i++] = '.';
str[i++] = '.';
str[i++] = (cqi_value[cqi_len - 1] == 0)?(char)'0':(char)'1';
}
str[i] = '\0'; str[i] = '\0';
} }

@ -71,12 +71,14 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti,
//fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(msg->format), msg->format); //fprintf(stderr, "Can't unpack DCI message %s (%d)\n", srslte_dci_format_string(msg->format), msg->format);
return ret; return ret;
} }
srslte_ra_dl_dci_to_grant(dl_dci, nof_prb, msg_rnti, grant);
if (SRSLTE_VERBOSE_ISINFO()) { if (!dl_dci->is_ra_order) {
srslte_ra_pdsch_fprint(stdout, dl_dci, nof_prb); srslte_ra_dl_dci_to_grant(dl_dci, nof_prb, msg_rnti, grant);
srslte_ra_dl_grant_fprint(stdout, grant);
if (SRSLTE_VERBOSE_ISINFO()) {
srslte_ra_pdsch_fprint(stdout, dl_dci, nof_prb);
srslte_ra_dl_grant_fprint(stdout, grant);
}
} }
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
@ -391,7 +393,7 @@ uint32_t srslte_dci_dl_info(char *info_str, uint32_t len, srslte_ra_dl_dci_t *dc
if (dci_msg->tb_en[0]) { if (dci_msg->tb_en[0]) {
n += snprintf(&info_str[n], len-n, "%d", dci_msg->mcs_idx); n += snprintf(&info_str[n], len-n, "%d", dci_msg->mcs_idx);
if (dci_msg->tb_en[1]) { if (dci_msg->tb_en[1]) {
n += snprintf(&info_str[n], len-n, ","); n += snprintf(&info_str[n], len-n, "/");
} else { } else {
n += snprintf(&info_str[n], len-n, "}, "); n += snprintf(&info_str[n], len-n, "}, ");
} }
@ -403,7 +405,7 @@ uint32_t srslte_dci_dl_info(char *info_str, uint32_t len, srslte_ra_dl_dci_t *dc
if (dci_msg->tb_en[0]) { if (dci_msg->tb_en[0]) {
n += snprintf(&info_str[n], len-n, "%d", dci_msg->rv_idx); n += snprintf(&info_str[n], len-n, "%d", dci_msg->rv_idx);
if (dci_msg->tb_en[1]) { if (dci_msg->tb_en[1]) {
n += snprintf(&info_str[n], len-n, ","); n += snprintf(&info_str[n], len-n, "/");
} else { } else {
n += snprintf(&info_str[n], len-n, "}, "); n += snprintf(&info_str[n], len-n, "}, ");
} }
@ -415,7 +417,7 @@ uint32_t srslte_dci_dl_info(char *info_str, uint32_t len, srslte_ra_dl_dci_t *dc
if (dci_msg->tb_en[0]) { if (dci_msg->tb_en[0]) {
n += snprintf(&info_str[n], len-n, "%d", dci_msg->ndi); n += snprintf(&info_str[n], len-n, "%d", dci_msg->ndi);
if (dci_msg->tb_en[1]) { if (dci_msg->tb_en[1]) {
n += snprintf(&info_str[n], len-n, ","); n += snprintf(&info_str[n], len-n, "/");
} else { } else {
n += snprintf(&info_str[n], len-n, "}, "); n += snprintf(&info_str[n], len-n, "}, ");
} }
@ -575,7 +577,7 @@ int dci_format0_unpack(srslte_dci_msg_t *msg, srslte_ra_ul_dci_t *data, uint32_t
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (*y++ != 0) { if (*y++ != 0) {
INFO("DCI message is Format1A\n", 0); INFO("DCI message is Format1A\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (*y++ == 0) { if (*y++ == 0) {
@ -834,7 +836,7 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32
} }
if (*y++ != 1) { if (*y++ != 1) {
INFO("DCI message is Format0\n", 0); INFO("DCI message is Format0\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -844,21 +846,31 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32
if (*y == 0) { if (*y == 0) {
int nof_bits = riv_nbits(nof_prb); int nof_bits = riv_nbits(nof_prb);
int i=0; int i=0;
while(i<nof_bits && y[1+i] == 1) // Check all bits in RBA are set to 1
while(i<nof_bits && y[1+i] == 1) {
i++; i++;
}
if (i == nof_bits) { if (i == nof_bits) {
//printf("Warning check me: could this be a RA PDCCH order??\n"); // Check all remaining bits are set to 0
i=1+10+nof_bits; i=1+10+nof_bits;
while(i<msg->nof_bits-1 && y[i] == 0) { while(i<msg->nof_bits-1 && y[i] == 0) {
i++; i++;
} }
if (i == msg->nof_bits-1) { if (i == msg->nof_bits-1) {
//printf("Received a Format1A RA PDCCH order. Not implemented!\n"); // This is a Random access order
return SRSLTE_ERROR; y+=1+nof_bits;
data->is_ra_order = true;
data->ra_preamble = srslte_bit_pack(&y, 6);
data->ra_mask_idx = srslte_bit_pack(&y, 4);
return SRSLTE_SUCCESS;
} }
} }
} }
data->is_ra_order = false;
data->alloc_type = SRSLTE_RA_ALLOC_TYPE2; data->alloc_type = SRSLTE_RA_ALLOC_TYPE2;
data->type2_alloc.mode = *y++; data->type2_alloc.mode = *y++;

@ -557,7 +557,7 @@ int srslte_pdcch_dci_encode(srslte_pdcch_t *q, uint8_t *data, uint8_t *e, uint32
srslte_pdcch_dci_encode_conv(q, data, nof_bits, tmp, rnti); srslte_pdcch_dci_encode_conv(q, data, nof_bits, tmp, rnti);
DEBUG("CConv output: ", 0); DEBUG("CConv output: ");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_b(stdout, tmp, 3 * (nof_bits + 16)); srslte_vec_fprint_b(stdout, tmp, 3 * (nof_bits + 16));
} }
@ -617,7 +617,7 @@ int srslte_pdcch_encode(srslte_pdcch_t *q, srslte_dci_msg_t *msg, srslte_dci_loc
srslte_scrambling_b_offset(&q->seq[nsubframe], q->e, 72 * location.ncce, e_bits); srslte_scrambling_b_offset(&q->seq[nsubframe], q->e, 72 * location.ncce, e_bits);
DEBUG("Scrambling output: ", 0); DEBUG("Scrambling output: ");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_b(stdout, q->e, e_bits); srslte_vec_fprint_b(stdout, q->e, e_bits);
} }

@ -29,6 +29,8 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <srslte/phy/phch/pdsch_cfg.h>
#include <srslte/srslte.h>
#include "prb_dl.h" #include "prb_dl.h"
#include "srslte/phy/phch/pdsch.h" #include "srslte/phy/phch/pdsch.h"
@ -656,8 +658,8 @@ int srslte_pdsch_decode(srslte_pdsch_t *q,
{ {
uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant); uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant);
INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d, mimo_type=%d, nof_layers=%d, nof_tb=%d\n", INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d, mimo_type=%s, nof_layers=%d, nof_tb=%d\n",
cfg->sf_idx, rnti, cfg->nbits[0].nof_re, cfg->grant.nof_prb, cfg->nof_layers, nof_tb); cfg->sf_idx, rnti, cfg->nbits[0].nof_re, cfg->grant.nof_prb, srslte_mod_string(cfg->grant.mcs->mod), cfg->nof_layers, nof_tb);
// Extract Symbols and Channel Estimates // Extract Symbols and Channel Estimates
for (int j=0;j<q->nof_rx_antennas;j++) { for (int j=0;j<q->nof_rx_antennas;j++) {

@ -148,7 +148,7 @@ uint8_t srslte_phich_ack_decode(float bits[SRSLTE_PHICH_NBITS], float *distance)
uint8_t index=0; uint8_t index=0;
if (SRSLTE_VERBOSE_ISINFO()) { if (SRSLTE_VERBOSE_ISINFO()) {
INFO("Received bits: ", 0); INFO("Received bits: ");
srslte_vec_fprint_f(stdout, bits, SRSLTE_PHICH_NBITS); srslte_vec_fprint_f(stdout, bits, SRSLTE_PHICH_NBITS);
} }
@ -244,8 +244,8 @@ int srslte_phich_decode(srslte_phich_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS],
srslte_predecoding_diversity_multi(q_sf_symbols, q_ce, x, q->nof_rx_antennas, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB, 1.0f); srslte_predecoding_diversity_multi(q_sf_symbols, q_ce, x, q->nof_rx_antennas, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB, 1.0f);
srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports);
} }
DEBUG("Recv!!: \n", 0); DEBUG("Recv!!: \n");
DEBUG("d0: ", 0); DEBUG("d0: ");
if (SRSLTE_VERBOSE_ISDEBUG()) if (SRSLTE_VERBOSE_ISDEBUG())
srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB); srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB);
@ -265,7 +265,7 @@ int srslte_phich_decode(srslte_phich_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS],
memcpy(q->d, q->d0, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t)); memcpy(q->d, q->d0, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t));
} }
DEBUG("d: ", 0); DEBUG("d: ");
if (SRSLTE_VERBOSE_ISDEBUG()) if (SRSLTE_VERBOSE_ISDEBUG())
srslte_vec_fprint_c(stdout, q->d, SRSLTE_PHICH_EXT_MSYMB); srslte_vec_fprint_c(stdout, q->d, SRSLTE_PHICH_EXT_MSYMB);
@ -290,7 +290,7 @@ int srslte_phich_decode(srslte_phich_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS],
} }
} }
DEBUG("z: ", 0); DEBUG("z: ");
if (SRSLTE_VERBOSE_ISDEBUG()) if (SRSLTE_VERBOSE_ISDEBUG())
srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS); srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS);
@ -353,7 +353,7 @@ int srslte_phich_encode(srslte_phich_t *q, uint8_t ack, uint32_t ngroup, uint32_
srslte_mod_modulate(&q->mod, q->data, q->z, SRSLTE_PHICH_NBITS); srslte_mod_modulate(&q->mod, q->data, q->z, SRSLTE_PHICH_NBITS);
DEBUG("data: ", 0); DEBUG("data: ");
if (SRSLTE_VERBOSE_ISDEBUG()) if (SRSLTE_VERBOSE_ISDEBUG())
srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS); srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS);
@ -370,7 +370,7 @@ int srslte_phich_encode(srslte_phich_t *q, uint8_t ack, uint32_t ngroup, uint32_
} }
} }
DEBUG("d: ", 0); DEBUG("d: ");
if (SRSLTE_VERBOSE_ISDEBUG()) if (SRSLTE_VERBOSE_ISDEBUG())
srslte_vec_fprint_c(stdout, q->d, SRSLTE_PHICH_EXT_MSYMB); srslte_vec_fprint_c(stdout, q->d, SRSLTE_PHICH_EXT_MSYMB);
@ -397,7 +397,7 @@ int srslte_phich_encode(srslte_phich_t *q, uint8_t ack, uint32_t ngroup, uint32_
memcpy(q->d0, q->d, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t)); memcpy(q->d0, q->d, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t));
} }
DEBUG("d0: ", 0); DEBUG("d0: ");
if (SRSLTE_VERBOSE_ISDEBUG()) if (SRSLTE_VERBOSE_ISDEBUG())
srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB); srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB);

@ -555,7 +555,7 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr
} }
void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, uint32_t sf_idx, void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, uint32_t sf_idx,
srslte_ra_nbits_t nbits [SRSLTE_MAX_CODEWORDS]) srslte_ra_nbits_t nbits[SRSLTE_MAX_CODEWORDS])
{ {
// Compute number of RE // Compute number of RE
for (int i = 0; i < SRSLTE_MAX_TB; i++) { for (int i = 0; i < SRSLTE_MAX_TB; i++) {

@ -494,7 +494,7 @@ static int decode_tb(srslte_sch_t *q,
((uint32_t) data[cb_segm->tbs/8+2]); ((uint32_t) data[cb_segm->tbs/8+2]);
if (par_rx == par_tx && par_rx) { if (par_rx == par_tx && par_rx) {
INFO("TB decoded OK\n",0); INFO("TB decoded OK\n");
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} else { } else {
INFO("Error in TB parity: par_tx=0x%x, par_rx=0x%x\n", par_tx, par_rx); INFO("Error in TB parity: par_tx=0x%x, par_rx=0x%x\n", par_tx, par_rx);

@ -154,7 +154,7 @@ int base_init() {
return -1; return -1;
} }
DEBUG("Memory init OK\n",0); DEBUG("Memory init OK\n");
return 0; return 0;
} }

@ -170,7 +170,7 @@ int base_init() {
return -1; return -1;
} }
DEBUG("Memory init OK\n",0); DEBUG("Memory init OK\n");
return 0; return 0;
} }
@ -232,7 +232,7 @@ int main(int argc, char **argv) {
/* Get channel estimates for each port */ /* Get channel estimates for each port */
srslte_chest_dl_estimate(&chest, fft_buffer, ce, 0); srslte_chest_dl_estimate(&chest, fft_buffer, ce, 0);
INFO("Decoding PCFICH\n", 0); INFO("Decoding PCFICH\n");
n = srslte_pcfich_decode(&pcfich, fft_buffer, ce, srslte_chest_dl_get_noise_estimate(&chest), 0, &cfi, &cfi_corr); n = srslte_pcfich_decode(&pcfich, fft_buffer, ce, srslte_chest_dl_get_noise_estimate(&chest), 0, &cfi, &cfi_corr);

@ -180,7 +180,7 @@ int base_init() {
exit(-1); exit(-1);
} }
DEBUG("Memory init OK\n",0); DEBUG("Memory init OK\n");
return 0; return 0;
} }
@ -244,7 +244,7 @@ int main(int argc, char **argv) {
return -1; return -1;
} }
if (rnti == SRSLTE_SIRNTI) { if (rnti == SRSLTE_SIRNTI) {
INFO("Initializing common search space for SI-RNTI\n",0); INFO("Initializing common search space for SI-RNTI\n");
nof_locations = srslte_pdcch_common_locations(&pdcch, locations, MAX_CANDIDATES, cfi); nof_locations = srslte_pdcch_common_locations(&pdcch, locations, MAX_CANDIDATES, cfi);
} else { } else {
INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti); INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti);

@ -148,7 +148,7 @@ int base_init() {
srslte_ue_dl_set_rnti(&ue_dl, rnti); srslte_ue_dl_set_rnti(&ue_dl, rnti);
DEBUG("Memory init OK\n",0); DEBUG("Memory init OK\n");
return 0; return 0;
} }

@ -51,7 +51,7 @@ srslte_cell_t cell = {
SRSLTE_PHICH_R_1_6 // PHICH resources SRSLTE_PHICH_R_1_6 // PHICH resources
}; };
char mimo_type_str [32] = "single"; char mimo_type_str[32] = "single";
srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
uint32_t cfi = 1; uint32_t cfi = 1;
uint32_t mcs[SRSLTE_MAX_CODEWORDS] = {0, 0}; uint32_t mcs[SRSLTE_MAX_CODEWORDS] = {0, 0};
@ -111,7 +111,8 @@ void parse_args(int argc, char **argv) {
cfi = atoi(argv[optind]); cfi = atoi(argv[optind]);
break; break;
case 'x': case 'x':
strncpy(mimo_type_str, argv[optind], 32); strncpy(mimo_type_str, argv[optind], sizeof(mimo_type_str)-1);
mimo_type_str[sizeof(mimo_type_str)-1] = 0;
break; break;
case 'p': case 'p':
pmi = (uint32_t) atoi(argv[optind]); pmi = (uint32_t) atoi(argv[optind]);

@ -194,7 +194,7 @@ int base_init() {
return -1; return -1;
} }
DEBUG("Memory init OK\n",0); DEBUG("Memory init OK\n");
return 0; return 0;
} }
@ -257,7 +257,7 @@ int main(int argc, char **argv) {
/* Get channel estimates for each port */ /* Get channel estimates for each port */
srslte_chest_dl_estimate(&chest, fft_buffer, ce, 0); srslte_chest_dl_estimate(&chest, fft_buffer, ce, 0);
INFO("Decoding PHICH\n", 0); INFO("Decoding PHICH\n");
/* Receive all PHICH groups and sequence numbers */ /* Receive all PHICH groups and sequence numbers */
for (ngroup=0;ngroup<srslte_phich_ngroups(&phich);ngroup++) { for (ngroup=0;ngroup<srslte_phich_ngroups(&phich);ngroup++) {

@ -102,7 +102,8 @@ void parse_args(int argc, char **argv) {
cfi = atoi(argv[optind]); cfi = atoi(argv[optind]);
break; break;
case 'x': case 'x':
strncpy(mimo_type_str, argv[optind], 32); strncpy(mimo_type_str, argv[optind], 31);
mimo_type_str[31] = 0;
break; break;
case 'p': case 'p':
pmi = (uint32_t) atoi(argv[optind]); pmi = (uint32_t) atoi(argv[optind]);

@ -193,7 +193,7 @@ int main(int argc, char **argv) {
uci_data_tx.uci_ack_len = 1; uci_data_tx.uci_ack_len = 1;
memcpy(&uci_data_rx, &uci_data_tx, sizeof(srslte_uci_data_t)); memcpy(&uci_data_rx, &uci_data_tx, sizeof(srslte_uci_data_t));
for (uint32_t i=0;i<20;i++) { for (uint32_t i=0;i<uci_data_tx.uci_cqi_len;i++) {
uci_data_tx.uci_cqi [i] = 1; uci_data_tx.uci_cqi [i] = 1;
} }
uci_data_tx.uci_ri = 1; uci_data_tx.uci_ri = 1;

@ -368,14 +368,14 @@ int encode_cqi_long(srslte_uci_cqi_pusch_t *q, uint8_t *data, uint32_t nof_bits,
memcpy(q->tmp_cqi, data, sizeof(uint8_t) * nof_bits); memcpy(q->tmp_cqi, data, sizeof(uint8_t) * nof_bits);
srslte_crc_attach(&q->crc, q->tmp_cqi, nof_bits); srslte_crc_attach(&q->crc, q->tmp_cqi, nof_bits);
DEBUG("cqi_crc_tx=", 0); DEBUG("cqi_crc_tx=");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_b(stdout, q->tmp_cqi, nof_bits+8); srslte_vec_fprint_b(stdout, q->tmp_cqi, nof_bits+8);
} }
srslte_convcoder_encode(&encoder, q->tmp_cqi, q->encoded_cqi, nof_bits + 8); srslte_convcoder_encode(&encoder, q->tmp_cqi, q->encoded_cqi, nof_bits + 8);
DEBUG("cconv_tx=", 0); DEBUG("cconv_tx=");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_b(stdout, q->encoded_cqi, 3 * (nof_bits + 8)); srslte_vec_fprint_b(stdout, q->encoded_cqi, 3 * (nof_bits + 8));
} }
@ -400,14 +400,14 @@ int decode_cqi_long(srslte_uci_cqi_pusch_t *q, int16_t *q_bits, uint32_t Q,
srslte_rm_conv_rx_s(q_bits, Q, q->encoded_cqi_s, 3 * (nof_bits + 8)); srslte_rm_conv_rx_s(q_bits, Q, q->encoded_cqi_s, 3 * (nof_bits + 8));
DEBUG("cconv_rx=", 0); DEBUG("cconv_rx=");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_s(stdout, q->encoded_cqi_s, 3 * (nof_bits + 8)); srslte_vec_fprint_s(stdout, q->encoded_cqi_s, 3 * (nof_bits + 8));
} }
srslte_viterbi_decode_s(&q->viterbi, q->encoded_cqi_s, q->tmp_cqi, nof_bits + 8); srslte_viterbi_decode_s(&q->viterbi, q->encoded_cqi_s, q->tmp_cqi, nof_bits + 8);
DEBUG("cqi_crc_rx=", 0); DEBUG("cqi_crc_rx=");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_b(stdout, q->tmp_cqi, nof_bits+8); srslte_vec_fprint_b(stdout, q->tmp_cqi, nof_bits+8);
} }

@ -150,7 +150,7 @@ int srslte_resample_arb_compute(srslte_resample_arb_t *q, cf_t *input, cf_t *out
res1 = srslte_resample_arb_dot_prod(filter_input, srslte_resample_arb_polyfilt[idx], SRSLTE_RESAMPLE_ARB_M); res1 = srslte_resample_arb_dot_prod(filter_input, srslte_resample_arb_polyfilt[idx], SRSLTE_RESAMPLE_ARB_M);
if(q->interpolate){ if(q->interpolate){
res2 = srslte_resample_arb_dot_prod(filter_input, srslte_resample_arb_polyfilt[(idx%SRSLTE_RESAMPLE_ARB_N)+1], SRSLTE_RESAMPLE_ARB_M); res2 = srslte_resample_arb_dot_prod(filter_input, srslte_resample_arb_polyfilt[(idx+1)%SRSLTE_RESAMPLE_ARB_N], SRSLTE_RESAMPLE_ARB_M);
} }
if(idx == SRSLTE_RESAMPLE_ARB_N){ if(idx == SRSLTE_RESAMPLE_ARB_N){

@ -97,7 +97,11 @@ char* rf_soapy_devname(void* h)
bool rf_soapy_rx_wait_lo_locked(void *h) bool rf_soapy_rx_wait_lo_locked(void *h)
{ {
printf("TODO: implement rf_soapy_rx_wait_lo_locked()\n"); rf_soapy_handler_t *handler = (rf_soapy_handler_t*)h;
char *ret = SoapySDRDevice_readChannelSensor(handler->device, SOAPY_SDR_RX, 0, "lo_locked");
if (ret != NULL) {
return (strcmp(ret, "true") == 0 ? true : false);
}
return true; return true;
} }
@ -197,14 +201,13 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
printf("No Soapy devices found.\n"); printf("No Soapy devices found.\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
char* devname; char* devname = NULL;
for (size_t i = 0; i < length; i++) { for (size_t i = 0; i < length; i++) {
printf("Soapy has Found device #%d: ", (int)i); printf("Soapy has found device #%d: ", (int)i);
for (size_t j = 0; j < soapy_args[i].size; j++) { for (size_t j = 0; j < soapy_args[i].size; j++) {
printf("%s=%s, ", soapy_args[i].keys[j], soapy_args[i].vals[j]); printf("%s=%s, ", soapy_args[i].keys[j], soapy_args[i].vals[j]);
if(!strcmp(soapy_args[i].keys[j],"name") && !strcmp(soapy_args[i].vals[j], "LimeSDR-USB")){ if(!strcmp(soapy_args[i].keys[j],"name") && !strcmp(soapy_args[i].vals[j], "LimeSDR-USB")){
devname = DEVNAME_LIME; devname = DEVNAME_LIME;
} }
} }
printf("\n"); printf("\n");
@ -212,7 +215,7 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
SoapySDRDevice *sdr = SoapySDRDevice_make(&(soapy_args[0])); SoapySDRDevice *sdr = SoapySDRDevice_make(&(soapy_args[0]));
if (sdr == NULL) { if (sdr == NULL) {
printf("failed to create SOAPY object\n"); printf("Failed to create Soapy object\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -225,7 +228,7 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
handler->rx_stream_active = false; handler->rx_stream_active = false;
handler->devname = devname; handler->devname = devname;
if(SoapySDRDevice_getNumChannels(handler->device,SOAPY_SDR_RX) > 0){ if(SoapySDRDevice_getNumChannels(handler->device,SOAPY_SDR_RX) > 0){
printf("setting up RX stream\n"); printf("Setting up RX stream\n");
if(SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) { if(SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) {
printf("Rx setupStream fail: %s\n", SoapySDRDevice_lastError()); printf("Rx setupStream fail: %s\n", SoapySDRDevice_lastError());
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -233,19 +236,27 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
} }
if(SoapySDRDevice_getNumChannels(handler->device,SOAPY_SDR_TX) > 0){ if(SoapySDRDevice_getNumChannels(handler->device,SOAPY_SDR_TX) > 0){
printf("setting up TX stream\n"); printf("Setting up TX stream\n");
if (SoapySDRDevice_setupStream(handler->device, &(handler->txStream), SOAPY_SDR_TX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) { if (SoapySDRDevice_setupStream(handler->device, &(handler->txStream), SOAPY_SDR_TX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) {
printf("Tx setupStream fail: %s\n", SoapySDRDevice_lastError()); printf("Tx setupStream fail: %s\n", SoapySDRDevice_lastError());
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
} }
// list device sensors
size_t sensor_length; size_t sensor_length;
char** sensors; char** sensors;
sensors = SoapySDRDevice_listSensors(handler->device, &sensor_length); sensors = SoapySDRDevice_listSensors(handler->device, &sensor_length);
for(int i = 0; i < sensor_length;i++) printf("Available device sensors: \n");
{ for(int i = 0; i < sensor_length; i++) {
printf("available sensors are : \n"); printf(" - %s\n", sensors[i]);
puts(sensors[i]); }
// list channel sensors
sensors = SoapySDRDevice_listChannelSensors(handler->device, SOAPY_SDR_RX, 0, &sensor_length);
printf("Available sensors for RX channel 0: \n");
for(int i = 0; i < sensor_length; i++) {
printf(" - %s\n", sensors[i]);
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
@ -399,7 +410,7 @@ void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs)
//TODO: add multi-channel support //TODO: add multi-channel support
int rf_soapy_recv_with_time_multi(void *h, int rf_soapy_recv_with_time_multi(void *h,
void **data, void *data[SRSLTE_MAX_PORTS],
uint32_t nsamples, uint32_t nsamples,
bool blocking, bool blocking,
time_t *secs, time_t *secs,
@ -408,6 +419,7 @@ int rf_soapy_recv_with_time_multi(void *h,
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
int flags; //flags set by receive operation int flags; //flags set by receive operation
int num_channels = 1; // temp int num_channels = 1; // temp
const long timeoutUs = 1000000; // arbitrarily chosen
int trials = 0; int trials = 0;
int ret = 0; int ret = 0;
@ -424,7 +436,7 @@ int rf_soapy_recv_with_time_multi(void *h,
cf_t *data_c = (cf_t*) data[i]; cf_t *data_c = (cf_t*) data[i];
buffs_ptr[i] = &data_c[n]; buffs_ptr[i] = &data_c[n];
} }
ret = SoapySDRDevice_readStream(handler->device, handler->rxStream, buffs_ptr, rx_samples, &flags, &timeNs, 1000000); ret = SoapySDRDevice_readStream(handler->device, handler->rxStream, buffs_ptr, rx_samples, &flags, &timeNs, timeoutUs);
if(ret < 0) { if(ret < 0) {
// continue when getting overflows // continue when getting overflows
if (ret == SOAPY_SDR_OVERFLOW) { if (ret == SOAPY_SDR_OVERFLOW) {
@ -446,8 +458,6 @@ int rf_soapy_recv_with_time_multi(void *h,
n += ret; n += ret;
trials++; trials++;
} while (n < nsamples && trials < 100); } while (n < nsamples && trials < 100);
return n; return n;
} }

@ -562,7 +562,10 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels)
perror("pthread_create"); perror("pthread_create");
return -1; return -1;
} }
/* Restore priorities */
uhd_set_thread_priority(0, false);
return 0; return 0;
} else { } else {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
@ -708,13 +711,12 @@ int rf_uhd_recv_with_time(void *h,
} }
int rf_uhd_recv_with_time_multi(void *h, int rf_uhd_recv_with_time_multi(void *h,
void **data, void *data[SRSLTE_MAX_PORTS],
uint32_t nsamples, uint32_t nsamples,
bool blocking, bool blocking,
time_t *secs, time_t *secs,
double *frac_secs) double *frac_secs)
{ {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_rx_metadata_handle *md = &handler->rx_md_first; uhd_rx_metadata_handle *md = &handler->rx_md_first;
size_t rxd_samples = 0; size_t rxd_samples = 0;

@ -117,7 +117,7 @@ int rf_mib_decoder(srslte_rf_t *rf, uint32_t nof_rx_antennas,cell_search_cfg_t *
INFO("Setting sampling frequency %.2f MHz for PSS search\n", (float) srate/1000000); INFO("Setting sampling frequency %.2f MHz for PSS search\n", (float) srate/1000000);
srslte_rf_set_rx_srate(rf, (float) srate); srslte_rf_set_rx_srate(rf, (float) srate);
INFO("Starting receiver...\n", 0); INFO("Starting receiver...\n");
srslte_rf_start_rx_stream(rf, false); srslte_rf_start_rx_stream(rf, false);
// Copy CFO estimate if provided and disable CP estimation during find // Copy CFO estimate if provided and disable CP estimation during find
@ -174,7 +174,7 @@ int rf_cell_search(srslte_rf_t *rf, uint32_t nof_rx_antennas,
INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000); INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000);
srslte_rf_set_rx_srate(rf, SRSLTE_CS_SAMP_FREQ); srslte_rf_set_rx_srate(rf, SRSLTE_CS_SAMP_FREQ);
INFO("Starting receiver...\n", 0); INFO("Starting receiver...\n");
srslte_rf_start_rx_stream(rf, false); srslte_rf_start_rx_stream(rf, false);
/* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */

@ -178,7 +178,6 @@ int srslte_sync_resize(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offse
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (q != NULL && if (q != NULL &&
frame_size <= 307200 &&
fft_size_isvalid(fft_size)) fft_size_isvalid(fft_size))
{ {
if (frame_size > q->max_frame_size) { if (frame_size > q->max_frame_size) {

@ -381,17 +381,6 @@ int srslte_ue_dl_decode_fft_estimate_mbsfn(srslte_ue_dl_t *q, uint32_t sf_idx, u
}else{ }else{
srslte_ofdm_rx_sf(&q->fft[j]); srslte_ofdm_rx_sf(&q->fft[j]);
} }
/* Correct SFO multiplying by complex exponential in the time domain */
if (q->sample_offset) {
int nsym = (sf_type == SRSLTE_SF_MBSFN)?SRSLTE_CP_EXT_NSYMB:SRSLTE_CP_NSYMB(q->cell.cp);
for (int i=0;i<2*nsym;i++) {
srslte_cfo_correct(&q->sfo_correct,
&q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE],
&q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE],
q->sample_offset / q->fft[j].symbol_sz);
}
}
} }
return srslte_ue_dl_decode_estimate_mbsfn(q, sf_idx, cfi, sf_type); return srslte_ue_dl_decode_estimate_mbsfn(q, sf_idx, cfi, sf_type);
} else { } else {
@ -561,6 +550,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q,
switch(dci_msg.format) { switch(dci_msg.format) {
case SRSLTE_DCI_FORMAT1: case SRSLTE_DCI_FORMAT1:
case SRSLTE_DCI_FORMAT1A: case SRSLTE_DCI_FORMAT1A:
case SRSLTE_DCI_FORMAT1C:
if (q->cell.nof_ports == 1) { if (q->cell.nof_ports == 1) {
mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
} else { } else {
@ -584,7 +574,6 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q,
/* Not implemented formats */ /* Not implemented formats */
case SRSLTE_DCI_FORMAT0: case SRSLTE_DCI_FORMAT0:
case SRSLTE_DCI_FORMAT1C:
case SRSLTE_DCI_FORMAT1B: case SRSLTE_DCI_FORMAT1B:
case SRSLTE_DCI_FORMAT1D: case SRSLTE_DCI_FORMAT1D:
case SRSLTE_DCI_FORMAT2B: case SRSLTE_DCI_FORMAT2B:

@ -751,7 +751,7 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE
break; break;
case SRSLTE_SYNC_FOUND_NOSPACE: case SRSLTE_SYNC_FOUND_NOSPACE:
/* If a peak was found but there is not enough space for SSS/CP detection, discard a few samples */ /* If a peak was found but there is not enough space for SSS/CP detection, discard a few samples */
INFO("No space for SSS/CP detection. Realigning frame...\n",0); INFO("No space for SSS/CP detection. Realigning frame...\n");
q->recv_callback(q->stream, dummy_offset_buffer, q->frame_len/2, NULL); q->recv_callback(q->stream, dummy_offset_buffer, q->frame_len/2, NULL);
srslte_sync_reset(&q->sfind); srslte_sync_reset(&q->sfind);
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;

@ -444,7 +444,6 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (q != NULL && if (q != NULL &&
softbuffer != NULL &&
output_signal != NULL) output_signal != NULL)
{ {

@ -49,8 +49,8 @@ bool verbose = false;
#define RANDOM_F() ((float)rand())/((float)RAND_MAX) #define RANDOM_F() ((float)rand())/((float)RAND_MAX)
#define RANDOM_S() ((int16_t)(rand() && 0x800F)) #define RANDOM_S() ((int16_t)(rand() & 0x800F))
#define RANDOM_B() ((int8_t)(rand() && 0x8008)) #define RANDOM_B() ((int8_t)(rand() & 0x8008))
#define RANDOM_CF() (RANDOM_F() + _Complex_I*RANDOM_F()) #define RANDOM_CF() (RANDOM_F() + _Complex_I*RANDOM_F())
#define TEST_CALL(TEST_CODE) gettimeofday(&start, NULL);\ #define TEST_CALL(TEST_CODE) gettimeofday(&start, NULL);\
@ -137,7 +137,7 @@ TEST(srslte_vec_dot_prod_sss,
MALLOC(int16_t, y); MALLOC(int16_t, y);
int16_t z; int16_t z;
cf_t gold = 0.0f; int16_t gold = 0.0f;
for (int i = 0; i < block_size; i++) { for (int i = 0; i < block_size; i++) {
x[i] = RANDOM_S(); x[i] = RANDOM_S();
y[i] = RANDOM_S(); y[i] = RANDOM_S();
@ -149,7 +149,7 @@ TEST(srslte_vec_dot_prod_sss,
gold += x[i] * y[i]; gold += x[i] * y[i];
} }
mse += cabsf(gold - z) / cabsf(gold); mse = (gold - z) / abs(gold);
free(x); free(x);
free(y); free(y);
@ -160,7 +160,7 @@ TEST(srslte_vec_sum_sss,
MALLOC(int16_t, y); MALLOC(int16_t, y);
MALLOC(int16_t, z); MALLOC(int16_t, z);
cf_t gold = 0.0f; int16_t gold = 0;
for (int i = 0; i < block_size; i++) { for (int i = 0; i < block_size; i++) {
x[i] = RANDOM_S(); x[i] = RANDOM_S();
y[i] = RANDOM_S(); y[i] = RANDOM_S();
@ -170,7 +170,7 @@ TEST(srslte_vec_sum_sss,
for (int i = 0; i < block_size; i++) { for (int i = 0; i < block_size; i++) {
gold = x[i] + y[i]; gold = x[i] + y[i];
mse += cabsf(gold - z[i]); mse += abs(gold - z[i]);
} }
free(x); free(x);
@ -183,7 +183,7 @@ TEST(srslte_vec_sub_sss,
MALLOC(int16_t, y); MALLOC(int16_t, y);
MALLOC(int16_t, z); MALLOC(int16_t, z);
cf_t gold = 0.0f; int16_t gold = 0.0f;
for (int i = 0; i < block_size; i++) { for (int i = 0; i < block_size; i++) {
x[i] = RANDOM_S(); x[i] = RANDOM_S();
y[i] = RANDOM_S(); y[i] = RANDOM_S();
@ -193,7 +193,7 @@ TEST(srslte_vec_sub_sss,
for (int i = 0; i < block_size; i++) { for (int i = 0; i < block_size; i++) {
gold = x[i] - y[i]; gold = x[i] - y[i];
mse += cabsf(gold - z[i]); mse += abs(gold - z[i]);
} }
free(x); free(x);
@ -206,7 +206,7 @@ TEST(srslte_vec_prod_sss,
MALLOC(int16_t, y); MALLOC(int16_t, y);
MALLOC(int16_t, z); MALLOC(int16_t, z);
cf_t gold = 0.0f; int16_t gold = 0.0f;
for (int i = 0; i < block_size; i++) { for (int i = 0; i < block_size; i++) {
x[i] = RANDOM_S(); x[i] = RANDOM_S();
y[i] = RANDOM_S(); y[i] = RANDOM_S();
@ -216,7 +216,7 @@ TEST(srslte_vec_prod_sss,
for (int i = 0; i < block_size; i++) { for (int i = 0; i < block_size; i++) {
gold = x[i] * y[i]; gold = x[i] * y[i];
mse += cabsf(gold - z[i]); mse += abs(gold - z[i]);
} }
free(x); free(x);
@ -802,16 +802,18 @@ int main(int argc, char **argv) {
size_count++; size_count++;
} }
char fname[68]; char fname[69];
FILE *f = NULL; FILE *f = NULL;
void * p = popen("(date +%g%m%d && hostname) | tr '\\r\\n' '__'", "r"); void * p = popen("(date +%g%m%d && hostname) | tr '\\r\\n' '__'", "r");
if (p) { if (p) {
fgets(fname, 64, p); fgets(fname, 64, p);
strncpy(fname + strnlen(fname, 64) - 1, ".tsv", 4); strncpy(fname + strnlen(fname, 64) - 1, ".tsv", 5);
f = fopen(fname, "w"); f = fopen(fname, "w");
if (f) printf("Saving benchmark results in '%s'\n", fname); if (f) {
printf("Saving benchmark results in '%s'\n", fname);
}
pclose(p);
} }
pclose(p);
printf("\n"); printf("\n");

@ -433,6 +433,7 @@ cf_t srslte_vec_dot_prod_ccc_simd(const cf_t *x, const cf_t *y, const int len) {
return result; return result;
} }
#ifdef ENABLE_C16
c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len) { c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len) {
int i = 0; int i = 0;
c16_t result = 0; c16_t result = 0;
@ -460,6 +461,7 @@ c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const in
return result; return result;
} }
#endif /* ENABLE_C16 */
cf_t srslte_vec_dot_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, const int len) cf_t srslte_vec_dot_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, const int len)
{ {
@ -620,6 +622,7 @@ void srslte_vec_prod_ccc_split_simd(const float *a_re, const float *a_im, const
} }
} }
#ifdef ENABLE_C16
void srslte_vec_prod_ccc_c16_simd(const int16_t *a_re, const int16_t *a_im, const int16_t *b_re, const int16_t *b_im, void srslte_vec_prod_ccc_c16_simd(const int16_t *a_re, const int16_t *a_im, const int16_t *b_re, const int16_t *b_im,
int16_t *r_re, int16_t *r_im, const int len) { int16_t *r_re, int16_t *r_im, const int len) {
int i = 0; int i = 0;
@ -652,6 +655,7 @@ void srslte_vec_prod_ccc_c16_simd(const int16_t *a_re, const int16_t *a_im, cons
r_im[i] = a_re[i]*b_im[i] + a_im[i]*b_re[i]; r_im[i] = a_re[i]*b_im[i] + a_im[i]*b_re[i];
} }
} }
#endif /* ENABLE_C16 */
void srslte_vec_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len) { void srslte_vec_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len) {
int i = 0; int i = 0;

@ -52,11 +52,6 @@ void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_
void pdcp::stop() void pdcp::stop()
{ {
for(uint32_t i=0;i<SRSLTE_N_RADIO_BEARERS;i++) {
if (pdcp_array[i].is_active()) {
pdcp_array[i].stop();
}
}
} }
void pdcp::reestablish() { void pdcp::reestablish() {

@ -62,20 +62,9 @@ void pdcp_entity::init(srsue::rlc_interface_pdcp *rlc_,
sn_len_bytes = (cfg.sn_len+7)/8; sn_len_bytes = (cfg.sn_len+7)/8;
} }
start(PDCP_THREAD_PRIO);
log->debug("Init %s\n", rrc->get_rb_name(lcid).c_str()); log->debug("Init %s\n", rrc->get_rb_name(lcid).c_str());
} }
void pdcp_entity::stop()
{
if(running) {
running = false;
thread_cancel();
wait_thread_finish();
}
}
// Reestablishment procedure: 36.323 5.2 // Reestablishment procedure: 36.323 5.2
void pdcp_entity::reestablish() { void pdcp_entity::reestablish() {
// For SRBs // For SRBs
@ -165,7 +154,53 @@ void pdcp_entity::enable_encryption()
// RLC interface // RLC interface
void pdcp_entity::write_pdu(byte_buffer_t *pdu) void pdcp_entity::write_pdu(byte_buffer_t *pdu)
{ {
rx_pdu_queue.write(pdu); log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU, do_integrity = %s, do_encryption = %s",
rrc->get_rb_name(lcid).c_str(), (do_integrity) ? "true" : "false", (do_encryption) ? "true" : "false");
// Handle DRB messages
if (cfg.is_data) {
uint32_t sn;
if (do_encryption) {
cipher_decrypt(&(pdu->msg[sn_len_bytes]),
rx_count,
pdu->N_bytes - sn_len_bytes,
&(pdu->msg[sn_len_bytes]));
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
}
if(12 == cfg.sn_len)
{
pdcp_unpack_data_pdu_long_sn(pdu, &sn);
} else {
pdcp_unpack_data_pdu_short_sn(pdu, &sn);
}
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU SN: %d", rrc->get_rb_name(lcid).c_str(), sn);
gw->write_pdu(lcid, pdu);
} else {
// Handle SRB messages
if (cfg.is_control) {
uint32_t sn;
if (do_encryption) {
cipher_decrypt(&(pdu->msg[sn_len_bytes]),
rx_count,
pdu->N_bytes - sn_len_bytes,
&(pdu->msg[sn_len_bytes]));
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
}
if (do_integrity) {
integrity_verify(pdu->msg,
rx_count,
pdu->N_bytes - 4,
&(pdu->msg[pdu->N_bytes - 4]));
}
pdcp_unpack_control_pdu(pdu, &sn);
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU SN: %d", rrc->get_rb_name(lcid).c_str(), sn);
}
// pass to RRC
rrc->write_pdu(lcid, pdu);
}
rx_count++;
} }
void pdcp_entity::integrity_generate( uint8_t *msg, void pdcp_entity::integrity_generate( uint8_t *msg,
@ -332,63 +367,6 @@ void pdcp_entity::cipher_decrypt(uint8_t *ct,
} }
void pdcp_entity::run_thread()
{
byte_buffer_t *pdu;
running = true;
while(running) {
rx_pdu_queue.read(&pdu);
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU, do_integrity = %s, do_encryption = %s",
rrc->get_rb_name(lcid).c_str(), (do_integrity) ? "true" : "false", (do_encryption) ? "true" : "false");
// Handle DRB messages
if (cfg.is_data) {
uint32_t sn;
if (do_encryption) {
cipher_decrypt(&(pdu->msg[sn_len_bytes]),
rx_count,
pdu->N_bytes - sn_len_bytes,
&(pdu->msg[sn_len_bytes]));
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
}
if(12 == cfg.sn_len)
{
pdcp_unpack_data_pdu_long_sn(pdu, &sn);
} else {
pdcp_unpack_data_pdu_short_sn(pdu, &sn);
}
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU SN: %d", rrc->get_rb_name(lcid).c_str(), sn);
gw->write_pdu(lcid, pdu);
} else {
// Handle SRB messages
if (cfg.is_control) {
uint32_t sn;
if (do_encryption) {
cipher_decrypt(&(pdu->msg[sn_len_bytes]),
rx_count,
pdu->N_bytes - sn_len_bytes,
&(pdu->msg[sn_len_bytes]));
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
}
if (do_integrity) {
integrity_verify(pdu->msg,
rx_count,
pdu->N_bytes - 4,
&(pdu->msg[pdu->N_bytes - 4]));
}
pdcp_unpack_control_pdu(pdu, &sn);
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU SN: %d", rrc->get_rb_name(lcid).c_str(), sn);
}
// pass to RRC
rrc->write_pdu(lcid, pdu);
}
rx_count++;
}
}
uint8_t pdcp_entity::get_bearer_id(uint8_t lcid) uint8_t pdcp_entity::get_bearer_id(uint8_t lcid)
{ {
#define RB_ID_SRB2 2 #define RB_ID_SRB2 2

@ -175,8 +175,8 @@ uint32_t rlc_am::get_bearer()
void rlc_am::write_sdu(byte_buffer_t *sdu) void rlc_am::write_sdu(byte_buffer_t *sdu)
{ {
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str());
tx_sdu_queue.write(sdu); tx_sdu_queue.write(sdu);
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size());
} }
/**************************************************************************** /****************************************************************************
@ -682,7 +682,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
tx_sdu->msg += to_move; tx_sdu->msg += to_move;
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;
@ -717,7 +717,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
tx_sdu->msg += to_move; tx_sdu->msg += to_move;
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;

@ -111,7 +111,7 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes)
ul_queue.read(&buf); ul_queue.read(&buf);
pdu_size = buf->N_bytes; pdu_size = buf->N_bytes;
memcpy(payload, buf->msg, buf->N_bytes); memcpy(payload, buf->msg, buf->N_bytes);
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), buf->get_latency_us()); rrc->get_rb_name(lcid).c_str(), buf->get_latency_us());
pool->deallocate(buf); pool->deallocate(buf);
log->info_hex(payload, pdu_size, "TX %s, %s PDU", rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM]); log->info_hex(payload, pdu_size, "TX %s, %s PDU", rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM]);

@ -153,8 +153,8 @@ uint32_t rlc_um::get_bearer()
void rlc_um::write_sdu(byte_buffer_t *sdu) void rlc_um::write_sdu(byte_buffer_t *sdu)
{ {
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str());
tx_sdu_queue.write(sdu); tx_sdu_queue.write(sdu);
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size());
} }
/**************************************************************************** /****************************************************************************
@ -178,7 +178,7 @@ uint32_t rlc_um::get_buffer_state()
// Room needed for fixed header? // Room needed for fixed header?
if(n_bytes > 0) if(n_bytes > 0)
n_bytes += 2; n_bytes += 3;
return n_bytes; return n_bytes;
} }
@ -300,7 +300,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
tx_sdu->msg += to_move; tx_sdu->msg += to_move;
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;
@ -329,7 +329,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
tx_sdu->msg += to_move; tx_sdu->msg += to_move;
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;

@ -117,7 +117,7 @@ void basic_test()
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(&sdu_bufs[i]);
} }
assert(13 == rlc1.get_buffer_state()); assert(14 == rlc1.get_buffer_state());
// Read 5 PDUs from RLC1 (1 byte each) // Read 5 PDUs from RLC1 (1 byte each)
byte_buffer_t pdu_bufs[NBUFS]; byte_buffer_t pdu_bufs[NBUFS];
@ -185,7 +185,7 @@ void loss_test()
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(&sdu_bufs[i]);
} }
assert(13 == rlc1.get_buffer_state()); assert(14 == rlc1.get_buffer_state());
// Read 5 PDUs from RLC1 (1 byte each) // Read 5 PDUs from RLC1 (1 byte each)
byte_buffer_t pdu_bufs[NBUFS]; byte_buffer_t pdu_bufs[NBUFS];

@ -97,6 +97,7 @@ typedef struct {
typedef struct { typedef struct {
std::string phy_level; std::string phy_level;
std::string phy_lib_level;
std::string mac_level; std::string mac_level;
std::string rlc_level; std::string rlc_level;
std::string pdcp_level; std::string pdcp_level;

@ -121,7 +121,7 @@ private:
static const uint32_t cfi = 3; static const uint32_t cfi = 3;
srslte_dci_location_t locations[MAX_LOCATIONS]; srslte_dci_location_t locations[MAX_LOCATIONS];
static const int MAC_PDU_THREAD_PRIO = 3; static const int MAC_PDU_THREAD_PRIO = 60;

@ -102,8 +102,8 @@ public:
ul_alloc_t get_alloc(); ul_alloc_t get_alloc();
void set_alloc(ul_alloc_t alloc); void set_alloc(ul_alloc_t alloc);
void same_alloc(); void re_alloc(ul_alloc_t alloc);
bool is_adaptive_retx(); bool is_adaptive_retx();
void reset_pending_data(); void reset_pending_data();
bool has_pending_ack(); bool has_pending_ack();

@ -84,7 +84,7 @@ public:
private: private:
static const int THREAD_PRIO = 7; static const int THREAD_PRIO = 65;
static const int GTPU_PORT = 2152; static const int GTPU_PORT = 2152;
srslte::byte_buffer_pool *pool; srslte::byte_buffer_pool *pool;
bool running; bool running;

@ -321,7 +321,7 @@ private:
const static uint32_t LCID_REM_USER = 0xffff0001; const static uint32_t LCID_REM_USER = 0xffff0001;
bool running; bool running;
static const int RRC_THREAD_PRIO = 7; static const int RRC_THREAD_PRIO = 65;
srslte::block_queue<rrc_pdu> rx_pdu_queue; srslte::block_queue<rrc_pdu> rx_pdu_queue;
typedef struct { typedef struct {

@ -85,7 +85,7 @@ public:
//void ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps); //void ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps);
private: private:
static const int S1AP_THREAD_PRIO = 7; static const int S1AP_THREAD_PRIO = 65;
static const int MME_PORT = 36412; static const int MME_PORT = 36412;
static const int ADDR_FAMILY = AF_INET; static const int ADDR_FAMILY = AF_INET;
static const int SOCK_TYPE = SOCK_STREAM; static const int SOCK_TYPE = SOCK_STREAM;

@ -715,7 +715,8 @@ int enb::parse_sib9(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_9_STRUC
if (!parser::parse_section(filename, &sib9)) { if (!parser::parse_section(filename, &sib9)) {
data->hnb_name_present = true; data->hnb_name_present = true;
if (name_enabled) { if (name_enabled) {
strncpy((char*) data->hnb_name, hnb_name.c_str(), 48); strncpy((char*) data->hnb_name, hnb_name.c_str(), 47);
data->hnb_name[47] = 0;
data->hnb_name_size = strnlen(hnb_name.c_str(), 48); data->hnb_name_size = strnlen(hnb_name.c_str(), 48);
} else if (hex_enabled) { } else if (hex_enabled) {
data->hnb_name_size = HexToBytes(hex_value, data->hnb_name, 48); data->hnb_name_size = HexToBytes(hex_value, data->hnb_name, 48);

@ -392,7 +392,7 @@ int mac::rach_detected(uint32_t tti, uint32_t preamble_idx, uint32_t time_adv)
// Find empty slot for pending rars // Find empty slot for pending rars
uint32_t ra_id=0; uint32_t ra_id=0;
while(pending_rars[ra_id].temp_crnti && ra_id<MAX_PENDING_RARS) { while(pending_rars[ra_id].temp_crnti && ra_id<MAX_PENDING_RARS-1) {
ra_id++; ra_id++;
} }
if (ra_id == MAX_PENDING_RARS) { if (ra_id == MAX_PENDING_RARS) {

@ -199,13 +199,14 @@ ul_harq_proc::ul_alloc_t ul_harq_proc::get_alloc()
void ul_harq_proc::set_alloc(ul_harq_proc::ul_alloc_t alloc) void ul_harq_proc::set_alloc(ul_harq_proc::ul_alloc_t alloc)
{ {
is_adaptive = false; is_adaptive = false;
memcpy(&allocation, &alloc, sizeof(ul_alloc_t)); memcpy(&allocation, &alloc, sizeof(ul_alloc_t));
} }
void ul_harq_proc::same_alloc() void ul_harq_proc::re_alloc(ul_harq_proc::ul_alloc_t alloc)
{ {
is_adaptive = true; is_adaptive = true;
memcpy(&allocation, &alloc, sizeof(ul_alloc_t));
} }
bool ul_harq_proc::is_adaptive_retx() bool ul_harq_proc::is_adaptive_retx()

@ -313,15 +313,14 @@ ul_harq_proc* ul_metric_rr::get_user_allocation(sched_ue *user)
// If can schedule the same mask, do it // If can schedule the same mask, do it
if (allocation_is_valid(alloc)) { if (allocation_is_valid(alloc)) {
update_allocation(alloc); update_allocation(alloc);
h->same_alloc(); return h;
return h;
} }
// If not, try to find another mask in the current tti // If not, try to find another mask in the current tti
if (new_allocation(alloc.L, &alloc)) { if (new_allocation(alloc.L, &alloc)) {
update_allocation(alloc); update_allocation(alloc);
h->set_alloc(alloc); h->set_alloc(alloc);
return h; return h;
} }
} }
// If could not schedule the reTx, or there wasn't any pending retx, find an empty PID // If could not schedule the reTx, or there wasn't any pending retx, find an empty PID

@ -212,6 +212,7 @@ bool sched_ue::pucch_sr_collision(uint32_t current_tti, uint32_t n_cce)
return false; return false;
} }
srslte_pucch_sched_t pucch_sched; srslte_pucch_sched_t pucch_sched;
pucch_sched.sps_enabled = false;
pucch_sched.n_pucch_sr = cfg.sr_N_pucch; pucch_sched.n_pucch_sr = cfg.sr_N_pucch;
pucch_sched.n_pucch_2 = cfg.n_pucch_cqi; pucch_sched.n_pucch_2 = cfg.n_pucch_cqi;
pucch_sched.N_pucch_1 = cfg.pucch_cfg.n1_pucch_an; pucch_sched.N_pucch_1 = cfg.pucch_cfg.n1_pucch_an;

@ -256,7 +256,7 @@ void ue::push_pdu(uint32_t tti, uint32_t len)
bool ue::process_ce(srslte::sch_subh *subh) { bool ue::process_ce(srslte::sch_subh *subh) {
uint32_t buff_size[4] = {0, 0, 0, 0}; uint32_t buff_size[4] = {0, 0, 0, 0};
float phr = 0; float phr = 0;
int idx = 0; int32_t idx = 0;
uint16_t old_rnti = 0; uint16_t old_rnti = 0;
bool is_bsr = false; bool is_bsr = false;
switch(subh->ce_type()) { switch(subh->ce_type()) {
@ -279,6 +279,10 @@ bool ue::process_ce(srslte::sch_subh *subh) {
case srslte::sch_subh::TRUNC_BSR: case srslte::sch_subh::TRUNC_BSR:
case srslte::sch_subh::SHORT_BSR: case srslte::sch_subh::SHORT_BSR:
idx = subh->get_bsr(buff_size); idx = subh->get_bsr(buff_size);
if(idx == -1){
Error("Invalid Index Passed to lc groups\n");
break;
}
for (uint32_t i=0;i<lc_groups[idx].size();i++) { for (uint32_t i=0;i<lc_groups[idx].size();i++) {
// Indicate BSR to scheduler // Indicate BSR to scheduler
sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]); sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]);
@ -289,7 +293,7 @@ bool ue::process_ce(srslte::sch_subh *subh) {
break; break;
case srslte::sch_subh::LONG_BSR: case srslte::sch_subh::LONG_BSR:
subh->get_bsr(buff_size); subh->get_bsr(buff_size);
for (int idx=0;idx<4;idx++) { for (idx=0;idx<4;idx++) {
for (uint32_t i=0;i<lc_groups[idx].size();i++) { for (uint32_t i=0;i<lc_groups[idx].size();i++) {
sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]); sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]);
} }
@ -320,7 +324,7 @@ void ue::allocate_sdu(srslte::sch_pdu *pdu, uint32_t lcid, uint32_t total_sdu_le
if (sdu_space > 0) { if (sdu_space > 0) {
int sdu_len = SRSLTE_MIN(total_sdu_len, (uint32_t) sdu_space); int sdu_len = SRSLTE_MIN(total_sdu_len, (uint32_t) sdu_space);
int n=1; int n=1;
while(sdu_len > 0 && n > 0) { while(sdu_len > 3 && n > 0) {
if (pdu->new_subh()) { // there is space for a new subheader if (pdu->new_subh()) { // there is space for a new subheader
log_h->debug("SDU: set_sdu(), lcid=%d, sdu_len=%d, sdu_space=%d\n", lcid, sdu_len, sdu_space); log_h->debug("SDU: set_sdu(), lcid=%d, sdu_len=%d, sdu_space=%d\n", lcid, sdu_len, sdu_space);
n = pdu->get()->set_sdu(lcid, sdu_len, this); n = pdu->get()->set_sdu(lcid, sdu_len, this);

@ -104,6 +104,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
("log.phy_level", bpo::value<string>(&args->log.phy_level), "PHY log level") ("log.phy_level", bpo::value<string>(&args->log.phy_level), "PHY log level")
("log.phy_hex_limit", bpo::value<int>(&args->log.phy_hex_limit), "PHY log hex dump limit") ("log.phy_hex_limit", bpo::value<int>(&args->log.phy_hex_limit), "PHY log hex dump limit")
("log.phy_lib_level", bpo::value<string>(&args->log.phy_lib_level)->default_value("none"), "PHY lib log level")
("log.mac_level", bpo::value<string>(&args->log.mac_level), "MAC log level") ("log.mac_level", bpo::value<string>(&args->log.mac_level), "MAC log level")
("log.mac_hex_limit", bpo::value<int>(&args->log.mac_hex_limit), "MAC log hex dump limit") ("log.mac_hex_limit", bpo::value<int>(&args->log.mac_hex_limit), "MAC log hex dump limit")
("log.rlc_level", bpo::value<string>(&args->log.rlc_level), "RLC log level") ("log.rlc_level", bpo::value<string>(&args->log.rlc_level), "RLC log level")
@ -274,6 +275,9 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
if(!vm.count("log.phy_level")) { if(!vm.count("log.phy_level")) {
args->log.phy_level = args->log.all_level; args->log.phy_level = args->log.all_level;
} }
if (!vm.count("log.phy_lib_level")) {
args->log.phy_lib_level = args->log.all_level;
}
if(!vm.count("log.mac_level")) { if(!vm.count("log.mac_level")) {
args->log.mac_level = args->log.all_level; args->log.mac_level = args->log.all_level;
} }
@ -340,14 +344,19 @@ void *input_loop(void *m)
char key; char key;
while(running) { while(running) {
cin >> key; cin >> key;
if('t' == key) { if (cin.eof() || cin.bad()) {
do_metrics = !do_metrics; cout << "Closing stdin thread." << endl;
if(do_metrics) { break;
cout << "Enter t to stop trace." << endl; } else {
} else { if('t' == key) {
cout << "Enter t to restart trace." << endl; do_metrics = !do_metrics;
if(do_metrics) {
cout << "Enter t to stop trace." << endl;
} else {
cout << "Enter t to restart trace." << endl;
}
metrics->toggle_print(do_metrics);
} }
metrics->toggle_print(do_metrics);
} }
} }
return NULL; return NULL;
@ -355,7 +364,8 @@ void *input_loop(void *m)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
signal(SIGINT, sig_int_handler); signal(SIGINT, sig_int_handler);
signal(SIGTERM, sig_int_handler);
all_args_t args; all_args_t args;
metrics_stdout metrics; metrics_stdout metrics;
enb *enb = enb::get_instance(); enb *enb = enb::get_instance();

@ -551,7 +551,7 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
ue_db[rnti].phich_info.n_prb_lowest = enb_ul.pusch_cfg.grant.n_prb_tilde[0]; ue_db[rnti].phich_info.n_prb_lowest = enb_ul.pusch_cfg.grant.n_prb_tilde[0];
ue_db[rnti].phich_info.n_dmrs = phy_grant.ncs_dmrs; ue_db[rnti].phich_info.n_dmrs = phy_grant.ncs_dmrs;
char cqi_str[64]; char cqi_str[SRSLTE_CQI_STR_MAX_CHAR];
if (cqi_enabled) { if (cqi_enabled) {
if (ue_db[rnti].cqi_en) { if (ue_db[rnti].cqi_en) {
wideband_cqi_value = cqi_value.wideband.wideband_cqi; wideband_cqi_value = cqi_value.wideband.wideband_cqi;
@ -578,7 +578,7 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
cqi_value.subband_hl.wideband_cqi_cw0, cqi_value.subband_hl.N); cqi_value.subband_hl.wideband_cqi_cw0, cqi_value.subband_hl.N);
} }
} }
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, 64); srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
//snprintf(cqi_str, 64, ", cqi=%s", wideband_cqi_value); //snprintf(cqi_str, 64, ", cqi=%s", wideband_cqi_value);
} }

@ -125,7 +125,7 @@ void gtpu::stop()
// gtpu_interface_pdcp // gtpu_interface_pdcp
void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu) void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu)
{ {
gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d", rnti, lcid); gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d, n_bytes=%d", rnti, lcid, pdu->N_bytes);
gtpu_header_t header; gtpu_header_t header;
header.flags = 0x30; header.flags = 0x30;
header.message_type = 0xFF; header.message_type = 0xFF;
@ -234,7 +234,7 @@ void gtpu::run_thread()
continue; continue;
} }
gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "RX GTPU PDU rnti=0x%x, lcid=%d", rnti, lcid); gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "RX GTPU PDU rnti=0x%x, lcid=%d, n_bytes=%d", rnti, lcid, pdu->N_bytes);
pdcp->write_sdu(rnti, lcid, pdu); pdcp->write_sdu(rnti, lcid, pdu);
do { do {

@ -153,8 +153,8 @@ void rlc::write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* sdu)
// communicate buffer state every time a new SDU is written // communicate buffer state every time a new SDU is written
uint32_t tx_queue = users[rnti].rlc->get_total_buffer_state(lcid); uint32_t tx_queue = users[rnti].rlc->get_total_buffer_state(lcid);
uint32_t retx_queue = 0; uint32_t retx_queue = 0;
log_h->info("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue);
mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue);
log_h->info("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue);
} else { } else {
pool->deallocate(sdu); pool->deallocate(sdu);
} }

@ -609,6 +609,7 @@ int setup_if_addr(char *ip_addr)
if(0 > ioctl(tun_fd, TUNSETIFF, &ifr)) if(0 > ioctl(tun_fd, TUNSETIFF, &ifr))
{ {
perror("ioctl1"); perror("ioctl1");
close(tun_fd);
return -1; return -1;
} }
@ -617,15 +618,21 @@ int setup_if_addr(char *ip_addr)
if(0 > ioctl(sock, SIOCGIFFLAGS, &ifr)) if(0 > ioctl(sock, SIOCGIFFLAGS, &ifr))
{ {
perror("socket"); perror("socket");
close(sock);
close(tun_fd);
return -1; return -1;
} }
ifr.ifr_flags |= IFF_UP | IFF_RUNNING; ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
if(0 > ioctl(sock, SIOCSIFFLAGS, &ifr)) if(0 > ioctl(sock, SIOCSIFFLAGS, &ifr))
{ {
perror("ioctl2"); perror("ioctl2");
close(sock);
close(tun_fd);
return -1; return -1;
} }
close(sock);
// Setup the IP address // Setup the IP address
sock = socket(AF_INET, SOCK_DGRAM, 0); sock = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET; ifr.ifr_addr.sa_family = AF_INET;
@ -633,6 +640,8 @@ int setup_if_addr(char *ip_addr)
if(0 > ioctl(sock, SIOCSIFADDR, &ifr)) if(0 > ioctl(sock, SIOCSIFADDR, &ifr))
{ {
perror("ioctl"); perror("ioctl");
close(sock);
close(tun_fd);
return -1; return -1;
} }
ifr.ifr_netmask.sa_family = AF_INET; ifr.ifr_netmask.sa_family = AF_INET;
@ -640,8 +649,12 @@ int setup_if_addr(char *ip_addr)
if(0 > ioctl(sock, SIOCSIFNETMASK, &ifr)) if(0 > ioctl(sock, SIOCSIFNETMASK, &ifr))
{ {
perror("ioctl"); perror("ioctl");
close(sock);
close(tun_fd);
return -1; return -1;
} }
close(sock);
return(tun_fd); return(tun_fd);
} }

@ -267,6 +267,8 @@ main (int argc,char * argv[] )
{ {
cout << endl <<"--- Software Radio Systems EPC ---" << endl << endl; cout << endl <<"--- Software Radio Systems EPC ---" << endl << endl;
signal(SIGINT, sig_int_handler); signal(SIGINT, sig_int_handler);
signal(SIGTERM, sig_int_handler);
signal(SIGKILL, sig_int_handler);
all_args_t args; all_args_t args;
parse_args(&args, argc, argv); parse_args(&args, argc, argv);

@ -112,8 +112,8 @@ public:
private: private:
void run_thread(); void run_thread();
static const int MAC_MAIN_THREAD_PRIO = 5; static const int MAC_MAIN_THREAD_PRIO = -1; // Use default high-priority below UHD
static const int MAC_PDU_THREAD_PRIO = 6; static const int MAC_PDU_THREAD_PRIO = -1;
static const int MAC_NOF_HARQ_PROC = 2*HARQ_DELAY_MS; static const int MAC_NOF_HARQ_PROC = 2*HARQ_DELAY_MS;
// Interaction with PHY // Interaction with PHY

@ -219,7 +219,13 @@ private:
// Receive and route HARQ feedbacks // Receive and route HARQ feedbacks
if (grant) { if (grant) {
if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi() && harq_feedback) || if (grant->has_cqi_request && grant->phy_grant.ul.mcs.tbs == 0) {
/* Only CQI reporting (without SCH) */
memcpy(&action->phy_grant.ul, &grant->phy_grant.ul, sizeof(srslte_ra_ul_grant_t));
memcpy(&cur_grant, grant, sizeof(Tgrant));
action->tx_enabled = true;
action->rnti = grant->rnti;
} else if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi() && harq_feedback) ||
(grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) || (grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) ||
grant->is_from_rar) grant->is_from_rar)
{ {

@ -47,10 +47,11 @@ class metrics_csv : public srslte::metrics_listener<ue_metrics_t>
{ {
public: public:
metrics_csv(std::string filename); metrics_csv(std::string filename);
~metrics_csv();
void set_periodicity(float metrics_report_period_sec); void set_metrics(ue_metrics_t &m, const uint32_t period_usec);
void set_metrics(ue_metrics_t &m);
void set_ue_handle(ue_metrics_interface *ue_); void set_ue_handle(ue_metrics_interface *ue_);
void stop();
private: private:
std::string float_to_string(float f, int digits, bool add_semicolon = true); std::string float_to_string(float f, int digits, bool add_semicolon = true);

@ -48,8 +48,9 @@ public:
void set_periodicity(float metrics_report_period_sec); void set_periodicity(float metrics_report_period_sec);
void toggle_print(bool b); void toggle_print(bool b);
void set_metrics(ue_metrics_t &m); void set_metrics(ue_metrics_t &m, const uint32_t period_usec);
void set_ue_handle(ue_metrics_interface *ue_); void set_ue_handle(ue_metrics_interface *ue_);
void stop() {};
private: private:
std::string float_to_string(float f, int digits); std::string float_to_string(float f, int digits);

@ -46,6 +46,7 @@ namespace srsue {
class chest_feedback_itf class chest_feedback_itf
{ {
public: public:
virtual void in_sync() = 0;
virtual void out_of_sync() = 0; virtual void out_of_sync() = 0;
virtual void set_cfo(float cfo) = 0; virtual void set_cfo(float cfo) = 0;
}; };
@ -69,6 +70,8 @@ public:
float avg_rsrp; float avg_rsrp;
float avg_rsrp_dbm; float avg_rsrp_dbm;
float avg_rsrq_db; float avg_rsrq_db;
float avg_rssi_dbm;
float last_radio_rssi;
float rx_gain_offset; float rx_gain_offset;
float avg_snr_db; float avg_snr_db;
float avg_noise; float avg_noise;

@ -75,6 +75,7 @@ public:
bool status_is_sync(); bool status_is_sync();
// from chest_feedback_itf // from chest_feedback_itf
void in_sync();
void out_of_sync(); void out_of_sync();
void set_cfo(float cfo); void set_cfo(float cfo);
@ -153,7 +154,7 @@ private:
srslte_ue_mib_t ue_mib; srslte_ue_mib_t ue_mib;
uint32_t cnt; uint32_t cnt;
uint32_t timeout; uint32_t timeout;
const static uint32_t SYNC_SFN_TIMEOUT = 200; const static uint32_t SYNC_SFN_TIMEOUT = 500;
}; };
// Class to perform cell measurements // Class to perform cell measurements
@ -324,9 +325,6 @@ private:
int cur_earfcn_index; int cur_earfcn_index;
bool cell_search_in_progress; bool cell_search_in_progress;
uint32_t out_of_sync_cnt;
uint32_t out_of_sync2_cnt;
float dl_freq; float dl_freq;
float ul_freq; float ul_freq;

@ -158,6 +158,8 @@ private:
float cfo; float cfo;
bool rar_cqi_request; bool rar_cqi_request;
uint32_t rssi_read_cnt;
// Metrics // Metrics
dl_metrics_t dl_metrics; dl_metrics_t dl_metrics;
ul_metrics_t ul_metrics; ul_metrics_t ul_metrics;

@ -56,6 +56,7 @@ namespace srsue {
bool set_cell(srslte_cell_t cell); bool set_cell(srslte_cell_t cell);
bool prepare_to_send(uint32_t preamble_idx, int allowed_subframe = -1, float target_power_dbm = -1); bool prepare_to_send(uint32_t preamble_idx, int allowed_subframe = -1, float target_power_dbm = -1);
bool is_ready_to_send(uint32_t current_tti); bool is_ready_to_send(uint32_t current_tti);
bool is_pending();
int tx_tti(); int tx_tti();
void send(srslte::radio* radio_handler, float cfo, float pathloss, srslte_timestamp_t rx_time); void send(srslte::radio* radio_handler, float cfo, float pathloss, srslte_timestamp_t rx_time);

@ -403,14 +403,19 @@ void *input_loop(void *m) {
char key; char key;
while (running) { while (running) {
cin >> key; cin >> key;
if ('t' == key) { if (cin.eof() || cin.bad()) {
do_metrics = !do_metrics; cout << "Closing stdin thread." << endl;
if (do_metrics) { break;
cout << "Enter t to stop trace." << endl; } else {
} else { if ('t' == key) {
cout << "Enter t to restart trace." << endl; do_metrics = !do_metrics;
if (do_metrics) {
cout << "Enter t to stop trace." << endl;
} else {
cout << "Enter t to restart trace." << endl;
}
metrics_screen.toggle_print(do_metrics);
} }
metrics_screen.toggle_print(do_metrics);
} }
} }
return NULL; return NULL;
@ -420,6 +425,7 @@ int main(int argc, char *argv[])
{ {
srslte::metrics_hub<ue_metrics_t> metricshub; srslte::metrics_hub<ue_metrics_t> metricshub;
signal(SIGINT, sig_int_handler); signal(SIGINT, sig_int_handler);
signal(SIGTERM, sig_int_handler);
all_args_t args; all_args_t args;
srslte_debug_handle_crash(argc, argv); srslte_debug_handle_crash(argc, argv);
@ -441,13 +447,11 @@ int main(int argc, char *argv[])
metricshub.init(ue, args.expert.metrics_period_secs); metricshub.init(ue, args.expert.metrics_period_secs);
metricshub.add_listener(&metrics_screen); metricshub.add_listener(&metrics_screen);
metrics_screen.set_ue_handle(ue); metrics_screen.set_ue_handle(ue);
metrics_screen.set_periodicity(args.expert.metrics_period_secs);
metrics_csv metrics_file(args.expert.metrics_csv_filename); metrics_csv metrics_file(args.expert.metrics_csv_filename);
if (args.expert.metrics_csv_enable) { if (args.expert.metrics_csv_enable) {
metricshub.add_listener(&metrics_file); metricshub.add_listener(&metrics_file);
metrics_file.set_ue_handle(ue); metrics_file.set_ue_handle(ue);
metrics_file.set_periodicity(args.expert.metrics_period_secs);
} }
pthread_t input; pthread_t input;

@ -46,7 +46,12 @@ metrics_csv::metrics_csv(std::string filename)
,metrics_report_period(1.0) ,metrics_report_period(1.0)
,ue(NULL) ,ue(NULL)
{ {
file.open(filename.c_str()); file.open(filename.c_str(), std::ios_base::out);
}
metrics_csv::~metrics_csv()
{
stop();
} }
void metrics_csv::set_ue_handle(ue_metrics_interface *ue_) void metrics_csv::set_ue_handle(ue_metrics_interface *ue_)
@ -54,15 +59,20 @@ void metrics_csv::set_ue_handle(ue_metrics_interface *ue_)
ue = ue_; ue = ue_;
} }
void metrics_csv::set_periodicity(float metrics_report_period_sec) { void metrics_csv::stop()
this->metrics_report_period = metrics_report_period_sec; {
if (file.is_open()) {
file << "#eof\n";
file.flush();
file.close();
}
} }
void metrics_csv::set_metrics(ue_metrics_t &metrics) void metrics_csv::set_metrics(ue_metrics_t &metrics, const uint32_t period_usec)
{ {
if (file.is_open() && ue != NULL) { if (file.is_open() && ue != NULL) {
if(n_reports == 0) { if(n_reports == 0) {
file << "time;rsrp;pl;cfo;dl_mcs;dl_snr;dl_turbo;dl_brate;dl_bler;ul_mcs;ul_buff;ul_brate;ul_bler;rf_o;rf_u;rf_l;is_attached" << endl; file << "time;rsrp;pl;cfo;dl_mcs;dl_snr;dl_turbo;dl_brate;dl_bler;ul_mcs;ul_buff;ul_brate;ul_bler;rf_o;rf_u;rf_l;is_attached\n";
} }
file << (metrics_report_period*n_reports) << ";"; file << (metrics_report_period*n_reports) << ";";
file << float_to_string(metrics.phy.dl.rsrp, 2); file << float_to_string(metrics.phy.dl.rsrp, 2);
@ -71,7 +81,7 @@ void metrics_csv::set_metrics(ue_metrics_t &metrics)
file << float_to_string(metrics.phy.dl.mcs, 2); file << float_to_string(metrics.phy.dl.mcs, 2);
file << float_to_string(metrics.phy.dl.sinr, 2); file << float_to_string(metrics.phy.dl.sinr, 2);
file << float_to_string(metrics.phy.dl.turbo_iters, 2); file << float_to_string(metrics.phy.dl.turbo_iters, 2);
file << float_to_string((float) metrics.mac.rx_brate/metrics_report_period, 2); file << float_to_string((float) metrics.mac.rx_brate/period_usec*1e6, 2);
if (metrics.mac.rx_pkts > 0) { if (metrics.mac.rx_pkts > 0) {
file << float_to_string((float) 100*metrics.mac.rx_errors/metrics.mac.rx_pkts, 1); file << float_to_string((float) 100*metrics.mac.rx_errors/metrics.mac.rx_pkts, 1);
} else { } else {
@ -79,7 +89,7 @@ void metrics_csv::set_metrics(ue_metrics_t &metrics)
} }
file << float_to_string(metrics.phy.ul.mcs, 2); file << float_to_string(metrics.phy.ul.mcs, 2);
file << float_to_string((float) metrics.mac.ul_buffer, 2); file << float_to_string((float) metrics.mac.ul_buffer, 2);
file << float_to_string((float) metrics.mac.tx_brate/metrics_report_period, 2); file << float_to_string((float) metrics.mac.tx_brate/period_usec*1e6, 2);
if (metrics.mac.tx_pkts > 0) { if (metrics.mac.tx_pkts > 0) {
file << float_to_string((float) 100*metrics.mac.tx_errors/metrics.mac.tx_pkts, 1); file << float_to_string((float) 100*metrics.mac.tx_errors/metrics.mac.tx_pkts, 1);
} else { } else {
@ -89,7 +99,7 @@ void metrics_csv::set_metrics(ue_metrics_t &metrics)
file << float_to_string(metrics.rf.rf_u, 2); file << float_to_string(metrics.rf.rf_u, 2);
file << float_to_string(metrics.rf.rf_l, 2); file << float_to_string(metrics.rf.rf_l, 2);
file << (ue->is_attached() ? "1.0" : "0.0"); file << (ue->is_attached() ? "1.0" : "0.0");
file << endl; file << "\n";
n_reports++; n_reports++;
} else { } else {

@ -50,7 +50,6 @@ char const * const prefixes[2][9] =
metrics_stdout::metrics_stdout() metrics_stdout::metrics_stdout()
:do_print(false) :do_print(false)
,n_reports(10) ,n_reports(10)
,metrics_report_period(1.0)
,ue(NULL) ,ue(NULL)
{ {
} }
@ -65,11 +64,7 @@ void metrics_stdout::toggle_print(bool b)
do_print = b; do_print = b;
} }
void metrics_stdout::set_periodicity(float metrics_report_period_sec) { void metrics_stdout::set_metrics(ue_metrics_t &metrics, const uint32_t period_usec)
this->metrics_report_period = metrics_report_period_sec;
}
void metrics_stdout::set_metrics(ue_metrics_t &metrics)
{ {
if(!do_print || ue == NULL) if(!do_print || ue == NULL)
return; return;
@ -92,7 +87,7 @@ void metrics_stdout::set_metrics(ue_metrics_t &metrics)
cout << float_to_string(metrics.phy.dl.mcs, 2); cout << float_to_string(metrics.phy.dl.mcs, 2);
cout << float_to_string(metrics.phy.dl.sinr, 2); cout << float_to_string(metrics.phy.dl.sinr, 2);
cout << float_to_string(metrics.phy.dl.turbo_iters, 2); cout << float_to_string(metrics.phy.dl.turbo_iters, 2);
cout << float_to_eng_string((float) metrics.mac.rx_brate/metrics_report_period, 2); cout << float_to_eng_string((float) metrics.mac.rx_brate/period_usec*1e6, 2);
if (metrics.mac.rx_pkts > 0) { if (metrics.mac.rx_pkts > 0) {
cout << float_to_string((float) 100*metrics.mac.rx_errors/metrics.mac.rx_pkts, 1) << "%"; cout << float_to_string((float) 100*metrics.mac.rx_errors/metrics.mac.rx_pkts, 1) << "%";
} else { } else {
@ -100,7 +95,7 @@ void metrics_stdout::set_metrics(ue_metrics_t &metrics)
} }
cout << float_to_string(metrics.phy.ul.mcs, 2); cout << float_to_string(metrics.phy.ul.mcs, 2);
cout << float_to_eng_string((float) metrics.mac.ul_buffer, 2); cout << float_to_eng_string((float) metrics.mac.ul_buffer, 2);
cout << float_to_eng_string((float) metrics.mac.tx_brate/metrics_report_period, 2); cout << float_to_eng_string((float) metrics.mac.tx_brate/period_usec*1e6, 2);
if (metrics.mac.tx_pkts > 0) { if (metrics.mac.tx_pkts > 0) {
cout << float_to_string((float) 100*metrics.mac.tx_errors/metrics.mac.tx_pkts, 1) << "%"; cout << float_to_string((float) 100*metrics.mac.tx_errors/metrics.mac.tx_pkts, 1) << "%";
} else { } else {

@ -97,7 +97,7 @@ void phch_recv::init(srslte::radio_multi *_radio_handler, mac_interface_phy *_ma
intra_freq_meas.init(worker_com, rrc, log_h); intra_freq_meas.init(worker_com, rrc, log_h);
reset(); reset();
running = true;
// Start main thread // Start main thread
if (sync_cpu_affinity < 0) { if (sync_cpu_affinity < 0) {
start(prio); start(prio);
@ -125,7 +125,6 @@ void phch_recv::stop()
void phch_recv::reset() void phch_recv::reset()
{ {
tx_mutex_cnt = 0; tx_mutex_cnt = 0;
running = true;
phy_state = IDLE; phy_state = IDLE;
time_adv_sec = 0; time_adv_sec = 0;
next_offset = 0; next_offset = 0;
@ -690,6 +689,12 @@ void phch_recv::run_thread()
worker->set_tti(tti, tx_mutex_cnt); worker->set_tti(tti, tx_mutex_cnt);
tx_mutex_cnt = (tx_mutex_cnt+1) % nof_tx_mutex; tx_mutex_cnt = (tx_mutex_cnt+1) % nof_tx_mutex;
// Reset Uplink TX buffer to avoid mixing packets in TX queue
if (prach_buffer->is_pending()) {
Info("SYNC: PRACH pending: Reset UL\n");
worker_com->reset_ul();
}
// Check if we need to TX a PRACH // Check if we need to TX a PRACH
if (prach_buffer->is_ready_to_send(tti)) { if (prach_buffer->is_ready_to_send(tti)) {
srslte_timestamp_copy(&tx_time_prach, &rx_time); srslte_timestamp_copy(&tx_time_prach, &rx_time);
@ -706,21 +711,11 @@ void phch_recv::run_thread()
srslte_pss_sic(&ue_sync.strack.pss, &buffer[0][SRSLTE_SF_LEN_PRB(cell.nof_prb)/2-ue_sync.strack.fft_size]); srslte_pss_sic(&ue_sync.strack.pss, &buffer[0][SRSLTE_SF_LEN_PRB(cell.nof_prb)/2-ue_sync.strack.fft_size]);
} }
intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb)); intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb));
out_of_sync_cnt = 0;
break; break;
case 0: case 0:
// Signal every 5 errors only (PSS is every 5) out_of_sync();
if (out_of_sync_cnt == 0) {
// Notify RRC of out-of-sync frame
log_h->error("SYNC: Sync error. Sending out-of-sync to RRC\n");
rrc->out_of_sync();
}
worker->release(); worker->release();
worker_com->reset_ul(); worker_com->reset_ul();
out_of_sync_cnt++;
if (out_of_sync_cnt >= 5) {
out_of_sync_cnt = 0;
}
break; break;
default: default:
radio_error(); radio_error();
@ -746,14 +741,12 @@ void phch_recv::run_thread()
} }
} }
void phch_recv::in_sync() {
rrc->in_sync();
}
void phch_recv::out_of_sync() { void phch_recv::out_of_sync() {
out_of_sync2_cnt++; rrc->out_of_sync();
Info("SYNC: Received out_of_sync from channel estimator (%d)\n", out_of_sync2_cnt);
if (out_of_sync2_cnt >= 2) {
out_of_sync2_cnt = 0;
Info("SYNC: Trying to resync signal\n");
resync_sfn(true, true);
}
} }
@ -1085,7 +1078,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe_sync(srslte_ue_syn
{ {
int sync_res = srslte_ue_sync_zerocopy_multi(ue_sync, buffer); int sync_res = srslte_ue_sync_zerocopy_multi(ue_sync, buffer);
if (sync_res == 1) { if (sync_res == 1) {
log_h->info("SYNC: CFO=%.1f KHz\n", srslte_ue_sync_get_cfo(ue_sync)); log_h->info("SYNC: CFO=%.1f KHz\n", srslte_ue_sync_get_cfo(ue_sync)/1000);
return run_subframe(sf_idx); return run_subframe(sf_idx);
} else { } else {
log_h->error("SYNC: Measuring RSRP: Sync error\n"); log_h->error("SYNC: Measuring RSRP: Sync error\n");
@ -1284,10 +1277,11 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
srslte_sync_reset(&sync_find); srslte_sync_reset(&sync_find);
srslte_sync_cfo_reset(&sync_find); srslte_sync_cfo_reset(&sync_find);
uint32_t sf5_cnt=0; int sf5_cnt=-1;
do { do {
sf5_cnt++;
sync_res = srslte_sync_find(&sync_find, input_buffer, sf5_cnt*5*sf_len, &peak_idx); sync_res = srslte_sync_find(&sync_find, input_buffer, sf5_cnt*5*sf_len, &peak_idx);
} while(sync_res != SRSLTE_SYNC_FOUND && sf5_cnt < nof_sf/5); } while(sync_res != SRSLTE_SYNC_FOUND && (uint32_t) sf5_cnt + 1 < nof_sf/5);
switch(sync_res) { switch(sync_res) {
case SRSLTE_SYNC_ERROR: case SRSLTE_SYNC_ERROR:
@ -1315,20 +1309,20 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
-srslte_sync_get_cfo(&sync_find)/sync_find.fft_size); -srslte_sync_get_cfo(&sync_find)/sync_find.fft_size);
switch(measure_p.run_multiple_subframes(input_cfo_corrected, peak_idx, sf_idx, nof_sf)) { switch(measure_p.run_multiple_subframes(input_cfo_corrected, peak_idx+sf5_cnt*5*sf_len, sf_idx, nof_sf)) {
case measure::MEASURE_OK: case measure::MEASURE_OK:
cells[nof_cells].pci = found_cell.id; cells[nof_cells].pci = found_cell.id;
cells[nof_cells].rsrp = measure_p.rsrp(); cells[nof_cells].rsrp = measure_p.rsrp();
cells[nof_cells].rsrq = measure_p.rsrq(); cells[nof_cells].rsrq = measure_p.rsrq();
cells[nof_cells].offset = measure_p.frame_st_idx(); cells[nof_cells].offset = measure_p.frame_st_idx();
Info("INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f n_id_2=%d, CFO=%6.1f Hz\n", Info("INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf5_cnt=%d, n_id_2=%d, CFO=%6.1f Hz\n",
nof_cells, cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, n_id_2, 15000*srslte_sync_get_cfo(&sync_find)); nof_cells, cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, sf5_cnt, n_id_2, 15000*srslte_sync_get_cfo(&sync_find));
nof_cells++; nof_cells++;
if (sic_pss_enabled) { if (sic_pss_enabled) {
srslte_pss_sic(&sync_find.pss, &input_buffer[sf_len/2-fft_sz]); srslte_pss_sic(&sync_find.pss, &input_buffer[sf5_cnt*5*sf_len+sf_len/2-fft_sz]);
} }
break; break;
@ -1349,7 +1343,7 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
default: default:
break; break;
} }
} while (sync_res == SRSLTE_SYNC_FOUND && sic_pss_enabled); } while (sync_res == SRSLTE_SYNC_FOUND && sic_pss_enabled && nof_cells < MAX_CELLS);
} }
} }
return nof_cells; return nof_cells;
@ -1477,16 +1471,16 @@ void phch_recv::intra_measure::write(uint32_t tti, cf_t *data, uint32_t nsamples
} }
if (receiving == true) { if (receiving == true) {
if (srslte_ringbuffer_write(&ring_buffer, data, nsamples*sizeof(cf_t)) < (int) (nsamples*sizeof(cf_t))) { if (srslte_ringbuffer_write(&ring_buffer, data, nsamples*sizeof(cf_t)) < (int) (nsamples*sizeof(cf_t))) {
Warning("Error writing to ringbuffer\n"); Warning("Error writting to ringbuffer\n");
receiving = false; receiving = false;
} else { } else {
receive_cnt++; receive_cnt++;
if (receive_cnt == CAPTURE_LEN_SF) { if (receive_cnt == CAPTURE_LEN_SF) {
tti_sync.increase(); tti_sync.increase();
receiving = false;
} }
} }
} }
} }
} }

@ -100,6 +100,7 @@ void phch_worker::reset()
rar_cqi_request = false; rar_cqi_request = false;
I_sr = 0; I_sr = 0;
cfi = 0; cfi = 0;
rssi_read_cnt = 0;
} }
void phch_worker::set_common(phch_common* phy_) void phch_worker::set_common(phch_common* phy_)
@ -175,8 +176,6 @@ void phch_worker::set_tti(uint32_t tti_, uint32_t tx_tti_)
tx_tti = tx_tti_; tx_tti = tx_tti_;
log_h->step(tti); log_h->step(tti);
log_phy_lib_h->step(tti); log_phy_lib_h->step(tti);
} }
void phch_worker::set_cfo(float cfo_) void phch_worker::set_cfo(float cfo_)
@ -224,13 +223,20 @@ void phch_worker::work_imp()
bool ul_grant_available = false; bool ul_grant_available = false;
bool dl_ack[SRSLTE_MAX_CODEWORDS] = {false}; bool dl_ack[SRSLTE_MAX_CODEWORDS] = {false};
mac_interface_phy::mac_grant_t dl_mac_grant; mac_interface_phy::mac_grant_t dl_mac_grant = {};
mac_interface_phy::tb_action_dl_t dl_action; mac_interface_phy::tb_action_dl_t dl_action = {};
bzero(&dl_action, sizeof(mac_interface_phy::tb_action_dl_t));
mac_interface_phy::mac_grant_t ul_mac_grant = {};
mac_interface_phy::tb_action_ul_t ul_action = {};
mac_interface_phy::mac_grant_t ul_mac_grant; /** Calculate RSSI on the input signal before generating the output */
mac_interface_phy::tb_action_ul_t ul_action;
bzero(&ul_action, sizeof(mac_interface_phy::tb_action_ul_t)); // Average RSSI over all symbols
float rssi_dbm = 10*log10(srslte_vec_avg_power_cf(signal_buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb))) + 30;
if (isnormal(rssi_dbm)) {
phy->avg_rssi_dbm = SRSLTE_VEC_EMA(rssi_dbm, phy->avg_rssi_dbm, phy->args->snr_ema_coeff);
}
/* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */ /* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */
bool chest_ok = extract_fft_and_pdcch_llr(); bool chest_ok = extract_fft_and_pdcch_llr();
@ -289,7 +295,8 @@ void phch_worker::work_imp()
// Decode PHICH // Decode PHICH
bool ul_ack = false; bool ul_ack = false;
bool ul_ack_available = decode_phich(&ul_ack); bool ul_ack_available = decode_phich(&ul_ack);
/***** Uplink Processing + Transmission *******/ /***** Uplink Processing + Transmission *******/
@ -364,13 +371,12 @@ void phch_worker::work_imp()
if (chest_ok) { if (chest_ok) {
if (snr_th_ok) { if (snr_th_ok) {
phy->rrc->in_sync(); log_h->debug("SNR=%.1f dB sync=in-sync from channel estimator\n", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)));
log_h->debug("SYNC: Sending in-sync to RRC\n"); chest_loop->in_sync();
} else if (snr_th_err) { } else if (snr_th_err) {
chest_loop->out_of_sync(); log_h->info("SNR=%.1f dB sync=out-of-sync from channel estimator\n",
phy->rrc->out_of_sync();
log_h->info("SNR=%.1f dB under threshold. Sending out-of-sync to RRC\n",
10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))); 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)));
chest_loop->out_of_sync();
} }
} }
@ -391,13 +397,14 @@ void phch_worker::compute_ri(uint8_t *ri, uint8_t *pmi, float *sinr) {
Debug("TM3 RI select %d layers, κ=%fdB\n", (*ri) + 1, cn); Debug("TM3 RI select %d layers, κ=%fdB\n", (*ri) + 1, cn);
} else { } else {
/* If only one receiving antenna, force RI for 1 layer */ /* If only one receiving antenna, force RI for 1 layer */
uci_data.uci_ri = 0; if (ri) {
*ri = 0;
}
} }
uci_data.uci_ri_len = 1; uci_data.uci_ri_len = 1;
} else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) { } else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
srslte_ue_dl_ri_pmi_select(&ue_dl, ri, pmi, sinr); srslte_ue_dl_ri_pmi_select(&ue_dl, ri, pmi, sinr);
Debug("TM4 ri=%d; pmi=%d; SINR=%.1fdB\n", ue_dl.ri, ue_dl.pmi[ue_dl.ri], 10*log10f(ue_dl.sinr[ue_dl.ri][ue_dl.pmi[ue_dl.ri]])); Debug("TM4 ri=%d; pmi=%d; SINR=%.1fdB\n", ue_dl.ri, ue_dl.pmi[ue_dl.ri], 10*log10f(ue_dl.sinr[ue_dl.ri][ue_dl.pmi[ue_dl.ri]]));
uci_data.uci_ri_len = 1;
} }
} }
@ -771,7 +778,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
// Handle Format0 adaptive retx // Handle Format0 adaptive retx
if (ret) { if (ret) {
// Use last TBS for this TB in case of mcs>28 // Use last TBS for this TB in case of mcs>28
if (grant->phy_grant.ul.mcs.idx > 28) { if (grant->phy_grant.ul.mcs.idx > 28 && grant->phy_grant.ul.mcs.mod == SRSLTE_MOD_LAST) {
// Make sure we received a grant in the previous TTI for this PID // Make sure we received a grant in the previous TTI for this PID
grant->phy_grant.ul.mcs.tbs = phy->last_ul_tbs[UL_PIDOF(TTI_TX(tti))]; grant->phy_grant.ul.mcs.tbs = phy->last_ul_tbs[UL_PIDOF(TTI_TX(tti))];
grant->phy_grant.ul.mcs.mod = phy->last_ul_mod[UL_PIDOF(TTI_TX(tti))]; grant->phy_grant.ul.mcs.mod = phy->last_ul_mod[UL_PIDOF(TTI_TX(tti))];
@ -898,11 +905,11 @@ void phch_worker::set_uci_aperiodic_cqi()
{ {
uint8_t ri = (uint8_t) ue_dl.ri; uint8_t ri = (uint8_t) ue_dl.ri;
uint8_t pmi = (uint8_t) ue_dl.pmi[ri]; uint8_t pmi = (uint8_t) ue_dl.pmi[ri];
float sinr = ue_dl.sinr[ri][pmi]; float sinr_db = ue_dl.sinr[ri][pmi];
if (phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic_present) { if (phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic_present) {
/* Compute RI, PMI and SINR */ /* Compute RI, PMI and SINR */
compute_ri(&ri, &pmi, &sinr); compute_ri(&ri, &pmi, &sinr_db);
switch(phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic) { switch(phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic) {
case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30: case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30:
@ -922,10 +929,24 @@ void phch_worker::set_uci_aperiodic_cqi()
// TODO: implement subband CQI properly // TODO: implement subband CQI properly
cqi_report.subband_hl.subband_diff_cqi_cw0 = 0; // Always report zero offset on all subbands cqi_report.subband_hl.subband_diff_cqi_cw0 = 0; // Always report zero offset on all subbands
cqi_report.subband_hl.N = (cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0; cqi_report.subband_hl.N = (cell.nof_prb > 7) ? (uint32_t) srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0;
int cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
if (cqi_len < 0) {
Error("Error packing CQI value (Aperiodic reporting mode RM31).");
return;
}
uci_data.uci_cqi_len = (uint32_t) cqi_len;
char cqi_str[SRSLTE_CQI_STR_MAX_CHAR] = {0};
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
Info("PUSCH: Aperiodic CQI=%d, SNR=%.1f dB, for %d subbands\n", cqi_report.wideband.wideband_cqi, phy->avg_snr_db, cqi_report.subband_hl.N); /* Set RI = 1 */
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi); uci_data.uci_ri = ri;
uci_data.uci_ri_len = 1;
Info("PUSCH: Aperiodic RM30 ri%s, CQI=%s, SNR=%.1f dB, for %d subbands\n",
(uci_data.uci_ri == 0)?"=1":"~1", cqi_str, phy->avg_snr_db, cqi_report.subband_hl.N);
} }
break; break;
case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM31: case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM31:
@ -941,11 +962,6 @@ void phch_worker::set_uci_aperiodic_cqi()
other transmission modes they are reported conditioned on rank 1. other transmission modes they are reported conditioned on rank 1.
*/ */
if (rnti_is_set) { if (rnti_is_set) {
/* Select RI, PMI and SINR */
uint32_t ri = ue_dl.ri; // Select RI (0: 1 layer, 1: 2 layer, otherwise: not implemented)
uint32_t pmi = ue_dl.pmi[ri]; // Select PMI
float sinr_db = 10 * log10(ue_dl.sinr[ri][pmi]);
/* Fill CQI Report */ /* Fill CQI Report */
srslte_cqi_value_t cqi_report = {0}; srslte_cqi_value_t cqi_report = {0};
cqi_report.type = SRSLTE_CQI_TYPE_SUBBAND_HL; cqi_report.type = SRSLTE_CQI_TYPE_SUBBAND_HL;
@ -966,16 +982,27 @@ void phch_worker::set_uci_aperiodic_cqi()
// TODO: implement subband CQI properly // TODO: implement subband CQI properly
cqi_report.subband_hl.N = (uint32_t) ((cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0); cqi_report.subband_hl.N = (uint32_t) ((cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0);
int cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
if (cqi_len < 0) {
Error("Error packing CQI value (Aperiodic reporting mode RM31).");
return;
}
uci_data.uci_cqi_len = (uint32_t) cqi_len;
uci_data.uci_ri_len = 1;
uci_data.uci_ri = ri;
char cqi_str[SRSLTE_CQI_STR_MAX_CHAR] = {0};
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
if (cqi_report.subband_hl.rank_is_not_one) { if (cqi_report.subband_hl.rank_is_not_one) {
Info("PUSCH: Aperiodic ri~1, CQI=%02d/%02d, SINR=%2.1f/%2.1fdB, pmi=%d for %d subbands\n", Info("PUSCH: Aperiodic RM31 ri~1, CQI=%02d/%02d, SINR=%2.1f/%2.1fdB, pmi=%d for %d subbands\n",
cqi_report.subband_hl.wideband_cqi_cw0, cqi_report.subband_hl.wideband_cqi_cw1, cqi_report.subband_hl.wideband_cqi_cw0, cqi_report.subband_hl.wideband_cqi_cw1,
sinr_db, sinr_db, pmi, cqi_report.subband_hl.N); sinr_db, sinr_db, pmi, cqi_report.subband_hl.N);
} else { } else {
Info("PUSCH: Aperiodic ri=1, CQI=%02d, SINR=%2.1f, pmi=%d for %d subbands\n", Info("PUSCH: Aperiodic RM31 ri=1, CQI=%02d, SINR=%2.1f, pmi=%d for %d subbands\n",
cqi_report.subband_hl.wideband_cqi_cw0, cqi_report.subband_hl.wideband_cqi_cw0,
sinr_db, pmi, cqi_report.subband_hl.N); sinr_db, pmi, cqi_report.subband_hl.N);
} }
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
} }
break; break;
default: default:
@ -1040,15 +1067,15 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, ui
snprintf(timestr, 64, ", tot_time=%4d us", (int) logtime_start[0].tv_usec); snprintf(timestr, 64, ", tot_time=%4d us", (int) logtime_start[0].tv_usec);
#endif #endif
char cqi_str[32] = ""; char cqi_str[SRSLTE_CQI_STR_MAX_CHAR] = "";
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, 32); srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
uint8_t dummy[2] = {0,0}; uint8_t dummy[2] = {0,0};
log_h->info("PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s%s\n", log_h->info("PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s%s\n",
(tti + HARQ_DELAY_MS) % 10240, (tti + HARQ_DELAY_MS) % 10240,
grant->n_prb[0], grant->n_prb[0] + grant->L_prb, grant->n_prb[0], grant->n_prb[0] + grant->L_prb,
grant->mcs.tbs / 8, grant->mcs.idx, rv, grant->mcs.tbs / 8, grant->mcs.idx, rv,
uci_data.uci_ack_len > 0 ? (uci_data.uci_ack ? ", ack=1" : "0") : "", uci_data.uci_ack_len > 0 ? (uci_data.uci_ack ? ", ack=1" : ", ack=0") : "",
uci_data.uci_ack_len > 1 ? (uci_data.uci_ack_2 ? "1" : "0") : "", uci_data.uci_ack_len > 1 ? (uci_data.uci_ack_2 ? "1" : "0") : "",
uci_data.uci_ri_len > 0 ? (uci_data.uci_ri ? ", ri=1" : ", ri=0") : "", uci_data.uci_ri_len > 0 ? (uci_data.uci_ri ? ", ri=1" : ", ri=0") : "",
cfo * 15, timestr, cfo * 15, timestr,
@ -1094,8 +1121,8 @@ void phch_worker::encode_pucch()
float tx_power = srslte_ue_ul_pucch_power(&ue_ul, phy->pathloss, ue_ul.last_pucch_format, uci_data.uci_cqi_len, uci_data.uci_ack_len); float tx_power = srslte_ue_ul_pucch_power(&ue_ul, phy->pathloss, ue_ul.last_pucch_format, uci_data.uci_cqi_len, uci_data.uci_ack_len);
float gain = set_power(tx_power); float gain = set_power(tx_power);
char str_cqi[32] = ""; char str_cqi[SRSLTE_CQI_STR_MAX_CHAR] = "";
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, str_cqi, 32); srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, str_cqi, SRSLTE_CQI_STR_MAX_CHAR);
Info("PUCCH: tti_tx=%d, n_pucch=%d, n_prb=%d, ack=%s%s%s%s%s, sr=%s, cfo=%.1f KHz%s\n", Info("PUCCH: tti_tx=%d, n_pucch=%d, n_prb=%d, ack=%s%s%s%s%s, sr=%s, cfo=%.1f KHz%s\n",
(tti + 4) % 10240, (tti + 4) % 10240,
@ -1132,10 +1159,7 @@ void phch_worker::encode_srs()
float tx_power = srslte_ue_ul_srs_power(&ue_ul, phy->pathloss); float tx_power = srslte_ue_ul_srs_power(&ue_ul, phy->pathloss);
float gain = set_power(tx_power); float gain = set_power(tx_power);
uint32_t fi = srslte_vec_max_fi((float*) signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
float *f = (float*) signal_buffer;
Info("SRS: power=%.2f dBm, tti_tx=%d%s\n", tx_power, TTI_TX(tti), timestr); Info("SRS: power=%.2f dBm, tti_tx=%d%s\n", tx_power, TTI_TX(tti), timestr);
} }
void phch_worker::enable_pregen_signals(bool enabled) void phch_worker::enable_pregen_signals(bool enabled)
@ -1316,42 +1340,50 @@ void phch_worker::update_measurements()
{ {
float snr_ema_coeff = phy->args->snr_ema_coeff; float snr_ema_coeff = phy->args->snr_ema_coeff;
if (chest_done) { if (chest_done) {
/* Compute ADC/RX gain offset every ~10s */
if (tti== 0 || phy->rx_gain_offset == 0) { /* Only worker 0 reads the RSSI sensor every ~1-nof_cores s */
float rx_gain_offset = 0; if (get_id() == 0) {
if (phy->get_radio()->has_rssi() && phy->args->rssi_sensor_enabled) { if (rssi_read_cnt) {
float rssi_all_signal = 30+10*log10(srslte_vec_avg_power_cf(signal_buffer[0],SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb)))); if (phy->get_radio()->has_rssi() && phy->args->rssi_sensor_enabled) {
rx_gain_offset = 30+rssi_all_signal-phy->get_radio()->get_rssi(); phy->last_radio_rssi = phy->get_radio()->get_rssi();
} else { phy->rx_gain_offset = phy->avg_rssi_dbm - phy->last_radio_rssi + 30;
rx_gain_offset = phy->get_radio()->get_rx_gain(); } else {
phy->rx_gain_offset = phy->get_radio()->get_rx_gain();
}
} }
if (phy->rx_gain_offset) { rssi_read_cnt++;
phy->rx_gain_offset = SRSLTE_VEC_EMA(rx_gain_offset, phy->rx_gain_offset, 0.5); if (rssi_read_cnt == 1000) {
} else { rssi_read_cnt = 0;
phy->rx_gain_offset = rx_gain_offset;
} }
} }
// Average RSRQ // Average RSRQ
float rsrq_db = 10*log10(srslte_chest_dl_get_rsrq(&ue_dl.chest)); float rsrq_db = 10*log10(srslte_chest_dl_get_rsrq(&ue_dl.chest));
if (isnormal(rsrq_db)) { if (isnormal(rsrq_db)) {
phy->avg_rsrq_db = SRSLTE_VEC_EMA(rsrq_db, phy->avg_rsrq_db, snr_ema_coeff); if (!phy->avg_rsrq_db) {
phy->avg_rsrq_db = SRSLTE_VEC_EMA(rsrq_db, phy->avg_rsrq_db, snr_ema_coeff);
} else {
phy->avg_rsrq_db = rsrq_db;
}
} }
// Average RSRP // Average RSRP
float rsrp_lin = srslte_chest_dl_get_rsrp(&ue_dl.chest); float rsrp_lin = srslte_chest_dl_get_rsrp(&ue_dl.chest);
if (isnormal(rsrp_lin)) { if (isnormal(rsrp_lin)) {
phy->avg_rsrp = SRSLTE_VEC_EMA(rsrp_lin, phy->avg_rsrp, snr_ema_coeff); if (!phy->avg_rsrp) {
phy->avg_rsrp = SRSLTE_VEC_EMA(rsrp_lin, phy->avg_rsrp, snr_ema_coeff);
} else {
phy->avg_rsrp = rsrp_lin;
}
} }
/* Correct absolute power measurements by RX gain offset */ /* Correct absolute power measurements by RX gain offset */
float rsrp_dbm = 10*log10(rsrp_lin) + 30 - phy->rx_gain_offset; float rsrp_dbm = 10*log10(rsrp_lin) + 30 - phy->rx_gain_offset;
float rssi_db = 10*log10(srslte_chest_dl_get_rssi(&ue_dl.chest)) + 30 - phy->rx_gain_offset;
// Serving cell measurements are averaged over DEFAULT_MEAS_PERIOD_MS then sent to RRC // Serving cell measurements are averaged over DEFAULT_MEAS_PERIOD_MS then sent to RRC
if (isnormal(rsrp_dbm)) { if (isnormal(rsrp_dbm)) {
if (!phy->avg_rsrp_dbm) { if (!phy->avg_rsrp_dbm) {
phy->avg_rsrp_dbm= rsrp_dbm; phy->avg_rsrp_dbm = rsrp_dbm;
} else { } else {
phy->avg_rsrp_dbm = SRSLTE_VEC_EMA(rsrp_dbm, phy->avg_rsrp_dbm, snr_ema_coeff); phy->avg_rsrp_dbm = SRSLTE_VEC_EMA(rsrp_dbm, phy->avg_rsrp_dbm, snr_ema_coeff);
} }
@ -1381,7 +1413,7 @@ void phch_worker::update_measurements()
dl_metrics.n = phy->avg_noise; dl_metrics.n = phy->avg_noise;
dl_metrics.rsrp = phy->avg_rsrp_dbm; dl_metrics.rsrp = phy->avg_rsrp_dbm;
dl_metrics.rsrq = phy->avg_rsrq_db; dl_metrics.rsrq = phy->avg_rsrq_db;
dl_metrics.rssi = rssi_db; dl_metrics.rssi = phy->avg_rssi_dbm;
dl_metrics.pathloss = phy->pathloss; dl_metrics.pathloss = phy->pathloss;
dl_metrics.sinr = phy->avg_snr_db; dl_metrics.sinr = phy->avg_snr_db;
dl_metrics.turbo_iters = srslte_pdsch_last_noi(&ue_dl.pdsch); dl_metrics.turbo_iters = srslte_pdsch_last_noi(&ue_dl.pdsch);

@ -152,8 +152,12 @@ bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float
} }
} }
bool prach::is_pending() {
return cell_initiated && preamble_idx >= 0 && preamble_idx < 64;
}
bool prach::is_ready_to_send(uint32_t current_tti_) { bool prach::is_ready_to_send(uint32_t current_tti_) {
if (cell_initiated && preamble_idx >= 0 && preamble_idx < 64) { if (is_pending()) {
// consider the number of subframes the transmission must be anticipated // consider the number of subframes the transmission must be anticipated
uint32_t current_tti = (current_tti_ + tx_advance_sf)%10240; uint32_t current_tti = (current_tti_ + tx_advance_sf)%10240;
if (srslte_prach_tti_opportunity(&prach_obj, current_tti, allowed_subframe)) { if (srslte_prach_tti_opportunity(&prach_obj, current_tti, allowed_subframe)) {

@ -201,7 +201,8 @@ srslte::error_t gw::init_if(char *err_str)
} }
memset(&ifr, 0, sizeof(ifr)); memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI; ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ); strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ-1);
ifr.ifr_ifrn.ifrn_name[IFNAMSIZ-1] = 0;
if(0 > ioctl(tun_fd, TUNSETIFF, &ifr)) if(0 > ioctl(tun_fd, TUNSETIFF, &ifr))
{ {
err_str = strerror(errno); err_str = strerror(errno);

@ -193,9 +193,9 @@ void nas::notify_connection_setup() {
} }
void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
uint8 pd; uint8 pd = 0;
uint8 msg_type; uint8 msg_type = 0;
uint8 sec_hdr_type; uint8 sec_hdr_type = 0;
bool mac_valid = false; bool mac_valid = false;
nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str()); nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str());
@ -216,7 +216,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT: case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT:
break; break;
default: default:
nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n",msg_type); nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type);
pool->deallocate(pdu); pool->deallocate(pdu);
break; break;
} }

@ -722,7 +722,6 @@ float rrc::get_squal(float Qqualmeas) {
// Detection of physical layer problems (5.3.11.1) // Detection of physical layer problems (5.3.11.1)
void rrc::out_of_sync() { void rrc::out_of_sync() {
// attempt resync
current_cell->in_sync = false; current_cell->in_sync = false;
if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) {
n310_cnt++; n310_cnt++;
@ -730,7 +729,8 @@ void rrc::out_of_sync() {
mac_timers->timer_get(t310)->reset(); mac_timers->timer_get(t310)->reset();
mac_timers->timer_get(t310)->run(); mac_timers->timer_get(t310)->run();
n310_cnt = 0; n310_cnt = 0;
rrc_log->info("Detected %d out-of-sync from PHY. Starting T310 timer\n", N310); phy->sync_reset();
rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer\n", N310);
} }
} }
} }

@ -132,7 +132,7 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srsue::ma
memcpy(&common.pusch_cnfg, &sib2->rr_config_common_sib.pusch_cnfg, sizeof(LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT)); memcpy(&common.pusch_cnfg, &sib2->rr_config_common_sib.pusch_cnfg, sizeof(LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT));
memcpy(&common.pucch_cnfg, &sib2->rr_config_common_sib.pucch_cnfg, sizeof(LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT)); memcpy(&common.pucch_cnfg, &sib2->rr_config_common_sib.pucch_cnfg, sizeof(LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT));
memcpy(&common.ul_pwr_ctrl, &sib2->rr_config_common_sib.ul_pwr_ctrl, sizeof(LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT)); memcpy(&common.ul_pwr_ctrl, &sib2->rr_config_common_sib.ul_pwr_ctrl, sizeof(LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT));
memcpy(&common.prach_cnfg, &sib2->rr_config_common_sib.prach_cnfg, sizeof(LIBLTE_RRC_PRACH_CONFIG_STRUCT)); memcpy(&common.prach_cnfg, &sib2->rr_config_common_sib.prach_cnfg, sizeof(LIBLTE_RRC_PRACH_CONFIG_SIB_STRUCT));
if (sib2->rr_config_common_sib.srs_ul_cnfg.present) { if (sib2->rr_config_common_sib.srs_ul_cnfg.present) {
memcpy(&common.srs_ul_cnfg, &sib2->rr_config_common_sib.srs_ul_cnfg, sizeof(LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT)); memcpy(&common.srs_ul_cnfg, &sib2->rr_config_common_sib.srs_ul_cnfg, sizeof(LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT));
} else { } else {

Loading…
Cancel
Save