UE itf working until SIB1 decoding

master
ismagom 10 years ago
parent 50babae358
commit 53171b1b8e

@ -208,7 +208,7 @@ int main(int argc, char **argv) {
/* Initialize subframe counter */ /* Initialize subframe counter */
sf_cnt = 0; sf_cnt = 0;
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initiating FFT\n"); fprintf(stderr, "Error initiating FFT\n");
return -1; return -1;
} }
@ -280,7 +280,7 @@ int main(int argc, char **argv) {
if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) {
/* Run FFT for all subframe data */ /* Run FFT for all subframe data */
srslte_ofdm_tx_sf(&fft, sf_buffer, sf_symbols); srslte_ofdm_rx_sf(&fft, sf_buffer, sf_symbols);
srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync)); srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync));

@ -215,7 +215,7 @@ void base_init() {
} }
/* create ifft object */ /* create ifft object */
if (srslte_ofdm_rx_init(&ifft, SRSLTE_CP_NORM, cell.nof_prb)) { if (srslte_ofdm_tx_init(&ifft, SRSLTE_CP_NORM, cell.nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n"); fprintf(stderr, "Error creating iFFT object\n");
exit(-1); exit(-1);
} }
@ -266,7 +266,7 @@ void base_free() {
srslte_regs_free(&regs); srslte_regs_free(&regs);
srslte_pbch_free(&pbch); srslte_pbch_free(&pbch);
srslte_ofdm_rx_free(&ifft); srslte_ofdm_tx_free(&ifft);
if (sf_buffer) { if (sf_buffer) {
free(sf_buffer); free(sf_buffer);
@ -586,7 +586,7 @@ int main(int argc, char **argv) {
} }
/* Transform to OFDM symbols */ /* Transform to OFDM symbols */
srslte_ofdm_rx_sf(&ifft, sf_buffer, output_buffer); srslte_ofdm_tx_sf(&ifft, sf_buffer, output_buffer);
float norm_factor = (float) cell.nof_prb/15/sqrtf(ra_dl.prb_alloc.slot[0].nof_prb); float norm_factor = (float) cell.nof_prb/15/sqrtf(ra_dl.prb_alloc.slot[0].nof_prb);
srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb)); srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));

@ -389,7 +389,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} else if (n == SRSLTE_UE_MIB_FOUND) { } else if (n == SRSLTE_UE_MIB_FOUND) {
srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); srslte_pbch_mib_unpack(bch_payload, &cell, &sfn);
srslte_pbch_mib_fprint(stdout, &cell, sfn, cell.id); srslte_pbch_mib_fprint(stdout, &cell, sfn);
printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset); printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset);
sfn = (sfn + sfn_offset)%1024; sfn = (sfn + sfn_offset)%1024;
state = DECODE_PDSCH; state = DECODE_PDSCH;

@ -459,7 +459,7 @@ int main(int argc, char **argv) {
if (state != RECV_RAR) { if (state != RECV_RAR) {
/* Run FFT for all subframe data */ /* Run FFT for all subframe data */
srslte_ofdm_tx_sf(&ue_dl.fft, sf_buffer, ue_dl.sf_symbols); srslte_ofdm_rx_sf(&ue_dl.fft, sf_buffer, ue_dl.sf_symbols);
/* Get channel estimates for each port */ /* Get channel estimates for each port */
srslte_chest_dl_estimate(&ue_dl.chest, ue_dl.sf_symbols, ue_dl.ce, srslte_ue_sync_get_sfidx(&ue_sync)); srslte_chest_dl_estimate(&ue_dl.chest, ue_dl.sf_symbols, ue_dl.ce, srslte_ue_sync_get_sfidx(&ue_sync));
@ -476,7 +476,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} else if (n == SRSLTE_UE_MIB_FOUND) { } else if (n == SRSLTE_UE_MIB_FOUND) {
srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); srslte_pbch_mib_unpack(bch_payload, &cell, &sfn);
srslte_pbch_mib_fprint(stdout, &cell, sfn, cell.id); srslte_pbch_mib_fprint(stdout, &cell, sfn);
printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset); printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset);
sfn = (sfn + sfn_offset)%1024; sfn = (sfn + sfn_offset)%1024;
state = SEND_PRACH; state = SEND_PRACH;

@ -178,7 +178,7 @@ int main(int argc, char **argv) {
} }
} }
if (decoded_mib && srslte_ue_sync_get_sfidx(&ue_sync) == 9 && sfn == 1023) { if (decoded_mib && srslte_ue_sync_get_sfidx(&ue_sync) == 9 && sfn == 1023) {
srslte_pbch_mib_fprint(stdout, &cell, sfn, cell.id); srslte_pbch_mib_fprint(stdout, &cell, sfn);
printf("Decoded MIB. SFN: %d\n", sfn); printf("Decoded MIB. SFN: %d\n", sfn);
state = SAVE_FILE; state = SAVE_FILE;
} }

@ -60,33 +60,33 @@ typedef struct SRSLTE_API{
cf_t *shift_buffer; cf_t *shift_buffer;
}srslte_ofdm_t; }srslte_ofdm_t;
SRSLTE_API int srslte_ofdm_tx_init(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_rx_init(srslte_ofdm_t *q,
srslte_cp_t cp_type, srslte_cp_t cp_type,
uint32_t nof_prb); uint32_t nof_prb);
SRSLTE_API void srslte_ofdm_tx_free(srslte_ofdm_t *q); SRSLTE_API void srslte_ofdm_rx_free(srslte_ofdm_t *q);
SRSLTE_API void srslte_ofdm_tx_slot(srslte_ofdm_t *q, SRSLTE_API void srslte_ofdm_rx_slot(srslte_ofdm_t *q,
cf_t *input, cf_t *input,
cf_t *output); cf_t *output);
SRSLTE_API void srslte_ofdm_tx_sf(srslte_ofdm_t *q, SRSLTE_API void srslte_ofdm_rx_sf(srslte_ofdm_t *q,
cf_t *input, cf_t *input,
cf_t *output); cf_t *output);
SRSLTE_API int srslte_ofdm_rx_init(srslte_ofdm_t *q, SRSLTE_API int srslte_ofdm_tx_init(srslte_ofdm_t *q,
srslte_cp_t cp_type, srslte_cp_t cp_type,
uint32_t nof_prb); uint32_t nof_prb);
SRSLTE_API void srslte_ofdm_rx_free(srslte_ofdm_t *q); SRSLTE_API void srslte_ofdm_tx_free(srslte_ofdm_t *q);
SRSLTE_API void srslte_ofdm_rx_slot(srslte_ofdm_t *q, SRSLTE_API void srslte_ofdm_tx_slot(srslte_ofdm_t *q,
cf_t *input, cf_t *input,
cf_t *output); cf_t *output);
SRSLTE_API void srslte_ofdm_rx_sf(srslte_ofdm_t *q, SRSLTE_API void srslte_ofdm_tx_sf(srslte_ofdm_t *q,
cf_t *input, cf_t *input,
cf_t *output); cf_t *output);

@ -84,34 +84,33 @@ typedef struct SRSLTE_API {
} srslte_pbch_t; } srslte_pbch_t;
SRSLTE_API int srslte_pbch_init(srslte_pbch_t *q, SRSLTE_API int srslte_pbch_init(srslte_pbch_t *q,
srslte_cell_t cell); srslte_cell_t cell);
SRSLTE_API void srslte_pbch_free(srslte_pbch_t *q); SRSLTE_API void srslte_pbch_free(srslte_pbch_t *q);
SRSLTE_API int srslte_pbch_decode(srslte_pbch_t *q, SRSLTE_API int srslte_pbch_decode(srslte_pbch_t *q,
cf_t *slot1_symbols, cf_t *slot1_symbols,
cf_t *ce_slot1[SRSLTE_MAX_PORTS], cf_t *ce_slot1[SRSLTE_MAX_PORTS],
float noise_estimate, float noise_estimate,
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN], uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN],
uint32_t *nof_tx_ports, uint32_t *nof_tx_ports,
uint32_t *sfn_offset); uint32_t *sfn_offset);
SRSLTE_API int srslte_pbch_encode(srslte_pbch_t *q, SRSLTE_API int srslte_pbch_encode(srslte_pbch_t *q,
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN], uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN],
cf_t *slot1_symbols[SRSLTE_MAX_PORTS]); cf_t *slot1_symbols[SRSLTE_MAX_PORTS]);
SRSLTE_API void srslte_pbch_decode_reset(srslte_pbch_t *q); SRSLTE_API void srslte_pbch_decode_reset(srslte_pbch_t *q);
SRSLTE_API void srslte_pbch_mib_unpack(uint8_t *msg, SRSLTE_API void srslte_pbch_mib_unpack(uint8_t *msg,
srslte_cell_t *cell, srslte_cell_t *cell,
uint32_t *sfn); uint32_t *sfn);
SRSLTE_API void srslte_pbch_mib_pack(srslte_cell_t *cell, SRSLTE_API void srslte_pbch_mib_pack(srslte_cell_t *cell,
uint32_t sfn, uint32_t sfn,
uint8_t *msg); uint8_t *msg);
SRSLTE_API void srslte_pbch_mib_fprint(FILE *stream, SRSLTE_API void srslte_pbch_mib_fprint(FILE *stream,
srslte_cell_t *cell, srslte_cell_t *cell,
uint32_t sfn, uint32_t sfn);
uint32_t cell_id);
#endif // PBCH_ #endif // PBCH_

