diff --git a/lib/examples/cell_measurement.c b/lib/examples/cell_measurement.c index 71c0864c8..3185b74f1 100644 --- a/lib/examples/cell_measurement.c +++ b/lib/examples/cell_measurement.c @@ -239,7 +239,7 @@ int main(int argc, char **argv) { 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_flush_buffer(&rf); diff --git a/lib/examples/cell_search.c b/lib/examples/cell_search.c index 17e75369f..4ea89a0ca 100644 --- a/lib/examples/cell_search.c +++ b/lib/examples/cell_search.c @@ -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); 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); n = srslte_ue_cellsearch_scan(&cs, found_cells, NULL); diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index dafff03b9..87ecfe6f1 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -185,7 +185,8 @@ void parse_args(int argc, char **argv) { cell.id = atoi(argv[optind]); break; case 'x': - strncpy(mimo_type_str, argv[optind], 32); + strncpy(mimo_type_str, argv[optind], 31); + mimo_type_str[31] = 0; break; case 'b': multiplex_pmi = (uint32_t) atoi(argv[optind]); @@ -528,9 +529,9 @@ int update_radl() { srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb); 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_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); dummy_grant.sf_type = SRSLTE_SF_NORM; if (pdsch_cfg.mimo_type != SRSLTE_MIMO_TYPE_SINGLE_ANTENNA) { @@ -858,7 +859,7 @@ int main(int argc, char **argv) { if (net_port > 0) { send_data = net_packet_ready; if (net_packet_ready) { - INFO("Transmitting packet\n",0); + INFO("Transmitting packet\n"); } } else { INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs); diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 702049f73..8ef620b56 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -473,7 +473,7 @@ int main(int argc, char **argv) { exit(-1); } - INFO("Stopping RF and flushing buffer...\r",0); + INFO("Stopping RF and flushing buffer...\r"); } #endif @@ -606,7 +606,7 @@ int main(int argc, char **argv) { srslte_pbch_decode_reset(&ue_mib.pbch); - INFO("\nEntering main loop...\n\n", 0); + INFO("\nEntering main loop...\n\n"); /* Main loop */ while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { 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 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(" 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(" 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)); diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 567203c75..81a6025a8 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -75,11 +75,16 @@ public: void print_all_buffers() { printf("%d buffers in queue\n", (int) used.size()); +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED for (uint32_t i=0;idebug_name)?used[i]->debug_name:"Undefined"); } +#endif + } + + bool is_almost_empty() { + return available.size() < capacity/20; } - buffer_t* allocate(const char *debug_name = NULL) { @@ -92,8 +97,9 @@ public: used.push_back(b); available.pop(); - if (available.size() < capacity/20) { + if (is_almost_empty()) { printf("Warning buffer pool capacity is %f %%\n", (float) 100*available.size()/capacity); + print_all_buffers(); } #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED if (debug_name) { diff --git a/lib/include/srslte/common/metrics_hub.h b/lib/include/srslte/common/metrics_hub.h index 5dc22f7c1..05ab4c5fa 100644 --- a/lib/include/srslte/common/metrics_hub.h +++ b/lib/include/srslte/common/metrics_hub.h @@ -10,6 +10,7 @@ #include #include "srslte/common/threads.h" +#include "srslte/srslte.h" namespace srslte { @@ -24,7 +25,8 @@ template class metrics_listener { 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 @@ -33,15 +35,19 @@ class metrics_hub : public periodic_thread public: metrics_hub() :m(NULL) - ,report_period_secs(1) + ,sleep_period_start() {} bool init(metrics_interface *m_, float report_period_secs_=1.0) { m = m_; - report_period_secs = report_period_secs_; - start_periodic(report_period_secs*1e6); + // Start with user-default priority + start_periodic(report_period_secs_*1e6, -2); return true; } void stop() { + // stop all listeners + for (uint32_t i=0;istop(); + } thread_cancel(); wait_thread_finish(); } @@ -51,18 +57,24 @@ public: } 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) { metrics_t metric = {}; m->get_metrics(metric); for (uint32_t i=0;iset_metrics(metric); + listeners[i]->set_metrics(metric, period); } } + // store start of sleep period + gettimeofday(&sleep_period_start[1], NULL); } metrics_interface *m; std::vector*> listeners; - float report_period_secs; + struct timeval sleep_period_start[3]; }; } // namespace srslte diff --git a/lib/include/srslte/common/threads.h b/lib/include/srslte/common/threads.h index 077dda72b..e87407870 100644 --- a/lib/include/srslte/common/threads.h +++ b/lib/include/srslte/common/threads.h @@ -30,6 +30,9 @@ #include #include +// Default priority for all threads below UHD threads +#define DEFAULT_PRIORITY 60 + #ifdef __cplusplus extern "C" { #endif // __cplusplus diff --git a/lib/include/srslte/config.h b/lib/include/srslte/config.h index 8a988a971..1e9d27aac 100644 --- a/lib/include/srslte/config.h +++ b/lib/include/srslte/config.h @@ -59,6 +59,9 @@ // cf_t definition typedef _Complex float cf_t; + +#ifdef ENABLE_C16 typedef _Complex short int c16_t; +#endif /* ENABLE_C16 */ #endif // CONFIG_H diff --git a/lib/include/srslte/phy/phch/cqi.h b/lib/include/srslte/phy/phch/cqi.h index f1f7eb03c..b8cc80ece 100644 --- a/lib/include/srslte/phy/phch/cqi.h +++ b/lib/include/srslte/phy/phch/cqi.h @@ -43,6 +43,7 @@ #define SRSLTE_CQI_MAX_BITS 64 #define SRSLTE_DIF_CQI_MAX_BITS 3 #define SRSLTE_PMI_MAX_BITS 4 +#define SRSLTE_CQI_STR_MAX_CHAR 32 typedef struct { bool configured; diff --git a/lib/include/srslte/phy/phch/ra.h b/lib/include/srslte/phy/phch/ra.h index f4274e416..80097f78e 100644 --- a/lib/include/srslte/phy/phch/ra.h +++ b/lib/include/srslte/phy/phch/ra.h @@ -139,7 +139,11 @@ typedef struct SRSLTE_API { uint8_t tpc_pucch; bool tb_en[2]; - + + bool is_ra_order; + uint32_t ra_preamble; + uint32_t ra_mask_idx; + bool dci_is_1a; bool dci_is_1c; } srslte_ra_dl_dci_t; diff --git a/lib/include/srslte/phy/utils/simd.h b/lib/include/srslte/phy/utils/simd.h index 7ea203290..e22a9ef09 100644 --- a/lib/include/srslte/phy/utils/simd.h +++ b/lib/include/srslte/phy/utils/simd.h @@ -150,7 +150,10 @@ #endif /* LV_HAVE_AVX2 */ #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 diff --git a/lib/include/srslte/phy/utils/vector_simd.h b/lib/include/srslte/phy/utils/vector_simd.h index 31725edb3..49268ca43 100644 --- a/lib/include/srslte/phy/utils/vector_simd.h +++ b/lib/include/srslte/phy/utils/vector_simd.h @@ -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); +#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); +#endif /* ENABLE_C16 */ SRSLTE_API int srslte_vec_dot_prod_sss_simd(const int16_t *x, const int16_t *y, const int len); diff --git a/lib/include/srslte/upper/pdcp_entity.h b/lib/include/srslte/upper/pdcp_entity.h index 186da3767..0894b6578 100644 --- a/lib/include/srslte/upper/pdcp_entity.h +++ b/lib/include/srslte/upper/pdcp_entity.h @@ -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 ***************************************************************************/ class pdcp_entity - :public thread { public: pdcp_entity(); @@ -71,7 +70,6 @@ public: srslte::log *log_, uint32_t lcid_, srslte_pdcp_config_t cfg_); - void stop(); void reset(); void reestablish(); @@ -97,10 +95,6 @@ private: srsue::rrc_interface_pdcp *rrc; srsue::gw_interface_pdcp *gw; - static const int PDCP_THREAD_PRIO = 7; - srslte::msg_queue rx_pdu_queue; - bool running; - bool active; uint32_t lcid; srslte_pdcp_config_t cfg; @@ -134,8 +128,6 @@ private: uint32_t ct_len, uint8_t *msg); - void run_thread(); - uint8_t get_bearer_id(uint8_t lcid); }; diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index c0289956c..e28e11618 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -180,8 +180,8 @@ private: int build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t retx); int build_data_pdu(uint8_t *payload, uint32_t nof_bytes); - void handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_header_t header); - void handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_header_t header); + void handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_header_t &header); + void handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_header_t &header); void handle_control_pdu(uint8_t *payload, uint32_t nof_bytes); void reassemble_rx_sdus(); diff --git a/lib/src/asn1/liblte_s1ap.cc b/lib/src/asn1/liblte_s1ap.cc index 31c7391ab..e6a8fe575 100644 --- a/lib/src/asn1/liblte_s1ap.cc +++ b/lib/src/asn1/liblte_s1ap.cc @@ -2243,6 +2243,12 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_imsi( if(ie != NULL && ptr != NULL) { + // max length of IE buffer is 8, so limit + if (ie->n_octets > 7) { + printf("Length in struct exceeds buffer (%d > 7).\n", ie->n_octets); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Dynamic octet string - IMSI // Length if(ie->n_octets < 128) { diff --git a/lib/src/common/log_filter.cc b/lib/src/common/log_filter.cc index 6720c21ad..b498d466c 100644 --- a/lib/src/common/log_filter.cc +++ b/lib/src/common/log_filter.cc @@ -126,7 +126,7 @@ void log_filter::all_log(srslte::LOG_LEVEL_ENUM level, ss << std::endl; } - if (hex_limit > 0) { + if (hex_limit > 0 && hex && size > 0) { ss << hex_string(hex, size); } str_ptr s_ptr(new std::string(ss.str())); diff --git a/lib/src/common/threads.c b/lib/src/common/threads.c index 0533aa1b6..b6fa31778 100644 --- a/lib/src/common/threads.c +++ b/lib/src/common/threads.c @@ -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"); } 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, ¶m)) { + perror("pthread_attr_setschedparam"); + fprintf(stderr, "Error not enough privileges to set Scheduling priority\n"); + } + attr_enable = true; } else if (prio_offset == -2) { param.sched_priority = 0; pthread_attr_init(&attr); diff --git a/lib/src/phy/common/phy_common.c b/lib/src/phy/common/phy_common.c index b4f5e122b..489d6b3a5 100644 --- a/lib/src/phy/common/phy_common.c +++ b/lib/src/phy/common/phy_common.c @@ -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) { - 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, " - CP: %s\n", srslte_cp_string(cell->cp)); fprintf(stream, " - PRB: %d\n", cell->nof_prb); diff --git a/lib/src/phy/fec/turbodecoder_simd.c b/lib/src/phy/fec/turbodecoder_simd.c index a32d52962..d8a5c1716 100644 --- a/lib/src/phy/fec/turbodecoder_simd.c +++ b/lib/src/phy/fec/turbodecoder_simd.c @@ -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; - int16_t *outptr[SRSLTE_TDEC_MAX_NPAR]; + int16_t *outptr[SRSLTE_TDEC_MAX_NPAR] = { NULL, NULL }; // Compute branch metrics switch(cb_mask) { diff --git a/lib/src/phy/fec/turbodecoder_sse_inter.c b/lib/src/phy/fec/turbodecoder_sse_inter.c index bb1168368..d75c8a649 100644 --- a/lib/src/phy/fec/turbodecoder_sse_inter.c +++ b/lib/src/phy/fec/turbodecoder_sse_inter.c @@ -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 *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--) { x = _mm_load_si128(inputPtr++); y = _mm_load_si128(parityPtr++); diff --git a/lib/src/phy/io/filesource.c b/lib/src/phy/io/filesource.c index 048ecb584..1324bf2b0 100644 --- a/lib/src/phy/io/filesource.c +++ b/lib/src/phy/io/filesource.c @@ -50,7 +50,9 @@ void srslte_filesource_free(srslte_filesource_t *q) { } 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) { diff --git a/lib/src/phy/mimo/precoding.c b/lib/src/phy/mimo/precoding.c index a78c13056..6d50e3ed2 100644 --- a/lib/src/phy/mimo/precoding.c +++ b/lib/src/phy/mimo/precoding.c @@ -2205,7 +2205,9 @@ int srslte_precoding_pmi_select_2l_gen(cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORT } /* Divide average by noise */ - sinr_list[i] /= count; + if (count) { + sinr_list[i] /= count; + } if (sinr_list[i] > max_sinr) { 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 */ - sinr_list[i] /= count; + if (count) { + sinr_list[i] /= count; + } if (sinr_list[i] > max_sinr) { 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 */ - sinr_list[i] /= count; + if (count) { + sinr_list[i] /= count; + } if (sinr_list[i] > max_sinr) { 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++; } - return cn_avg/count; + if (count) { + cn_avg /= count; + } + + return cn_avg; } /* Computes the condition number for a given number of antennas, diff --git a/lib/src/phy/mimo/test/pmi_select_test.c b/lib/src/phy/mimo/test/pmi_select_test.c index c7e5b5c8e..a40723d34 100644 --- a/lib/src/phy/mimo/test/pmi_select_test.c +++ b/lib/src/phy/mimo/test/pmi_select_test.c @@ -124,7 +124,7 @@ int main(int argc, char **argv) { /* Condition number */ 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; } diff --git a/lib/src/phy/mimo/test/precoder_test.c b/lib/src/phy/mimo/test/precoder_test.c index 589e3d51c..1054545c3 100644 --- a/lib/src/phy/mimo/test/precoder_test.c +++ b/lib/src/phy/mimo/test/precoder_test.c @@ -42,7 +42,7 @@ int nof_symbols = 1000; uint32_t codebook_idx = 0; int nof_layers = 1, nof_tx_ports = 1, nof_rx_ports = 1, nof_re = 1; char *mimo_type_name = NULL; -char decoder_type_name [16] = "zf"; +char decoder_type_name [17] = "zf"; float snr_db = 100.0f; float scaling = 0.1f; @@ -56,7 +56,7 @@ void usage(char *prog) { printf("\t-g Scaling [Default %.1f]*\n", scaling); printf("\t-d decoder type [zf|mmse] [Default %s]\n", decoder_type_name); 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) { @@ -82,7 +82,8 @@ void parse_args(int argc, char **argv) { codebook_idx = (uint32_t) atoi(argv[optind]); break; case 'd': - strncpy(decoder_type_name, argv[optind], 16); + strncpy(decoder_type_name, argv[optind], 15); + decoder_type_name[15] = 0; break; case 's': snr_db = (float) atof(argv[optind]); diff --git a/lib/src/phy/phch/cqi.c b/lib/src/phy/phch/cqi.c index a115bcd28..522cdf10b 100644 --- a/lib/src/phy/phch/cqi.c +++ b/lib/src/phy/phch/cqi.c @@ -383,7 +383,7 @@ bool srslte_ri_send(uint32_t I_cqi_pmi, uint32_t I_ri, uint32_t tti) { return false; } - if (M_ri) { + if (M_ri && N_p) { if ((tti - N_offset_p + N_offset_ri) % (N_p * M_ri) == 0) { 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) { 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'; } + + 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'; } diff --git a/lib/src/phy/phch/dci.c b/lib/src/phy/phch/dci.c index 7d4ccd1ea..6766ca5f0 100644 --- a/lib/src/phy/phch/dci.c +++ b/lib/src/phy/phch/dci.c @@ -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); return ret; } - - srslte_ra_dl_dci_to_grant(dl_dci, nof_prb, msg_rnti, grant); - if (SRSLTE_VERBOSE_ISINFO()) { - srslte_ra_pdsch_fprint(stdout, dl_dci, nof_prb); - srslte_ra_dl_grant_fprint(stdout, grant); + if (!dl_dci->is_ra_order) { + srslte_ra_dl_dci_to_grant(dl_dci, nof_prb, msg_rnti, grant); + + if (SRSLTE_VERBOSE_ISINFO()) { + srslte_ra_pdsch_fprint(stdout, dl_dci, nof_prb); + srslte_ra_dl_grant_fprint(stdout, grant); + } } 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]) { n += snprintf(&info_str[n], len-n, "%d", dci_msg->mcs_idx); if (dci_msg->tb_en[1]) { - n += snprintf(&info_str[n], len-n, ","); + n += snprintf(&info_str[n], len-n, "/"); } else { 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]) { n += snprintf(&info_str[n], len-n, "%d", dci_msg->rv_idx); if (dci_msg->tb_en[1]) { - n += snprintf(&info_str[n], len-n, ","); + n += snprintf(&info_str[n], len-n, "/"); } else { 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]) { n += snprintf(&info_str[n], len-n, "%d", dci_msg->ndi); if (dci_msg->tb_en[1]) { - n += snprintf(&info_str[n], len-n, ","); + n += snprintf(&info_str[n], len-n, "/"); } else { 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; } if (*y++ != 0) { - INFO("DCI message is Format1A\n", 0); + INFO("DCI message is Format1A\n"); return SRSLTE_ERROR; } 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) { - INFO("DCI message is Format0\n", 0); + INFO("DCI message is Format0\n"); 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) { int nof_bits = riv_nbits(nof_prb); int i=0; - while(inof_bits-1 && y[i] == 0) { i++; } if (i == msg->nof_bits-1) { - //printf("Received a Format1A RA PDCCH order. Not implemented!\n"); - return SRSLTE_ERROR; + // This is a Random access order + 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->type2_alloc.mode = *y++; diff --git a/lib/src/phy/phch/pdcch.c b/lib/src/phy/phch/pdcch.c index ca8480bc6..969b53cf7 100644 --- a/lib/src/phy/phch/pdcch.c +++ b/lib/src/phy/phch/pdcch.c @@ -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); - DEBUG("CConv output: ", 0); + DEBUG("CConv output: "); if (SRSLTE_VERBOSE_ISDEBUG()) { 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); - DEBUG("Scrambling output: ", 0); + DEBUG("Scrambling output: "); if (SRSLTE_VERBOSE_ISDEBUG()) { srslte_vec_fprint_b(stdout, q->e, e_bits); } diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index fbf0860be..1cf4af4e2 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include "prb_dl.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); - INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d, mimo_type=%d, 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); + 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, srslte_mod_string(cfg->grant.mcs->mod), cfg->nof_layers, nof_tb); // Extract Symbols and Channel Estimates for (int j=0;jnof_rx_antennas;j++) { diff --git a/lib/src/phy/phch/phich.c b/lib/src/phy/phch/phich.c index 37b8e1b7a..6990d69e2 100644 --- a/lib/src/phy/phch/phich.c +++ b/lib/src/phy/phch/phich.c @@ -148,7 +148,7 @@ uint8_t srslte_phich_ack_decode(float bits[SRSLTE_PHICH_NBITS], float *distance) uint8_t index=0; if (SRSLTE_VERBOSE_ISINFO()) { - INFO("Received bits: ", 0); + INFO("Received bits: "); 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_layerdemap_diversity(x, q->d0, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); } - DEBUG("Recv!!: \n", 0); - DEBUG("d0: ", 0); + DEBUG("Recv!!: \n"); + DEBUG("d0: "); if (SRSLTE_VERBOSE_ISDEBUG()) 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)); } - DEBUG("d: ", 0); + DEBUG("d: "); if (SRSLTE_VERBOSE_ISDEBUG()) 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()) 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); - DEBUG("data: ", 0); + DEBUG("data: "); if (SRSLTE_VERBOSE_ISDEBUG()) 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()) 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)); } - DEBUG("d0: ", 0); + DEBUG("d0: "); if (SRSLTE_VERBOSE_ISDEBUG()) srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB); diff --git a/lib/src/phy/phch/ra.c b/lib/src/phy/phch/ra.c index e1eaa5de2..7107ab2f6 100644 --- a/lib/src/phy/phch/ra.c +++ b/lib/src/phy/phch/ra.c @@ -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, - srslte_ra_nbits_t nbits [SRSLTE_MAX_CODEWORDS]) + srslte_ra_nbits_t nbits[SRSLTE_MAX_CODEWORDS]) { // Compute number of RE for (int i = 0; i < SRSLTE_MAX_TB; i++) { diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index a2da3195c..e6b7d49b9 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -89,7 +89,8 @@ uint32_t srslte_sch_find_Ioffset_cqi(float beta) { int srslte_sch_init(srslte_sch_t *q) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - if (q) { + if (q) { + ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_sch_t)); if (srslte_crc_init(&q->crc_tb, SRSLTE_LTE_CRC24A, 24)) { @@ -494,7 +495,7 @@ static int decode_tb(srslte_sch_t *q, ((uint32_t) data[cb_segm->tbs/8+2]); if (par_rx == par_tx && par_rx) { - INFO("TB decoded OK\n",0); + INFO("TB decoded OK\n"); return SRSLTE_SUCCESS; } else { INFO("Error in TB parity: par_tx=0x%x, par_rx=0x%x\n", par_tx, par_rx); @@ -753,7 +754,11 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q, uint32_t nb_q = cfg->nbits.nof_bits; uint32_t Qm = cfg->grant.Qm; - + + if (Qm == 0) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + if (uci_data.uci_ri_len > 0) { float beta = beta_ri_offset[cfg->uci_cfg.I_offset_ri]; if (cfg->cb_segm.tbs == 0) { diff --git a/lib/src/phy/phch/test/pbch_file_test.c b/lib/src/phy/phch/test/pbch_file_test.c index 2ca12e4c9..6b79db422 100644 --- a/lib/src/phy/phch/test/pbch_file_test.c +++ b/lib/src/phy/phch/test/pbch_file_test.c @@ -154,7 +154,7 @@ int base_init() { return -1; } - DEBUG("Memory init OK\n",0); + DEBUG("Memory init OK\n"); return 0; } diff --git a/lib/src/phy/phch/test/pcfich_file_test.c b/lib/src/phy/phch/test/pcfich_file_test.c index e92d6c7ba..98ff829be 100644 --- a/lib/src/phy/phch/test/pcfich_file_test.c +++ b/lib/src/phy/phch/test/pcfich_file_test.c @@ -170,7 +170,7 @@ int base_init() { return -1; } - DEBUG("Memory init OK\n",0); + DEBUG("Memory init OK\n"); return 0; } @@ -232,7 +232,7 @@ int main(int argc, char **argv) { /* Get channel estimates for each port */ 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); diff --git a/lib/src/phy/phch/test/pdcch_file_test.c b/lib/src/phy/phch/test/pdcch_file_test.c index 5482d9f98..2f0ae30cc 100644 --- a/lib/src/phy/phch/test/pdcch_file_test.c +++ b/lib/src/phy/phch/test/pdcch_file_test.c @@ -180,7 +180,7 @@ int base_init() { exit(-1); } - DEBUG("Memory init OK\n",0); + DEBUG("Memory init OK\n"); return 0; } @@ -244,7 +244,7 @@ int main(int argc, char **argv) { return -1; } 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); } else { INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti); diff --git a/lib/src/phy/phch/test/pdsch_pdcch_file_test.c b/lib/src/phy/phch/test/pdsch_pdcch_file_test.c index ba662bc49..76f48b959 100644 --- a/lib/src/phy/phch/test/pdsch_pdcch_file_test.c +++ b/lib/src/phy/phch/test/pdsch_pdcch_file_test.c @@ -148,7 +148,7 @@ int base_init() { srslte_ue_dl_set_rnti(&ue_dl, rnti); - DEBUG("Memory init OK\n",0); + DEBUG("Memory init OK\n"); return 0; } diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index 0b18d8b10..27802d7c3 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -51,7 +51,7 @@ srslte_cell_t cell = { 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; uint32_t cfi = 1; uint32_t mcs[SRSLTE_MAX_CODEWORDS] = {0, 0}; @@ -111,7 +111,8 @@ void parse_args(int argc, char **argv) { cfi = atoi(argv[optind]); break; case 'x': - strncpy(mimo_type_str, argv[optind], 32); + strncpy(mimo_type_str, argv[optind], sizeof(mimo_type_str)); + mimo_type_str[sizeof(mimo_type_str)-1] = 0; break; case 'p': pmi = (uint32_t) atoi(argv[optind]); @@ -177,21 +178,10 @@ int main(int argc, char **argv) { goto quit; } - switch(mimo_type) { - - case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA: - cell.nof_ports = 1; - break; - case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX: - case SRSLTE_MIMO_TYPE_CDD: - if (nof_rx_antennas < 2) { - ERROR("At least two receiving antennas are required"); - goto quit; - } - case SRSLTE_MIMO_TYPE_TX_DIVERSITY: - default: - cell.nof_ports = 2; - break; + if (mimo_type == SRSLTE_MIMO_TYPE_SINGLE_ANTENNA) { + cell.nof_ports = 1; + } else { + cell.nof_ports = 2; } srslte_ra_dl_dci_t dci; @@ -249,7 +239,7 @@ int main(int argc, char **argv) { for (i=0;i 1e6) { - if (30720%((int) srate/1000) == 0) { + if (srate > 1e6 && (srate/1000) > 0) { + if (30720%(srate/1000) == 0) { srslte_rf_set_master_clock_rate(&rf, 30.72e6); } else { srslte_rf_set_master_clock_rate(&rf, 23.04e6); diff --git a/lib/src/phy/phch/test/pusch_test.c b/lib/src/phy/phch/test/pusch_test.c index 651803617..a7a3c49bf 100644 --- a/lib/src/phy/phch/test/pusch_test.c +++ b/lib/src/phy/phch/test/pusch_test.c @@ -193,7 +193,7 @@ int main(int argc, char **argv) { uci_data_tx.uci_ack_len = 1; 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;itmp_cqi, data, sizeof(uint8_t) * 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()) { srslte_vec_fprint_b(stdout, q->tmp_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()) { 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)); - DEBUG("cconv_rx=", 0); + DEBUG("cconv_rx="); if (SRSLTE_VERBOSE_ISDEBUG()) { 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); - DEBUG("cqi_crc_rx=", 0); + DEBUG("cqi_crc_rx="); if (SRSLTE_VERBOSE_ISDEBUG()) { srslte_vec_fprint_b(stdout, q->tmp_cqi, nof_bits+8); } @@ -655,11 +655,19 @@ int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg, uint8_t acks[2], uint32_t nof uint32_t nof_encoded_bits = encode_ri_ack(acks, nof_acks, q_encoded_bits, cfg->grant.Qm); - for (uint32_t i=0;igrant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ack_bits[cfg->grant.Qm*i]); - uci_ulsch_interleave_put(&q_encoded_bits[(i*cfg->grant.Qm)%nof_encoded_bits], cfg->grant.Qm, &ack_bits[cfg->grant.Qm*i]); + if (nof_encoded_bits > 0) { + for (uint32_t i = 0; i < Qprime; i++) { + uci_ulsch_interleave_ack_gen(i, + cfg->grant.Qm, + H_prime_total, + cfg->nbits.nof_symb, + cfg->cp, + &ack_bits[cfg->grant.Qm * i]); + uci_ulsch_interleave_put(&q_encoded_bits[(i * cfg->grant.Qm) % nof_encoded_bits], + cfg->grant.Qm, + &ack_bits[cfg->grant.Qm * i]); + } } - return (int) Qprime; } @@ -706,25 +714,27 @@ int srslte_uci_encode_ack_ri(srslte_pusch_cfg_t *cfg, uint32_t nof_encoded_bits = encode_ri_ack(data, data_len, q_encoded_bits, cfg->grant.Qm); - for (uint32_t i = 0; i < Qprime; i++) { - if (ack_ri) { - uci_ulsch_interleave_ri_gen(i, - cfg->grant.Qm, - H_prime_total, - cfg->nbits.nof_symb, - cfg->cp, - &bits[cfg->grant.Qm * i]); - } else { - uci_ulsch_interleave_ack_gen(i, - cfg->grant.Qm, - H_prime_total, - cfg->nbits.nof_symb, - cfg->cp, - &bits[cfg->grant.Qm * i]); + if (nof_encoded_bits > 0) { + for (uint32_t i = 0; i < Qprime; i++) { + if (ack_ri) { + uci_ulsch_interleave_ri_gen(i, + cfg->grant.Qm, + H_prime_total, + cfg->nbits.nof_symb, + cfg->cp, + &bits[cfg->grant.Qm * i]); + } else { + uci_ulsch_interleave_ack_gen(i, + cfg->grant.Qm, + H_prime_total, + cfg->nbits.nof_symb, + cfg->cp, + &bits[cfg->grant.Qm * i]); + } + uci_ulsch_interleave_put(&q_encoded_bits[(i * cfg->grant.Qm) % nof_encoded_bits], + cfg->grant.Qm, + &bits[cfg->grant.Qm * i]); } - uci_ulsch_interleave_put(&q_encoded_bits[(i * cfg->grant.Qm) % nof_encoded_bits], - cfg->grant.Qm, - &bits[cfg->grant.Qm * i]); } return (int) Qprime; diff --git a/lib/src/phy/resampling/resample_arb.c b/lib/src/phy/resampling/resample_arb.c index 441e8c0dc..5cea28ed2 100644 --- a/lib/src/phy/resampling/resample_arb.c +++ b/lib/src/phy/resampling/resample_arb.c @@ -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); 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){ diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 7421275b5..9a45ff8f1 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -97,7 +97,11 @@ char* rf_soapy_devname(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; } @@ -197,14 +201,13 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) printf("No Soapy devices found.\n"); return SRSLTE_ERROR; } - char* devname; + char* devname = NULL; 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++) { 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")){ devname = DEVNAME_LIME; - } } 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])); if (sdr == NULL) { - printf("failed to create SOAPY object\n"); + printf("Failed to create Soapy object\n"); 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->devname = devname; 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) { printf("Rx setupStream fail: %s\n", SoapySDRDevice_lastError()); 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){ - 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) { printf("Tx setupStream fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } } + + // list device sensors size_t sensor_length; char** sensors; sensors = SoapySDRDevice_listSensors(handler->device, &sensor_length); - for(int i = 0; i < sensor_length;i++) - { - printf("available sensors are : \n"); - puts(sensors[i]); + printf("Available device sensors: \n"); + for(int i = 0; i < sensor_length; i++) { + printf(" - %s\n", 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; @@ -399,7 +410,7 @@ void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs) //TODO: add multi-channel support int rf_soapy_recv_with_time_multi(void *h, - void **data, + void *data[SRSLTE_MAX_PORTS], uint32_t nsamples, bool blocking, 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; int flags; //flags set by receive operation int num_channels = 1; // temp + const long timeoutUs = 1000000; // arbitrarily chosen int trials = 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]; 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) { // continue when getting overflows if (ret == SOAPY_SDR_OVERFLOW) { @@ -446,8 +458,6 @@ int rf_soapy_recv_with_time_multi(void *h, n += ret; trials++; } while (n < nsamples && trials < 100); - - return n; } diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index c9c3c4866..0fc70c547 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -562,7 +562,10 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) perror("pthread_create"); return -1; } - + + /* Restore priorities */ + uhd_set_thread_priority(0, false); + return 0; } else { 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, - void **data, + void *data[SRSLTE_MAX_PORTS], uint32_t nsamples, bool blocking, time_t *secs, double *frac_secs) { - rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; uhd_rx_metadata_handle *md = &handler->rx_md_first; size_t rxd_samples = 0; diff --git a/lib/src/phy/rf/rf_utils.c b/lib/src/phy/rf/rf_utils.c index ea016c721..4587ebdcb 100644 --- a/lib/src/phy/rf/rf_utils.c +++ b/lib/src/phy/rf/rf_utils.c @@ -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); srslte_rf_set_rx_srate(rf, (float) srate); - INFO("Starting receiver...\n", 0); + INFO("Starting receiver...\n"); srslte_rf_start_rx_stream(rf, false); // 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); 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); /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index bf86eef4d..c948a53d4 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -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; if (q != NULL && - frame_size <= 307200 && fft_size_isvalid(fft_size)) { if (frame_size > q->max_frame_size) { diff --git a/lib/src/phy/sync/test/pss_file.c b/lib/src/phy/sync/test/pss_file.c index 4087366ec..d1ec2a130 100644 --- a/lib/src/phy/sync/test/pss_file.c +++ b/lib/src/phy/sync/test/pss_file.c @@ -59,7 +59,7 @@ void usage(char *prog) { printf("Usage: %s [nlestodv] -i cell_id -f input_file_name\n", prog); printf("\t-n nof_frames [Default %d]\n", nof_frames); printf("\t-l N_id_2 to sync [Default use cell_id]\n"); - printf("\t-e Extended CP [Default Normal]\n", fft_size); + printf("\t-e Extended CP [Default Normal]\n"); printf("\t-s symbol_sz [Default %d]\n", fft_size); printf("\t-t threshold [Default %.2f]\n", threshold); printf("\t-o file read offset [Default %d]\n", file_offset); @@ -266,7 +266,7 @@ int main(int argc, char **argv) { } } else { - INFO("No space for CFO computation. Frame starts at \n",peak_idx); + INFO("No space for CFO computation. Frame starts at \n"); } if(srslte_sss_subframe(m0,m1) == 0) diff --git a/lib/src/phy/sync/test/pss_usrp.c b/lib/src/phy/sync/test/pss_usrp.c index 70881f15b..d82555c95 100644 --- a/lib/src/phy/sync/test/pss_usrp.c +++ b/lib/src/phy/sync/test/pss_usrp.c @@ -61,7 +61,7 @@ void usage(char *prog) { printf("\t-g RF Gain [Default %.2f dB]\n", rf_gain); printf("\t-n nof_frames [Default %d]\n", nof_frames); printf("\t-l N_id_2 to sync [Default use cell_id]\n"); - printf("\t-e Extended CP [Default Normal]\n", fft_size); + printf("\t-e Extended CP [Default Normal]\n"); printf("\t-s symbol_sz [Default %d]\n", fft_size); printf("\t-t threshold [Default %.2f]\n", threshold); #ifndef DISABLE_GRAPHICS @@ -291,7 +291,7 @@ int main(int argc, char **argv) { } } else { - INFO("No space for CFO computation. Frame starts at \n",peak_idx); + INFO("No space for CFO computation. Frame starts at \n"); } if(srslte_sss_subframe(m0,m1) == 0) diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 1569c420f..cbd84093a 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -550,6 +550,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, switch(dci_msg.format) { case SRSLTE_DCI_FORMAT1: case SRSLTE_DCI_FORMAT1A: + case SRSLTE_DCI_FORMAT1C: if (q->cell.nof_ports == 1) { mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; } else { @@ -573,7 +574,6 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, /* Not implemented formats */ case SRSLTE_DCI_FORMAT0: - case SRSLTE_DCI_FORMAT1C: case SRSLTE_DCI_FORMAT1B: case SRSLTE_DCI_FORMAT1D: case SRSLTE_DCI_FORMAT2B: @@ -896,7 +896,7 @@ static int find_dl_dci_type_crnti(srslte_ue_dl_t *q, uint32_t tm, uint32_t cfi, dci_blind_search_t *current_ss = &search_space; if (cfi < 1 || cfi > 3) { - ERROR("CFI must be 1 ≤ cfi ≤ 3", cfi); + ERROR("CFI must be 1 ≤ cfi ≤ 3 (cfi=%d)", cfi); return SRSLTE_ERROR; } diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index 480835e6b..7ee97c21b 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -751,7 +751,7 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE break; case SRSLTE_SYNC_FOUND_NOSPACE: /* 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); srslte_sync_reset(&q->sfind); ret = SRSLTE_SUCCESS; diff --git a/lib/src/phy/ue/ue_ul.c b/lib/src/phy/ue/ue_ul.c index 5580a99d1..a0accb579 100644 --- a/lib/src/phy/ue/ue_ul.c +++ b/lib/src/phy/ue/ue_ul.c @@ -444,7 +444,6 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && - softbuffer != NULL && output_signal != NULL) { diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index cb7eff480..ebda516ea 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -49,8 +49,8 @@ bool verbose = false; #define RANDOM_F() ((float)rand())/((float)RAND_MAX) -#define RANDOM_S() ((int16_t)(rand() && 0x800F)) -#define RANDOM_B() ((int8_t)(rand() && 0x8008)) +#define RANDOM_S() ((int16_t)(rand() & 0x800F)) +#define RANDOM_B() ((int8_t)(rand() & 0x8008)) #define RANDOM_CF() (RANDOM_F() + _Complex_I*RANDOM_F()) #define TEST_CALL(TEST_CODE) gettimeofday(&start, NULL);\ @@ -137,7 +137,7 @@ TEST(srslte_vec_dot_prod_sss, MALLOC(int16_t, y); int16_t z; - cf_t gold = 0.0f; + int16_t gold = 0.0f; for (int i = 0; i < block_size; i++) { x[i] = RANDOM_S(); y[i] = RANDOM_S(); @@ -149,7 +149,7 @@ TEST(srslte_vec_dot_prod_sss, gold += x[i] * y[i]; } - mse += cabsf(gold - z) / cabsf(gold); + mse = (gold - z) / abs(gold); free(x); free(y); @@ -160,7 +160,7 @@ TEST(srslte_vec_sum_sss, MALLOC(int16_t, y); MALLOC(int16_t, z); - cf_t gold = 0.0f; + int16_t gold = 0; for (int i = 0; i < block_size; i++) { x[i] = RANDOM_S(); y[i] = RANDOM_S(); @@ -170,7 +170,7 @@ TEST(srslte_vec_sum_sss, for (int i = 0; i < block_size; i++) { gold = x[i] + y[i]; - mse += cabsf(gold - z[i]); + mse += abs(gold - z[i]); } free(x); @@ -183,7 +183,7 @@ TEST(srslte_vec_sub_sss, MALLOC(int16_t, y); MALLOC(int16_t, z); - cf_t gold = 0.0f; + int16_t gold = 0.0f; for (int i = 0; i < block_size; i++) { x[i] = RANDOM_S(); y[i] = RANDOM_S(); @@ -193,7 +193,7 @@ TEST(srslte_vec_sub_sss, for (int i = 0; i < block_size; i++) { gold = x[i] - y[i]; - mse += cabsf(gold - z[i]); + mse += abs(gold - z[i]); } free(x); @@ -206,7 +206,7 @@ TEST(srslte_vec_prod_sss, MALLOC(int16_t, y); MALLOC(int16_t, z); - cf_t gold = 0.0f; + int16_t gold = 0.0f; for (int i = 0; i < block_size; i++) { x[i] = RANDOM_S(); y[i] = RANDOM_S(); @@ -216,7 +216,7 @@ TEST(srslte_vec_prod_sss, for (int i = 0; i < block_size; i++) { gold = x[i] * y[i]; - mse += cabsf(gold - z[i]); + mse += abs(gold - z[i]); } free(x); @@ -802,16 +802,18 @@ int main(int argc, char **argv) { size_count++; } - char fname[68]; + char fname[69]; FILE *f = NULL; void * p = popen("(date +%g%m%d && hostname) | tr '\\r\\n' '__'", "r"); if (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"); - 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"); diff --git a/lib/src/phy/utils/vector_simd.c b/lib/src/phy/utils/vector_simd.c index 024b3849f..df8a1ea4e 100644 --- a/lib/src/phy/utils/vector_simd.c +++ b/lib/src/phy/utils/vector_simd.c @@ -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; } +#ifdef ENABLE_C16 c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len) { int i = 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; } +#endif /* ENABLE_C16 */ 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, int16_t *r_re, int16_t *r_im, const int len) { 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]; } } +#endif /* ENABLE_C16 */ void srslte_vec_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len) { int i = 0; diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index e7c02c179..188c56c97 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -30,7 +30,14 @@ namespace srslte { pdcp::pdcp() -{} +{ + rlc = NULL; + rrc = NULL; + gw = NULL; + pdcp_log = NULL; + lcid = 0; + direction = 0; +} void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, uint32_t lcid_, uint8_t direction_) { @@ -52,11 +59,6 @@ void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_ void pdcp::stop() { - for(uint32_t i=0;idebug("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 void pdcp_entity::reestablish() { // For SRBs @@ -165,7 +165,53 @@ void pdcp_entity::enable_encryption() // RLC interface 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, @@ -332,63 +378,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) { #define RB_ID_SRB2 2 diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index 7a7180e45..a626f3002 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -35,6 +35,15 @@ namespace srslte { rlc::rlc() { pool = byte_buffer_pool::get_instance(); + rlc_log = NULL; + pdcp = NULL; + rrc = NULL; + mac_timers = NULL; + ue = NULL; + default_lcid = 0; + bzero(metrics_time, sizeof(metrics_time)); + bzero(ul_tput_bytes, sizeof(ul_tput_bytes)); + bzero(dl_tput_bytes, sizeof(dl_tput_bytes)); } void rlc::init(srsue::pdcp_interface_rlc *pdcp_, @@ -233,13 +242,13 @@ void rlc::add_bearer(uint32_t lcid) void rlc::add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg) { - if(lcid < 0 || lcid >= SRSLTE_N_RADIO_BEARERS) { + if(lcid >= SRSLTE_N_RADIO_BEARERS) { rlc_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); return; } if (!rlc_array[lcid].active()) { - rlc_log->info("Adding radio bearer %s with mode %s\n", + rlc_log->warning("Adding radio bearer %s with mode %s\n", rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg.rlc_mode]); switch(cnfg.rlc_mode) { @@ -271,10 +280,9 @@ void rlc::add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg) *******************************************************************************/ bool rlc::valid_lcid(uint32_t lcid) { - if(lcid < 0 || lcid >= SRSLTE_N_RADIO_BEARERS) { + if(lcid >= SRSLTE_N_RADIO_BEARERS) { return false; - } - if(!rlc_array[lcid].active()) { + } else if(!rlc_array[lcid].active()) { return false; } return true; diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index c6c69c12b..6905151f0 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -38,6 +38,12 @@ namespace srslte { rlc_am::rlc_am() : tx_sdu_queue(16) { + log = NULL; + pdcp = NULL; + rrc = NULL; + lcid = 0; + bzero(&cfg, sizeof(srslte_rlc_am_config_t)); + tx_sdu = NULL; rx_sdu = NULL; pool = byte_buffer_pool::get_instance(); @@ -77,7 +83,7 @@ void rlc_am::init(srslte::log *log_, void rlc_am::configure(srslte_rlc_config_t cfg_) { cfg = cfg_.am; - log->info("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " + log->warning("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " "t_reordering=%d, t_status_prohibit=%d\n", rrc->get_rb_name(lcid).c_str(), cfg.t_poll_retx, cfg.poll_pdu, cfg.poll_byte, cfg.max_retx_thresh, cfg.t_reordering, cfg.t_status_prohibit); @@ -175,8 +181,8 @@ uint32_t rlc_am::get_bearer() 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); + 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 +688,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) tx_sdu->msg += to_move; 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()); pool->deallocate(tx_sdu); tx_sdu = NULL; @@ -717,7 +723,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) tx_sdu->msg += to_move; 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()); pool->deallocate(tx_sdu); tx_sdu = NULL; @@ -768,7 +774,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) return (ptr-payload) + pdu->N_bytes; } -void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_header_t header) +void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_header_t &header) { std::map::iterator it; @@ -806,7 +812,7 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h memcpy(pdu.buf->msg, payload, nof_bytes); pdu.buf->N_bytes = nof_bytes; - pdu.header = header; + memcpy(&pdu.header, &header, sizeof(rlc_amd_pdu_header_t)); rx_window[header.sn] = pdu; @@ -865,7 +871,7 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h debug_state(); } -void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_header_t header) +void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_header_t &header) { std::map::iterator it; @@ -891,7 +897,7 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a } memcpy(segment.buf->msg, payload, nof_bytes); segment.buf->N_bytes = nof_bytes; - segment.header = header; + memcpy(&segment.header, &header, sizeof(rlc_amd_pdu_header_t)); // Check if we already have a segment from the same PDU it = rx_segments.find(header.sn); diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index 627752494..bcf3cd20a 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -31,6 +31,10 @@ namespace srslte { rlc_tm::rlc_tm() : ul_queue(16) { + log = NULL; + pdcp = NULL; + rrc = NULL; + lcid = 0; pool = byte_buffer_pool::get_instance(); } @@ -111,7 +115,7 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) ul_queue.read(&buf); pdu_size = 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()); 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]); diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 4756e2f7c..213e8c840 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -33,6 +33,14 @@ namespace srslte { rlc_um::rlc_um() : tx_sdu_queue(16) { + log = NULL; + pdcp = NULL; + rrc = NULL; + reordering_timer = NULL; + lcid = 0; + reordering_timer_id = 0; + bzero(&cfg, sizeof(srslte_rlc_um_config_t)); + tx_sdu = NULL; rx_sdu = NULL; pool = byte_buffer_pool::get_instance(); @@ -73,18 +81,18 @@ void rlc_um::configure(srslte_rlc_config_t cnfg_) switch(cnfg_.rlc_mode) { case LIBLTE_RRC_RLC_MODE_UM_BI: - log->info("%s configured in %s mode: " + log->warning("%s configured in %s mode: " "t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]); break; case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: - log->info("%s configured in %s mode: tx_sn_field_length=%u bits\n", + log->warning("%s configured in %s mode: tx_sn_field_length=%u bits\n", rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], rlc_umd_sn_size_num[cfg.rx_sn_field_length]); break; case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: - log->info("%s configured in %s mode: " + log->warning("%s configured in %s mode: " "t_reordering=%d ms, rx_sn_field_length=%u bits\n", rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length]); @@ -153,8 +161,8 @@ uint32_t rlc_um::get_bearer() 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); + 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 +186,7 @@ uint32_t rlc_um::get_buffer_state() // Room needed for fixed header? if(n_bytes > 0) - n_bytes += 2; + n_bytes += 3; return n_bytes; } @@ -300,7 +308,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) tx_sdu->msg += to_move; 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()); pool->deallocate(tx_sdu); tx_sdu = NULL; @@ -329,7 +337,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) tx_sdu->msg += to_move; 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()); pool->deallocate(tx_sdu); tx_sdu = NULL; diff --git a/lib/test/common/CMakeLists.txt b/lib/test/common/CMakeLists.txt index bbdc74613..9c8bece01 100644 --- a/lib/test/common/CMakeLists.txt +++ b/lib/test/common/CMakeLists.txt @@ -37,6 +37,10 @@ add_executable(test_eea2 test_eea2.cc) target_link_libraries(test_eea2 srslte_common ${CMAKE_THREAD_LIBS_INIT}) add_test(test_eea2 test_eea2) +add_executable(test_f12345 test_f12345.cc) +target_link_libraries(test_f12345 srslte_common ${CMAKE_THREAD_LIBS_INIT}) +add_test(test_f12345 test_f12345) + add_executable(log_filter_test log_filter_test.cc) target_link_libraries(log_filter_test srslte_phy srslte_common srslte_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) diff --git a/lib/test/common/logger_test.cc b/lib/test/common/logger_test.cc index 845d4c104..895db4e77 100644 --- a/lib/test/common/logger_test.cc +++ b/lib/test/common/logger_test.cc @@ -67,7 +67,7 @@ void write(std::string filename) { bool read(std::string filename) { bool pass = true; bool written[NTHREADS][NMSGS]; - int thread, msg; + int thread = 0, msg = 0; int r; for(int i=0;i +#include +#include + +#include "srslte/common/liblte_security.h" + + +/* + * Prototypes + */ + +int32 arrcmp(uint8_t const * const a, uint8_t const * const b, uint32 len) { + uint32 i = 0; + + for (i = 0; i < len; i++) { + if (a[i] != b[i]) { + return a[i] - b[i]; + } + } + return 0; +} + +void arrprint(uint8_t const * const a, uint32 len) { + uint32 i = 0; + + for (i = 0; i < len; i++) { + printf("0x%02x ", a[i]); + if ((i%16==0) && i) + printf("\n"); + } + printf("\n"); + return; +} + + + +/* + * Tests + * + * Document Reference: 35.208 e00 + */ + + + +/* + * Functions + */ + + +void test_set_2() +{ + LIBLTE_ERROR_ENUM err_lte = LIBLTE_ERROR_INVALID_INPUTS; + int32 err_cmp = 0; + + uint8_t k[] = {0x46, 0x5b, 0x5c, 0xe8, 0xb1, 0x99, 0xb4, 0x9f, 0xaa, 0x5f, 0x0a, 0x2e, 0xe2, 0x38, 0xa6, 0xbc}; + uint8_t rand[] = {0x23, 0x55, 0x3c, 0xbe, 0x96, 0x37, 0xa8, 0x9d, 0x21, 0x8a, 0xe6, 0x4d, 0xae, 0x47, 0xbf, 0x35}; + uint8_t sqn[] = {0xff, 0x9b, 0xb4, 0xd0, 0xb6, 0x07}; + uint8_t amf[] = {0xb9, 0xb9}; + uint8_t op[] = {0xcd, 0xc2, 0x02, 0xd5, 0x12, 0x3e, 0x20, 0xf6, 0x2b, 0x6d, 0x67, 0x6a, 0xc7, 0x2c, 0xb3, 0x18}; + // f1 + + uint8_t mac_o[8]; + err_lte = liblte_security_milenage_f1(k, + op, + rand, + sqn, + amf, + mac_o); + assert(err_lte == LIBLTE_SUCCESS); + + arrprint(mac_o, sizeof(mac_o)); + + uint8_t mac_a[] = {0x4a, 0x9f, 0xfa, 0xc3, 0x54, 0xdf, 0xaf, 0xb3}; + + // compare mac a + err_cmp = arrcmp(mac_o, mac_a, sizeof(mac_a)); + assert(err_cmp == 0); + + // f1 star + + uint8_t mac_so[8]; + err_lte = liblte_security_milenage_f1_star(k, + op, + rand, + sqn, + amf, + mac_so); + + assert(err_lte == LIBLTE_SUCCESS); + + uint8_t mac_s[] = {0x01, 0xcf, 0xaf, 0x9e, 0xc4, 0xe8, 0x71, 0xe9}; + + arrprint(mac_so, sizeof(mac_so)); + + err_cmp = arrcmp(mac_so, mac_s, sizeof(mac_s)); + assert(err_cmp == 0); + + // f2345 + uint8_t res_o[8]; + uint8_t ck_o[16]; + uint8_t ik_o[16]; + uint8_t ak_o[6]; + + err_lte = liblte_security_milenage_f2345(k, + op, + rand, + res_o, + ck_o, + ik_o, + ak_o); + + assert(err_lte == LIBLTE_SUCCESS); + + uint8_t res[] = {0xa5, 0x42, 0x11, 0xd5, 0xe3, 0xba, 0x50, 0xbf}; + uint8_t ck[] = {0xb4, 0x0b, 0xa9, 0xa3, 0xc5, 0x8b, 0x2a, 0x05, 0xbb, 0xf0, 0xd9, 0x87, 0xb2, 0x1b, 0xf8, 0xcb}; + uint8_t ik[] = {0xf7, 0x69, 0xbc, 0xd7, 0x51, 0x04, 0x46, 0x04, 0x12, 0x76, 0x72, 0x71, 0x1c, 0x6d, 0x34, 0x41}; + uint8_t ak[] = {0xaa, 0x68, 0x9c, 0x64, 0x83, 0x70}; + + // RESPONSE + arrprint(res_o, sizeof(res_o)); + + err_cmp = arrcmp(res_o, res, sizeof(res)); + assert(err_cmp == 0); + + // CK + arrprint(ck_o, sizeof(ck_o)); + + err_cmp = arrcmp(ck_o, ck, sizeof(ck)); + assert(err_cmp == 0); + + // IK + arrprint(ik_o, sizeof(ik_o)); + err_cmp = arrcmp(ik_o, ik, sizeof(ik)); + assert(err_cmp == 0); + + // AK + arrprint(ak_o, sizeof(ak_o)); + err_cmp = arrcmp(ak_o, ak, sizeof(ak)); + assert(err_cmp == 0); + + // f star + uint8_t ak_star_o[6]; + + err_lte = liblte_security_milenage_f5_star(k, op, rand, ak_star_o); + assert(err_lte == LIBLTE_SUCCESS); + + arrprint(ak_star_o, sizeof(ak_star_o)); + uint8_t ak_star[] = {0x45, 0x1e, 0x8b, 0xec, 0xa4, 0x3b}; + err_cmp = arrcmp(ak_star_o, ak_star, sizeof(ak_star)); + assert(err_cmp == 0); + return; +} + +/* + Own test sets +*/ + +int main(int argc, char * argv[]) { + test_set_2(); + /* + test_set_3(); + test_set_4(); + test_set_5(); + test_set_6(); + */ +} diff --git a/lib/test/common/timeout_test.cc b/lib/test/common/timeout_test.cc index 0c2593102..5c08e1b66 100644 --- a/lib/test/common/timeout_test.cc +++ b/lib/test/common/timeout_test.cc @@ -39,6 +39,7 @@ public: finished = false; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cvar, NULL); + bzero(&start_time, sizeof(start_time)); } void timeout_expired(uint32_t timeout_id) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index e0d0aabf4..c379724cc 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -54,7 +54,10 @@ class rlc_am_tester ,public rrc_interface_rlc { public: - rlc_am_tester(){n_sdus = 0;} + rlc_am_tester(){ + bzero(sdus, sizeof(sdus)); + n_sdus = 0; + } // PDCP interface void write_pdu(uint32_t lcid, byte_buffer_t *sdu) diff --git a/lib/test/upper/rlc_um_test.cc b/lib/test/upper/rlc_um_test.cc index 8abcfae3c..6ce39ef7f 100644 --- a/lib/test/upper/rlc_um_test.cc +++ b/lib/test/upper/rlc_um_test.cc @@ -57,7 +57,10 @@ class rlc_um_tester ,public rrc_interface_rlc { public: - rlc_um_tester(){n_sdus = 0;} + rlc_um_tester(){ + bzero(sdus, sizeof(sdus)); + n_sdus = 0; + } // PDCP interface void write_pdu(uint32_t lcid, byte_buffer_t *sdu) @@ -117,7 +120,7 @@ void basic_test() 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) byte_buffer_t pdu_bufs[NBUFS]; @@ -185,7 +188,7 @@ void loss_test() 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) byte_buffer_t pdu_bufs[NBUFS]; diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index f030ae12e..ff314977a 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -97,6 +97,7 @@ typedef struct { typedef struct { std::string phy_level; + std::string phy_lib_level; std::string mac_level; std::string rlc_level; std::string pdcp_level; diff --git a/srsenb/hdr/mac/mac.h b/srsenb/hdr/mac/mac.h index 4e37d439f..c99b733fb 100644 --- a/srsenb/hdr/mac/mac.h +++ b/srsenb/hdr/mac/mac.h @@ -121,7 +121,7 @@ private: static const uint32_t cfi = 3; srslte_dci_location_t locations[MAX_LOCATIONS]; - static const int MAC_PDU_THREAD_PRIO = 3; + static const int MAC_PDU_THREAD_PRIO = 60; diff --git a/srsenb/hdr/mac/scheduler_harq.h b/srsenb/hdr/mac/scheduler_harq.h index 211ec7d8d..ec2aa43c0 100644 --- a/srsenb/hdr/mac/scheduler_harq.h +++ b/srsenb/hdr/mac/scheduler_harq.h @@ -102,8 +102,8 @@ public: ul_alloc_t get_alloc(); void set_alloc(ul_alloc_t alloc); - void same_alloc(); - bool is_adaptive_retx(); + void re_alloc(ul_alloc_t alloc); + bool is_adaptive_retx(); void reset_pending_data(); bool has_pending_ack(); diff --git a/srsenb/hdr/mac/ue.h b/srsenb/hdr/mac/ue.h index b940bec43..3b81a10ec 100644 --- a/srsenb/hdr/mac/ue.h +++ b/srsenb/hdr/mac/ue.h @@ -43,7 +43,14 @@ class ue : public srslte::read_pdu_interface, { public: - ue() : mac_msg_dl(20), mac_msg_ul(20), pdus(128) { + ue() : mac_msg_dl(20), mac_msg_ul(20), conres_id_available(false), + dl_ri_counter(0), + dl_pmi_counter(0), + conres_id(0), + last_tti(0), + pdus(128) { + rrc = NULL; + sched = NULL; rlc = NULL; log_h = NULL; rnti = 0; @@ -55,6 +62,14 @@ public: for (int i=0;i rx_pdu_queue; typedef struct { diff --git a/srsenb/hdr/upper/s1ap.h b/srsenb/hdr/upper/s1ap.h index 02e5e207e..714035638 100644 --- a/srsenb/hdr/upper/s1ap.h +++ b/srsenb/hdr/upper/s1ap.h @@ -85,7 +85,7 @@ public: //void ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps); private: - static const int S1AP_THREAD_PRIO = 7; + static const int S1AP_THREAD_PRIO = 65; static const int MME_PORT = 36412; static const int ADDR_FAMILY = AF_INET; static const int SOCK_TYPE = SOCK_STREAM; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 5cf335e7c..e440081d0 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -54,11 +54,14 @@ void enb::cleanup(void) } } -enb::enb() - :started(false) -{ +enb::enb() : started(false) { srslte_dft_load(); pool = srslte::byte_buffer_pool::get_instance(); + + logger = NULL; + args = NULL; + + bzero(&rf_metrics, sizeof(rf_metrics)); } enb::~enb() diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 26458e7a2..4750de50e 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -55,8 +55,8 @@ int enb::parse_cell_cfg(all_args_t *args, srslte_cell_t *cell) { ); parser::parse_section(args->enb_files.rr_config, &phy_cnfg); - cell->phich_length = (srslte_phich_length_t) phichcfg.dur; - cell->phich_resources = (srslte_phich_resources_t) phichcfg.res; + cell->phich_length = (srslte_phich_length_t) (int) phichcfg.dur; + cell->phich_resources = (srslte_phich_resources_t) (int) phichcfg.res; if (!srslte_cell_isvalid(cell)) { fprintf(stderr, "Invalid cell parameters: nof_prb=%d, cell_id=%d\n", args->enb.n_prb, args->enb.s1ap.cell_id); @@ -716,6 +716,7 @@ int enb::parse_sib9(std::string filename, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_9_STRUC data->hnb_name_present = true; if (name_enabled) { strncpy((char*) data->hnb_name, hnb_name.c_str(), 48); + data->hnb_name[47] = 0; data->hnb_name_size = strnlen(hnb_name.c_str(), 48); } else if (hex_enabled) { data->hnb_name_size = HexToBytes(hex_value, data->hnb_name, 48); @@ -844,7 +845,7 @@ int enb::parse_rr(all_args_t* args, rrc_cfg_t* rrc_cfg) { /* Transmission mode config section */ - if (args->enb.transmission_mode < 0 || args->enb.transmission_mode > 4) { + if (args->enb.transmission_mode < 1 || args->enb.transmission_mode > 4) { ERROR("Invalid transmission mode (%d). Only indexes 1-4 are implemented.\n", args->enb.transmission_mode); return SRSLTE_ERROR; } else if (args->enb.transmission_mode == 1 && args->enb.nof_ports > 1) { diff --git a/srsenb/src/mac/mac.cc b/srsenb/src/mac/mac.cc index f7a4d5b55..8b76cc4f3 100644 --- a/srsenb/src/mac/mac.cc +++ b/srsenb/src/mac/mac.cc @@ -42,13 +42,26 @@ namespace srsenb { -mac::mac() : timers_db(128), - timers_thread(&timers_db), - rar_pdu_msg(sched_interface::MAX_RAR_LIST), +mac::mac() : timers_db(128), timers_thread(&timers_db), tti(0), last_rnti(0), + rar_pdu_msg(sched_interface::MAX_RAR_LIST), rar_payload(), pdu_process_thread(this) { started = false; - pcap = NULL; + pcap = NULL; + phy_h = NULL; + rlc_h = NULL; + rrc_h = NULL; + log_h = NULL; + + bzero(&locations, sizeof(locations)); + bzero(&cell, sizeof(cell)); + bzero(&args, sizeof(args)); + bzero(&pending_rars, sizeof(pending_rars)); + bzero(&bcch_dlsch_payload, sizeof(bcch_dlsch_payload)); + bzero(&pcch_payload_buffer, sizeof(pcch_payload_buffer)); + bzero(&bcch_softbuffer_tx, sizeof(bcch_softbuffer_tx)); + bzero(&pcch_softbuffer_tx, sizeof(pcch_softbuffer_tx)); + bzero(&rar_softbuffer_tx, sizeof(rar_softbuffer_tx)); } bool mac::init(mac_args_t *args_, srslte_cell_t *cell_, phy_interface_mac *phy, rlc_interface_mac *rlc, rrc_interface_mac *rrc, srslte::log *log_h_) @@ -392,7 +405,7 @@ int mac::rach_detected(uint32_t tti, uint32_t preamble_idx, uint32_t time_adv) // Find empty slot for pending rars uint32_t ra_id=0; - while(pending_rars[ra_id].temp_crnti && ra_idsame_alloc(); - return h; + return h; } // If not, try to find another mask in the current tti if (new_allocation(alloc.L, &alloc)) { update_allocation(alloc); - h->set_alloc(alloc); - return h; + h->set_alloc(alloc); + return h; } } // If could not schedule the reTx, or there wasn't any pending retx, find an empty PID diff --git a/srsenb/src/mac/scheduler_ue.cc b/srsenb/src/mac/scheduler_ue.cc index eb8f2459f..6948f922a 100644 --- a/srsenb/src/mac/scheduler_ue.cc +++ b/srsenb/src/mac/scheduler_ue.cc @@ -49,9 +49,18 @@ namespace srsenb { * *******************************************************/ -sched_ue::sched_ue() +sched_ue::sched_ue() : ue_idx(0), has_pucch(false), power_headroom(0), rnti(0), max_mcs_dl(0), max_mcs_ul(0), + fixed_mcs_ul(0), fixed_mcs_dl(0), phy_config_dedicated_enabled(false) { - reset(); + log_h = NULL; + + bzero(&cell, sizeof(cell)); + bzero(&lch, sizeof(lch)); + bzero(&dci_locations, sizeof(dci_locations)); + bzero(&dl_harq, sizeof(dl_harq)); + bzero(&ul_harq, sizeof(ul_harq)); + bzero(&dl_ant_info, sizeof(dl_ant_info)); + reset(); } void sched_ue::set_cfg(uint16_t rnti_, sched_interface::ue_cfg_t *cfg_, sched_interface::cell_cfg_t *cell_cfg, @@ -92,17 +101,21 @@ void sched_ue::set_cfg(uint16_t rnti_, sched_interface::ue_cfg_t *cfg_, sched_in void sched_ue::reset() { bzero(&cfg, sizeof(sched_interface::ue_cfg_t)); - sr = false; + sr = false; next_tpc_pusch = 1; next_tpc_pucch = 1; buf_mac = 0; buf_ul = 0; - phy_config_dedicated_enabled = false; - dl_cqi = 1; - ul_cqi = 1; - dl_cqi_tti = 0; - ul_cqi_tti = 0; - cqi_request_tti = 0; + phy_config_dedicated_enabled = false; + dl_cqi = 1; + ul_cqi = 1; + dl_cqi_tti = 0; + ul_cqi_tti = 0; + dl_ri = 0; + dl_ri_tti = 0; + dl_pmi = 0; + dl_pmi_tti = 0; + cqi_request_tti = 0; for (int i=0;ice_type()) { @@ -279,6 +279,10 @@ bool ue::process_ce(srslte::sch_subh *subh) { case srslte::sch_subh::TRUNC_BSR: case srslte::sch_subh::SHORT_BSR: idx = subh->get_bsr(buff_size); + if(idx == -1){ + Error("Invalid Index Passed to lc groups\n"); + break; + } for (uint32_t i=0;iul_bsr(rnti, lc_groups[idx][i], buff_size[idx]); @@ -289,7 +293,7 @@ bool ue::process_ce(srslte::sch_subh *subh) { break; case srslte::sch_subh::LONG_BSR: subh->get_bsr(buff_size); - for (int idx=0;idx<4;idx++) { + for (idx=0;idx<4;idx++) { for (uint32_t i=0;iul_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) { int sdu_len = SRSLTE_MIN(total_sdu_len, (uint32_t) sdu_space); 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 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); @@ -364,8 +368,7 @@ uint8_t* ue::generate_pdu(uint32_t tb_idx, sched_interface::dl_sched_pdu_t pdu[s { uint8_t *ret = NULL; pthread_mutex_lock(&mutex); - if (rlc) - { + if (rlc) { mac_msg_dl.init_tx(tx_payload_buffer[tb_idx], grant_size, false); for (uint32_t i=0;i(&args->log.phy_level), "PHY log level") ("log.phy_hex_limit", bpo::value(&args->log.phy_hex_limit), "PHY log hex dump limit") + ("log.phy_lib_level", bpo::value(&args->log.phy_lib_level)->default_value("none"), "PHY lib log level") ("log.mac_level", bpo::value(&args->log.mac_level), "MAC log level") ("log.mac_hex_limit", bpo::value(&args->log.mac_hex_limit), "MAC log hex dump limit") ("log.rlc_level", bpo::value(&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")) { 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")) { args->log.mac_level = args->log.all_level; } @@ -340,14 +344,19 @@ void *input_loop(void *m) char key; while(running) { cin >> key; - if('t' == key) { - do_metrics = !do_metrics; - if(do_metrics) { - cout << "Enter t to stop trace." << endl; - } else { - cout << "Enter t to restart trace." << endl; + if (cin.eof() || cin.bad()) { + cout << "Closing stdin thread." << endl; + break; + } else { + if('t' == key) { + 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; @@ -355,7 +364,8 @@ void *input_loop(void *m) 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; metrics_stdout metrics; enb *enb = enb::get_instance(); diff --git a/srsenb/src/metrics_stdout.cc b/srsenb/src/metrics_stdout.cc index 10ab47f4c..5687f25e1 100644 --- a/srsenb/src/metrics_stdout.cc +++ b/srsenb/src/metrics_stdout.cc @@ -35,6 +35,7 @@ #include #include +#include using namespace std; @@ -46,11 +47,11 @@ char const * const prefixes[2][9] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y", }, }; -metrics_stdout::metrics_stdout() - :started(false) - ,do_print(false) - ,n_reports(10) +metrics_stdout::metrics_stdout() : started(false) ,do_print(false), metrics_report_period(0.0f),n_reports(10) { + enb_ = NULL; + bzero(&metrics_thread, sizeof(metrics_thread)); + bzero(&metrics, sizeof(metrics)); } bool metrics_stdout::init(enb_metrics_interface *u, float report_period_secs) @@ -101,6 +102,8 @@ void metrics_stdout::metrics_thread_run() void metrics_stdout::print_metrics() { + std::ios::fmtflags f(cout.flags()); // For avoiding Coverity defect: Not restoring ostream format + if(!do_print) return; @@ -157,7 +160,8 @@ void metrics_stdout::print_metrics() if(metrics.rf.rf_error) { printf("RF status: O=%d, U=%d, L=%d\n", metrics.rf.rf_o, metrics.rf.rf_u, metrics.rf.rf_l); } - + + cout.flags(f); // For avoiding Coverity defect: Not restoring ostream format } void metrics_stdout::print_disconnect() diff --git a/srsenb/src/phy/phch_worker.cc b/srsenb/src/phy/phch_worker.cc index cffc02d22..8013a7d5c 100644 --- a/srsenb/src/phy/phch_worker.cc +++ b/srsenb/src/phy/phch_worker.cc @@ -73,6 +73,11 @@ namespace srsenb { phch_worker::phch_worker() { phy = NULL; + + bzero(&enb_dl, sizeof(enb_dl)); + bzero(&enb_ul, sizeof(enb_ul)); + bzero(&tx_time, sizeof(tx_time)); + reset(); } @@ -551,7 +556,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_dmrs = phy_grant.ncs_dmrs; - char cqi_str[64]; + char cqi_str[SRSLTE_CQI_STR_MAX_CHAR]; if (cqi_enabled) { if (ue_db[rnti].cqi_en) { wideband_cqi_value = cqi_value.wideband.wideband_cqi; @@ -578,7 +583,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); } } - 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); } diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index f171dee85..d47998fa9 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -48,8 +48,11 @@ namespace srsenb { phy::phy() : workers_pool(MAX_WORKERS), workers(MAX_WORKERS), - workers_common(txrx::MUTEX_X_WORKER*MAX_WORKERS) + workers_common(txrx::MUTEX_X_WORKER*MAX_WORKERS), + nof_workers(0) { + radio_handler = NULL; + bzero(&prach_cfg, sizeof(prach_cfg)); } void phy::parse_config(phy_cfg_t* cfg) diff --git a/srsenb/src/phy/txrx.cc b/srsenb/src/phy/txrx.cc index a247f3d63..7e97bd1af 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -42,13 +42,13 @@ using namespace std; namespace srsenb { -txrx::txrx() -{ +txrx::txrx() : tx_mutex_cnt(0), nof_tx_mutex(0), tti(0) { running = false; radio_h = NULL; log_h = NULL; workers_pool = NULL; - worker_com = NULL; + worker_com = NULL; + prach = NULL; } bool txrx::init(srslte::radio* radio_h_, srslte::thread_pool* workers_pool_, phch_common* worker_com_, prach_worker *prach_, srslte::log* log_h_, uint32_t prio_) diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 5d64cb4e5..53b7cffdb 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -125,7 +125,7 @@ void gtpu::stop() // gtpu_interface_pdcp 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; header.flags = 0x30; header.message_type = 0xFF; @@ -234,7 +234,7 @@ void gtpu::run_thread() 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); do { diff --git a/srsenb/src/upper/rlc.cc b/srsenb/src/upper/rlc.cc index fff674112..0b7babbac 100644 --- a/srsenb/src/upper/rlc.cc +++ b/srsenb/src/upper/rlc.cc @@ -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 uint32_t tx_queue = users[rnti].rlc->get_total_buffer_state(lcid); 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); + log_h->info("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue); } else { pool->deallocate(sdu); } diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index 69a03500e..f1ae51016 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -553,61 +553,67 @@ void rrc::read_pdu_pcch(uint8_t *payload, uint32_t buffer_size) void rrc::parse_ul_ccch(uint16_t rnti, byte_buffer_t *pdu) { uint16_t old_rnti = 0; - - LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; - bzero(&ul_ccch_msg, sizeof(LIBLTE_RRC_UL_CCCH_MSG_STRUCT)); - - srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes*8); - bit_buf.N_bits = pdu->N_bytes*8; - liblte_rrc_unpack_ul_ccch_msg((LIBLTE_BIT_MSG_STRUCT*)&bit_buf, &ul_ccch_msg); - rrc_log->info_hex(pdu->msg, pdu->N_bytes, - "SRB0 - Rx: %s", - liblte_rrc_ul_ccch_msg_type_text[ul_ccch_msg.msg_type]); + if (pdu) { + LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; + bzero(&ul_ccch_msg, sizeof(LIBLTE_RRC_UL_CCCH_MSG_STRUCT)); - switch(ul_ccch_msg.msg_type) { - case LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ: - if (users.count(rnti)) { - users[rnti].handle_rrc_con_req(&ul_ccch_msg.msg.rrc_con_req); - } else { - rrc_log->error("Received ConnectionSetup for rnti=0x%x without context\n", rnti); - } - break; - case LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REEST_REQ: - rrc_log->debug("rnti=0x%x, phyid=0x%x, smac=0x%x, cause=%s\n", - ul_ccch_msg.msg.rrc_con_reest_req.ue_id.c_rnti, ul_ccch_msg.msg.rrc_con_reest_req.ue_id.phys_cell_id, - ul_ccch_msg.msg.rrc_con_reest_req.ue_id.short_mac_i, liblte_rrc_con_reest_req_cause_text[ul_ccch_msg.msg.rrc_con_reest_req.cause] - ); - if (users[rnti].is_idle()) { - old_rnti = ul_ccch_msg.msg.rrc_con_reest_req.ue_id.c_rnti; - if (users.count(old_rnti)) { - rrc_log->error("Not supported: ConnectionReestablishment. Sending Connection Reject\n", old_rnti); - users[rnti].send_connection_reest_rej(); - rem_user_thread(old_rnti); + srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); + bit_buf.N_bits = pdu->N_bytes * 8; + liblte_rrc_unpack_ul_ccch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &ul_ccch_msg); + + rrc_log->info_hex(pdu->msg, pdu->N_bytes, + "SRB0 - Rx: %s", + liblte_rrc_ul_ccch_msg_type_text[ul_ccch_msg.msg_type]); + + switch (ul_ccch_msg.msg_type) { + case LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ: + if (users.count(rnti)) { + users[rnti].handle_rrc_con_req(&ul_ccch_msg.msg.rrc_con_req); } else { - rrc_log->error("Received ConnectionReestablishment for rnti=0x%x without context\n", old_rnti); - users[rnti].send_connection_reest_rej(); + rrc_log->error("Received ConnectionSetup for rnti=0x%x without context\n", rnti); } - // remove temporal rnti - rem_user_thread(rnti); - } else { - rrc_log->error("Received ReestablishmentRequest from an rnti=0x%x not in IDLE\n", rnti); - } - break; - default: - rrc_log->error("UL CCCH message not recognised\n"); - break; + break; + case LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REEST_REQ: + rrc_log->debug("rnti=0x%x, phyid=0x%x, smac=0x%x, cause=%s\n", + ul_ccch_msg.msg.rrc_con_reest_req.ue_id.c_rnti, + ul_ccch_msg.msg.rrc_con_reest_req.ue_id.phys_cell_id, + ul_ccch_msg.msg.rrc_con_reest_req.ue_id.short_mac_i, + liblte_rrc_con_reest_req_cause_text[ul_ccch_msg.msg.rrc_con_reest_req.cause] + ); + if (users[rnti].is_idle()) { + old_rnti = ul_ccch_msg.msg.rrc_con_reest_req.ue_id.c_rnti; + if (users.count(old_rnti)) { + rrc_log->error("Not supported: ConnectionReestablishment. Sending Connection Reject\n", old_rnti); + users[rnti].send_connection_reest_rej(); + rem_user_thread(old_rnti); + } else { + rrc_log->error("Received ConnectionReestablishment for rnti=0x%x without context\n", old_rnti); + users[rnti].send_connection_reest_rej(); + } + // remove temporal rnti + rem_user_thread(rnti); + } else { + rrc_log->error("Received ReestablishmentRequest from an rnti=0x%x not in IDLE\n", rnti); + } + break; + default: + rrc_log->error("UL CCCH message not recognised\n"); + break; + } + + pool->deallocate(pdu); } - - pool->deallocate(pdu); } void rrc::parse_ul_dcch(uint16_t rnti, uint32_t lcid, byte_buffer_t *pdu) { - if (users.count(rnti)) { - users[rnti].parse_ul_dcch(lcid, pdu); - } else { - rrc_log->error("Processing %s: Unkown rnti=0x%x\n", rb_id_text[lcid], rnti); + if (pdu) { + if (users.count(rnti)) { + users[rnti].parse_ul_dcch(lcid, pdu); + } else { + rrc_log->error("Processing %s: Unkown rnti=0x%x\n", rb_id_text[lcid], rnti); + } } } @@ -1757,7 +1763,7 @@ int rrc::ue::cqi_allocate(uint32_t period, uint32_t *pmi_idx, uint32_t *n_pucch) *pmi_idx = 318 + parent->cfg.cqi_cfg.sf_mapping[j_min]; } else if (period == 64) { *pmi_idx = 350 + parent->cfg.cqi_cfg.sf_mapping[j_min]; - } else if (period == 64) { + } else if (period == 128) { *pmi_idx = 414 + parent->cfg.cqi_cfg.sf_mapping[j_min]; } } diff --git a/srsenb/test/upper/ip_test.cc b/srsenb/test/upper/ip_test.cc index 2b789cf27..820974b4d 100644 --- a/srsenb/test/upper/ip_test.cc +++ b/srsenb/test/upper/ip_test.cc @@ -590,15 +590,15 @@ int main(int argc, char *argv[]) /******************* This is copied from srsue gw **********************/ int setup_if_addr(char *ip_addr) { - char *dev = (char*) "tun_srsenb"; + int sock; // Construct the TUN device int tun_fd = open("/dev/net/tun", O_RDWR); if(0 > tun_fd) { perror("open"); - return(-1); + return SRSLTE_ERROR; } struct ifreq ifr; @@ -609,21 +609,21 @@ int setup_if_addr(char *ip_addr) if(0 > ioctl(tun_fd, TUNSETIFF, &ifr)) { perror("ioctl1"); - return -1; + goto clean_exit; } // Bring up the interface - int sock = socket(AF_INET, SOCK_DGRAM, 0); + sock = socket(AF_INET, SOCK_DGRAM, 0); if(0 > ioctl(sock, SIOCGIFFLAGS, &ifr)) { perror("socket"); - return -1; + goto clean_exit; } ifr.ifr_flags |= IFF_UP | IFF_RUNNING; if(0 > ioctl(sock, SIOCSIFFLAGS, &ifr)) { perror("ioctl2"); - return -1; + goto clean_exit; } // Setup the IP address @@ -633,15 +633,21 @@ int setup_if_addr(char *ip_addr) if(0 > ioctl(sock, SIOCSIFADDR, &ifr)) { perror("ioctl"); - return -1; + goto clean_exit; } ifr.ifr_netmask.sa_family = AF_INET; ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr("255.255.255.0"); if(0 > ioctl(sock, SIOCSIFNETMASK, &ifr)) { perror("ioctl"); - return -1; + goto clean_exit; } + shutdown(sock, SHUT_RDWR); return(tun_fd); + +clean_exit: + shutdown(sock, SHUT_RDWR); + close(tun_fd); + return SRSLTE_ERROR; } diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 4074aeb9a..25863b7eb 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -46,6 +46,8 @@ namespace srsepc{ typedef struct{ std::string auth_algo; std::string db_file; + uint16_t mcc; + uint16_t mnc; }hss_args_t; typedef struct{ @@ -98,7 +100,9 @@ private: /*Logs*/ srslte::log_filter *m_hss_log; - + + uint16_t mcc; + uint16_t mnc; }; } // namespace srsepc diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 36b47d0e3..2dd6fc58d 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -92,7 +92,10 @@ hss::init(hss_args_t *hss_args, srslte::log_filter *hss_log) return -1; } - m_hss_log->info("HSS Initialized. DB file %s, authentication algorithm %s\n", hss_args->db_file.c_str(),hss_args->auth_algo.c_str()); + mcc = hss_args->mcc; + mnc = hss_args->mnc; + + m_hss_log->info("HSS Initialized. DB file %s, authentication algorithm %s, MCC: %d, MNC: %d\n", hss_args->db_file.c_str(),hss_args->auth_algo.c_str(), mcc, mnc); m_hss_log->console("HSS Initialized\n"); return 0; } @@ -205,8 +208,6 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn uint8_t ak[6]; uint8_t mac[8]; - uint16_t mcc=61441; //001 - uint16_t mnc=65281; //01 if(!get_k_amf_op(imsi,k,amf,op)) { @@ -214,7 +215,7 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn } gen_rand(rand); get_sqn(sqn); - + security_milenage_f2345( k, op, rand, @@ -223,6 +224,14 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn ik, ak); + m_hss_log->debug_hex(k, 16, "User Key : "); + m_hss_log->debug_hex(op, 16, "User OP : "); + m_hss_log->debug_hex(rand, 16, "User Rand : "); + m_hss_log->debug_hex(xres, 8, "User XRES: "); + m_hss_log->debug_hex(ck, 16, "User CK: "); + m_hss_log->debug_hex(ik, 16, "User IK: "); + m_hss_log->debug_hex(ak, 6, "User AK: "); + security_milenage_f1( k, op, rand, @@ -230,6 +239,9 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn amf, mac); + m_hss_log->debug_hex(sqn, 6, "User SQN : "); + m_hss_log->debug_hex(mac, 8, "User MAC : "); + // Generate K_asme security_generate_k_asme( ck, ik, @@ -239,6 +251,9 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn mnc, k_asme); + m_hss_log->debug("User MCC : %x MNC : %x \n", mcc, mnc); + m_hss_log->debug_hex(k_asme, 32, "User k_asme : "); + //Generate AUTN (autn = sqn ^ ak |+| amf |+| mac) for(int i=0;i<6;i++ ) { @@ -252,10 +267,8 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn { autn[8+i]=mac[i]; } - - m_hss_log->debug_hex(sqn, 6, "User SQN : "); - m_hss_log->debug_hex(autn, 8, "User AUTN: "); - m_hss_log->debug_hex(xres, 8, "User XRES: "); + + m_hss_log->debug_hex(autn, 16, "User AUTN: "); return true; } @@ -276,9 +289,6 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin uint8_t ak[6]; uint8_t mac[8]; - uint16_t mcc=61441; //001 - uint16_t mnc=65281; //01 - int i = 0; if(!get_k_amf_op(imsi,k,amf,op)) @@ -302,6 +312,14 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin ak[i] = xdout[i+3]; } + m_hss_log->debug_hex(k, 16, "User Key : "); + m_hss_log->debug_hex(op, 16, "User OP : "); + m_hss_log->debug_hex(rand, 16, "User Rand : "); + m_hss_log->debug_hex(xres, 8, "User XRES: "); + m_hss_log->debug_hex(ck, 16, "User CK: "); + m_hss_log->debug_hex(ik, 16, "User IK: "); + m_hss_log->debug_hex(ak, 6, "User AK: "); + // Generate cdout for(i=0; i<6; i++) { cdout[i] = sqn[i]; @@ -315,6 +333,9 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin mac[i] = xdout[i] ^ cdout[i]; } + m_hss_log->debug_hex(sqn, 6, "User SQN : "); + m_hss_log->debug_hex(mac, 8, "User MAC : "); + //Generate AUTN (autn = sqn ^ ak |+| amf |+| mac) for(int i=0;i<6;i++ ) { @@ -337,6 +358,9 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin mcc, mnc, k_asme); + + m_hss_log->debug("User MCC : %x MNC : %x \n", mcc, mnc); + m_hss_log->debug_hex(k_asme, 32, "User k_asme : "); //Generate AUTN (autn = sqn ^ ak |+| amf |+| mac) for(int i=0;i<6;i++ ) @@ -352,9 +376,7 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin autn[8+i]=mac[i]; } - m_hss_log->debug_hex(sqn, 6, "User SQN : "); m_hss_log->debug_hex(autn, 8, "User AUTN: "); - m_hss_log->debug_hex(xres, 8, "User XRES: "); return true; } diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index f70473505..40f19b486 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -189,12 +189,20 @@ parse_args(all_args_t *args, int argc, char* argv[]) { } // Convert MCC/MNC strings if(!srslte::string_to_mcc(mcc, &args->mme_args.s1ap_args.mcc)) { - cout << "Error parsing enb.mcc:" << mcc << " - must be a 3-digit string." << endl; + cout << "Error parsing mme.mcc:" << mcc << " - must be a 3-digit string." << endl; } if(!srslte::string_to_mnc(mnc, &args->mme_args.s1ap_args.mnc)) { - cout << "Error parsing enb.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; + cout << "Error parsing mme.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; } + // Convert MCC/MNC strings + if(!srslte::string_to_mcc(mcc, &args->hss_args.mcc)) { + cout << "Error parsing mme.mcc:" << mcc << " - must be a 3-digit string." << endl; + } + if(!srslte::string_to_mnc(mnc, &args->hss_args.mnc)) { + cout << "Error parsing mme.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; + } + args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr; args->spgw_args.gtpu_bind_addr = spgw_bind_addr; args->spgw_args.sgi_if_addr = sgi_if_addr; @@ -259,6 +267,8 @@ main (int argc,char * argv[] ) { cout << endl <<"--- Software Radio Systems EPC ---" << endl << endl; signal(SIGINT, sig_int_handler); + signal(SIGTERM, sig_int_handler); + signal(SIGKILL, sig_int_handler); all_args_t args; parse_args(&args, argc, argv); @@ -302,7 +312,7 @@ main (int argc,char * argv[] ) cout << "Error initializing MME" << endl; exit(1); } - + hss *hss = hss::get_instance(); if (hss->init(&args.hss_args,&hss_log)) { cout << "Error initializing HSS" << endl; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index ef6a116f4..85a07596c 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -196,6 +196,7 @@ s1ap::enb_listen() evnts.sctp_data_io_event = 1; evnts.sctp_shutdown_event=1; if(setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof (evnts))){ + close(sock_fd); m_s1ap_log->console("Subscribing to sctp_data_io_events failed\n"); return -1; } @@ -207,6 +208,7 @@ s1ap::enb_listen() s1mme_addr.sin_port = htons(S1MME_PORT); err = bind(sock_fd, (struct sockaddr*) &s1mme_addr, sizeof (s1mme_addr)); if (err != 0){ + close(sock_fd); m_s1ap_log->error("Error binding SCTP socket\n"); m_s1ap_log->console("Error binding SCTP socket\n"); return -1; @@ -215,6 +217,7 @@ s1ap::enb_listen() //Listen for connections err = listen(sock_fd,SOMAXCONN); if (err != 0){ + close(sock_fd); m_s1ap_log->error("Error in SCTP socket listen\n"); m_s1ap_log->console("Error in SCTP socket listen\n"); return -1; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 52e8e6775..c6f86db56 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -245,7 +245,7 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, { uint8_t k_asme[32]; uint8_t autn[16]; - uint8_t rand[6]; + uint8_t rand[16]; uint8_t xres[8]; ue_ctx_t ue_ctx; @@ -321,7 +321,7 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, m_s1ap->add_new_ue_ctx(ue_ctx); //Pack NAS Authentication Request in Downlink NAS Transport msg pack_authentication_request(reply_buffer, ue_ctx.enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id, autn, rand); - + //Send reply to eNB *reply_flag = true; m_s1ap_log->info("Downlink NAS: Sending Athentication Request\n"); @@ -444,22 +444,19 @@ s1ap_nas_transport::handle_nas_authentication_response(srslte::byte_buffer_t *na bool ue_valid=true; m_s1ap_log->console("Authentication Response -- IMSI %015lu\n", ue_ctx->imsi); - m_s1ap_log->console("Authentication Response -- RES 0x%x%x%x%x%x%x%x%x\n", - auth_resp.res[0], - auth_resp.res[1], - auth_resp.res[2], - auth_resp.res[3], - auth_resp.res[4], - auth_resp.res[5], - auth_resp.res[6], - auth_resp.res[7] - ); + //Get NAS authentication response LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &auth_resp); if(err != LIBLTE_SUCCESS){ m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]); return false; } + m_s1ap_log->console("Authentication Response -- RES 0x%x%x%x%x%x%x%x%x\n", + auth_resp.res[0], auth_resp.res[1], auth_resp.res[2], auth_resp.res[3], + auth_resp.res[4], auth_resp.res[5], auth_resp.res[6], auth_resp.res[7]); + m_s1ap_log->info("Authentication Response -- RES 0x%x%x%x%x%x%x%x%x\n", + auth_resp.res[0], auth_resp.res[1], auth_resp.res[2], auth_resp.res[3], + auth_resp.res[4], auth_resp.res[5], auth_resp.res[6], auth_resp.res[7]); for(int i=0; i<8;i++) { @@ -563,7 +560,7 @@ s1ap_nas_transport::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, u m_s1ap_log->console("Unpacked Attached Complete Message\n"); m_s1ap_log->console("Unpacked Activavate Default EPS Bearer message. EPS Bearer id %d\n",act_bearer.eps_bearer_id); //ue_ctx->erabs_ctx[act_bearer->eps_bearer_id].enb_fteid; - if(act_bearer.eps_bearer_id < 5 || act_bearer.eps_bearer_id > 16) + if(act_bearer.eps_bearer_id < 5 || act_bearer.eps_bearer_id > 15) { m_s1ap_log->error("EPS Bearer ID out of range\n"); return false; @@ -600,7 +597,7 @@ bool s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag) { uint8_t autn[16]; - uint8_t rand[6]; + uint8_t rand[16]; uint8_t xres[8]; LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp; @@ -625,7 +622,7 @@ s1ap_nas_transport::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ m_s1ap_log->info("User not found. IMSI %015lu\n",imsi); return false; } - + //Pack NAS Authentication Request in Downlink NAS Transport msg pack_authentication_request(reply_msg, ue_ctx->enb_ue_s1ap_id, ue_ctx->mme_ue_s1ap_id, autn, rand); diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 2f0e0e468..ad08555bb 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -177,7 +177,9 @@ spgw::init_sgi_if(spgw_args_t *args) memset(&ifr, 0, sizeof(ifr)); 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(ioctl(m_sgi_if, TUNSETIFF, &ifr) < 0) { m_spgw_log->error("Failed to set TUN device name: %s\n", strerror(errno)); diff --git a/srsue/hdr/mac/mac.h b/srsue/hdr/mac/mac.h index b1b649de7..ee79456fc 100644 --- a/srsue/hdr/mac/mac.h +++ b/srsue/hdr/mac/mac.h @@ -112,8 +112,8 @@ public: private: void run_thread(); - static const int MAC_MAIN_THREAD_PRIO = 5; - static const int MAC_PDU_THREAD_PRIO = 6; + static const int MAC_MAIN_THREAD_PRIO = -1; // Use default high-priority below UHD + static const int MAC_PDU_THREAD_PRIO = -1; static const int MAC_NOF_HARQ_PROC = 2*HARQ_DELAY_MS; // Interaction with PHY diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 5b33be1ec..52307e162 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -219,7 +219,13 @@ private: // Receive and route HARQ feedbacks 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->is_from_rar) { diff --git a/srsue/hdr/metrics_csv.h b/srsue/hdr/metrics_csv.h index f0b3e48c4..72a9dc050 100644 --- a/srsue/hdr/metrics_csv.h +++ b/srsue/hdr/metrics_csv.h @@ -47,10 +47,11 @@ class metrics_csv : public srslte::metrics_listener { public: metrics_csv(std::string filename); + ~metrics_csv(); - void set_periodicity(float metrics_report_period_sec); - 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 stop(); private: std::string float_to_string(float f, int digits, bool add_semicolon = true); diff --git a/srsue/hdr/metrics_stdout.h b/srsue/hdr/metrics_stdout.h index 87a67cb2e..01f28f35e 100644 --- a/srsue/hdr/metrics_stdout.h +++ b/srsue/hdr/metrics_stdout.h @@ -48,15 +48,15 @@ public: void set_periodicity(float metrics_report_period_sec); 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 stop() {}; private: std::string float_to_string(float f, int digits); std::string float_to_eng_string(float f, int digits); std::string int_to_eng_string(int f, int digits); - float metrics_report_period; bool do_print; uint8_t n_reports; ue_metrics_interface* ue; diff --git a/srsue/hdr/phy/phch_common.h b/srsue/hdr/phy/phch_common.h index fd73d9421..31bf06122 100644 --- a/srsue/hdr/phy/phch_common.h +++ b/srsue/hdr/phy/phch_common.h @@ -46,6 +46,7 @@ namespace srsue { class chest_feedback_itf { public: + virtual void in_sync() = 0; virtual void out_of_sync() = 0; virtual void set_cfo(float cfo) = 0; }; @@ -69,6 +70,8 @@ public: float avg_rsrp; float avg_rsrp_dbm; float avg_rsrq_db; + float avg_rssi_dbm; + float last_radio_rssi; float rx_gain_offset; float avg_snr_db; float avg_noise; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index ed4bd706a..50ea28f96 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -75,6 +75,7 @@ public: bool status_is_sync(); // from chest_feedback_itf + void in_sync(); void out_of_sync(); void set_cfo(float cfo); @@ -153,7 +154,7 @@ private: srslte_ue_mib_t ue_mib; uint32_t cnt; uint32_t timeout; - const static uint32_t SYNC_SFN_TIMEOUT = 200; + const static uint32_t SYNC_SFN_TIMEOUT = 500; }; // Class to perform cell measurements @@ -290,6 +291,13 @@ private: // Sync metrics sync_metrics_t metrics; + // in-sync / out-of-sync counters + uint32_t out_of_sync_cnt; + uint32_t in_sync_cnt; + + const static uint32_t NOF_OUT_OF_SYNC_SF = 200; + const static uint32_t NOF_IN_SYNC_SF = 100; + // State for primary cell enum { IDLE = 0, @@ -324,9 +332,6 @@ private: int cur_earfcn_index; bool cell_search_in_progress; - uint32_t out_of_sync_cnt; - uint32_t out_of_sync2_cnt; - float dl_freq; float ul_freq; diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 5430a2d18..d73214514 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -158,6 +158,8 @@ private: float cfo; bool rar_cqi_request; + uint32_t rssi_read_cnt; + // Metrics dl_metrics_t dl_metrics; ul_metrics_t ul_metrics; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 5a1ac14a7..53d4f6e13 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -78,6 +78,7 @@ public: void set_earfcn(std::vector earfcns); void force_freq(float dl_freq, float ul_freq); + void radio_overflow(); /********** RRC INTERFACE ********************/ void reset(); diff --git a/srsue/hdr/phy/prach.h b/srsue/hdr/phy/prach.h index 8218ca644..09be0c9b2 100644 --- a/srsue/hdr/phy/prach.h +++ b/srsue/hdr/phy/prach.h @@ -56,6 +56,7 @@ namespace srsue { 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 is_ready_to_send(uint32_t current_tti); + bool is_pending(); int tx_tti(); void send(srslte::radio* radio_handler, float cfo, float pathloss, srslte_timestamp_t rx_time); diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index b008b2fd5..763531261 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -73,13 +73,14 @@ public: void start_plot(); static void rf_msg(srslte_rf_error_t error); - void handle_rf_msg(srslte_rf_error_t error); // UE metrics interface bool get_metrics(ue_metrics_t &m); void pregenerate_signals(bool enable); + void radio_overflow(); + private: virtual ~ue(); diff --git a/srsue/hdr/ue_base.h b/srsue/hdr/ue_base.h index 9674a1486..256813d5f 100644 --- a/srsue/hdr/ue_base.h +++ b/srsue/hdr/ue_base.h @@ -156,6 +156,8 @@ public: virtual void stop() = 0; virtual bool is_attached() = 0; virtual void start_plot() = 0; + + virtual void radio_overflow() = 0; void handle_rf_msg(srslte_rf_error_t error); diff --git a/srsue/hdr/upper/usim.h b/srsue/hdr/upper/usim.h index cf5a4c820..e37f58218 100644 --- a/srsue/hdr/upper/usim.h +++ b/srsue/hdr/upper/usim.h @@ -43,7 +43,6 @@ typedef enum{ typedef struct{ std::string algo; std::string op; - std::string amf; std::string imsi; std::string imei; std::string k; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 0f668b927..498aacd54 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -124,7 +124,6 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { ("usim.algo", bpo::value(&args->usim.algo), "USIM authentication algorithm") ("usim.op", bpo::value(&args->usim.op), "USIM operator variant") - ("usim.amf", bpo::value(&args->usim.amf), "USIM authentication management field") ("usim.imsi", bpo::value(&args->usim.imsi), "USIM IMSI") ("usim.imei", bpo::value(&args->usim.imei), "USIM IMEI") ("usim.k", bpo::value(&args->usim.k), "USIM K") @@ -403,14 +402,19 @@ void *input_loop(void *m) { char key; while (running) { cin >> key; - if ('t' == key) { - do_metrics = !do_metrics; - if (do_metrics) { - cout << "Enter t to stop trace." << endl; - } else { - cout << "Enter t to restart trace." << endl; + if (cin.eof() || cin.bad()) { + cout << "Closing stdin thread." << endl; + break; + } else { + if ('t' == key) { + 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; @@ -420,6 +424,7 @@ int main(int argc, char *argv[]) { srslte::metrics_hub metricshub; signal(SIGINT, sig_int_handler); + signal(SIGTERM, sig_int_handler); all_args_t args; srslte_debug_handle_crash(argc, argv); @@ -441,13 +446,11 @@ int main(int argc, char *argv[]) metricshub.init(ue, args.expert.metrics_period_secs); metricshub.add_listener(&metrics_screen); metrics_screen.set_ue_handle(ue); - metrics_screen.set_periodicity(args.expert.metrics_period_secs); metrics_csv metrics_file(args.expert.metrics_csv_filename); if (args.expert.metrics_csv_enable) { metricshub.add_listener(&metrics_file); metrics_file.set_ue_handle(ue); - metrics_file.set_periodicity(args.expert.metrics_period_secs); } pthread_t input; diff --git a/srsue/src/metrics_csv.cc b/srsue/src/metrics_csv.cc index 7c84659b5..54702dc26 100644 --- a/srsue/src/metrics_csv.cc +++ b/srsue/src/metrics_csv.cc @@ -46,7 +46,12 @@ metrics_csv::metrics_csv(std::string filename) ,metrics_report_period(1.0) ,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_) @@ -54,15 +59,20 @@ void metrics_csv::set_ue_handle(ue_metrics_interface *ue_) ue = ue_; } -void metrics_csv::set_periodicity(float metrics_report_period_sec) { - this->metrics_report_period = metrics_report_period_sec; +void metrics_csv::stop() +{ + 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(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 << 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.sinr, 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) { file << float_to_string((float) 100*metrics.mac.rx_errors/metrics.mac.rx_pkts, 1); } 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((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) { file << float_to_string((float) 100*metrics.mac.tx_errors/metrics.mac.tx_pkts, 1); } 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_l, 2); file << (ue->is_attached() ? "1.0" : "0.0"); - file << endl; + file << "\n"; n_reports++; } else { diff --git a/srsue/src/metrics_stdout.cc b/srsue/src/metrics_stdout.cc index 9f413b65f..c8f373284 100644 --- a/srsue/src/metrics_stdout.cc +++ b/srsue/src/metrics_stdout.cc @@ -50,7 +50,6 @@ char const * const prefixes[2][9] = metrics_stdout::metrics_stdout() :do_print(false) ,n_reports(10) - ,metrics_report_period(1.0) ,ue(NULL) { } @@ -65,11 +64,7 @@ void metrics_stdout::toggle_print(bool b) do_print = b; } -void metrics_stdout::set_periodicity(float metrics_report_period_sec) { - this->metrics_report_period = metrics_report_period_sec; -} - -void metrics_stdout::set_metrics(ue_metrics_t &metrics) +void metrics_stdout::set_metrics(ue_metrics_t &metrics, const uint32_t period_usec) { if(!do_print || ue == NULL) 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.sinr, 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) { cout << float_to_string((float) 100*metrics.mac.rx_errors/metrics.mac.rx_pkts, 1) << "%"; } 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_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) { cout << float_to_string((float) 100*metrics.mac.tx_errors/metrics.mac.tx_pkts, 1) << "%"; } else { diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index bbefd7f3d..944a6e955 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -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); reset(); - + running = true; // Start main thread if (sync_cpu_affinity < 0) { start(prio); @@ -124,8 +124,9 @@ void phch_recv::stop() void phch_recv::reset() { + in_sync_cnt = 0; + out_of_sync_cnt = 0; tx_mutex_cnt = 0; - running = true; phy_state = IDLE; time_adv_sec = 0; next_offset = 0; @@ -295,15 +296,17 @@ bool phch_recv::stop_sync() { usleep(10000); cnt++; } + if (!is_in_idle) { + Warning("SYNC: Could not go to IDLE\n"); + } return is_in_idle; } } void phch_recv::reset_sync() { - wait_radio_reset(); - Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); + search_p.reset(); srslte_ue_sync_reset(&ue_sync); resync_sfn(true, true); @@ -690,6 +693,12 @@ void phch_recv::run_thread() worker->set_tti(tti, tx_mutex_cnt); 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 if (prach_buffer->is_ready_to_send(tti)) { srslte_timestamp_copy(&tx_time_prach, &rx_time); @@ -706,21 +715,12 @@ 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]); } intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb)); - out_of_sync_cnt = 0; break; case 0: - // Signal every 5 errors only (PSS is every 5) - 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(); - } + Warning("SYNC: Out-of-sync detected in PSS/SSS\n"); + out_of_sync(); worker->release(); worker_com->reset_ul(); - out_of_sync_cnt++; - if (out_of_sync_cnt >= 5) { - out_of_sync_cnt = 0; - } break; default: radio_error(); @@ -746,13 +746,24 @@ void phch_recv::run_thread() } } +void phch_recv::in_sync() { + out_of_sync_cnt = 0; + in_sync_cnt++; + // Send RRC in-sync signal after 100 ms consecutive subframes + if (in_sync_cnt == NOF_IN_SYNC_SF) { + rrc->in_sync(); + in_sync_cnt = 0; + } +} + +// Out of sync called by worker or phch_recv every 1 or 5 ms void phch_recv::out_of_sync() { - out_of_sync2_cnt++; - 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); + in_sync_cnt = 0; + // Send RRC out-of-sync signal after 200 ms consecutive subframes + out_of_sync_cnt++; + if (out_of_sync_cnt >= NOF_OUT_OF_SYNC_SF) { + rrc->out_of_sync(); + out_of_sync_cnt = 0; } } @@ -1085,7 +1096,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); 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); } else { log_h->error("SYNC: Measuring RSRP: Sync error\n"); @@ -1284,10 +1295,11 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, srslte_sync_reset(&sync_find); srslte_sync_cfo_reset(&sync_find); - uint32_t sf5_cnt=0; + int sf5_cnt=-1; do { + sf5_cnt++; 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) { case SRSLTE_SYNC_ERROR: @@ -1315,20 +1327,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); - 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: cells[nof_cells].pci = found_cell.id; cells[nof_cells].rsrp = measure_p.rsrp(); cells[nof_cells].rsrq = measure_p.rsrq(); 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", - 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)); + 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, sf5_cnt, n_id_2, 15000*srslte_sync_get_cfo(&sync_find)); nof_cells++; 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; @@ -1349,7 +1361,7 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, default: 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; @@ -1477,16 +1489,16 @@ void phch_recv::intra_measure::write(uint32_t tti, cf_t *data, uint32_t nsamples } if (receiving == true) { 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; } else { receive_cnt++; if (receive_cnt == CAPTURE_LEN_SF) { tti_sync.increase(); + receiving = false; } } } - } } diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 2910f07ff..3d051825d 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -100,6 +100,7 @@ void phch_worker::reset() rar_cqi_request = false; I_sr = 0; cfi = 0; + rssi_read_cnt = 0; } 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_; log_h->step(tti); log_phy_lib_h->step(tti); - - } void phch_worker::set_cfo(float cfo_) @@ -224,26 +223,30 @@ void phch_worker::work_imp() bool ul_grant_available = false; bool dl_ack[SRSLTE_MAX_CODEWORDS] = {false}; - mac_interface_phy::mac_grant_t dl_mac_grant; - 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 dl_mac_grant = {}; + mac_interface_phy::tb_action_dl_t dl_action = {}; - mac_interface_phy::mac_grant_t ul_mac_grant; - mac_interface_phy::tb_action_ul_t ul_action; - bzero(&ul_action, sizeof(mac_interface_phy::tb_action_ul_t)); + mac_interface_phy::mac_grant_t ul_mac_grant = {}; + mac_interface_phy::tb_action_ul_t ul_action = {}; + + + /** Calculate RSSI on the input signal before generating the output */ + + // Average RSSI over all symbols (make sure SF length is non-zero) + float rssi_dbm = SRSLTE_SF_LEN_PRB(cell.nof_prb) > 0 ? (10*log10(srslte_vec_avg_power_cf(signal_buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb))) + 30) : 0; + 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 */ bool chest_ok = extract_fft_and_pdcch_llr(); - bool snr_th_err = 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))<-20.0; - bool snr_th_ok = 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))>-15.0; - // Call feedback loop for chest if (chest_loop && ((1<<(tti%10)) & phy->args->cfo_ref_mask)) { chest_loop->set_cfo(srslte_chest_dl_get_cfo(&ue_dl.chest)); } - if (chest_ok && !snr_th_err) { + if (chest_ok) { /***** Downlink Processing *******/ @@ -289,7 +292,8 @@ void phch_worker::work_imp() // Decode PHICH bool ul_ack = false; - bool ul_ack_available = decode_phich(&ul_ack); + bool ul_ack_available = decode_phich(&ul_ack); + /***** Uplink Processing + Transmission *******/ @@ -363,14 +367,14 @@ void phch_worker::work_imp() update_measurements(); if (chest_ok) { - if (snr_th_ok) { - phy->rrc->in_sync(); - log_h->debug("SYNC: Sending in-sync to RRC\n"); - } else if (snr_th_err) { + if (phy->avg_rsrp_dbm > -124.0 && 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)) > -30.0) { + log_h->debug("SNR=%.1f dB, RSRP=%.1f dBm sync=in-sync from channel estimator\n", + 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), phy->avg_rsrp_dbm); + chest_loop->in_sync(); + } else { + log_h->warning("SNR=%.1f dB RSRP=%.1f dBm, sync=out-of-sync from channel estimator\n", + 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), phy->avg_rsrp_dbm); chest_loop->out_of_sync(); - 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))); } } @@ -391,13 +395,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); } else { /* 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; } 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); 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 +776,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) // Handle Format0 adaptive retx if (ret) { // 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 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))]; @@ -898,11 +903,11 @@ void phch_worker::set_uci_aperiodic_cqi() { uint8_t ri = (uint8_t) ue_dl.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) { /* 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) { case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30: @@ -922,10 +927,24 @@ void phch_worker::set_uci_aperiodic_cqi() // 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.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; - 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); - uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi); + 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); + + /* Set RI = 1 */ + 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; case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM31: @@ -941,11 +960,6 @@ void phch_worker::set_uci_aperiodic_cqi() other transmission modes they are reported conditioned on rank 1. */ 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 */ srslte_cqi_value_t cqi_report = {0}; cqi_report.type = SRSLTE_CQI_TYPE_SUBBAND_HL; @@ -966,16 +980,27 @@ void phch_worker::set_uci_aperiodic_cqi() // 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); + 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) { - 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, sinr_db, sinr_db, pmi, cqi_report.subband_hl.N); } 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, sinr_db, pmi, cqi_report.subband_hl.N); } - uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi); } break; default: @@ -1040,15 +1065,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); #endif - char cqi_str[32] = ""; - srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, 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, SRSLTE_CQI_STR_MAX_CHAR); 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", (tti + HARQ_DELAY_MS) % 10240, grant->n_prb[0], grant->n_prb[0] + grant->L_prb, 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_ri_len > 0 ? (uci_data.uci_ri ? ", ri=1" : ", ri=0") : "", cfo * 15, timestr, @@ -1094,8 +1119,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 gain = set_power(tx_power); - char str_cqi[32] = ""; - srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, 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, 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", (tti + 4) % 10240, @@ -1132,10 +1157,7 @@ void phch_worker::encode_srs() float tx_power = srslte_ue_ul_srs_power(&ue_ul, phy->pathloss); 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); - } void phch_worker::enable_pregen_signals(bool enabled) @@ -1316,42 +1338,50 @@ void phch_worker::update_measurements() { float snr_ema_coeff = phy->args->snr_ema_coeff; if (chest_done) { - /* Compute ADC/RX gain offset every ~10s */ - if (tti== 0 || phy->rx_gain_offset == 0) { - float rx_gain_offset = 0; - if (phy->get_radio()->has_rssi() && phy->args->rssi_sensor_enabled) { - float rssi_all_signal = 30+10*log10(srslte_vec_avg_power_cf(signal_buffer[0],SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb)))); - rx_gain_offset = 30+rssi_all_signal-phy->get_radio()->get_rssi(); - } else { - rx_gain_offset = phy->get_radio()->get_rx_gain(); + + /* Only worker 0 reads the RSSI sensor every ~1-nof_cores s */ + if (get_id() == 0) { + if (rssi_read_cnt) { + if (phy->get_radio()->has_rssi() && phy->args->rssi_sensor_enabled) { + phy->last_radio_rssi = phy->get_radio()->get_rssi(); + phy->rx_gain_offset = phy->avg_rssi_dbm - phy->last_radio_rssi + 30; + } else { + phy->rx_gain_offset = phy->get_radio()->get_rx_gain(); + } } - if (phy->rx_gain_offset) { - phy->rx_gain_offset = SRSLTE_VEC_EMA(rx_gain_offset, phy->rx_gain_offset, 0.5); - } else { - phy->rx_gain_offset = rx_gain_offset; + rssi_read_cnt++; + if (rssi_read_cnt == 1000) { + rssi_read_cnt = 0; } } // Average RSRQ float rsrq_db = 10*log10(srslte_chest_dl_get_rsrq(&ue_dl.chest)); 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 float rsrp_lin = srslte_chest_dl_get_rsrp(&ue_dl.chest); 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 */ 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 if (isnormal(rsrp_dbm)) { if (!phy->avg_rsrp_dbm) { - phy->avg_rsrp_dbm= rsrp_dbm; + phy->avg_rsrp_dbm = rsrp_dbm; } else { phy->avg_rsrp_dbm = SRSLTE_VEC_EMA(rsrp_dbm, phy->avg_rsrp_dbm, snr_ema_coeff); } @@ -1381,7 +1411,7 @@ void phch_worker::update_measurements() dl_metrics.n = phy->avg_noise; dl_metrics.rsrp = phy->avg_rsrp_dbm; 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.sinr = phy->avg_snr_db; dl_metrics.turbo_iters = srslte_pdsch_last_noi(&ue_dl.pdsch); diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 0763b09cb..820cf1351 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -352,6 +352,11 @@ int phy::prach_tx_tti() return prach_buffer.tx_tti(); } +// Handle the case of a radio overflow. Resynchronise inmediatly +void phy::radio_overflow() { + sf_recv.reset_sync(); +} + void phy::reset() { Info("Resetting PHY\n"); diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index 498ea1c6a..fdf925642 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -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_) { - if (cell_initiated && preamble_idx >= 0 && preamble_idx < 64) { + if (is_pending()) { // consider the number of subframes the transmission must be anticipated uint32_t current_tti = (current_tti_ + tx_advance_sf)%10240; if (srslte_prach_tti_opportunity(&prach_obj, current_tti, allowed_subframe)) { diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 78988ef9e..a9277e62c 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -81,6 +81,7 @@ bool ue::init(all_args_t *args_) // Init logs rf_log.set_level(srslte::LOG_LEVEL_INFO); + rf_log.info("Starting UE\n"); for (int i=0;iexpert.phy.nof_phy_threads;i++) { ((srslte::log_filter*) phy_log[i])->set_level(level(args->log.phy_level)); } @@ -296,10 +297,17 @@ bool ue::get_metrics(ue_metrics_t &m) return false; } +void ue::radio_overflow() { + phy.radio_overflow(); +} + void ue::rf_msg(srslte_rf_error_t error) { ue_base *ue = ue_base::get_instance(LTE); ue->handle_rf_msg(error); + if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) { + ue->radio_overflow(); + } } } // namespace srsue diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index d8b4a8fdc..5bc94d3e7 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -202,6 +202,7 @@ srslte::error_t gw::init_if(char *err_str) memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN | IFF_NO_PI; strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ); + ifr.ifr_ifrn.ifrn_name[IFNAMSIZ-1] = 0; if(0 > ioctl(tun_fd, TUNSETIFF, &ifr)) { err_str = strerror(errno); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 9a9015af7..67305aaa3 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -193,9 +193,9 @@ void nas::notify_connection_setup() { } void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { - uint8 pd; - uint8 msg_type; - uint8 sec_hdr_type; + uint8 pd = 0; + uint8 msg_type = 0; + uint8 sec_hdr_type = 0; bool mac_valid = false; 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: break; 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); break; } diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 39846f425..f34c80979 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -722,7 +722,6 @@ float rrc::get_squal(float Qqualmeas) { // Detection of physical layer problems (5.3.11.1) void rrc::out_of_sync() { - // attempt resync current_cell->in_sync = false; if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { n310_cnt++; @@ -730,7 +729,8 @@ void rrc::out_of_sync() { mac_timers->timer_get(t310)->reset(); mac_timers->timer_get(t310)->run(); 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); } } } @@ -837,7 +837,12 @@ void rrc::send_con_request() { ul_ccch_msg.msg.rrc_con_req.ue_id.s_tmsi = s_tmsi; } else { ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_RANDOM_VALUE; - ul_ccch_msg.msg.rrc_con_req.ue_id.random = rand() % 2^40; + // TODO use proper RNG + uint64_t random_id = 0; + for (uint i = 0; i < 5; i++) { // fill random ID bytewise, 40 bits = 5 bytes + random_id |= ( (uint64_t)rand() & 0xFF ) << i*8; + } + ul_ccch_msg.msg.rrc_con_req.ue_id.random = random_id; } ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING; @@ -953,6 +958,8 @@ void rrc::send_con_setup_complete(byte_buffer_t *nas_msg) { memcpy(ul_dcch_msg.msg.rrc_con_setup_complete.dedicated_info_nas.msg, nas_msg->msg, nas_msg->N_bytes); ul_dcch_msg.msg.rrc_con_setup_complete.dedicated_info_nas.N_bytes = nas_msg->N_bytes; + pool->deallocate(nas_msg); + send_ul_dcch_msg(); } diff --git a/srsue/src/upper/usim.cc b/srsue/src/upper/usim.cc index fe70797e3..b9f4fda0e 100644 --- a/srsue/src/upper/usim.cc +++ b/srsue/src/upper/usim.cc @@ -53,13 +53,6 @@ void usim::init(usim_args_t *args, srslte::log *usim_log_) usim_log->console("Invalid length for OP: %d should be %d", args->op.length(), 32); } - if(4 == args->amf.length()) { - str_to_hex(args->amf, amf); - } else { - usim_log->error("Invalid length for AMF: %d should be %d", args->amf.length(), 4); - usim_log->console("Invalid length for AMF: %d should be %d", args->amf.length(), 4); - } - if(15 == args->imsi.length()) { imsi = 0; for(i=0; i<15; i++) @@ -356,6 +349,11 @@ void usim::gen_auth_res_milenage( uint8_t *rand, { sqn[i] = autn_enb[i] ^ ak[i]; } + // Extract AMF from autn + for(int i=0;i<2;i++) + { + amf[i]=autn_enb[6+i]; + } // Generate MAC security_milenage_f1( k, @@ -431,6 +429,10 @@ void usim::gen_auth_res_xor(uint8_t *rand, for(i=0;i<6;i++) { sqn[i] = autn_enb[i] ^ ak[i]; } + // Extract AMF from autn + for(int i=0;i<2;i++){ + amf[i]=autn_enb[6+i]; + } // Generate cdout for(i=0; i<6; i++) { diff --git a/srsue/test/mac/mac_test.cc b/srsue/test/mac/mac_test.cc index 4cb47e9f8..324189427 100644 --- a/srsue/test/mac/mac_test.cc +++ b/srsue/test/mac/mac_test.cc @@ -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.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.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) { memcpy(&common.srs_ul_cnfg, &sib2->rr_config_common_sib.srs_ul_cnfg, sizeof(LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT)); } else { diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index f328d77df..4f4ffb687 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -117,7 +117,6 @@ int security_command_test() usim_args_t args; args.algo = "xor"; - args.amf = "9001"; args.imei = "353490069873319"; args.imsi = "001010123456789"; args.k = "00112233445566778899aabbccddeeff"; @@ -179,7 +178,6 @@ int mme_attach_request_test() srsue::usim usim; usim_args_t args; args.algo = "xor"; - args.amf = "9001"; args.imei = "353490069873319"; args.imsi = "001010123456789"; args.k = "00112233445566778899aabbccddeeff"; diff --git a/srsue/test/upper/usim_test.cc b/srsue/test/upper/usim_test.cc index 4ac468673..bf60e124c 100644 --- a/srsue/test/upper/usim_test.cc +++ b/srsue/test/upper/usim_test.cc @@ -74,7 +74,6 @@ int main(int argc, char **argv) usim_args_t args; args.algo = "milenage"; - args.amf = "8000"; args.imei = "35609204079301"; args.imsi = "208930000000001"; args.k = "8BAF473F2F8FD09487CCCBD7097C6862"; diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 347822072..140662ac0 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -93,7 +93,6 @@ file_max_size = -1 [usim] algo = xor op = 63BFA50EE6523365FF14C1F45F88737D -amf = 9001 k = 00112233445566778899aabbccddeeff imsi = 001010123456789 imei = 353490069873319