Merge branch 'next' into epc

master
Pedro Alvarez 7 years ago
commit 094e4a6f8e

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

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

@ -185,7 +185,8 @@ void parse_args(int argc, char **argv) {
cell.id = atoi(argv[optind]); cell.id = atoi(argv[optind]);
break; break;
case 'x': case 'x':
strncpy(mimo_type_str, argv[optind], 32); strncpy(mimo_type_str, argv[optind], 31);
mimo_type_str[31] = 0;
break; break;
case 'b': case 'b':
multiplex_pmi = (uint32_t) atoi(argv[optind]); 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_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
srslte_ra_dl_grant_t dummy_grant; srslte_ra_dl_grant_t dummy_grant;
srslte_ra_nbits_t dummy_nbits; srslte_ra_nbits_t dummy_nbits[SRSLTE_MAX_CODEWORDS];
srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, UE_CRNTI, &dummy_grant); srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, UE_CRNTI, &dummy_grant);
srslte_ra_dl_grant_to_nbits(&dummy_grant, cfi, cell, 0, &dummy_nbits); srslte_ra_dl_grant_to_nbits(&dummy_grant, cfi, cell, 0, dummy_nbits);
srslte_ra_dl_grant_fprint(stdout, &dummy_grant); srslte_ra_dl_grant_fprint(stdout, &dummy_grant);
dummy_grant.sf_type = SRSLTE_SF_NORM; dummy_grant.sf_type = SRSLTE_SF_NORM;
if (pdsch_cfg.mimo_type != SRSLTE_MIMO_TYPE_SINGLE_ANTENNA) { if (pdsch_cfg.mimo_type != SRSLTE_MIMO_TYPE_SINGLE_ANTENNA) {
@ -858,7 +859,7 @@ int main(int argc, char **argv) {
if (net_port > 0) { if (net_port > 0) {
send_data = net_packet_ready; send_data = net_packet_ready;
if (net_packet_ready) { if (net_packet_ready) {
INFO("Transmitting packet\n",0); INFO("Transmitting packet\n");
} }
} else { } else {
INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs); INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs);

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

@ -75,11 +75,16 @@ public:
void print_all_buffers() void print_all_buffers()
{ {
printf("%d buffers in queue\n", (int) used.size()); printf("%d buffers in queue\n", (int) used.size());
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
for (uint32_t i=0;i<used.size();i++) { for (uint32_t i=0;i<used.size();i++) {
printf("%s\n", strlen(used[i]->debug_name)?used[i]->debug_name:"Undefined"); printf("%s\n", strlen(used[i]->debug_name)?used[i]->debug_name:"Undefined");
} }
#endif
}
bool is_almost_empty() {
return available.size() < capacity/20;
} }
buffer_t* allocate(const char *debug_name = NULL) buffer_t* allocate(const char *debug_name = NULL)
{ {
@ -92,8 +97,9 @@ public:
used.push_back(b); used.push_back(b);
available.pop(); available.pop();
if (available.size() < capacity/20) { if (is_almost_empty()) {
printf("Warning buffer pool capacity is %f %%\n", (float) 100*available.size()/capacity); printf("Warning buffer pool capacity is %f %%\n", (float) 100*available.size()/capacity);
print_all_buffers();
} }
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
if (debug_name) { if (debug_name) {

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

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

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

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

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

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

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

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

@ -180,8 +180,8 @@ private:
int build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t retx); 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); 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(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_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 handle_control_pdu(uint8_t *payload, uint32_t nof_bytes);
void reassemble_rx_sdus(); void reassemble_rx_sdus();

@ -2243,6 +2243,12 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_imsi(
if(ie != NULL && if(ie != NULL &&
ptr != NULL) ptr != NULL)
{ {
// max length of IE buffer is 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 // Dynamic octet string - IMSI
// Length // Length
if(ie->n_octets < 128) { if(ie->n_octets < 128) {

@ -126,7 +126,7 @@ void log_filter::all_log(srslte::LOG_LEVEL_ENUM level,
ss << std::endl; ss << std::endl;
} }
if (hex_limit > 0) { if (hex_limit > 0 && hex && size > 0) {
ss << hex_string(hex, size); ss << hex_string(hex, size);
} }
str_ptr s_ptr(new std::string(ss.str())); str_ptr s_ptr(new std::string(ss.str()));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -89,7 +89,8 @@ uint32_t srslte_sch_find_Ioffset_cqi(float beta) {
int srslte_sch_init(srslte_sch_t *q) { int srslte_sch_init(srslte_sch_t *q) {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (q) { if (q) {
ret = SRSLTE_ERROR;
bzero(q, sizeof(srslte_sch_t)); bzero(q, sizeof(srslte_sch_t));
if (srslte_crc_init(&q->crc_tb, SRSLTE_LTE_CRC24A, 24)) { 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]); ((uint32_t) data[cb_segm->tbs/8+2]);
if (par_rx == par_tx && par_rx) { if (par_rx == par_tx && par_rx) {
INFO("TB decoded OK\n",0); INFO("TB decoded OK\n");
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} else { } else {
INFO("Error in TB parity: par_tx=0x%x, par_rx=0x%x\n", par_tx, par_rx); INFO("Error in TB parity: par_tx=0x%x, par_rx=0x%x\n", par_tx, par_rx);
@ -753,7 +754,11 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q,
uint32_t nb_q = cfg->nbits.nof_bits; uint32_t nb_q = cfg->nbits.nof_bits;
uint32_t Qm = cfg->grant.Qm; uint32_t Qm = cfg->grant.Qm;
if (Qm == 0) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
if (uci_data.uci_ri_len > 0) { if (uci_data.uci_ri_len > 0) {
float beta = beta_ri_offset[cfg->uci_cfg.I_offset_ri]; float beta = beta_ri_offset[cfg->uci_cfg.I_offset_ri];
if (cfg->cb_segm.tbs == 0) { if (cfg->cb_segm.tbs == 0) {

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

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

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

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

@ -51,7 +51,7 @@ srslte_cell_t cell = {
SRSLTE_PHICH_R_1_6 // PHICH resources SRSLTE_PHICH_R_1_6 // PHICH resources
}; };
char mimo_type_str [32] = "single"; char mimo_type_str[32] = "single";
srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
uint32_t cfi = 1; uint32_t cfi = 1;
uint32_t mcs[SRSLTE_MAX_CODEWORDS] = {0, 0}; uint32_t mcs[SRSLTE_MAX_CODEWORDS] = {0, 0};
@ -111,7 +111,8 @@ void parse_args(int argc, char **argv) {
cfi = atoi(argv[optind]); cfi = atoi(argv[optind]);
break; break;
case 'x': case 'x':
strncpy(mimo_type_str, argv[optind], 32); strncpy(mimo_type_str, argv[optind], sizeof(mimo_type_str));
mimo_type_str[sizeof(mimo_type_str)-1] = 0;
break; break;
case 'p': case 'p':
pmi = (uint32_t) atoi(argv[optind]); pmi = (uint32_t) atoi(argv[optind]);
@ -177,21 +178,10 @@ int main(int argc, char **argv) {
goto quit; goto quit;
} }
switch(mimo_type) { if (mimo_type == SRSLTE_MIMO_TYPE_SINGLE_ANTENNA) {
cell.nof_ports = 1;
case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA: } else {
cell.nof_ports = 1; cell.nof_ports = 2;
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;
} }
srslte_ra_dl_dci_t dci; srslte_ra_dl_dci_t dci;
@ -249,7 +239,7 @@ int main(int argc, char **argv) {
for (i=0;i<SRSLTE_MAX_PORTS;i++) { for (i=0;i<SRSLTE_MAX_PORTS;i++) {
for (j = 0; j < SRSLTE_MAX_PORTS; j++) { for (j = 0; j < SRSLTE_MAX_PORTS; j++) {
ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * NOF_CE_SYMBOLS); ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * NOF_CE_SYMBOLS);
if (!ce[i]) { if (!ce[i][j]) {
perror("srslte_vec_malloc"); perror("srslte_vec_malloc");
goto quit; goto quit;
} }

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

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

@ -176,8 +176,8 @@ int main(int argc, char **argv) {
srslte_rf_set_rx_freq(&rf, uhd_freq); srslte_rf_set_rx_freq(&rf, uhd_freq);
srslte_rf_set_tx_freq(&rf, uhd_freq); srslte_rf_set_tx_freq(&rf, uhd_freq);
if (srate > 1e6) { if (srate > 1e6 && (srate/1000) > 0) {
if (30720%((int) srate/1000) == 0) { if (30720%(srate/1000) == 0) {
srslte_rf_set_master_clock_rate(&rf, 30.72e6); srslte_rf_set_master_clock_rate(&rf, 30.72e6);
} else { } else {
srslte_rf_set_master_clock_rate(&rf, 23.04e6); srslte_rf_set_master_clock_rate(&rf, 23.04e6);

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

@ -368,14 +368,14 @@ int encode_cqi_long(srslte_uci_cqi_pusch_t *q, uint8_t *data, uint32_t nof_bits,
memcpy(q->tmp_cqi, data, sizeof(uint8_t) * nof_bits); memcpy(q->tmp_cqi, data, sizeof(uint8_t) * nof_bits);
srslte_crc_attach(&q->crc, q->tmp_cqi, nof_bits); srslte_crc_attach(&q->crc, q->tmp_cqi, nof_bits);
DEBUG("cqi_crc_tx=", 0); DEBUG("cqi_crc_tx=");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_b(stdout, q->tmp_cqi, nof_bits+8); srslte_vec_fprint_b(stdout, q->tmp_cqi, nof_bits+8);
} }
srslte_convcoder_encode(&encoder, q->tmp_cqi, q->encoded_cqi, nof_bits + 8); srslte_convcoder_encode(&encoder, q->tmp_cqi, q->encoded_cqi, nof_bits + 8);
DEBUG("cconv_tx=", 0); DEBUG("cconv_tx=");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_b(stdout, q->encoded_cqi, 3 * (nof_bits + 8)); srslte_vec_fprint_b(stdout, q->encoded_cqi, 3 * (nof_bits + 8));
} }
@ -400,14 +400,14 @@ int decode_cqi_long(srslte_uci_cqi_pusch_t *q, int16_t *q_bits, uint32_t Q,
srslte_rm_conv_rx_s(q_bits, Q, q->encoded_cqi_s, 3 * (nof_bits + 8)); srslte_rm_conv_rx_s(q_bits, Q, q->encoded_cqi_s, 3 * (nof_bits + 8));
DEBUG("cconv_rx=", 0); DEBUG("cconv_rx=");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_s(stdout, q->encoded_cqi_s, 3 * (nof_bits + 8)); srslte_vec_fprint_s(stdout, q->encoded_cqi_s, 3 * (nof_bits + 8));
} }
srslte_viterbi_decode_s(&q->viterbi, q->encoded_cqi_s, q->tmp_cqi, nof_bits + 8); srslte_viterbi_decode_s(&q->viterbi, q->encoded_cqi_s, q->tmp_cqi, nof_bits + 8);
DEBUG("cqi_crc_rx=", 0); DEBUG("cqi_crc_rx=");
if (SRSLTE_VERBOSE_ISDEBUG()) { if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_b(stdout, q->tmp_cqi, nof_bits+8); srslte_vec_fprint_b(stdout, q->tmp_cqi, nof_bits+8);
} }
@ -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); uint32_t nof_encoded_bits = encode_ri_ack(acks, nof_acks, q_encoded_bits, cfg->grant.Qm);
for (uint32_t i=0;i<Qprime;i++) { if (nof_encoded_bits > 0) {
uci_ulsch_interleave_ack_gen(i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ack_bits[cfg->grant.Qm*i]); for (uint32_t i = 0; i < Qprime; i++) {
uci_ulsch_interleave_put(&q_encoded_bits[(i*cfg->grant.Qm)%nof_encoded_bits], cfg->grant.Qm, &ack_bits[cfg->grant.Qm*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; 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); 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 (nof_encoded_bits > 0) {
if (ack_ri) { for (uint32_t i = 0; i < Qprime; i++) {
uci_ulsch_interleave_ri_gen(i, if (ack_ri) {
cfg->grant.Qm, uci_ulsch_interleave_ri_gen(i,
H_prime_total, cfg->grant.Qm,
cfg->nbits.nof_symb, H_prime_total,
cfg->cp, cfg->nbits.nof_symb,
&bits[cfg->grant.Qm * i]); cfg->cp,
} else { &bits[cfg->grant.Qm * i]);
uci_ulsch_interleave_ack_gen(i, } else {
cfg->grant.Qm, uci_ulsch_interleave_ack_gen(i,
H_prime_total, cfg->grant.Qm,
cfg->nbits.nof_symb, H_prime_total,
cfg->cp, cfg->nbits.nof_symb,
&bits[cfg->grant.Qm * i]); 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; return (int) Qprime;

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

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

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

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

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

@ -59,7 +59,7 @@ void usage(char *prog) {
printf("Usage: %s [nlestodv] -i cell_id -f input_file_name\n", 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-n nof_frames [Default %d]\n", nof_frames);
printf("\t-l N_id_2 to sync [Default use cell_id]\n"); 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-s symbol_sz [Default %d]\n", fft_size);
printf("\t-t threshold [Default %.2f]\n", threshold); printf("\t-t threshold [Default %.2f]\n", threshold);
printf("\t-o file read offset [Default %d]\n", file_offset); printf("\t-o file read offset [Default %d]\n", file_offset);
@ -266,7 +266,7 @@ int main(int argc, char **argv) {
} }
} else { } 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) if(srslte_sss_subframe(m0,m1) == 0)

@ -61,7 +61,7 @@ void usage(char *prog) {
printf("\t-g RF Gain [Default %.2f dB]\n", rf_gain); printf("\t-g RF Gain [Default %.2f dB]\n", rf_gain);
printf("\t-n nof_frames [Default %d]\n", nof_frames); 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-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-s symbol_sz [Default %d]\n", fft_size);
printf("\t-t threshold [Default %.2f]\n", threshold); printf("\t-t threshold [Default %.2f]\n", threshold);
#ifndef DISABLE_GRAPHICS #ifndef DISABLE_GRAPHICS
@ -291,7 +291,7 @@ int main(int argc, char **argv) {
} }
} else { } 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) if(srslte_sss_subframe(m0,m1) == 0)

@ -550,6 +550,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q,
switch(dci_msg.format) { switch(dci_msg.format) {
case SRSLTE_DCI_FORMAT1: case SRSLTE_DCI_FORMAT1:
case SRSLTE_DCI_FORMAT1A: case SRSLTE_DCI_FORMAT1A:
case SRSLTE_DCI_FORMAT1C:
if (q->cell.nof_ports == 1) { if (q->cell.nof_ports == 1) {
mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
} else { } else {
@ -573,7 +574,6 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q,
/* Not implemented formats */ /* Not implemented formats */
case SRSLTE_DCI_FORMAT0: case SRSLTE_DCI_FORMAT0:
case SRSLTE_DCI_FORMAT1C:
case SRSLTE_DCI_FORMAT1B: case SRSLTE_DCI_FORMAT1B:
case SRSLTE_DCI_FORMAT1D: case SRSLTE_DCI_FORMAT1D:
case SRSLTE_DCI_FORMAT2B: case SRSLTE_DCI_FORMAT2B:
@ -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; dci_blind_search_t *current_ss = &search_space;
if (cfi < 1 || cfi > 3) { 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; return SRSLTE_ERROR;
} }

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

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

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

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

@ -30,7 +30,14 @@
namespace srslte { namespace srslte {
pdcp::pdcp() 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_) 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() void pdcp::stop()
{ {
for(uint32_t i=0;i<SRSLTE_N_RADIO_BEARERS;i++) {
if (pdcp_array[i].is_active()) {
pdcp_array[i].stop();
}
}
} }
void pdcp::reestablish() { void pdcp::reestablish() {

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

@ -35,6 +35,15 @@ namespace srslte {
rlc::rlc() rlc::rlc()
{ {
pool = byte_buffer_pool::get_instance(); 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_, 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) 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); rlc_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid);
return; return;
} }
if (!rlc_array[lcid].active()) { 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]); rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg.rlc_mode]);
switch(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) bool rlc::valid_lcid(uint32_t lcid)
{ {
if(lcid < 0 || lcid >= SRSLTE_N_RADIO_BEARERS) { if(lcid >= SRSLTE_N_RADIO_BEARERS) {
return false; return false;
} } else if(!rlc_array[lcid].active()) {
if(!rlc_array[lcid].active()) {
return false; return false;
} }
return true; return true;

@ -38,6 +38,12 @@ namespace srslte {
rlc_am::rlc_am() : tx_sdu_queue(16) 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; tx_sdu = NULL;
rx_sdu = NULL; rx_sdu = NULL;
pool = byte_buffer_pool::get_instance(); 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_) void rlc_am::configure(srslte_rlc_config_t cfg_)
{ {
cfg = cfg_.am; 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", "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, 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); 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) void rlc_am::write_sdu(byte_buffer_t *sdu)
{ {
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str());
tx_sdu_queue.write(sdu); tx_sdu_queue.write(sdu);
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size());
} }
/**************************************************************************** /****************************************************************************
@ -682,7 +688,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
tx_sdu->msg += to_move; tx_sdu->msg += to_move;
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;
@ -717,7 +723,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
tx_sdu->msg += to_move; tx_sdu->msg += to_move;
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;
@ -768,7 +774,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
return (ptr-payload) + pdu->N_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<uint32_t, rlc_amd_rx_pdu_t>::iterator it; std::map<uint32_t, rlc_amd_rx_pdu_t>::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); memcpy(pdu.buf->msg, payload, nof_bytes);
pdu.buf->N_bytes = 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; 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(); 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<uint32_t, rlc_amd_rx_pdu_segments_t>::iterator it; std::map<uint32_t, rlc_amd_rx_pdu_segments_t>::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); memcpy(segment.buf->msg, payload, nof_bytes);
segment.buf->N_bytes = 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 // Check if we already have a segment from the same PDU
it = rx_segments.find(header.sn); it = rx_segments.find(header.sn);

@ -31,6 +31,10 @@ namespace srslte {
rlc_tm::rlc_tm() : ul_queue(16) rlc_tm::rlc_tm() : ul_queue(16)
{ {
log = NULL;
pdcp = NULL;
rrc = NULL;
lcid = 0;
pool = byte_buffer_pool::get_instance(); 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); ul_queue.read(&buf);
pdu_size = buf->N_bytes; pdu_size = buf->N_bytes;
memcpy(payload, buf->msg, buf->N_bytes); memcpy(payload, buf->msg, buf->N_bytes);
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), buf->get_latency_us()); rrc->get_rb_name(lcid).c_str(), buf->get_latency_us());
pool->deallocate(buf); pool->deallocate(buf);
log->info_hex(payload, pdu_size, "TX %s, %s PDU", rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM]); log->info_hex(payload, pdu_size, "TX %s, %s PDU", rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM]);

@ -33,6 +33,14 @@ namespace srslte {
rlc_um::rlc_um() : tx_sdu_queue(16) 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; tx_sdu = NULL;
rx_sdu = NULL; rx_sdu = NULL;
pool = byte_buffer_pool::get_instance(); pool = byte_buffer_pool::get_instance();
@ -73,18 +81,18 @@ void rlc_um::configure(srslte_rlc_config_t cnfg_)
switch(cnfg_.rlc_mode) switch(cnfg_.rlc_mode)
{ {
case LIBLTE_RRC_RLC_MODE_UM_BI: 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", "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], 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]); cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]);
break; break;
case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: 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], 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]); rlc_umd_sn_size_num[cfg.rx_sn_field_length]);
break; break;
case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: 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", "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], 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]); 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) void rlc_um::write_sdu(byte_buffer_t *sdu)
{ {
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str());
tx_sdu_queue.write(sdu); tx_sdu_queue.write(sdu);
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size());
} }
/**************************************************************************** /****************************************************************************
@ -178,7 +186,7 @@ uint32_t rlc_um::get_buffer_state()
// Room needed for fixed header? // Room needed for fixed header?
if(n_bytes > 0) if(n_bytes > 0)
n_bytes += 2; n_bytes += 3;
return n_bytes; return n_bytes;
} }
@ -300,7 +308,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
tx_sdu->msg += to_move; tx_sdu->msg += to_move;
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;
@ -329,7 +337,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
tx_sdu->msg += to_move; tx_sdu->msg += to_move;
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;

@ -37,6 +37,10 @@ add_executable(test_eea2 test_eea2.cc)
target_link_libraries(test_eea2 srslte_common ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(test_eea2 srslte_common ${CMAKE_THREAD_LIBS_INIT})
add_test(test_eea2 test_eea2) 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) 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}) target_link_libraries(log_filter_test srslte_phy srslte_common srslte_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})

@ -67,7 +67,7 @@ void write(std::string filename) {
bool read(std::string filename) { bool read(std::string filename) {
bool pass = true; bool pass = true;
bool written[NTHREADS][NMSGS]; bool written[NTHREADS][NMSGS];
int thread, msg; int thread = 0, msg = 0;
int r; int r;
for(int i=0;i<NTHREADS;i++) { for(int i=0;i<NTHREADS;i++) {
@ -78,7 +78,13 @@ bool read(std::string filename) {
FILE *f = fopen(filename.c_str(), "r"); FILE *f = fopen(filename.c_str(), "r");
if(f!=NULL) { if(f!=NULL) {
while(fscanf(f, "Thread %d: %d\n", &thread, &msg)) { while(fscanf(f, "Thread %d: %d\n", &thread, &msg)) {
written[thread][msg] = true; if (thread < NTHREADS && msg < NMSGS) {
written[thread][msg] = true;
} else {
perror("Wrong thread and/or msg");
fclose(f);
return false;
}
} }
fclose(f); fclose(f);
} }
@ -95,7 +101,11 @@ int main(int argc, char **argv) {
std::string f("log.txt"); std::string f("log.txt");
write(f); write(f);
result = read(f); result = read(f);
remove(f.c_str());
if (remove(f.c_str())) {
perror("Removing file");
}
if(result) { if(result) {
printf("Passed\n"); printf("Passed\n");
exit(0); exit(0);

@ -0,0 +1,170 @@
/*
* Includes
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#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();
*/
}

@ -39,6 +39,7 @@ public:
finished = false; finished = false;
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cvar, NULL); pthread_cond_init(&cvar, NULL);
bzero(&start_time, sizeof(start_time));
} }
void timeout_expired(uint32_t timeout_id) void timeout_expired(uint32_t timeout_id)

@ -54,7 +54,10 @@ class rlc_am_tester
,public rrc_interface_rlc ,public rrc_interface_rlc
{ {
public: public:
rlc_am_tester(){n_sdus = 0;} rlc_am_tester(){
bzero(sdus, sizeof(sdus));
n_sdus = 0;
}
// PDCP interface // PDCP interface
void write_pdu(uint32_t lcid, byte_buffer_t *sdu) void write_pdu(uint32_t lcid, byte_buffer_t *sdu)

@ -57,7 +57,10 @@ class rlc_um_tester
,public rrc_interface_rlc ,public rrc_interface_rlc
{ {
public: public:
rlc_um_tester(){n_sdus = 0;} rlc_um_tester(){
bzero(sdus, sizeof(sdus));
n_sdus = 0;
}
// PDCP interface // PDCP interface
void write_pdu(uint32_t lcid, byte_buffer_t *sdu) void write_pdu(uint32_t lcid, byte_buffer_t *sdu)
@ -117,7 +120,7 @@ void basic_test()
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(&sdu_bufs[i]);
} }
assert(13 == rlc1.get_buffer_state()); assert(14 == rlc1.get_buffer_state());
// Read 5 PDUs from RLC1 (1 byte each) // Read 5 PDUs from RLC1 (1 byte each)
byte_buffer_t pdu_bufs[NBUFS]; byte_buffer_t pdu_bufs[NBUFS];
@ -185,7 +188,7 @@ void loss_test()
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(&sdu_bufs[i]);
} }
assert(13 == rlc1.get_buffer_state()); assert(14 == rlc1.get_buffer_state());
// Read 5 PDUs from RLC1 (1 byte each) // Read 5 PDUs from RLC1 (1 byte each)
byte_buffer_t pdu_bufs[NBUFS]; byte_buffer_t pdu_bufs[NBUFS];

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

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

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

@ -43,7 +43,14 @@ class ue : public srslte::read_pdu_interface,
{ {
public: 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; rlc = NULL;
log_h = NULL; log_h = NULL;
rnti = 0; rnti = 0;
@ -55,6 +62,14 @@ public:
for (int i=0;i<NOF_HARQ_PROCESSES;i++) { for (int i=0;i<NOF_HARQ_PROCESSES;i++) {
pending_buffers[i] = NULL; pending_buffers[i] = NULL;
} }
bzero(&metrics, sizeof(mac_metrics_t));
bzero(&mutex, sizeof(pthread_mutex_t));
bzero(softbuffer_tx, sizeof(softbuffer_tx));
bzero(softbuffer_rx, sizeof(softbuffer_rx));
for (int i = 0; i < SRSLTE_MAX_TB; ++i) {
bzero(tx_payload_buffer, sizeof(uint8_t) * payload_buffer_len);
}
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
} }

@ -56,7 +56,17 @@ public:
phch_common(uint32_t max_mutex_) : tx_mutex(max_mutex_) { phch_common(uint32_t max_mutex_) : tx_mutex(max_mutex_) {
nof_mutex = 0; nof_mutex = 0;
max_mutex = max_mutex_; max_mutex = max_mutex_;
params.max_prach_offset_us = 20; params.max_prach_offset_us = 20;
radio = NULL;
mac = NULL;
is_first_tx = false;
is_first_of_burst = false;
pdsch_p_b = 0;
nof_workers = 0;
bzero(&pusch_cfg, sizeof(pusch_cfg));
bzero(&hopping_cfg, sizeof(hopping_cfg));
bzero(&pucch_cfg, sizeof(pucch_cfg));
bzero(&ul_grants, sizeof(ul_grants));
} }
bool init(srslte_cell_t *cell, srslte::radio *radio_handler, mac_interface_phy *mac); bool init(srslte_cell_t *cell, srslte::radio *radio_handler, mac_interface_phy *mac);

@ -103,7 +103,11 @@ private:
class ue { class ue {
public: public:
ue() : I_sr(0), I_sr_en(false), cqi_en(false), pucch_cqi_ack(false), pmi_idx(0), has_grant_tti(0), ue() : I_sr(0), I_sr_en(false), cqi_en(false), pucch_cqi_ack(false), pmi_idx(0), has_grant_tti(0),
dedicated_ack(false) {bzero(&metrics, sizeof(phy_metrics_t));} dedicated_ack(false), ri_idx(0), ri_en(false), rnti(0) {
bzero(&dedicated, sizeof(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT));
bzero(&phich_info, sizeof(srslte_enb_ul_phich_info_t));
bzero(&metrics, sizeof(phy_metrics_t));
}
uint32_t I_sr; uint32_t I_sr;
uint32_t pmi_idx; uint32_t pmi_idx;
uint32_t ri_idx; uint32_t ri_idx;

@ -36,7 +36,20 @@ namespace srsenb {
class prach_worker : thread class prach_worker : thread
{ {
public: public:
prach_worker() : initiated(false),max_prach_offset_us(0) {} prach_worker() : initiated(false), prach_nof_det(0), max_prach_offset_us(0), pending_tti(0), processed_tti(0),
running(false), nof_sf(0), sf_cnt(0) {
log_h = NULL;
mac = NULL;
signal_buffer_rx = NULL;
bzero(&prach, sizeof(srslte_prach_t));
bzero(&prach_indices, sizeof(prach_indices));
bzero(&prach_offsets, sizeof(prach_offsets));
bzero(&prach_p2avg, sizeof(prach_p2avg));
bzero(&cell, sizeof(cell));
bzero(&prach_cfg, sizeof(prach_cfg));
bzero(&mutex, sizeof(mutex));
bzero(&cvar, sizeof(cvar));
}
int init(srslte_cell_t *cell, srslte_prach_cfg_t *prach_cfg, mac_interface_phy *mac, srslte::log *log_h, int priority); int init(srslte_cell_t *cell, srslte_prach_cfg_t *prach_cfg, mac_interface_phy *mac, srslte::log *log_h, int priority);
int new_tti(uint32_t tti, cf_t *buffer); int new_tti(uint32_t tti, cf_t *buffer);

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

@ -103,8 +103,28 @@ class rrc : public rrc_interface_pdcp,
public thread public thread
{ {
public: public:
rrc() : act_monitor(this), cnotifier(NULL) {} rrc() : act_monitor(this), cnotifier(NULL), running(false), nof_si_messages(0) {
users.clear();
pending_paging.clear();
pool = NULL;
phy = NULL;
mac = NULL;
rlc = NULL;
pdcp = NULL;
gtpu = NULL;
s1ap = NULL;
rrc_log = NULL;
bzero(&sr_sched, sizeof(sr_sched));
bzero(&cqi_sched, sizeof(cqi_sched));
bzero(&cfg, sizeof(cfg));
bzero(&sib2, sizeof(sib2));
bzero(&user_mutex, sizeof(user_mutex));
bzero(&paging_mutex, sizeof(paging_mutex));
}
void init(rrc_cfg_t *cfg, void init(rrc_cfg_t *cfg,
phy_interface_rrc *phy, phy_interface_rrc *phy,
@ -321,7 +341,7 @@ private:
const static uint32_t LCID_REM_USER = 0xffff0001; const static uint32_t LCID_REM_USER = 0xffff0001;
bool running; bool running;
static const int RRC_THREAD_PRIO = 7; static const int RRC_THREAD_PRIO = 65;
srslte::block_queue<rrc_pdu> rx_pdu_queue; srslte::block_queue<rrc_pdu> rx_pdu_queue;
typedef struct { typedef struct {

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

@ -54,11 +54,14 @@ void enb::cleanup(void)
} }
} }
enb::enb() enb::enb() : started(false) {
:started(false)
{
srslte_dft_load(); srslte_dft_load();
pool = srslte::byte_buffer_pool::get_instance(); pool = srslte::byte_buffer_pool::get_instance();
logger = NULL;
args = NULL;
bzero(&rf_metrics, sizeof(rf_metrics));
} }
enb::~enb() enb::~enb()

@ -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); parser::parse_section(args->enb_files.rr_config, &phy_cnfg);
cell->phich_length = (srslte_phich_length_t) phichcfg.dur; cell->phich_length = (srslte_phich_length_t) (int) phichcfg.dur;
cell->phich_resources = (srslte_phich_resources_t) phichcfg.res; cell->phich_resources = (srslte_phich_resources_t) (int) phichcfg.res;
if (!srslte_cell_isvalid(cell)) { 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); 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; data->hnb_name_present = true;
if (name_enabled) { if (name_enabled) {
strncpy((char*) data->hnb_name, hnb_name.c_str(), 48); strncpy((char*) data->hnb_name, hnb_name.c_str(), 48);
data->hnb_name[47] = 0;
data->hnb_name_size = strnlen(hnb_name.c_str(), 48); data->hnb_name_size = strnlen(hnb_name.c_str(), 48);
} else if (hex_enabled) { } else if (hex_enabled) {
data->hnb_name_size = HexToBytes(hex_value, data->hnb_name, 48); data->hnb_name_size = HexToBytes(hex_value, data->hnb_name, 48);
@ -844,7 +845,7 @@ int enb::parse_rr(all_args_t* args, rrc_cfg_t* rrc_cfg)
{ {
/* Transmission mode config section */ /* 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); ERROR("Invalid transmission mode (%d). Only indexes 1-4 are implemented.\n", args->enb.transmission_mode);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} else if (args->enb.transmission_mode == 1 && args->enb.nof_ports > 1) { } else if (args->enb.transmission_mode == 1 && args->enb.nof_ports > 1) {

@ -42,13 +42,26 @@
namespace srsenb { namespace srsenb {
mac::mac() : timers_db(128), mac::mac() : timers_db(128), timers_thread(&timers_db), tti(0), last_rnti(0),
timers_thread(&timers_db), rar_pdu_msg(sched_interface::MAX_RAR_LIST), rar_payload(),
rar_pdu_msg(sched_interface::MAX_RAR_LIST),
pdu_process_thread(this) pdu_process_thread(this)
{ {
started = false; 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_) 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 // Find empty slot for pending rars
uint32_t ra_id=0; uint32_t ra_id=0;
while(pending_rars[ra_id].temp_crnti && ra_id<MAX_PENDING_RARS) { while(pending_rars[ra_id].temp_crnti && ra_id<MAX_PENDING_RARS-1) {
ra_id++; ra_id++;
} }
if (ra_id == MAX_PENDING_RARS) { if (ra_id == MAX_PENDING_RARS) {
@ -722,8 +735,7 @@ void mac::timer_thread::tti_clock()
* DEMU unit * DEMU unit
* *
*******************************************************/ *******************************************************/
mac::pdu_process::pdu_process(pdu_process_handler *h) mac::pdu_process::pdu_process(pdu_process_handler *h) : running(false) {
{
handler = h; handler = h;
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cvar, NULL); pthread_cond_init(&cvar, NULL);

@ -18,10 +18,26 @@ namespace srsenb {
* Initialization and sched configuration functions * Initialization and sched configuration functions
* *
*******************************************************/ *******************************************************/
sched::sched() sched::sched() : bc_aggr_level(0), rar_aggr_level(0), avail_rbg(0), P(0), start_rbg(0), si_n_rbg(0), rar_n_rb(0),
{ nof_rbg(0), sf_idx(0), sfn(0), current_cfi(0) {
current_tti = 0; current_tti = 0;
log_h = NULL; log_h = NULL;
dl_metric = NULL;
ul_metric = NULL;
rrc = NULL;
bzero(&cfg, sizeof(cfg));
bzero(&regs, sizeof(regs));
bzero(&used_cce, sizeof(used_cce));
bzero(&sched_cfg, sizeof(sched_cfg));
bzero(&common_locations, sizeof(common_locations));
bzero(&pdsch_re, sizeof(pdsch_re));
bzero(&mutex, sizeof(mutex));
for (int i = 0; i < 3; i++) {
bzero(rar_locations[i], sizeof(sched_ue::sched_dci_cce_t) * 10);
}
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
reset(); reset();
} }
@ -80,7 +96,10 @@ int sched::cell_cfg(sched_interface::cell_cfg_t* cell_cfg)
memcpy(&cfg, cell_cfg, sizeof(sched_interface::cell_cfg_t)); memcpy(&cfg, cell_cfg, sizeof(sched_interface::cell_cfg_t));
// Get DCI locations // Get DCI locations
srslte_regs_init(&regs, cfg.cell); if (srslte_regs_init(&regs, cfg.cell)) {
Error("Getting DCI locations\n");
return SRSLTE_ERROR;
}
P = srslte_ra_type0_P(cfg.cell.nof_prb); P = srslte_ra_type0_P(cfg.cell.nof_prb);
si_n_rbg = 4/P; si_n_rbg = 4/P;

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

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

@ -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, 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() void sched_ue::reset()
{ {
bzero(&cfg, sizeof(sched_interface::ue_cfg_t)); bzero(&cfg, sizeof(sched_interface::ue_cfg_t));
sr = false; sr = false;
next_tpc_pusch = 1; next_tpc_pusch = 1;
next_tpc_pucch = 1; next_tpc_pucch = 1;
buf_mac = 0; buf_mac = 0;
buf_ul = 0; buf_ul = 0;
phy_config_dedicated_enabled = false; phy_config_dedicated_enabled = false;
dl_cqi = 1; dl_cqi = 1;
ul_cqi = 1; ul_cqi = 1;
dl_cqi_tti = 0; dl_cqi_tti = 0;
ul_cqi_tti = 0; ul_cqi_tti = 0;
cqi_request_tti = 0; dl_ri = 0;
dl_ri_tti = 0;
dl_pmi = 0;
dl_pmi_tti = 0;
cqi_request_tti = 0;
for (int i=0;i<SCHED_MAX_HARQ_PROC;i++) { for (int i=0;i<SCHED_MAX_HARQ_PROC;i++) {
for(uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { for(uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
dl_harq[i].reset(tb); dl_harq[i].reset(tb);
@ -212,6 +225,7 @@ bool sched_ue::pucch_sr_collision(uint32_t current_tti, uint32_t n_cce)
return false; return false;
} }
srslte_pucch_sched_t pucch_sched; srslte_pucch_sched_t pucch_sched;
pucch_sched.sps_enabled = false;
pucch_sched.n_pucch_sr = cfg.sr_N_pucch; pucch_sched.n_pucch_sr = cfg.sr_N_pucch;
pucch_sched.n_pucch_2 = cfg.n_pucch_cqi; pucch_sched.n_pucch_2 = cfg.n_pucch_cqi;
pucch_sched.N_pucch_1 = cfg.pucch_cfg.n1_pucch_an; pucch_sched.N_pucch_1 = cfg.pucch_cfg.n1_pucch_an;

@ -256,7 +256,7 @@ void ue::push_pdu(uint32_t tti, uint32_t len)
bool ue::process_ce(srslte::sch_subh *subh) { bool ue::process_ce(srslte::sch_subh *subh) {
uint32_t buff_size[4] = {0, 0, 0, 0}; uint32_t buff_size[4] = {0, 0, 0, 0};
float phr = 0; float phr = 0;
int idx = 0; int32_t idx = 0;
uint16_t old_rnti = 0; uint16_t old_rnti = 0;
bool is_bsr = false; bool is_bsr = false;
switch(subh->ce_type()) { switch(subh->ce_type()) {
@ -279,6 +279,10 @@ bool ue::process_ce(srslte::sch_subh *subh) {
case srslte::sch_subh::TRUNC_BSR: case srslte::sch_subh::TRUNC_BSR:
case srslte::sch_subh::SHORT_BSR: case srslte::sch_subh::SHORT_BSR:
idx = subh->get_bsr(buff_size); idx = subh->get_bsr(buff_size);
if(idx == -1){
Error("Invalid Index Passed to lc groups\n");
break;
}
for (uint32_t i=0;i<lc_groups[idx].size();i++) { for (uint32_t i=0;i<lc_groups[idx].size();i++) {
// Indicate BSR to scheduler // Indicate BSR to scheduler
sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]); sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]);
@ -289,7 +293,7 @@ bool ue::process_ce(srslte::sch_subh *subh) {
break; break;
case srslte::sch_subh::LONG_BSR: case srslte::sch_subh::LONG_BSR:
subh->get_bsr(buff_size); subh->get_bsr(buff_size);
for (int idx=0;idx<4;idx++) { for (idx=0;idx<4;idx++) {
for (uint32_t i=0;i<lc_groups[idx].size();i++) { for (uint32_t i=0;i<lc_groups[idx].size();i++) {
sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]); sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]);
} }
@ -320,7 +324,7 @@ void ue::allocate_sdu(srslte::sch_pdu *pdu, uint32_t lcid, uint32_t total_sdu_le
if (sdu_space > 0) { if (sdu_space > 0) {
int sdu_len = SRSLTE_MIN(total_sdu_len, (uint32_t) sdu_space); int sdu_len = SRSLTE_MIN(total_sdu_len, (uint32_t) sdu_space);
int n=1; int n=1;
while(sdu_len > 0 && n > 0) { while(sdu_len > 3 && n > 0) {
if (pdu->new_subh()) { // there is space for a new subheader if (pdu->new_subh()) { // there is space for a new subheader
log_h->debug("SDU: set_sdu(), lcid=%d, sdu_len=%d, sdu_space=%d\n", lcid, sdu_len, sdu_space); log_h->debug("SDU: set_sdu(), lcid=%d, sdu_len=%d, sdu_space=%d\n", lcid, sdu_len, sdu_space);
n = pdu->get()->set_sdu(lcid, sdu_len, this); n = pdu->get()->set_sdu(lcid, sdu_len, this);
@ -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; uint8_t *ret = NULL;
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
if (rlc) if (rlc) {
{
mac_msg_dl.init_tx(tx_payload_buffer[tb_idx], grant_size, false); mac_msg_dl.init_tx(tx_payload_buffer[tb_idx], grant_size, false);
for (uint32_t i=0;i<nof_pdu_elems;i++) { for (uint32_t i=0;i<nof_pdu_elems;i++) {
if (pdu[i].lcid <= srslte::sch_subh::PHR_REPORT) { if (pdu[i].lcid <= srslte::sch_subh::PHR_REPORT) {
@ -379,7 +382,6 @@ uint8_t* ue::generate_pdu(uint32_t tb_idx, sched_interface::dl_sched_pdu_t pdu[s
} else { } else {
std::cout << "Error ue not configured (must call config() first" << std::endl; std::cout << "Error ue not configured (must call config() first" << std::endl;
return NULL;
} }
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);

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

@ -35,6 +35,7 @@
#include <iostream> #include <iostream>
#include <stdio.h> #include <stdio.h>
#include <string.h>
using namespace std; using namespace std;
@ -46,11 +47,11 @@ char const * const prefixes[2][9] =
{ "", "k", "M", "G", "T", "P", "E", "Z", "Y", }, { "", "k", "M", "G", "T", "P", "E", "Z", "Y", },
}; };
metrics_stdout::metrics_stdout() metrics_stdout::metrics_stdout() : started(false) ,do_print(false), metrics_report_period(0.0f),n_reports(10)
:started(false)
,do_print(false)
,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) 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() void metrics_stdout::print_metrics()
{ {
std::ios::fmtflags f(cout.flags()); // For avoiding Coverity defect: Not restoring ostream format
if(!do_print) if(!do_print)
return; return;
@ -157,7 +160,8 @@ void metrics_stdout::print_metrics()
if(metrics.rf.rf_error) { 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); 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() void metrics_stdout::print_disconnect()

@ -73,6 +73,11 @@ namespace srsenb {
phch_worker::phch_worker() phch_worker::phch_worker()
{ {
phy = NULL; phy = NULL;
bzero(&enb_dl, sizeof(enb_dl));
bzero(&enb_ul, sizeof(enb_ul));
bzero(&tx_time, sizeof(tx_time));
reset(); 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_prb_lowest = enb_ul.pusch_cfg.grant.n_prb_tilde[0];
ue_db[rnti].phich_info.n_dmrs = phy_grant.ncs_dmrs; ue_db[rnti].phich_info.n_dmrs = phy_grant.ncs_dmrs;
char cqi_str[64]; char cqi_str[SRSLTE_CQI_STR_MAX_CHAR];
if (cqi_enabled) { if (cqi_enabled) {
if (ue_db[rnti].cqi_en) { if (ue_db[rnti].cqi_en) {
wideband_cqi_value = cqi_value.wideband.wideband_cqi; wideband_cqi_value = cqi_value.wideband.wideband_cqi;
@ -578,7 +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); cqi_value.subband_hl.wideband_cqi_cw0, cqi_value.subband_hl.N);
} }
} }
srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, 64); srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
//snprintf(cqi_str, 64, ", cqi=%s", wideband_cqi_value); //snprintf(cqi_str, 64, ", cqi=%s", wideband_cqi_value);
} }

@ -48,8 +48,11 @@ namespace srsenb {
phy::phy() : workers_pool(MAX_WORKERS), phy::phy() : workers_pool(MAX_WORKERS),
workers(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) void phy::parse_config(phy_cfg_t* cfg)

@ -42,13 +42,13 @@ using namespace std;
namespace srsenb { namespace srsenb {
txrx::txrx() txrx::txrx() : tx_mutex_cnt(0), nof_tx_mutex(0), tti(0) {
{
running = false; running = false;
radio_h = NULL; radio_h = NULL;
log_h = NULL; log_h = NULL;
workers_pool = 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_) 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_)

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

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

@ -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) void rrc::parse_ul_ccch(uint16_t rnti, byte_buffer_t *pdu)
{ {
uint16_t old_rnti = 0; uint16_t old_rnti = 0;
LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; if (pdu) {
bzero(&ul_ccch_msg, sizeof(LIBLTE_RRC_UL_CCCH_MSG_STRUCT)); 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; srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8);
liblte_rrc_unpack_ul_ccch_msg((LIBLTE_BIT_MSG_STRUCT*)&bit_buf, &ul_ccch_msg); 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", rrc_log->info_hex(pdu->msg, pdu->N_bytes,
liblte_rrc_ul_ccch_msg_type_text[ul_ccch_msg.msg_type]); "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: switch (ul_ccch_msg.msg_type) {
if (users.count(rnti)) { case LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ:
users[rnti].handle_rrc_con_req(&ul_ccch_msg.msg.rrc_con_req); if (users.count(rnti)) {
} else { users[rnti].handle_rrc_con_req(&ul_ccch_msg.msg.rrc_con_req);
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);
} else { } else {
rrc_log->error("Received ConnectionReestablishment for rnti=0x%x without context\n", old_rnti); rrc_log->error("Received ConnectionSetup for rnti=0x%x without context\n", rnti);
users[rnti].send_connection_reest_rej();
} }
// remove temporal rnti break;
rem_user_thread(rnti); case LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REEST_REQ:
} else { rrc_log->debug("rnti=0x%x, phyid=0x%x, smac=0x%x, cause=%s\n",
rrc_log->error("Received ReestablishmentRequest from an rnti=0x%x not in IDLE\n", rnti); 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,
break; ul_ccch_msg.msg.rrc_con_reest_req.ue_id.short_mac_i,
default: liblte_rrc_con_reest_req_cause_text[ul_ccch_msg.msg.rrc_con_reest_req.cause]
rrc_log->error("UL CCCH message not recognised\n"); );
break; 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) void rrc::parse_ul_dcch(uint16_t rnti, uint32_t lcid, byte_buffer_t *pdu)
{ {
if (users.count(rnti)) { if (pdu) {
users[rnti].parse_ul_dcch(lcid, pdu); if (users.count(rnti)) {
} else { users[rnti].parse_ul_dcch(lcid, pdu);
rrc_log->error("Processing %s: Unkown rnti=0x%x\n", rb_id_text[lcid], rnti); } 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]; *pmi_idx = 318 + parent->cfg.cqi_cfg.sf_mapping[j_min];
} else if (period == 64) { } else if (period == 64) {
*pmi_idx = 350 + parent->cfg.cqi_cfg.sf_mapping[j_min]; *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]; *pmi_idx = 414 + parent->cfg.cqi_cfg.sf_mapping[j_min];
} }
} }

@ -590,15 +590,15 @@ int main(int argc, char *argv[])
/******************* This is copied from srsue gw **********************/ /******************* This is copied from srsue gw **********************/
int setup_if_addr(char *ip_addr) int setup_if_addr(char *ip_addr)
{ {
char *dev = (char*) "tun_srsenb"; char *dev = (char*) "tun_srsenb";
int sock;
// Construct the TUN device // Construct the TUN device
int tun_fd = open("/dev/net/tun", O_RDWR); int tun_fd = open("/dev/net/tun", O_RDWR);
if(0 > tun_fd) if(0 > tun_fd)
{ {
perror("open"); perror("open");
return(-1); return SRSLTE_ERROR;
} }
struct ifreq ifr; struct ifreq ifr;
@ -609,21 +609,21 @@ int setup_if_addr(char *ip_addr)
if(0 > ioctl(tun_fd, TUNSETIFF, &ifr)) if(0 > ioctl(tun_fd, TUNSETIFF, &ifr))
{ {
perror("ioctl1"); perror("ioctl1");
return -1; goto clean_exit;
} }
// Bring up the interface // 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)) if(0 > ioctl(sock, SIOCGIFFLAGS, &ifr))
{ {
perror("socket"); perror("socket");
return -1; goto clean_exit;
} }
ifr.ifr_flags |= IFF_UP | IFF_RUNNING; ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
if(0 > ioctl(sock, SIOCSIFFLAGS, &ifr)) if(0 > ioctl(sock, SIOCSIFFLAGS, &ifr))
{ {
perror("ioctl2"); perror("ioctl2");
return -1; goto clean_exit;
} }
// Setup the IP address // Setup the IP address
@ -633,15 +633,21 @@ int setup_if_addr(char *ip_addr)
if(0 > ioctl(sock, SIOCSIFADDR, &ifr)) if(0 > ioctl(sock, SIOCSIFADDR, &ifr))
{ {
perror("ioctl"); perror("ioctl");
return -1; goto clean_exit;
} }
ifr.ifr_netmask.sa_family = AF_INET; ifr.ifr_netmask.sa_family = AF_INET;
((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr("255.255.255.0"); ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr("255.255.255.0");
if(0 > ioctl(sock, SIOCSIFNETMASK, &ifr)) if(0 > ioctl(sock, SIOCSIFNETMASK, &ifr))
{ {
perror("ioctl"); perror("ioctl");
return -1; goto clean_exit;
} }
shutdown(sock, SHUT_RDWR);
return(tun_fd); return(tun_fd);
clean_exit:
shutdown(sock, SHUT_RDWR);
close(tun_fd);
return SRSLTE_ERROR;
} }

@ -46,6 +46,8 @@ namespace srsepc{
typedef struct{ typedef struct{
std::string auth_algo; std::string auth_algo;
std::string db_file; std::string db_file;
uint16_t mcc;
uint16_t mnc;
}hss_args_t; }hss_args_t;
typedef struct{ typedef struct{
@ -98,7 +100,9 @@ private:
/*Logs*/ /*Logs*/
srslte::log_filter *m_hss_log; srslte::log_filter *m_hss_log;
uint16_t mcc;
uint16_t mnc;
}; };
} // namespace srsepc } // namespace srsepc

@ -92,7 +92,10 @@ hss::init(hss_args_t *hss_args, srslte::log_filter *hss_log)
return -1; 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"); m_hss_log->console("HSS Initialized\n");
return 0; 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 ak[6];
uint8_t mac[8]; uint8_t mac[8];
uint16_t mcc=61441; //001
uint16_t mnc=65281; //01
if(!get_k_amf_op(imsi,k,amf,op)) 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); gen_rand(rand);
get_sqn(sqn); get_sqn(sqn);
security_milenage_f2345( k, security_milenage_f2345( k,
op, op,
rand, rand,
@ -223,6 +224,14 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn
ik, ik,
ak); 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, security_milenage_f1( k,
op, op,
rand, rand,
@ -230,6 +239,9 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn
amf, amf,
mac); mac);
m_hss_log->debug_hex(sqn, 6, "User SQN : ");
m_hss_log->debug_hex(mac, 8, "User MAC : ");
// Generate K_asme // Generate K_asme
security_generate_k_asme( ck, security_generate_k_asme( ck,
ik, ik,
@ -239,6 +251,9 @@ hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn
mnc, mnc,
k_asme); 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) //Generate AUTN (autn = sqn ^ ak |+| amf |+| mac)
for(int i=0;i<6;i++ ) 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]; autn[8+i]=mac[i];
} }
m_hss_log->debug_hex(sqn, 6, "User SQN : "); m_hss_log->debug_hex(autn, 16, "User AUTN: ");
m_hss_log->debug_hex(autn, 8, "User AUTN: ");
m_hss_log->debug_hex(xres, 8, "User XRES: ");
return true; 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 ak[6];
uint8_t mac[8]; uint8_t mac[8];
uint16_t mcc=61441; //001
uint16_t mnc=65281; //01
int i = 0; int i = 0;
if(!get_k_amf_op(imsi,k,amf,op)) 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]; 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 // Generate cdout
for(i=0; i<6; i++) { for(i=0; i<6; i++) {
cdout[i] = sqn[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]; 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) //Generate AUTN (autn = sqn ^ ak |+| amf |+| mac)
for(int i=0;i<6;i++ ) 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, mcc,
mnc, mnc,
k_asme); 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) //Generate AUTN (autn = sqn ^ ak |+| amf |+| mac)
for(int i=0;i<6;i++ ) 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]; 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(autn, 8, "User AUTN: ");
m_hss_log->debug_hex(xres, 8, "User XRES: ");
return true; return true;
} }

@ -189,12 +189,20 @@ parse_args(all_args_t *args, int argc, char* argv[]) {
} }
// Convert MCC/MNC strings // Convert MCC/MNC strings
if(!srslte::string_to_mcc(mcc, &args->mme_args.s1ap_args.mcc)) { 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)) { 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->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr;
args->spgw_args.gtpu_bind_addr = spgw_bind_addr; args->spgw_args.gtpu_bind_addr = spgw_bind_addr;
args->spgw_args.sgi_if_addr = sgi_if_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; cout << endl <<"--- Software Radio Systems EPC ---" << endl << endl;
signal(SIGINT, sig_int_handler); signal(SIGINT, sig_int_handler);
signal(SIGTERM, sig_int_handler);
signal(SIGKILL, sig_int_handler);
all_args_t args; all_args_t args;
parse_args(&args, argc, argv); parse_args(&args, argc, argv);
@ -302,7 +312,7 @@ main (int argc,char * argv[] )
cout << "Error initializing MME" << endl; cout << "Error initializing MME" << endl;
exit(1); exit(1);
} }
hss *hss = hss::get_instance(); hss *hss = hss::get_instance();
if (hss->init(&args.hss_args,&hss_log)) { if (hss->init(&args.hss_args,&hss_log)) {
cout << "Error initializing HSS" << endl; cout << "Error initializing HSS" << endl;

@ -196,6 +196,7 @@ s1ap::enb_listen()
evnts.sctp_data_io_event = 1; evnts.sctp_data_io_event = 1;
evnts.sctp_shutdown_event=1; evnts.sctp_shutdown_event=1;
if(setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof (evnts))){ 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"); m_s1ap_log->console("Subscribing to sctp_data_io_events failed\n");
return -1; return -1;
} }
@ -207,6 +208,7 @@ s1ap::enb_listen()
s1mme_addr.sin_port = htons(S1MME_PORT); s1mme_addr.sin_port = htons(S1MME_PORT);
err = bind(sock_fd, (struct sockaddr*) &s1mme_addr, sizeof (s1mme_addr)); err = bind(sock_fd, (struct sockaddr*) &s1mme_addr, sizeof (s1mme_addr));
if (err != 0){ if (err != 0){
close(sock_fd);
m_s1ap_log->error("Error binding SCTP socket\n"); m_s1ap_log->error("Error binding SCTP socket\n");
m_s1ap_log->console("Error binding SCTP socket\n"); m_s1ap_log->console("Error binding SCTP socket\n");
return -1; return -1;
@ -215,6 +217,7 @@ s1ap::enb_listen()
//Listen for connections //Listen for connections
err = listen(sock_fd,SOMAXCONN); err = listen(sock_fd,SOMAXCONN);
if (err != 0){ if (err != 0){
close(sock_fd);
m_s1ap_log->error("Error in SCTP socket listen\n"); m_s1ap_log->error("Error in SCTP socket listen\n");
m_s1ap_log->console("Error in SCTP socket listen\n"); m_s1ap_log->console("Error in SCTP socket listen\n");
return -1; return -1;

@ -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 k_asme[32];
uint8_t autn[16]; uint8_t autn[16];
uint8_t rand[6]; uint8_t rand[16];
uint8_t xres[8]; uint8_t xres[8];
ue_ctx_t ue_ctx; 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); m_s1ap->add_new_ue_ctx(ue_ctx);
//Pack NAS Authentication Request in Downlink NAS Transport msg //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); pack_authentication_request(reply_buffer, ue_ctx.enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id, autn, rand);
//Send reply to eNB //Send reply to eNB
*reply_flag = true; *reply_flag = true;
m_s1ap_log->info("Downlink NAS: Sending Athentication Request\n"); 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; bool ue_valid=true;
m_s1ap_log->console("Authentication Response -- IMSI %015lu\n", ue_ctx->imsi); 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 //Get NAS authentication response
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &auth_resp); LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &auth_resp);
if(err != LIBLTE_SUCCESS){ if(err != LIBLTE_SUCCESS){
m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]); m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]);
return false; 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++) 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 Attached Complete Message\n");
m_s1ap_log->console("Unpacked Activavate Default EPS Bearer message. EPS Bearer id %d\n",act_bearer.eps_bearer_id); 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; //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"); m_s1ap_log->error("EPS Bearer ID out of range\n");
return false; 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) 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 autn[16];
uint8_t rand[6]; uint8_t rand[16];
uint8_t xres[8]; uint8_t xres[8];
LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp; 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); m_s1ap_log->info("User not found. IMSI %015lu\n",imsi);
return false; return false;
} }
//Pack NAS Authentication Request in Downlink NAS Transport msg //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); pack_authentication_request(reply_msg, ue_ctx->enb_ue_s1ap_id, ue_ctx->mme_ue_s1ap_id, autn, rand);

@ -177,7 +177,9 @@ spgw::init_sgi_if(spgw_args_t *args)
memset(&ifr, 0, sizeof(ifr)); memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI; ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ); strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ-1);
ifr.ifr_ifrn.ifrn_name[IFNAMSIZ-1]='\0';
if(ioctl(m_sgi_if, TUNSETIFF, &ifr) < 0) if(ioctl(m_sgi_if, TUNSETIFF, &ifr) < 0)
{ {
m_spgw_log->error("Failed to set TUN device name: %s\n", strerror(errno)); m_spgw_log->error("Failed to set TUN device name: %s\n", strerror(errno));

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

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

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save