@ -59,9 +59,11 @@ namespace ue {
PDCCH_DL_SEARCH_SPS PDCCH_DL_SEARCH_SPS
} pdcch_dl_search_t; } pdcch_dl_search_t;
int buffer_id;
bool init_cell(srslte_cell_t cell, params *params_db); bool init_cell(srslte_cell_t cell, params *params_db);
void free_cell(); void free_cell();
bool recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time); bool recv_ue_sync(uint32_t current_tti, srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time);
bool get_ul_grant(pdcch_ul_search_t mode, uint32_t rnti, sched_grant *grant); bool get_ul_grant(pdcch_ul_search_t mode, uint32_t rnti, sched_grant *grant);
bool get_dl_grant(pdcch_dl_search_t mode, uint32_t rnti, sched_grant *grant); bool get_dl_grant(pdcch_dl_search_t mode, uint32_t rnti, sched_grant *grant);
bool decode_phich(srslte_phich_alloc_t assignment); bool decode_phich(srslte_phich_alloc_t assignment);

@ -42,8 +42,7 @@ namespace ue {
CELLSEARCH_TIMEOUT_PSS_NFRAMES, CELLSEARCH_TIMEOUT_PSS_NFRAMES,
CELLSEARCH_TIMEOUT_MIB_NFRAMES, CELLSEARCH_TIMEOUT_MIB_NFRAMES,
CELLSEARCH_FORCE_N_ID_2, CELLSEARCH_TIMEOUT_PSS_CORRELATION_THRESHOLD, // integer that will be divided by 10
CELLSEARCH_CORRELATION_THRESHOLD, // integer that will be divided by 10
PUSCH_BETA, PUSCH_BETA,

@ -43,35 +43,62 @@
namespace srslte { namespace srslte {
namespace ue { namespace ue {
/* The procedure for attaching to an eNodeB is the following:
*
* 1) Call init() to initialize the PHY (starts an internal thread)
* 2) Call set_rx_freq() and set_rx_gain() to set Downlink frequency and receiver gain
* 3) Call decode_mib() to receive and decode MIB from PBCH in the current frequency
* 4) Call set_cell() to set the current eNodeB
* 5) Call start_rxtx() to start continuous RX/TX stream
* 6) Call set_tx_freq()/set_tx_gain() to set Uplink frequency and transmitter gain
* 7) Call send_prach() to send the PRACH
*
*/
typedef _Complex float cf_t; typedef _Complex float cf_t;
class SRSLTE_API phy class SRSLTE_API phy
{ {
public: public:
#if SYNC_MODE==SYNC_MODE_CALLBACK typedef void (*ue_phy_callback_tti_t) (uint32_t);
typedef void (*ue_phy_callback_t) (void); typedef void (*ue_phy_callback_status_t) (void);
ue_phy_callback_t tti_clock_callback; ue_phy_callback_tti_t tti_clock_callback;
ue_phy_callback_t status_change; ue_phy_callback_status_t status_change;
phy(ue_phy_callback_t tti_clock_callback, ue_phy_callback_t status_change); bool init(ue_phy_callback_tti_t tti_clock_callback, ue_phy_callback_status_t status_change);
#else void stop();
phy();
#endif // These functions can be called only if PHY is in IDLE (ie, not RX/TX)
~phy(); bool measure(); // TBD
bool decode_mib(uint32_t N_id_2, srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]);
bool decode_mib_best(srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]);
bool set_cell(srslte_cell_t cell);
void measure(); // TBD // Sets the PHY in continuous RX/TX mode
void dl_bch(); bool start_rxtx();
void start_rxtx(); bool stop_rxtx();
void stop_rxtx();
void send_prach(uint32_t preamble_idx); // Indicate the PHY to send PRACH as soon as possible
bool send_prach(uint32_t preamble_idx);
// Control USRP freq/gain
void set_tx_gain(float gain);
void set_rx_gain(float gain);
void set_tx_freq(float freq);
void set_rx_freq(float freq);
// Get status
bool status_is_idle(); bool status_is_idle();
bool status_is_rxtx(); bool status_is_rxtx();
bool status_is_bch_decoded(uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]);
void set_param(params::param_t param, int64_t value);
uint32_t get_tti(); uint32_t get_current_tti();
#if SYNC_MODE==SYNC_MODE_CV static uint32_t tti_to_SFN(uint32_t tti);
static uint32_t tti_to_subf(uint32_t tti);
#if SYNC_MODE==SYNC_MODE_CV
std::condition_variable tti_cv; std::condition_variable tti_cv;
std::mutex tti_mutex; std::mutex tti_mutex;
#endif #endif
@ -83,14 +110,14 @@ public:
private: private:
enum { enum {
IDLE, MEASURE, RX_BCH, MIB_DECODED, RXTX IDLE, RXTX
} phy_state; } phy_state;
srslte_cell_t cell; srslte_cell_t cell;
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; bool cell_is_set;
bool is_sfn_synched = false; bool is_sfn_synched = false;
bool started = false; bool started = false;
uint32_t current_tti; uint32_t current_tti;
srslte_ue_sync_t ue_sync; srslte_ue_sync_t ue_sync;
srslte_ue_mib_t ue_mib; srslte_ue_mib_t ue_mib;
@ -103,10 +130,11 @@ private:
pthread_t radio_thread; pthread_t radio_thread;
void *radio_handler; void *radio_handler;
static void *radio_thread_fnc(void *arg); static void *radio_thread_fnc(void *arg);
void run_rx_bch_state(); bool decode_mib_N_id_2(int force_N_id_2, srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]);
bool rx_bch();
int sync_sfn(); int sync_sfn();
void run_rx_tx_state(); void run_rx_tx_state();
bool init_radio_handler(char *args);
}; };
} }

@ -43,7 +43,7 @@ namespace ue {
bool is_ready_to_send(uint32_t current_tti); bool is_ready_to_send(uint32_t current_tti);
bool send(void *radio_handler, srslte_timestamp_t rx_time); bool send(void *radio_handler, srslte_timestamp_t rx_time);
private: private:
params *params_db; params *params_db = NULL;
int preamble_idx; int preamble_idx;
bool initiated = false; bool initiated = false;
uint32_t len; uint32_t len;

@ -50,6 +50,7 @@ namespace ue {
bool is_uplink(); bool is_uplink();
bool is_downlink(); bool is_downlink();
void* get_grant_ptr(); void* get_grant_ptr();
uint32_t get_tbs();
protected: protected:
union { union {
srslte_ra_pusch_t ul_grant; srslte_ra_pusch_t ul_grant;

@ -41,6 +41,7 @@ namespace ue {
* for transmission. The MAC must call generate_pusch() to set the packet ready for transmission * for transmission. The MAC must call generate_pusch() to set the packet ready for transmission
*/ */
class SRSLTE_API ul_buffer : public queue::element { class SRSLTE_API ul_buffer : public queue::element {
public: public:
bool init_cell(srslte_cell_t cell, params *params_db); bool init_cell(srslte_cell_t cell, params *params_db);
void free_cell(); void free_cell();
@ -49,11 +50,13 @@ namespace ue {
bool generate_pusch(sched_grant pusch_grant, uint8_t *payload, srslte_uci_data_t uci_data); bool generate_pusch(sched_grant pusch_grant, uint8_t *payload, srslte_uci_data_t uci_data);
bool generate_pucch(srslte_uci_data_t uci_data); bool generate_pucch(srslte_uci_data_t uci_data);
bool send_packet(void *radio_handler, srslte_timestamp_t rx_time); bool send_packet(void *radio_handler, srslte_timestamp_t rx_time);
private: private:
params *params_db; params *params_db;
srslte_cell_t cell; srslte_cell_t cell;
srslte_ue_ul_t ue_ul; srslte_ue_ul_t ue_ul;
bool signal_generated; bool signal_generated;
bool cell_initiated;
cf_t* signal_buffer; cf_t* signal_buffer;
uint32_t tti; uint32_t tti;
uint32_t current_tx_nb; uint32_t current_tx_nb;

@ -78,19 +78,23 @@ FOREACH (_file ${cmakefiles})
ENDFOREACH() ENDFOREACH()
######################################################################## ########################################################################
# Create C++ library # Create C++ library only if UHD is found
######################################################################## ########################################################################
FILE(GLOB modules *) LIST(FIND OPTIONAL_LIBS cuhd CUHD_FIND)
SET(SOURCES_CPP_ALL "") IF(${CUHD_FIND} GREATER -1)
FOREACH (_module ${modules})
IF(IS_DIRECTORY ${_module}) FILE(GLOB modules *)
FILE(GLOB_RECURSE tmp "${_module}/src/*.cc") SET(SOURCES_CPP_ALL "")
LIST(APPEND SOURCES_CPP_ALL ${tmp}) FOREACH (_module ${modules})
ENDIF(IS_DIRECTORY ${_module}) IF(IS_DIRECTORY ${_module})
ENDFOREACH() FILE(GLOB_RECURSE tmp "${_module}/src/*.cc")
LIST(APPEND SOURCES_CPP_ALL ${tmp})
ENDIF(IS_DIRECTORY ${_module})
ENDFOREACH()
ADD_LIBRARY(srslte++ SHARED ${SOURCES_CPP_ALL}) ADD_LIBRARY(srslte++ SHARED ${SOURCES_CPP_ALL})
TARGET_LINK_LIBRARIES(srslte++ srslte m pthread ${FFTW3F_LIBRARIES}) TARGET_LINK_LIBRARIES(srslte++ cuhd srslte m pthread ${FFTW3F_LIBRARIES})
INSTALL(TARGETS srslte++ DESTINATION ${LIBRARY_DIR}) INSTALL(TARGETS srslte++ DESTINATION ${LIBRARY_DIR})
LIBLTE_SET_PIC(srslte++) LIBLTE_SET_PIC(srslte++)
ENDIF(${CUHD_FIND} GREATER -1)

@ -37,7 +37,7 @@
#include "srslte/utils/debug.h" #include "srslte/utils/debug.h"
#include "srslte/utils/vector.h" #include "srslte/utils/vector.h"
int srslte_ofdm_tx_init_(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb, srslte_dft_dir_t dir) { int srslte_ofdm_init_(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb, srslte_dft_dir_t dir) {
int symbol_sz = srslte_symbol_sz(nof_prb); int symbol_sz = srslte_symbol_sz(nof_prb);
if (symbol_sz < 0) { if (symbol_sz < 0) {
@ -84,19 +84,19 @@ void srslte_ofdm_free_(srslte_ofdm_t *q) {
bzero(q, sizeof(srslte_ofdm_t)); bzero(q, sizeof(srslte_ofdm_t));
} }
int srslte_ofdm_tx_init(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb) { int srslte_ofdm_rx_init(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb) {
return srslte_ofdm_tx_init_(q, cp, nof_prb, SRSLTE_DFT_FORWARD); return srslte_ofdm_init_(q, cp, nof_prb, SRSLTE_DFT_FORWARD);
} }
void srslte_ofdm_tx_free(srslte_ofdm_t *q) { void srslte_ofdm_rx_free(srslte_ofdm_t *q) {
srslte_ofdm_free_(q); srslte_ofdm_free_(q);
} }
int srslte_ofdm_rx_init(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb) { int srslte_ofdm_tx_init(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb) {
uint32_t i; uint32_t i;
int ret; int ret;
ret = srslte_ofdm_tx_init_(q, cp, nof_prb, SRSLTE_DFT_BACKWARD); ret = srslte_ofdm_init_(q, cp, nof_prb, SRSLTE_DFT_BACKWARD);
if (ret == SRSLTE_SUCCESS) { if (ret == SRSLTE_SUCCESS) {
srslte_dft_plan_set_norm(&q->fft_plan, true); srslte_dft_plan_set_norm(&q->fft_plan, true);
@ -139,14 +139,14 @@ int srslte_ofdm_set_freq_shift(srslte_ofdm_t *q, float freq_shift) {
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
void srslte_ofdm_rx_free(srslte_ofdm_t *q) { void srslte_ofdm_tx_free(srslte_ofdm_t *q) {
srslte_ofdm_free_(q); srslte_ofdm_free_(q);
} }
/* Transforms input samples into output OFDM symbols. /* Transforms input samples into output OFDM symbols.
* Performs FFT on a each symbol and removes CP. * Performs FFT on a each symbol and removes CP.
*/ */
void srslte_ofdm_tx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) { void srslte_ofdm_rx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
uint32_t i; uint32_t i;
for (i=0;i<q->nof_symbols;i++) { for (i=0;i<q->nof_symbols;i++) {
input += SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM(i, q->symbol_sz):SRSLTE_CP_EXT(q->symbol_sz); input += SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM(i, q->symbol_sz):SRSLTE_CP_EXT(q->symbol_sz);
@ -157,20 +157,20 @@ void srslte_ofdm_tx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
} }
} }
void srslte_ofdm_tx_sf(srslte_ofdm_t *q, cf_t *input, cf_t *output) { void srslte_ofdm_rx_sf(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
uint32_t n; uint32_t n;
if (q->freq_shift) { if (q->freq_shift) {
srslte_vec_prod_ccc(input, q->shift_buffer, input, 2*q->slot_sz); srslte_vec_prod_ccc(input, q->shift_buffer, input, 2*q->slot_sz);
} }
for (n=0;n<2;n++) { for (n=0;n<2;n++) {
srslte_ofdm_tx_slot(q, &input[n*q->slot_sz], &output[n*q->nof_re*q->nof_symbols]); srslte_ofdm_rx_slot(q, &input[n*q->slot_sz], &output[n*q->nof_re*q->nof_symbols]);
} }
} }
/* Transforms input OFDM symbols into output samples. /* Transforms input OFDM symbols into output samples.
* Performs FFT on a each symbol and adds CP. * Performs FFT on a each symbol and adds CP.
*/ */
void srslte_ofdm_rx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) { void srslte_ofdm_tx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
uint32_t i, cp_len; uint32_t i, cp_len;
for (i=0;i<q->nof_symbols;i++) { for (i=0;i<q->nof_symbols;i++) {
cp_len = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM(i, q->symbol_sz):SRSLTE_CP_EXT(q->symbol_sz); cp_len = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM(i, q->symbol_sz):SRSLTE_CP_EXT(q->symbol_sz);
@ -187,10 +187,10 @@ void srslte_ofdm_set_normalize(srslte_ofdm_t *q, bool normalize_enable) {
srslte_dft_plan_set_norm(&q->fft_plan, normalize_enable); srslte_dft_plan_set_norm(&q->fft_plan, normalize_enable);
} }
void srslte_ofdm_rx_sf(srslte_ofdm_t *q, cf_t *input, cf_t *output) { void srslte_ofdm_tx_sf(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
uint32_t n; uint32_t n;
for (n=0;n<2;n++) { for (n=0;n<2;n++) {
srslte_ofdm_rx_slot(q, &input[n*q->nof_re*q->nof_symbols], &output[n*q->slot_sz]); srslte_ofdm_tx_slot(q, &input[n*q->nof_re*q->nof_symbols], &output[n*q->slot_sz]);
} }
if (q->freq_shift) { if (q->freq_shift) {
srslte_vec_prod_ccc(output, q->shift_buffer, output, 2*q->slot_sz); srslte_vec_prod_ccc(output, q->shift_buffer, output, 2*q->slot_sz);

@ -98,13 +98,13 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (srslte_ofdm_tx_init(&fft, cp, n_prb)) { if (srslte_ofdm_rx_init(&fft, cp, n_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
exit(-1); exit(-1);
} }
srslte_dft_plan_set_norm(&fft.fft_plan, true); srslte_dft_plan_set_norm(&fft.fft_plan, true);
if (srslte_ofdm_rx_init(&ifft, cp, n_prb)) { if (srslte_ofdm_tx_init(&ifft, cp, n_prb)) {
fprintf(stderr, "Error initializing iFFT\n"); fprintf(stderr, "Error initializing iFFT\n");
exit(-1); exit(-1);
} }
@ -114,8 +114,8 @@ int main(int argc, char **argv) {
input[i] = 100 * ((float) rand()/RAND_MAX + (float) I*rand()/RAND_MAX); input[i] = 100 * ((float) rand()/RAND_MAX + (float) I*rand()/RAND_MAX);
} }
srslte_ofdm_rx_slot(&ifft, input, outfft); srslte_ofdm_tx_slot(&ifft, input, outfft);
srslte_ofdm_tx_slot(&fft, outfft, outifft); srslte_ofdm_rx_slot(&fft, outfft, outifft);
/* compute MSE */ /* compute MSE */
@ -130,8 +130,8 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_ofdm_rx_free(&ifft); srslte_ofdm_tx_free(&ifft);
free(input); free(input);
free(outfft); free(outfft);

@ -329,8 +329,8 @@ void srslte_pbch_mib_pack(srslte_cell_t *cell, uint32_t sfn, uint8_t *msg) {
srslte_bit_pack(sfn >> 2, &msg, 8); srslte_bit_pack(sfn >> 2, &msg, 8);
} }
void srslte_pbch_mib_fprint(FILE *stream, srslte_cell_t *cell, uint32_t sfn, uint32_t cell_id) { void srslte_pbch_mib_fprint(FILE *stream, srslte_cell_t *cell, uint32_t sfn) {
printf(" - Cell ID: %d\n", cell_id); printf(" - Cell ID: %d\n", cell->id);
printf(" - Nof ports: %d\n", cell->nof_ports); printf(" - Nof ports: %d\n", cell->nof_ports);
printf(" - PRB: %d\n", cell->nof_prb); printf(" - PRB: %d\n", cell->nof_prb);
printf(" - PHICH Length: %s\n", printf(" - PHICH Length: %s\n",

@ -242,7 +242,7 @@ int srslte_prach_gen_seqs(srslte_prach_t *p)
}else{ }else{
u = prach_zc_roots[(p->rsi + p->N_roots)%838]; u = prach_zc_roots[(p->rsi + p->N_roots)%838];
} }
printf("Seq#%d, u: %3d (rsi: %d, n_roots: %d\n", i, u, p->rsi, p->N_roots);
for(int j=0;j<p->N_zc;j++){ for(int j=0;j<p->N_zc;j++){
double phase = -M_PI*u*j*(j+1)/p->N_zc; double phase = -M_PI*u*j*(j+1)/p->N_zc;
root[j] = cexp(phase*I); root[j] = cexp(phase*I);

@ -138,7 +138,7 @@ int base_init() {
return -1; return -1;
} }
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return -1; return -1;
} }
@ -165,7 +165,7 @@ void base_free() {
free(ce[i]); free(ce[i]);
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_pbch_free(&pbch); srslte_pbch_free(&pbch);
} }
@ -196,7 +196,7 @@ int main(int argc, char **argv) {
if (nread > 0) { if (nread > 0) {
// process 1st subframe only // process 1st subframe only
srslte_ofdm_tx_sf(&fft, input_buffer, fft_buffer); srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer);
/* 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);

@ -81,7 +81,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return; return;
} }
@ -91,7 +91,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
srslte_ofdm_tx_sf(&fft, input_symbols, input_fft); srslte_ofdm_rx_sf(&fft, input_symbols, input_fft);
if (nrhs > NOF_INPUTS) { if (nrhs > NOF_INPUTS) {
cf_t *cearray; cf_t *cearray;
@ -148,7 +148,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_pbch_free(&pbch); srslte_pbch_free(&pbch);
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {

@ -149,7 +149,7 @@ int base_init() {
return -1; return -1;
} }
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return -1; return -1;
} }
@ -184,7 +184,7 @@ void base_free() {
free(ce[i]); free(ce[i]);
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_pcfich_free(&pcfich); srslte_pcfich_free(&pcfich);
srslte_regs_free(&regs); srslte_regs_free(&regs);
@ -209,7 +209,7 @@ int main(int argc, char **argv) {
n = srslte_filesource_read(&fsrc, input_buffer, flen); n = srslte_filesource_read(&fsrc, input_buffer, flen);
srslte_ofdm_tx_sf(&fft, input_buffer, fft_buffer); srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer);
if (fmatlab) { if (fmatlab) {
fprintf(fmatlab, "infft="); fprintf(fmatlab, "infft=");

@ -74,7 +74,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
mexErrMsgTxt("Error initializing FFT\n"); mexErrMsgTxt("Error initializing FFT\n");
return; return;
} }
@ -102,7 +102,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
} }
srslte_ofdm_tx_sf(&fft, input_signal, input_fft); srslte_ofdm_rx_sf(&fft, input_signal, input_fft);
if (nrhs > NOF_INPUTS) { if (nrhs > NOF_INPUTS) {
cf_t *cearray; cf_t *cearray;
@ -143,7 +143,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_pcfich_free(&pcfich); srslte_pcfich_free(&pcfich);
srslte_regs_free(&regs); srslte_regs_free(&regs);

@ -157,7 +157,7 @@ int base_init() {
return -1; return -1;
} }
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return -1; return -1;
} }
@ -193,7 +193,7 @@ void base_free() {
free(ce[i]); free(ce[i]);
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_pdcch_free(&pdcch); srslte_pdcch_free(&pdcch);
srslte_regs_free(&regs); srslte_regs_free(&regs);
@ -227,7 +227,7 @@ int main(int argc, char **argv) {
INFO("Reading %d samples sub-frame %d\n", flen, frame_cnt); INFO("Reading %d samples sub-frame %d\n", flen, frame_cnt);
srslte_ofdm_tx_sf(&fft, input_buffer, fft_buffer); srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer);
/* Get channel estimates for each port */ /* Get channel estimates for each port */
srslte_chest_dl_estimate(&chest, fft_buffer, ce, frame_cnt %10); srslte_chest_dl_estimate(&chest, fft_buffer, ce, frame_cnt %10);

@ -94,7 +94,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return; return;
} }
@ -129,7 +129,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
} }
srslte_ofdm_tx_sf(&fft, input_signal, input_fft); srslte_ofdm_rx_sf(&fft, input_signal, input_fft);
if (nrhs > NOF_INPUTS) { if (nrhs > NOF_INPUTS) {
cf_t *cearray; cf_t *cearray;
@ -187,7 +187,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_pdcch_free(&pdcch); srslte_pdcch_free(&pdcch);
srslte_regs_free(&regs); srslte_regs_free(&regs);

@ -166,7 +166,7 @@ int base_init() {
return -1; return -1;
} }
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return -1; return -1;
} }
@ -214,7 +214,7 @@ void base_free() {
free(ce[i]); free(ce[i]);
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_pdcch_free(&pdcch); srslte_pdcch_free(&pdcch);
srslte_pdsch_free(&pdsch); srslte_pdsch_free(&pdsch);
@ -257,7 +257,7 @@ int main(int argc, char **argv) {
srslte_filesource_read(&fsrc, input_buffer, flen); srslte_filesource_read(&fsrc, input_buffer, flen);
INFO("Reading %d samples sub-frame %d\n", flen, sf_idx); INFO("Reading %d samples sub-frame %d\n", flen, sf_idx);
srslte_ofdm_tx_sf(&fft, input_buffer, fft_buffer); srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer);
/* Get channel estimates for each port */ /* Get channel estimates for each port */
srslte_chest_dl_estimate(&chest, fft_buffer, ce, sf_idx); srslte_chest_dl_estimate(&chest, fft_buffer, ce, sf_idx);

@ -103,7 +103,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
mexErrMsgTxt("Error initializing FFT\n"); mexErrMsgTxt("Error initializing FFT\n");
return; return;
} }
@ -180,7 +180,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
} }
srslte_ofdm_tx_sf(&fft, input_signal, input_fft); srslte_ofdm_rx_sf(&fft, input_signal, input_fft);
if (nrhs > NOF_INPUTS) { if (nrhs > NOF_INPUTS) {
cf_t *cearray = NULL; cf_t *cearray = NULL;
@ -229,7 +229,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_pdsch_free(&pdsch); srslte_pdsch_free(&pdsch);
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {

@ -172,7 +172,7 @@ int base_init() {
return -1; return -1;
} }
if (srslte_ofdm_tx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return -1; return -1;
} }
@ -207,7 +207,7 @@ void base_free() {
free(ce[i]); free(ce[i]);
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_tx_free(&fft); srslte_ofdm_rx_free(&fft);
srslte_phich_free(&phich); srslte_phich_free(&phich);
srslte_regs_free(&regs); srslte_regs_free(&regs);
@ -235,7 +235,7 @@ int main(int argc, char **argv) {
n = srslte_filesource_read(&fsrc, input_buffer, flen); n = srslte_filesource_read(&fsrc, input_buffer, flen);
srslte_ofdm_tx_sf(&fft, input_buffer, fft_buffer); srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer);
if (fmatlab) { if (fmatlab) {
fprintf(fmatlab, "infft="); fprintf(fmatlab, "infft=");

@ -195,10 +195,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
srslte_ofdm_t fft; srslte_ofdm_t fft;
srslte_ofdm_rx_init(&fft, SRSLTE_CP_NORM, cell.nof_prb); srslte_ofdm_tx_init(&fft, SRSLTE_CP_NORM, cell.nof_prb);
srslte_ofdm_set_normalize(&fft, true); srslte_ofdm_set_normalize(&fft, true);
srslte_ofdm_set_freq_shift(&fft, 0.5); srslte_ofdm_set_freq_shift(&fft, 0.5);
srslte_ofdm_rx_sf(&fft, sf_symbols, scfdma); srslte_ofdm_tx_sf(&fft, sf_symbols, scfdma);
// Matlab toolbox expects further normalization // Matlab toolbox expects further normalization
srslte_vec_sc_prod_cfc(scfdma, 1.0/sqrtf(srslte_symbol_sz(cell.nof_prb)), scfdma, SRSLTE_SF_LEN_PRB(cell.nof_prb)); srslte_vec_sc_prod_cfc(scfdma, 1.0/sqrtf(srslte_symbol_sz(cell.nof_prb)), scfdma, SRSLTE_SF_LEN_PRB(cell.nof_prb));

@ -237,9 +237,9 @@ int main(int argc, char **argv) {
cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
srslte_ofdm_t fft; srslte_ofdm_t fft;
srslte_ofdm_rx_init(&fft, SRSLTE_CP_NORM, cell.nof_prb); srslte_ofdm_tx_init(&fft, SRSLTE_CP_NORM, cell.nof_prb);
srslte_ofdm_set_freq_shift(&fft, 0.5); srslte_ofdm_set_freq_shift(&fft, 0.5);
srslte_ofdm_rx_sf(&fft, sf_symbols, scfdma); srslte_ofdm_tx_sf(&fft, sf_symbols, scfdma);
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
//int r = srslte_pusch_decode(&pusch, slot_symbols[0], ce, 0, data, subframe, &harq_process, rv); //int r = srslte_pusch_decode(&pusch, slot_symbols[0], ce, 0, data, subframe, &harq_process, rv);

@ -110,7 +110,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (srslte_ofdm_rx_init(&ifft, cp, nof_prb)) { if (srslte_ofdm_tx_init(&ifft, cp, nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n"); fprintf(stderr, "Error creating iFFT object\n");
exit(-1); exit(-1);
} }
@ -147,7 +147,7 @@ int main(int argc, char **argv) {
/* Transform to OFDM symbols */ /* Transform to OFDM symbols */
memset(fft_buffer, 0, sizeof(cf_t) * FLEN); memset(fft_buffer, 0, sizeof(cf_t) * FLEN);
srslte_ofdm_rx_slot(&ifft, buffer, &fft_buffer[offset]); srslte_ofdm_tx_slot(&ifft, buffer, &fft_buffer[offset]);
if (srslte_sync_find(&sync, fft_buffer, 0, &find_idx) < 0) { if (srslte_sync_find(&sync, fft_buffer, 0, &find_idx) < 0) {
fprintf(stderr, "Error running srslte_sync_find\n"); fprintf(stderr, "Error running srslte_sync_find\n");
@ -176,7 +176,7 @@ int main(int argc, char **argv) {
free(buffer); free(buffer);
srslte_sync_free(&sync); srslte_sync_free(&sync);
srslte_ofdm_rx_free(&ifft); srslte_ofdm_tx_free(&ifft);
printf("Ok\n"); printf("Ok\n");
exit(0); exit(0);

@ -258,13 +258,6 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, uint32_t N_id_2
nof_detected_frames < 4) && nof_detected_frames < 4) &&
nof_scanned_frames < q->nof_frames_to_scan); nof_scanned_frames < q->nof_frames_to_scan);
/*
srslte_vec_save_file("sss_corr",tmp_sss_corr, nof_detected_frames*sizeof(float)*31);
srslte_vec_save_file("track_corr",tmp_pss_corr, nof_detected_frames*sizeof(float)*32);
srslte_vec_save_file("find_corr",q->ue_sync.sfind.pss.conv_output_avg,
sizeof(float)*(9600+127));
*/
/* In either case, check if the mean PSR is above the minimum threshold */ /* In either case, check if the mean PSR is above the minimum threshold */
if (nof_detected_frames > 0) { if (nof_detected_frames > 0) {
ret = 1; // A cell has been found. ret = 1; // A cell has been found.

@ -54,7 +54,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q,
q->pkt_errors = 0; q->pkt_errors = 0;
q->pkts_total = 0; q->pkts_total = 0;
if (srslte_ofdm_tx_init(&q->fft, q->cell.cp, q->cell.nof_prb)) { if (srslte_ofdm_rx_init(&q->fft, q->cell.cp, q->cell.nof_prb)) {
fprintf(stderr, "Error initiating FFT\n"); fprintf(stderr, "Error initiating FFT\n");
goto clean_exit; goto clean_exit;
} }
@ -114,7 +114,7 @@ clean_exit:
void srslte_ue_dl_free(srslte_ue_dl_t *q) { void srslte_ue_dl_free(srslte_ue_dl_t *q) {
if (q) { if (q) {
srslte_ofdm_tx_free(&q->fft); srslte_ofdm_rx_free(&q->fft);
srslte_chest_dl_free(&q->chest); srslte_chest_dl_free(&q->chest);
srslte_regs_free(&q->regs); srslte_regs_free(&q->regs);
srslte_pcfich_free(&q->pcfich); srslte_pcfich_free(&q->pcfich);
@ -176,7 +176,7 @@ int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input, uint32_t sf
if (input && q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { if (input && q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) {
/* Run FFT for all subframe data */ /* Run FFT for all subframe data */
srslte_ofdm_tx_sf(&q->fft, input, q->sf_symbols); srslte_ofdm_rx_sf(&q->fft, input, q->sf_symbols);
/* Get channel estimates for each port */ /* Get channel estimates for each port */
srslte_chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, sf_idx); srslte_chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, sf_idx);

@ -62,7 +62,7 @@ int srslte_ue_mib_init(srslte_ue_mib_t * q,
} }
} }
if (srslte_ofdm_tx_init(&q->fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&q->fft, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
goto clean_exit; goto clean_exit;
} }
@ -99,7 +99,7 @@ void srslte_ue_mib_free(srslte_ue_mib_t * q)
srslte_sync_free(&q->sfind); srslte_sync_free(&q->sfind);
srslte_chest_dl_free(&q->chest); srslte_chest_dl_free(&q->chest);
srslte_pbch_free(&q->pbch); srslte_pbch_free(&q->pbch);
srslte_ofdm_tx_free(&q->fft); srslte_ofdm_rx_free(&q->fft);
bzero(q, sizeof(srslte_ue_mib_t)); bzero(q, sizeof(srslte_ue_mib_t));
@ -119,7 +119,7 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input,
cf_t *ce_slot1[SRSLTE_MAX_PORTS]; cf_t *ce_slot1[SRSLTE_MAX_PORTS];
/* Run FFT for the slot symbols */ /* Run FFT for the slot symbols */
srslte_ofdm_tx_sf(&q->fft, input, q->sf_symbols); srslte_ofdm_rx_sf(&q->fft, input, q->sf_symbols);
/* Get channel estimates of sf idx #0 for each port */ /* Get channel estimates of sf idx #0 for each port */
ret = srslte_chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, 0); ret = srslte_chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, 0);

@ -52,7 +52,7 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q,
q->cell = cell; q->cell = cell;
if (srslte_ofdm_rx_init(&q->fft, q->cell.cp, q->cell.nof_prb)) { if (srslte_ofdm_tx_init(&q->fft, q->cell.cp, q->cell.nof_prb)) {
fprintf(stderr, "Error initiating FFT\n"); fprintf(stderr, "Error initiating FFT\n");
goto clean_exit; goto clean_exit;
} }
@ -106,7 +106,7 @@ clean_exit:
void srslte_ue_ul_free(srslte_ue_ul_t *q) { void srslte_ue_ul_free(srslte_ue_ul_t *q) {
if (q) { if (q) {
srslte_ofdm_tx_free(&q->fft); srslte_ofdm_rx_free(&q->fft);
srslte_pusch_free(&q->pusch); srslte_pusch_free(&q->pusch);
for (uint32_t i=0;i<SRSLTE_UE_UL_NOF_HARQ_PROCESSES; i++) { for (uint32_t i=0;i<SRSLTE_UE_UL_NOF_HARQ_PROCESSES; i++) {
srslte_harq_free(&q->harq_process[i]); srslte_harq_free(&q->harq_process[i]);
@ -212,7 +212,7 @@ int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, srslte_ra_pusch_t *ra_
q->harq_process[0].ul_alloc.n_prb_tilde, q->harq_process[0].ul_alloc.n_prb_tilde,
q->sf_symbols); q->sf_symbols);
srslte_ofdm_rx_sf(&q->fft, q->sf_symbols, output_signal); srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal);
//srslte_cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / srslte_symbol_sz(q->cell.nof_prb)); //srslte_cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / srslte_symbol_sz(q->cell.nof_prb));

@ -46,7 +46,7 @@ bool dl_buffer::init_cell(srslte_cell_t cell_, params *params_db_)
sf_symbols_and_ce_done = false; sf_symbols_and_ce_done = false;
pdcch_llr_extracted = false; pdcch_llr_extracted = false;
tti = 0; tti = 0;
if (srslte_ue_dl_init(&ue_dl, cell)) { if (!srslte_ue_dl_init(&ue_dl, cell)) {
signal_buffer = (cf_t*) srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); signal_buffer = (cf_t*) srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
return signal_buffer?true:false; return signal_buffer?true:false;
} else { } else {
@ -63,108 +63,120 @@ void dl_buffer::free_cell()
} }
// FIXME: Avoid this memcpy modifying ue_sync to directly write into provided pointer // FIXME: Avoid this memcpy modifying ue_sync to directly write into provided pointer
bool dl_buffer::recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time) bool dl_buffer::recv_ue_sync(uint32_t current_tti, srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time)
{ {
cf_t *sf_buffer = NULL; if (signal_buffer) {
if (srslte_ue_sync_get_buffer(ue_sync, &sf_buffer)) { printf("DL_buffer %d receiving tti %d...\n", buffer_id, current_tti);
return false; cf_t *sf_buffer = NULL;
tti = current_tti;
if (srslte_ue_sync_get_buffer(ue_sync, &sf_buffer) == 1) {
memcpy(signal_buffer, sf_buffer, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
srslte_ue_sync_get_last_timestamp(ue_sync, rx_time);
} else {
return false;
}
} }
memcpy(signal_buffer, sf_buffer, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
srslte_ue_sync_get_last_timestamp(ue_sync, rx_time);
} }
bool dl_buffer::get_ul_grant(pdcch_ul_search_t mode, uint32_t rnti, sched_grant *grant) bool dl_buffer::get_ul_grant(pdcch_ul_search_t mode, uint32_t rnti, sched_grant *grant)
{ {
if (!sf_symbols_and_ce_done) { if (signal_buffer) {
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { if (!sf_symbols_and_ce_done) {
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) {
return false;
}
sf_symbols_and_ce_done = true;
}
if (!pdcch_llr_extracted) {
if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) {
return false;
}
pdcch_llr_extracted = true;
}
srslte_dci_msg_t dci_msg;
if (srslte_ue_dl_find_ul_dci(&ue_dl, &dci_msg, cfi, tti%10, rnti)) {
return false; return false;
} }
sf_symbols_and_ce_done = true;
} if (srslte_dci_msg_to_ra_ul(&dci_msg, cell.nof_prb,
if (!pdcch_llr_extracted) { params_db->get_param(params::PUSCH_HOPPING_OFFSET),
if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) { (srslte_ra_pusch_t*) grant->get_grant_ptr()))
{
return false; return false;
} }
pdcch_llr_extracted = true;
} return true;
srslte_dci_msg_t dci_msg;
if (srslte_ue_dl_find_ul_dci(&ue_dl, &dci_msg, cfi, tti%10, rnti)) {
return false;
}
if (srslte_dci_msg_to_ra_ul(&dci_msg, cell.nof_prb,
params_db->get_param(params::PUSCH_HOPPING_OFFSET),
(srslte_ra_pusch_t*) grant->get_grant_ptr()))
{
return false;
} }
return true;
} }
bool dl_buffer::get_dl_grant(pdcch_dl_search_t mode, uint32_t rnti, sched_grant *grant) bool dl_buffer::get_dl_grant(pdcch_dl_search_t mode, uint32_t rnti, sched_grant *grant)
{ {
if (!sf_symbols_and_ce_done) { if (signal_buffer) {
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { if (!sf_symbols_and_ce_done) {
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) {
return false;
}
sf_symbols_and_ce_done = true;
}
if (!pdcch_llr_extracted) {
if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) {
return false;
}
pdcch_llr_extracted = true;
}
srslte_dci_msg_t dci_msg;
if (srslte_ue_dl_find_dl_dci(&ue_dl, &dci_msg, cfi, tti%10, rnti) != 1) {
return false; return false;
} }
sf_symbols_and_ce_done = true;
} if (srslte_dci_msg_to_ra_dl(&dci_msg, rnti, cell, cfi,
if (!pdcch_llr_extracted) { (srslte_ra_pdsch_t*) grant->get_grant_ptr())) {
if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) {
return false; return false;
} }
pdcch_llr_extracted = true; return true;
}
srslte_dci_msg_t dci_msg;
if (srslte_ue_dl_find_dl_dci(&ue_dl, &dci_msg, cfi, tti%10, rnti)) {
return false;
}
if (srslte_dci_msg_to_ra_dl(&dci_msg, rnti, cell, cfi,
(srslte_ra_pdsch_t*) grant->get_grant_ptr()))
{
return false;
} }
return true;
} }
bool dl_buffer::decode_phich(srslte_phich_alloc_t assignment) bool dl_buffer::decode_phich(srslte_phich_alloc_t assignment)
{ {
if (!sf_symbols_and_ce_done) { if (signal_buffer) {
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { if (!sf_symbols_and_ce_done) {
return false; if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) {
return false;
}
sf_symbols_and_ce_done = true;
} }
sf_symbols_and_ce_done = true; return false;
} }
return false;
} }
bool dl_buffer::decode_pdsch(sched_grant pdsch_grant, uint8_t *payload) bool dl_buffer::decode_pdsch(sched_grant pdsch_grant, uint8_t *payload)
{ {
if (!sf_symbols_and_ce_done) { if (signal_buffer) {
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { if (!sf_symbols_and_ce_done) {
return false; if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) {
return false;
}
sf_symbols_and_ce_done = true;
} }
sf_symbols_and_ce_done = true; srslte_ra_pdsch_t *ra_dl = (srslte_ra_pdsch_t*) pdsch_grant.get_grant_ptr();
} if (srslte_harq_setup_dl(&ue_dl.harq_process[0], ra_dl->mcs,
srslte_ra_pdsch_t *ra_dl = (srslte_ra_pdsch_t*) pdsch_grant.get_grant_ptr(); pdsch_grant.get_rv(), tti%10, &ra_dl->prb_alloc)) {
if (srslte_harq_setup_dl(&ue_dl.harq_process[0], ra_dl->mcs, fprintf(stderr, "Error configuring HARQ process\n");
pdsch_grant.get_rv(), tti%10, &ra_dl->prb_alloc)) { return SRSLTE_ERROR;
fprintf(stderr, "Error configuring HARQ process\n"); }
return SRSLTE_ERROR; if (ue_dl.harq_process[0].mcs.mod > 0 && ue_dl.harq_process[0].mcs.tbs >= 0) {
} int ret = srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.harq_process[0], ue_dl.sf_symbols,
if (ue_dl.harq_process[0].mcs.mod > 0 && ue_dl.harq_process[0].mcs.tbs >= 0) { ue_dl.ce, 0, pdsch_grant.get_rnti(), payload);
int ret = srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.harq_process[0], ue_dl.sf_symbols, if (ret == SRSLTE_SUCCESS) {
ue_dl.ce, 0, pdsch_grant.get_rnti(), payload); return true;
if (ret == SRSLTE_SUCCESS) { }
return true; }
} return false;
} }
return false;
} }
} }

@ -28,7 +28,10 @@
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <pthread.h> #include <pthread.h>
#include <unistd.h>
#include "srslte/srslte.h" #include "srslte/srslte.h"
#include "srslte/cuhd/cuhd.h"
#include "srslte/ue_itf/phy.h" #include "srslte/ue_itf/phy.h"
#include "srslte/ue_itf/prach.h" #include "srslte/ue_itf/prach.h"
@ -38,28 +41,38 @@
namespace srslte { namespace srslte {
namespace ue { namespace ue {
#if SYNC_MODE==SYNC_MODE_CALLBACK
phy::phy(ue_phy_callback_t tti_clock_callback_, ue_phy_callback_t status_change_) bool phy::init_radio_handler(char *args) {
printf("Opening UHD device...\n");
if (cuhd_open(args, &radio_handler)) {
fprintf(stderr, "Error opening uhd\n");
return false;
}
return true;
}
bool phy::init(ue_phy_callback_tti_t tti_clock_callback_, ue_phy_callback_status_t status_change_)
{ {
started = false;
tti_clock_callback = tti_clock_callback_; tti_clock_callback = tti_clock_callback_;
status_change = status_change_; status_change = status_change_;
ul_buffer_queue = new queue(6, sizeof(ul_buffer)); ul_buffer_queue = new queue(6, sizeof(ul_buffer));
dl_buffer_queue = new queue(6, sizeof(dl_buffer)); dl_buffer_queue = new queue(6, sizeof(dl_buffer));
started = true; // Set default params
params_db.set_param(params::CELLSEARCH_TIMEOUT_PSS_NFRAMES, 100);
pthread_create(&radio_thread, NULL, radio_thread_fnc, this); params_db.set_param(params::CELLSEARCH_TIMEOUT_PSS_CORRELATION_THRESHOLD, 160);
} params_db.set_param(params::CELLSEARCH_TIMEOUT_MIB_NFRAMES, 100);
#else
phy()
{
if (init_radio_handler("")) {
pthread_create(&radio_thread, NULL, radio_thread_fnc, this);
started = true;
}
return started;
} }
#endif void phy::stop()
phy::~phy()
{ {
started = false; started = false;
@ -76,9 +89,33 @@ phy::~phy()
prach_buffer.free_cell(); prach_buffer.free_cell();
} }
void phy::set_tx_gain(float gain) {
float x = cuhd_set_tx_gain(radio_handler, gain);
printf("Set TX gain to %.1f dB\n", x);
}
void phy::set_rx_gain(float gain) {
float x = cuhd_set_rx_gain(radio_handler, gain);
printf("Set RX gain to %.1f dB\n", x);
}
void phy::set_tx_freq(float freq) {
float x = cuhd_set_tx_freq(radio_handler, freq);
printf("Set TX freq to %.1f MHz\n", x/1000000);
}
void phy::set_rx_freq(float freq) {
float x = cuhd_set_rx_freq(radio_handler, freq);
printf("Set RX freq to %.1f MHz\n", x/1000000);
}
void phy::set_param(params::param_t param, int64_t value) {
params_db.set_param(param, value);
}
// FIXME: Add PRACH power control // FIXME: Add PRACH power control
void phy::send_prach(uint32_t preamble_idx) bool phy::send_prach(uint32_t preamble_idx)
{ {
if (phy_state == RXTX) { if (phy_state == RXTX) {
prach_buffer.ready_to_send(preamble_idx); prach_buffer.ready_to_send(preamble_idx);
@ -86,39 +123,50 @@ void phy::send_prach(uint32_t preamble_idx)
} }
// Do fast measurement on RSSI and/or PSS autocorrelation energy or PSR // Do fast measurement on RSSI and/or PSS autocorrelation energy or PSR
void phy::measure() bool phy::measure()
{ {
if (phy_state == IDLE) { if (phy_state == IDLE) {
// capture and do measurement // capture and do measurement
status_change();
} }
return false;
} }
void phy::dl_bch() bool phy::start_rxtx()
{ {
if (phy_state == IDLE) { if (phy_state == IDLE) {
phy_state = RX_BCH; if (cell_is_set) {
status_change(); // Set RX/TX sampling rate
} cuhd_set_rx_srate(radio_handler, srslte_sampling_freq_hz(cell.nof_prb));
cuhd_set_tx_srate(radio_handler, srslte_sampling_freq_hz(cell.nof_prb));
// Start streaming
cuhd_start_rx_stream(radio_handler);
phy_state = RXTX;
status_change();
return true;
} else {
fprintf(stderr, "Can not change state to RXTX: cell is not set\n");
}
} else {
fprintf(stderr, "Can not change state to RXTX: invalid state %d\n", phy_state);
}
return false;
} }
void phy::start_rxtx() bool phy::stop_rxtx()
{ {
if (phy_state == MIB_DECODED) { if (phy_state == RXTX) {
// Set sampling freq to MIB PRB // Stop streaming
// start radio streaming cuhd_stop_rx_stream(radio_handler);
phy_state = RXTX; phy_state = IDLE;
status_change(); status_change();
} return true;
} else {
fprintf(stderr, "Can not change state to RXTX: invalid state %d\n", phy_state);
}
return false;
} }
void phy::stop_rxtx()
{
// stop radio
phy_state = IDLE;
status_change();
}
bool phy::status_is_idle() { bool phy::status_is_idle() {
return phy_state == IDLE; return phy_state == IDLE;
} }
@ -127,60 +175,54 @@ bool phy::status_is_rxtx() {
return phy_state == RXTX; return phy_state == RXTX;
} }
bool phy::status_is_bch_decoded(uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]) uint32_t phy::get_current_tti() {
{ return current_tti;
if (phy_state == MIB_DECODED) { }
memcpy(payload, bch_payload, SRSLTE_BCH_PAYLOAD_LEN*sizeof(uint8_t)); uint32_t phy::tti_to_SFN(uint32_t tti) {
} return tti/10;
} }
uint32_t phy::tti_to_subf(uint32_t tti) {
return tti%10;
}
void* phy::radio_thread_fnc(void *arg) { void* phy::radio_thread_fnc(void *arg) {
phy* phy = static_cast<srslte::ue::phy*>(arg); phy* phy = static_cast<srslte::ue::phy*>(arg);
phy->main_radio_loop(); phy->main_radio_loop();
return NULL; return NULL;
} }
int radio_recv_wrapper_cs(void*,void*,uint32_t,srslte_timestamp_t*) int radio_recv_wrapper_cs(void *h,void *data, uint32_t nsamples, srslte_timestamp_t*)
{ {
return cuhd_recv(h, data, nsamples, 1);
} }
bool phy::set_cell(srslte_cell_t cell_) {
void phy::run_rx_bch_state() { if (phy_state == IDLE) {
phy_state = IDLE; cell_is_set = false;
if (rx_bch()) { cell = cell_;
for(uint32_t i=0;i<6;i++) { if (!srslte_ue_mib_init(&ue_mib, cell))
get_ul_buffer(i)->init_cell(cell, &params_db); {
get_dl_buffer(i)->init_cell(cell, &params_db); if (!srslte_ue_sync_init(&ue_sync, cell, radio_recv_wrapper_cs, radio_handler))
} {
if (srslte_ue_mib_init(&ue_mib, cell)) { if (prach_buffer.init_cell(cell, &params_db)) {
fprintf(stderr, "Error initiating UE mib\n"); for(uint32_t i=0;i<6;i++) {
} else { get_ul_buffer(i)->init_cell(cell, &params_db);
if (srslte_ue_sync_init(&ue_sync, cell, radio_recv_wrapper_cs, radio_handler)) { get_dl_buffer(i)->init_cell(cell, &params_db);
fprintf(stderr, "Error initiating ue_sync"); get_dl_buffer(i)->buffer_id = i;
}
cell_is_set = true;
}
} else { } else {
phy_state = MIB_DECODED; fprintf(stderr, "Error setting cell: initiating ue_sync");
} }
} } else {
} fprintf(stderr, "Error setting cell: initiating ue_mib\n");
status_change(); }
} } else {
fprintf(stderr, "Error setting cell: Invalid state %d\n", phy_state);
void phy::main_radio_loop() {
while(started) {
switch(phy_state) {
case IDLE:
case MIB_DECODED:
break;
case RX_BCH:
run_rx_bch_state();
break;
case RXTX:
run_rx_tx_state();
break;
}
} }
return cell_is_set;
} }
ul_buffer* phy::get_ul_buffer(uint32_t tti) ul_buffer* phy::get_ul_buffer(uint32_t tti)
@ -193,11 +235,20 @@ dl_buffer* phy::get_dl_buffer(uint32_t tti)
return (dl_buffer*) dl_buffer_queue->get(tti); return (dl_buffer*) dl_buffer_queue->get(tti);
} }
bool phy::rx_bch()
bool phy::decode_mib(uint32_t N_id_2, srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]) {
return decode_mib_N_id_2((int) N_id_2, cell, payload);
}
bool phy::decode_mib_best(srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]) {
return decode_mib_N_id_2(-1, cell, payload);
}
bool phy::decode_mib_N_id_2(int force_N_id_2, srslte_cell_t *cell_ptr, uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN])
{ {
srslte_ue_cellsearch_result_t found_cells[3]; srslte_ue_cellsearch_result_t found_cells[3];
srslte_ue_cellsearch_t cs; srslte_ue_cellsearch_t cs;
bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t));
if (srslte_ue_cellsearch_init(&cs, radio_recv_wrapper_cs, radio_handler)) { if (srslte_ue_cellsearch_init(&cs, radio_recv_wrapper_cs, radio_handler)) {
@ -205,67 +256,60 @@ bool phy::rx_bch()
} }
srslte_ue_cellsearch_set_nof_frames_to_scan(&cs, params_db.get_param(params::CELLSEARCH_TIMEOUT_PSS_NFRAMES)); srslte_ue_cellsearch_set_nof_frames_to_scan(&cs, params_db.get_param(params::CELLSEARCH_TIMEOUT_PSS_NFRAMES));
srslte_ue_cellsearch_set_threshold(&cs, (float) params_db.get_param(params::CELLSEARCH_CORRELATION_THRESHOLD)/10); srslte_ue_cellsearch_set_threshold(&cs, (float) params_db.get_param(params::CELLSEARCH_TIMEOUT_PSS_CORRELATION_THRESHOLD)/10);
// set sampling freq 1.92 MHz cuhd_set_rx_srate(radio_handler, 1920000.0);
// set frequency, gain etc cuhd_start_rx_stream(radio_handler);
// start radio streaming
/* 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 */
uint32_t max_peak_cell = 0; uint32_t max_peak_cell = 0;
int ret = SRSLTE_ERROR; int ret = SRSLTE_ERROR;
uint32_t force_N_id_2 = params_db.get_param(params::CELLSEARCH_FORCE_N_ID_2);
if (force_N_id_2 >= 0 && force_N_id_2 < 3) { if (force_N_id_2 >= 0 && force_N_id_2 < 3) {
ret = srslte_ue_cellsearch_scan_N_id_2(&cs, force_N_id_2, &found_cells[force_N_id_2]); ret = srslte_ue_cellsearch_scan_N_id_2(&cs, force_N_id_2, &found_cells[force_N_id_2]);
max_peak_cell = force_N_id_2; max_peak_cell = force_N_id_2;
} else { } else {
ret = srslte_ue_cellsearch_scan(&cs, found_cells, &max_peak_cell); ret = srslte_ue_cellsearch_scan(&cs, found_cells, &max_peak_cell);
} }
// Stop radio
cuhd_stop_rx_stream(radio_handler);
srslte_ue_cellsearch_free(&cs); srslte_ue_cellsearch_free(&cs);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error searching cell"); fprintf(stderr, "Error decoding MIB: Error searching PSS\n");
return false; return false;
} else if (ret == 0) { } else if (ret == 0) {
fprintf(stderr, "Could not find any cell in this frequency"); fprintf(stderr, "Error decoding MIB: Could not find any PSS in this frequency\n");
return false; return false;
} }
// Save result // Save result
cell.id = found_cells[max_peak_cell].cell_id; cell_ptr->id = found_cells[max_peak_cell].cell_id;
cell.cp = found_cells[max_peak_cell].cp; cell_ptr->cp = found_cells[max_peak_cell].cp;
printf("Found CELL PHY_ID: %d, CP: %s PSR: %.1f AbsPower: %.1f dBm", INFO("\nFound CELL ID: %d CP: %s\n", cell_ptr->id, srslte_cp_string(cell_ptr->cp));
cell.id, srslte_cp_string(cell.cp),
found_cells[max_peak_cell].psr, 30+10*log10(found_cells[max_peak_cell].peak));
srslte_ue_mib_sync_t ue_mib_sync; srslte_ue_mib_sync_t ue_mib_sync;
if (srslte_ue_mib_sync_init(&ue_mib_sync, cell.id, cell.cp, radio_recv_wrapper_cs, radio_handler)) { if (srslte_ue_mib_sync_init(&ue_mib_sync, cell_ptr->id, cell_ptr->cp, radio_recv_wrapper_cs, radio_handler)) {
return false; return false;
} }
/* Find and decode MIB */
uint32_t sfn, sfn_offset; uint32_t sfn, sfn_offset;
/* Find and decode MIB */ cuhd_start_rx_stream(radio_handler);
// Start RX stream again
ret = srslte_ue_mib_sync_decode(&ue_mib_sync, params_db.get_param(params::CELLSEARCH_TIMEOUT_MIB_NFRAMES), ret = srslte_ue_mib_sync_decode(&ue_mib_sync, params_db.get_param(params::CELLSEARCH_TIMEOUT_MIB_NFRAMES),
bch_payload, &cell.nof_ports, &sfn_offset); bch_payload, &cell_ptr->nof_ports, &sfn_offset);
// Stop RX stream again cuhd_stop_rx_stream(radio_handler);
srslte_ue_mib_sync_free(&ue_mib_sync); srslte_ue_mib_sync_free(&ue_mib_sync);
if (ret == 1) { if (ret == 1) {
srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); srslte_pbch_mib_unpack(bch_payload, cell_ptr, &sfn);
sfn = (sfn + sfn_offset)%1024; sfn = (sfn + sfn_offset)%1024;
current_tti = sfn*10+1; current_tti = sfn*10+1;
printf("MIB decoded: %d ports, SFN: %d, TTI: %d", cell.nof_ports, sfn, current_tti);
return true; return true;
} else { } else {
printf("Error decoding MIB"); printf("Error decoding MIB: Error decoding PBCH\n");
return false; return false;
} }
} }
@ -275,6 +319,7 @@ int phy::sync_sfn(void) {
cf_t *sf_buffer = NULL; cf_t *sf_buffer = NULL;
int ret = SRSLTE_ERROR; int ret = SRSLTE_ERROR;
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);
if (ret < 0) { if (ret < 0) {
@ -295,7 +340,7 @@ int phy::sync_sfn(void) {
srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); srslte_pbch_mib_unpack(bch_payload, &cell, &sfn);
sfn = (sfn + sfn_offset)%1024; sfn = (sfn + sfn_offset)%1024;
current_tti = sfn*10; current_tti = sfn*10 + 1;
return 1; return 1;
} }
} }
@ -308,12 +353,14 @@ void phy::run_rx_tx_state()
{ {
int ret; int ret;
if (!is_sfn_synched) { if (!is_sfn_synched) {
printf("Synchronising SFN...\n");
ret = sync_sfn(); ret = sync_sfn();
switch(ret) { switch(ret) {
default: default:
phy_state = IDLE; phy_state = IDLE;
break; break;
case 1: case 1:
printf("SFN synched ok\n");
is_sfn_synched = true; is_sfn_synched = true;
break; break;
case 0: case 0:
@ -322,7 +369,7 @@ void phy::run_rx_tx_state()
} else { } else {
// Receive alligned buffer for the current tti // Receive alligned buffer for the current tti
srslte_timestamp_t rx_time; srslte_timestamp_t rx_time;
get_dl_buffer(current_tti)->recv_ue_sync(&ue_sync, &rx_time); get_dl_buffer(current_tti)->recv_ue_sync(current_tti, &ue_sync, &rx_time);
// send prach if we have to // send prach if we have to
if (prach_buffer.is_ready_to_send(current_tti)) { if (prach_buffer.is_ready_to_send(current_tti)) {
@ -332,10 +379,28 @@ void phy::run_rx_tx_state()
if (get_ul_buffer(current_tti)->is_ready_to_send()) { if (get_ul_buffer(current_tti)->is_ready_to_send()) {
get_ul_buffer(current_tti)->send_packet(radio_handler, rx_time); get_ul_buffer(current_tti)->send_packet(radio_handler, rx_time);
} }
tti_clock_callback(current_tti);
current_tti = (current_tti + 1)%10240;
} }
current_tti++;
tti_clock_callback();
} }
void phy::main_radio_loop() {
printf("PHY initiated\n");
while(started) {
switch(phy_state) {
case IDLE:
usleep(50000);
break;
case RXTX:
printf("Run RX_TX\n");
run_rx_tx_state();
break;
}
}
}
} }
} }

@ -87,7 +87,7 @@ bool prach::ready_to_send(uint32_t preamble_idx_)
} }
bool prach::is_ready_to_send(uint32_t current_tti) { bool prach::is_ready_to_send(uint32_t current_tti) {
if (preamble_idx >= 0 && preamble_idx < 64) { if (preamble_idx >= 0 && preamble_idx < 64 && params_db != NULL) {
uint32_t config_idx = (uint32_t) params_db->get_param(params::PRACH_CONFIG_INDEX); uint32_t config_idx = (uint32_t) params_db->get_param(params::PRACH_CONFIG_INDEX);
srslte_prach_sfn_t prach_sfn = srslte_prach_get_sfn(config_idx); srslte_prach_sfn_t prach_sfn = srslte_prach_get_sfn(config_idx);
if (prach_sfn == SRSLTE_PRACH_SFN_EVEN && ((current_tti/10)%2)==0 || if (prach_sfn == SRSLTE_PRACH_SFN_EVEN && ((current_tti/10)%2)==0 ||

@ -24,13 +24,16 @@
* and at http://www.gnu.org/licenses/. * and at http://www.gnu.org/licenses/.
* *
*/ */
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "srslte/ue_itf/queue.h" #include "srslte/ue_itf/queue.h"
namespace srslte { namespace srslte {
namespace ue { namespace ue {
queue::queue(uint32_t nof_elements, uint32_t element_size) queue::queue(uint32_t nof_elements_, uint32_t element_size)
{ {
nof_elements = nof_elements_;
buffer_of_elements = (queue::element**) malloc(sizeof(queue::element*) * nof_elements); buffer_of_elements = (queue::element**) malloc(sizeof(queue::element*) * nof_elements);
for (int i=0;i<nof_elements;i++) { for (int i=0;i<nof_elements;i++) {
buffer_of_elements[i] = (queue::element*) malloc(element_size); buffer_of_elements[i] = (queue::element*) malloc(element_size);
@ -39,15 +42,20 @@ namespace ue {
queue::~queue() queue::~queue()
{ {
printf("destroying %d elements\n", nof_elements);
for (int i=0;i<nof_elements;i++) { for (int i=0;i<nof_elements;i++) {
free(buffer_of_elements[i]); if (buffer_of_elements[i]) {
free(buffer_of_elements[i]);
}
}
if (buffer_of_elements) {
free(buffer_of_elements);
} }
free(buffer_of_elements);
} }
queue::element* queue::get(uint32_t idx) queue::element* queue::get(uint32_t idx)
{ {
return (queue::element*) buffer_of_elements[idx%nof_elements]; return (queue::element*) buffer_of_elements[idx%nof_elements];
} }
} // namespace ue } // namespace ue

@ -47,6 +47,14 @@ namespace ue {
return dl_grant.rv_idx; return dl_grant.rv_idx;
} }
} }
uint32_t sched_grant::get_tbs() {
if (dir == UPLINK) {
return ul_grant.mcs.tbs;
} else {
return dl_grant.mcs.tbs;
}
}
void sched_grant::set_rv(uint32_t rv) { void sched_grant::set_rv(uint32_t rv) {
if (dir == UPLINK) { if (dir == UPLINK) {

@ -45,17 +45,20 @@ bool ul_buffer::init_cell(srslte_cell_t cell_, params *params_db) {
current_tx_nb = 0; current_tx_nb = 0;
if (!srslte_ue_ul_init(&ue_ul, cell)) { if (!srslte_ue_ul_init(&ue_ul, cell)) {
signal_buffer = (cf_t*) srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); signal_buffer = (cf_t*) srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
return signal_buffer?true:false; cell_initiated = signal_buffer?true:false;
return cell_initiated;
} else { } else {
return false; return false;
} }
} }
void ul_buffer::free_cell() { void ul_buffer::free_cell() {
if (signal_buffer) { if (cell_initiated) {
free(signal_buffer); if (signal_buffer) {
free(signal_buffer);
}
srslte_ue_ul_free(&ue_ul);
} }
srslte_ue_ul_free(&ue_ul);
} }
bool ul_buffer::generate_pusch(sched_grant pusch_grant, bool ul_buffer::generate_pusch(sched_grant pusch_grant,

@ -20,5 +20,8 @@
# #
ADD_EXECUTABLE(ue_itf_test ue_itf_test.cc) LIST(FIND OPTIONAL_LIBS cuhd CUHD_FIND)
TARGET_LINK_LIBRARIES(ue_itf_test srslte++) IF(${CUHD_FIND} GREATER -1)
ADD_EXECUTABLE(ue_itf_test ue_itf_test.cc)
TARGET_LINK_LIBRARIES(ue_itf_test srslte++ cuhd)
ENDIF(${CUHD_FIND} GREATER -1)

@ -27,43 +27,66 @@
#include <unistd.h> #include <unistd.h>
#include "srslte/utils/debug.h"
#include "srslte/ue_itf/phy.h" #include "srslte/ue_itf/phy.h"
void tti_callback(); void tti_callback();
void status_change(); void status_change();
srslte::ue::phy phy = srslte::ue::phy(tti_callback, status_change); srslte::ue::phy phy;
void tti_callback() {
printf("called tti callback\n"); uint8_t payload[1024];
void tti_callback(uint32_t tti) {
printf("called tti: %d\n", tti);
// This is the MAC implementation
if ((phy.tti_to_SFN(tti)%2) == 0 && phy.tti_to_subf(tti) == 5) {
srslte::ue::sched_grant grant;
srslte_verbose = SRSLTE_VERBOSE_DEBUG;
if (phy.get_dl_buffer(tti)->get_dl_grant(srslte::ue::dl_buffer::PDCCH_DL_SEARCH_SIRNTI, SRSLTE_SIRNTI, &grant)) {
if (phy.get_dl_buffer(tti)->decode_pdsch(grant, payload)) {
printf("Decoded SIB1 ok TBS: %d\n", grant.get_tbs());
srslte_vec_fprint_hex(stdout, payload, grant.get_tbs());
} else {
fprintf(stderr, "Could not decode SIB\n");
}
} else {
fprintf(stderr, "Error getting DL grant\n");
}
exit(0);
}
} }
bool status_changed;
void status_change() { void status_change() {
printf("called status change\n"); printf("called status change\n");
status_changed=true;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
srslte_cell_t cell;
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
phy.init(tti_callback, status_change);
sleep(1); sleep(1);
phy.set_rx_freq(1825000000);
phy.set_rx_gain(60.0);
/* Instruct the PHY to decode BCH */ /* Instruct the PHY to decode BCH */
status_changed=false; if (!phy.decode_mib_best(&cell, bch_payload)) {
phy.dl_bch();
while(!status_changed);
if (!phy.status_is_bch_decoded(bch_payload)) {
printf("Could not decode BCH\n");
exit(-1); exit(-1);
} }
srslte_pbch_mib_fprint(stdout, &cell, phy.get_current_tti()/10);
srslte_vec_fprint_hex(stdout, bch_payload, SRSLTE_BCH_PAYLOAD_LEN); srslte_vec_fprint_hex(stdout, bch_payload, SRSLTE_BCH_PAYLOAD_LEN);
// Set the current PHY cell to the detected cell
if (!phy.set_cell(cell)) {
printf("Error setting cell\n");
exit(-1);
}
/* Instruct the PHY to start RX streaming and synchronize */ /* Instruct the PHY to start RX streaming and synchronize */
status_changed=false; if (!phy.start_rxtx()) {
phy.start_rxtx();
while(!status_changed);
if (!phy.status_is_rxtx()) {
printf("Could not start RX\n"); printf("Could not start RX\n");
exit(-1); exit(-1);
} }

@ -145,7 +145,7 @@ void base_init() {
} }
/* create ifft object */ /* create ifft object */
if (srslte_ofdm_rx_init(&ifft, SRSLTE_CP_NORM, cell.nof_prb)) { if (srslte_ofdm_tx_init(&ifft, SRSLTE_CP_NORM, cell.nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n"); fprintf(stderr, "Error creating iFFT object\n");
exit(-1); exit(-1);
} }
@ -154,7 +154,7 @@ void base_init() {
void base_free() { void base_free() {
srslte_ofdm_rx_free(&ifft); srslte_ofdm_tx_free(&ifft);
if (sf_buffer) { if (sf_buffer) {
free(sf_buffer); free(sf_buffer);
@ -232,7 +232,7 @@ int main(int argc, char **argv) {
srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_buffer, cell.nof_prb, srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_buffer, cell.nof_prb,
SRSLTE_CP_NORM); SRSLTE_CP_NORM);
/* Transform to OFDM symbols */ /* Transform to OFDM symbols */
srslte_ofdm_rx_sf(&ifft, sf_buffer, output_buffer); srslte_ofdm_tx_sf(&ifft, sf_buffer, output_buffer);
float norm_factor = (float) sqrtf(cell.nof_prb)/15; float norm_factor = (float) sqrtf(cell.nof_prb)/15;
srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb)); srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));

@ -393,7 +393,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} else if (n == SRSLTE_UE_MIB_FOUND) { } else if (n == SRSLTE_UE_MIB_FOUND) {
srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); srslte_pbch_mib_unpack(bch_payload, &cell, &sfn);
srslte_pbch_mib_fprint(stdout, &cell, sfn, cell.id); srslte_pbch_mib_fprint(stdout, &cell, sfn);
printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset); printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset);
sfn = (sfn + sfn_offset)%1024; sfn = (sfn + sfn_offset)%1024;
state = DECODE_PDSCH; state = DECODE_PDSCH;

Loading…
Cancel
Save