diff --git a/srsapps/common/include/srsapps/common/mac_interface.h b/srsapps/common/include/srsapps/common/mac_interface.h index d027d2e80..440c380b0 100644 --- a/srsapps/common/include/srsapps/common/mac_interface.h +++ b/srsapps/common/include/srsapps/common/mac_interface.h @@ -54,13 +54,15 @@ public: uint32_t tti; bool ndi; uint32_t tbs; - srslte_rnti_type_t rnti_type; + uint32_t rv; + uint16_t rnti; srslte_phy_grant_t phy_grant; } mac_grant_t; typedef struct { bool decode_enabled; - uint16_t rv; + uint32_t rv; + uint16_t rnti; bool generate_ack; bool default_ack; uint8_t *payload_ptr; @@ -70,7 +72,9 @@ public: typedef struct { bool tx_enabled; - uint16_t rv; + bool expect_ack; + uint32_t rv; + uint16_t rnti; uint32_t current_tx_nb; srslte_softbuffer_tx_t *softbuffer; srslte_phy_grant_t phy_grant; @@ -95,6 +99,11 @@ public: /* Indicate successfull decoding of BCH TB through PBCH */ virtual void bch_decoded_ok(uint8_t *payload) = 0; + /* Function called every start of a subframe (TTI). Warning, this function is called + * from a high priority thread and should terminate asap + */ + virtual void tti_clock(uint32_t tti) = 0; + }; /* Interface RLC -> MAC */ diff --git a/srsapps/common/include/srsapps/common/params_db.h b/srsapps/common/include/srsapps/common/params_db.h index 61af784a3..ae0ee1a7f 100644 --- a/srsapps/common/include/srsapps/common/params_db.h +++ b/srsapps/common/include/srsapps/common/params_db.h @@ -40,13 +40,13 @@ namespace ue { public: params_db(uint32_t nof_params_) { nof_params = nof_params_; - db = new int64_t[nof_params]; + db = (int64_t*) calloc(sizeof(int64_t), nof_params); for (int i=0;i #include "srsapps/common/thread_pool.h" namespace srslte { -void thread_pool::worker::setup(uint32_t id, thread_pool *parent) +void thread_pool::worker::setup(uint32_t id, thread_pool *parent, uint32_t prio) { my_id = id; my_parent = parent; - start(); + start(prio); } void thread_pool::worker::run_thread() @@ -44,14 +45,20 @@ void thread_pool::worker::run_thread() wait_to_start(); if (running) { work_imp(); + finished(); } - finished(); } } +uint32_t thread_pool::worker::get_id() +{ + return my_id; +} + void thread_pool::worker::stop() { running = false; + wait_thread_finish(); } void thread_pool::worker::wait_to_start() @@ -77,31 +84,46 @@ thread_pool::thread_pool(uint32_t nof_workers_) : workers(nof_workers_), begin( for (int i=0;isetup(id, this); + printf("Added worker to available_workers, len=%lu\n", available_workers.size()); + obj->setup(id, this, prio); + pthread_cond_signal(&cvar_stop); + pthread_mutex_unlock(&mutex_stop); } } void thread_pool::stop() { + /* Stop any thread waiting for available worker */ + running = false; + pthread_mutex_lock(&mutex_stop); + pthread_cond_signal(&cvar_start); + pthread_mutex_unlock(&mutex_stop); + + /* Now stop all workers */ for (uint32_t i=0;istop(); + // Need to call start to wake it up start_worker(i); workers[i]->wait_thread_finish(); } } + + /* And destroy mutexes */ pthread_mutex_destroy(&mutex_start); pthread_mutex_destroy(&mutex_stop); pthread_cond_destroy(&cvar_start); @@ -143,11 +165,15 @@ thread_pool::worker* thread_pool::wait_worker() { thread_pool::worker *x; pthread_mutex_lock(&mutex_stop); - while(!available_workers.empty()) { + while(available_workers.empty() && running) { pthread_cond_wait(&cvar_stop, &mutex_stop); } - x = (worker*) available_workers.top(); - available_workers.pop(); + if (running) { + x = (worker*) available_workers.top(); + available_workers.pop(); + } else { + x = NULL; + } pthread_mutex_unlock(&mutex_stop); return x; } diff --git a/srsapps/ue/CMakeLists.txt b/srsapps/ue/CMakeLists.txt index c23f9567e..980e7c5a1 100644 --- a/srsapps/ue/CMakeLists.txt +++ b/srsapps/ue/CMakeLists.txt @@ -23,5 +23,5 @@ INCLUDE_DIRECTORIES(phy/include/) INCLUDE_DIRECTORIES(mac/include/) add_subdirectory(phy) -#add_subdirectory(mac) +add_subdirectory(mac) diff --git a/srsapps/ue/mac/CMakeLists.txt b/srsapps/ue/mac/CMakeLists.txt index 525b13f91..2cc99ceac 100644 --- a/srsapps/ue/mac/CMakeLists.txt +++ b/srsapps/ue/mac/CMakeLists.txt @@ -33,4 +33,4 @@ SRSLTE_SET_PIC(srsapps_ue_mac) FILE(GLOB HEADERS_ALL "include/srsapps/ue/mac/*.h") ADD_CUSTOM_TARGET (add_ue_mac_headers SOURCES ${HEADERS_ALL}) -ADD_SUBDIRECTORY(test) +#ADD_SUBDIRECTORY(test) diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h index 2b060b1a3..dde4879ee 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h @@ -30,8 +30,6 @@ #include #include "srsapps/common/log.h" -#include "srsapps/common/tti_sync.h" -#include "srsapps/common/tti_sync_cv.h" #include "srsapps/ue/phy/phy.h" #include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/dl_harq.h" @@ -49,6 +47,7 @@ #include "srsapps/ue/mac/sdu_handler.h" #include "srsapps/ue/mac/mac_pcap.h" #include "srsapps/common/trace.h" +#include "srsapps/common/mac_interface.h" #ifndef UEMAC_H @@ -59,7 +58,7 @@ namespace ue { typedef _Complex float cf_t; -class mac : public timer_callback +class mac : public timer_callback, mac_interface_phy, mac_interface_rlc { public: mac() : timers_db((uint32_t) NOF_MAC_TIMERS), tr_exec_total(1024*10), tr_exec_dl(1024*10), tr_exec_ul(1024*10) {started=false; pcap = NULL; } diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phch_common.h b/srsapps/ue/phy/include/srsapps/ue/phy/phch_common.h index 56cafe10f..433ce5e47 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phch_common.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phch_common.h @@ -63,7 +63,7 @@ namespace ue { srslte_rnti_type_t get_dl_rnti_type(); void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]); - bool get_pending_rar(uint32_t tti, srslte_dci_rar_grant_t *rar_grant); + bool get_pending_rar(uint32_t tti, srslte_dci_rar_grant_t *rar_grant = NULL); void reset_pending_ack(uint32_t tti); void set_pending_ack(uint32_t tti, uint32_t I_lowest, uint32_t n_dmrs); diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phch_recv.h b/srsapps/ue/phy/include/srsapps/ue/phy/phch_recv.h index b31c055b5..edbe8a72c 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phch_recv.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phch_recv.h @@ -50,7 +50,7 @@ class phch_recv : public thread public: phch_recv(); bool init(radio* radio_handler, mac_interface_phy *mac, prach *prach_buffer, thread_pool *_workers_pool, - phch_common *_worker_com, log* _log_h, bool do_agc); + phch_common *_worker_com, log* _log_h, bool do_agc = false, uint32_t prio = 1); void stop(); uint32_t get_current_tti(); @@ -60,6 +60,7 @@ public: bool status_is_sync(); void set_time_adv_sec(float time_adv_sec); + void get_current_cell(srslte_cell_t *cell); private: void run_thread(); @@ -75,7 +76,7 @@ private: prach *prach_buffer; srslte_ue_sync_t ue_sync; - srslte_ue_mib_t ue_mib; + srslte_ue_mib_t ue_mib; enum { IDLE, CELL_SEARCH, SYNCING, SYNC_DONE diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phch_worker.h b/srsapps/ue/phy/include/srsapps/ue/phy/phch_worker.h index 3dfa2134b..9a6f14f3c 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phch_worker.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phch_worker.h @@ -56,6 +56,7 @@ public: void set_cfo(float cfo); void set_ul_params(); + void reset_ul_params(); void set_crnti(uint16_t rnti); void enable_pregen_signals(bool enabled); @@ -71,10 +72,10 @@ private: bool decode_pdcch_ul(mac_interface_phy::mac_grant_t *grant); bool decode_pdcch_dl(mac_interface_phy::mac_grant_t *grant); bool decode_phich(bool *ack); - bool decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t* softbuffer, uint32_t rv); + bool decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t* softbuffer, uint32_t rv, uint16_t rnti); /* ... for UL */ - void encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t rv_idx, uint32_t current_tx_nb, srslte_softbuffer_tx_t *softbuffer); + void encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t current_tx_nb, srslte_softbuffer_tx_t *softbuffer, uint32_t rv, uint16_t rnti); void encode_pucch(); void encode_srs(); void reset_uci(); @@ -116,6 +117,7 @@ private: uint32_t I_sr; float cfo; bool rar_cqi_request; + uint32_t ul_payload_max_len; }; diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h index 7757144a5..1377d97f3 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h @@ -95,7 +95,9 @@ public: /* Instruct the PHY to decode PDCCH with the CRC scrambled with given RNTI */ void pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1); void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1); - + void pdcch_ul_search_reset(); + void pdcch_dl_search_reset(); + /* Get/Set PHY parameters */ void set_param(phy_param_t param, int64_t value); int64_t get_param(phy_param_t param); @@ -103,10 +105,11 @@ public: void reset(); uint32_t get_current_tti(); + void get_current_cell(srslte_cell_t *cell); private: - const static int NOF_WORKERS = 1; + const static int NOF_WORKERS = 1; const static int SF_RECV_THREAD_PRIO = 1; const static int WORKERS_THREAD_PRIO = 0; @@ -124,8 +127,6 @@ private: /* Current time advance */ uint32_t n_ta; - srslte_cell_t cell; - bool init_(radio *radio_handler, mac_interface_phy *mac, log *log_h, bool do_agc); trace tr_start_time; diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/prach.h b/srsapps/ue/phy/include/srsapps/ue/phy/prach.h index 853fb496a..e4aae9105 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/prach.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/prach.h @@ -57,7 +57,7 @@ namespace ue { bool send(radio* radio_handler, float cfo, srslte_timestamp_t rx_time); private: - static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission + static const uint32_t tx_advance_sf = 4; // Number of subframes to advance transmission phy_params *params_db; log *log_h; int preamble_idx; diff --git a/srsapps/ue/phy/src/phch_common.cc b/srsapps/ue/phy/src/phch_common.cc index 33090c70c..51e2c45d9 100644 --- a/srsapps/ue/phy/src/phch_common.cc +++ b/srsapps/ue/phy/src/phch_common.cc @@ -60,14 +60,18 @@ bool phch_common::ul_rnti_active(uint32_t tti) { (tti < ul_rnti_end && ul_rnti_end >= 0 || ul_rnti_end < 0)) { return true; + } else { + return false; } } bool phch_common::dl_rnti_active(uint32_t tti) { - if ((tti >= dl_rnti_start && dl_rnti_start >= 0 || dl_rnti_start < 0) && - (tti < dl_rnti_end && dl_rnti_end >= 0 || dl_rnti_end < 0)) + if (((tti >= dl_rnti_start && dl_rnti_start >= 0) || dl_rnti_start < 0) && + ((tti < dl_rnti_end && dl_rnti_end >= 0) || dl_rnti_end < 0)) { return true; + } else { + return false; } } @@ -76,6 +80,8 @@ void phch_common::set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_G { srslte_dci_rar_grant_unpack(&rar_grant, grant_payload); rar_grant_pending = true; + Info("Setting RAR grant: \n"); + srslte_dci_rar_grant_fprint(stdout, &rar_grant); // PUSCH is at n+6 or n+7 and phch_worker assumes default delay of 4 ttis if (rar_grant.ul_delay) { rar_grant_tti = (tti + 3) % 10240; @@ -86,8 +92,11 @@ void phch_common::set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_G bool phch_common::get_pending_rar(uint32_t tti, srslte_dci_rar_grant_t *rar_grant_) { - if (rar_grant_pending && tti >= rar_grant_tti) { - memcpy(rar_grant_, &rar_grant, sizeof(srslte_dci_rar_grant_t)); + if (rar_grant_pending && (tti >= rar_grant_tti || (tti < 10 && rar_grant_pending > 10235))) { + if (rar_grant_) { + rar_grant_pending = false; + memcpy(rar_grant_, &rar_grant, sizeof(srslte_dci_rar_grant_t)); + } return true; } return false; @@ -97,6 +106,8 @@ bool phch_common::get_pending_rar(uint32_t tti, srslte_dci_rar_grant_t *rar_gran uint16_t phch_common::get_ul_rnti(uint32_t tti) { if (ul_rnti_active(tti)) { return ul_rnti; + } else { + return 0; } } srslte_rnti_type_t phch_common::get_ul_rnti_type() { @@ -111,6 +122,8 @@ void phch_common::set_ul_rnti(srslte_rnti_type_t type, uint16_t rnti_value, int uint16_t phch_common::get_dl_rnti(uint32_t tti) { if (dl_rnti_active(tti)) { return dl_rnti; + } else { + return 0; } } srslte_rnti_type_t phch_common::get_dl_rnti_type() { @@ -121,6 +134,7 @@ void phch_common::set_dl_rnti(srslte_rnti_type_t type, uint16_t rnti_value, int dl_rnti_type = type; dl_rnti_start = tti_start; dl_rnti_end = tti_end; + Debug("Set DL rnti: start=%d, end=%d, value=0x%x\n", tti_start, tti_end, rnti_value); } void phch_common::reset_pending_ack(uint32_t tti) { @@ -131,6 +145,7 @@ void phch_common::set_pending_ack(uint32_t tti, uint32_t I_lowest, uint32_t n_dm pending_ack[tti%10].enabled = true; pending_ack[tti%10].I_lowest = I_lowest; pending_ack[tti%10].n_dmrs = n_dmrs; + Debug("Set pending ACK for tti=%d I_lowest=%d, n_dmrs=%d\n", tti, I_lowest, n_dmrs); } bool phch_common::get_pending_ack(uint32_t tti) { diff --git a/srsapps/ue/phy/src/phch_recv.cc b/srsapps/ue/phy/src/phch_recv.cc index 3c3ad8fe3..73e7f9ca3 100644 --- a/srsapps/ue/phy/src/phch_recv.cc +++ b/srsapps/ue/phy/src/phch_recv.cc @@ -42,7 +42,7 @@ phch_recv::phch_recv() { } bool phch_recv::init(radio* _radio_handler, mac_interface_phy *_mac, prach* _prach_buffer, thread_pool* _workers_pool, - phch_common* _worker_com, log* _log_h, bool do_agc_) + phch_common* _worker_com, log* _log_h, bool do_agc_, uint32_t prio) { radio_h = _radio_handler; log_h = _log_h; @@ -55,18 +55,22 @@ bool phch_recv::init(radio* _radio_handler, mac_interface_phy *_mac, prach* _pra time_adv_sec = 0; cell_is_set = false; do_agc = do_agc_; - start(); + start(prio); } void phch_recv::stop() { running = false; + wait_thread_finish(); } -int radio_recv_wrapper_cs(void *h,void *data, uint32_t nsamples, srslte_timestamp_t *rx_time) +int radio_recv_wrapper_cs(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *rx_time) { radio *radio_h = (radio*) h; - int n = radio_h->rx_now(data, nsamples, rx_time); - return n; + if (radio_h->rx_now(data, nsamples, rx_time)) { + return nsamples; + } else { + return -1; + } } double callback_set_rx_gain(void *h, double gain) { @@ -79,33 +83,29 @@ void phch_recv::set_time_adv_sec(float _time_adv_sec) { } bool phch_recv::init_cell() { - if (phy_state == IDLE) { - cell_is_set = false; - if (!srslte_ue_mib_init(&ue_mib, cell)) + cell_is_set = false; + if (!srslte_ue_mib_init(&ue_mib, cell)) + { + if (!srslte_ue_sync_init(&ue_sync, cell, radio_recv_wrapper_cs, radio_h)) { - if (!srslte_ue_sync_init(&ue_sync, cell, radio_recv_wrapper_cs, radio_h)) - { - - for (int i=0;iget_nof_workers();i++) { - if (((phch_worker*) workers_pool->get_worker(i))->init_cell(cell)) { - Error("Error setting cell: initiating PHCH worker\n"); - return false; - } - } - if (do_agc) { - srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, last_gain); + + for (int i=0;iget_nof_workers();i++) { + if (!((phch_worker*) workers_pool->get_worker(i))->init_cell(cell)) { + Error("Error setting cell: initiating PHCH worker\n"); + return false; } - srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo); - cell_is_set = true; - } else { - Error("Error setting cell: initiating ue_sync"); } + if (do_agc) { + srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, last_gain); + } + srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo); + cell_is_set = true; } else { - Error("Error setting cell: initiating ue_mib\n"); - } + Error("Error setting cell: initiating ue_sync"); + } } else { - Error("Error setting cell: Invalid state %d\n", phy_state); - } + Error("Error setting cell: initiating ue_mib\n"); + } return cell_is_set; } @@ -130,6 +130,7 @@ bool phch_recv::cell_search(int force_N_id_2) bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); if (srslte_ue_cellsearch_init(&cs, radio_recv_wrapper_cs, radio_h)) { + Error("Initiating UE cell search\n"); return false; } @@ -148,6 +149,7 @@ bool phch_recv::cell_search(int force_N_id_2) /* 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; int ret = SRSLTE_ERROR; + 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]); max_peak_cell = force_N_id_2; @@ -178,6 +180,7 @@ bool phch_recv::cell_search(int force_N_id_2) 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_h)) { + Error("Initiating UE MIB synchronization\n"); return false; } @@ -187,7 +190,6 @@ bool phch_recv::cell_search(int force_N_id_2) /* Find and decode MIB */ uint32_t sfn, sfn_offset; - radio_h->start_rx(); ret = srslte_ue_mib_sync_decode(&ue_mib_sync, worker_com->params_db->get_param(phy_interface_params::CELLSEARCH_TIMEOUT_MIB_NFRAMES), @@ -198,6 +200,7 @@ bool phch_recv::cell_search(int force_N_id_2) if (ret == 1) { srslte_pbch_mib_unpack(bch_payload, &cell, NULL); + srslte_cell_fprint(stdout, &cell, 0); mac->bch_decoded_ok(bch_payload); return true; } else { @@ -254,7 +257,10 @@ void phch_recv::run_thread() init_cell(); radio_h->set_rx_srate((float) srslte_sampling_freq_hz(cell.nof_prb)); radio_h->set_tx_srate((float) srslte_sampling_freq_hz(cell.nof_prb)); + Info("Cell found. Synchronizing...\n"); phy_state = SYNCING; + } else { + phy_state = IDLE; } break; case SYNCING: @@ -269,6 +275,7 @@ void phch_recv::run_thread() phy_state = IDLE; break; case 1: + Info("Synchronized.\n"); phy_state = SYNC_DONE; break; case 0: @@ -277,34 +284,44 @@ void phch_recv::run_thread() break; case SYNC_DONE: worker = (phch_worker*) workers_pool->wait_worker(); - buffer = worker->get_buffer(); - if (srslte_ue_sync_zerocopy(&ue_sync, buffer) == 1) { - - float cfo = srslte_ue_sync_get_cfo(&ue_sync)/15000; - worker->set_cfo(cfo); - - srslte_timestamp_t rx_time; - srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time); - srslte_timestamp_add(&rx_time, 0, 1e-3 - time_adv_sec); - worker->set_tx_time(rx_time); - worker->set_tti(tti); - - // Check if we need to TX a PRACH - if (prach_buffer->is_ready_to_send(tti)) { - // send prach if we have to - prach_buffer->send(radio_h, cfo, rx_time); - radio_h->tx_end(); + if (worker) { + buffer = worker->get_buffer(); + if (srslte_ue_sync_zerocopy(&ue_sync, buffer) == 1) { + tti = (tti + 1) % 10240; + log_h->step(tti); - /* Setup DL RNTI search to look for RAR as configured by MAC */ - uint16_t rar_rnti; - uint32_t rar_start, rar_end; - prach_buffer->get_rar_cfg(&rar_rnti, &rar_start, &rar_end); - worker_com->set_dl_rnti(SRSLTE_RNTI_RAR, rar_rnti, (int) rar_start, (int) rar_end); - } else { - workers_pool->start_worker(worker); + float cfo = srslte_ue_sync_get_cfo(&ue_sync)/15000; + worker->set_cfo(cfo); + + /* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */ + srslte_timestamp_t rx_time, tx_time; + srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time); + srslte_timestamp_copy(&tx_time, &rx_time); + srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec); + worker->set_tx_time(tx_time); + worker->set_tti(tti); + + // Check if we need to TX a PRACH + if (prach_buffer->is_ready_to_send(tti)) { + srslte_timestamp_t cur_time; + radio_h->get_time(&cur_time); + Info("TX PRACH now. RX time: %d:%f, Now: %d:%f\n", rx_time.full_secs, rx_time.frac_secs, cur_time.full_secs, cur_time.frac_secs); + // send prach if we have to + prach_buffer->send(radio_h, cfo, tx_time); + radio_h->tx_end(); + + /* Setup DL RNTI search to look for RAR as configured by MAC */ + uint16_t rar_rnti; + uint32_t rar_start, rar_end; + prach_buffer->get_rar_cfg(&rar_rnti, &rar_start, &rar_end); + worker_com->set_dl_rnti(SRSLTE_RNTI_RAR, rar_rnti, (int) rar_start, (int) rar_end); + } + workers_pool->start_worker(worker); } + } else { + // wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here + running = false; } - tti = (tti + 1) % 10240; break; case IDLE: usleep(1000); @@ -323,6 +340,13 @@ bool phch_recv::status_is_sync() return phy_state == SYNC_DONE; } +void phch_recv::get_current_cell(srslte_cell_t* cell_) +{ + if (cell_) { + memcpy(cell_, &cell, sizeof(srslte_cell_t)); + } +} + void phch_recv::sync_start() { phy_state = CELL_SEARCH; diff --git a/srsapps/ue/phy/src/phch_worker.cc b/srsapps/ue/phy/src/phch_worker.cc index 20a0087ce..e73a0a6e5 100644 --- a/srsapps/ue/phy/src/phch_worker.cc +++ b/srsapps/ue/phy/src/phch_worker.cc @@ -39,16 +39,14 @@ phch_worker::phch_worker() { phy = NULL; signal_buffer = NULL; - - bzero(&cell, sizeof(srslte_cell_t)); - bzero(&ue_dl, sizeof(srslte_ue_dl_t)); - bzero(&ue_ul, sizeof(srslte_ue_ul_t)); - bzero(&uci_data, sizeof(srslte_uci_data_t)); + ul_payload = NULL; cell_initiated = false; pregen_enabled = false; rar_cqi_request = false; - cfi = 0; + cfi = 0; + + reset_ul_params(); } @@ -67,6 +65,13 @@ bool phch_worker::init_cell(srslte_cell_t cell_) Error("Allocating memory\n"); return false; } + ul_payload_max_len = srslte_ra_tbs_from_idx(26, cell.nof_prb); + ul_payload = (uint8_t*) srslte_vec_malloc(sizeof(uint8_t) * ul_payload_max_len); + if (!ul_payload) { + Error("Allocating memory\n"); + return false; + } + if (srslte_ue_dl_init(&ue_dl, cell)) { Error("Initiating UE DL\n"); return false; @@ -80,7 +85,7 @@ bool phch_worker::init_cell(srslte_cell_t cell_) srslte_ue_ul_set_normalization(&ue_ul, false); srslte_ue_ul_set_cfo_enable(&ue_ul, true); - cell_initiated = false; + cell_initiated = true; return true; } @@ -139,6 +144,7 @@ void phch_worker::work_imp() /* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */ if (extract_fft_and_pdcch_llr()) { + /***** Downlink Processing *******/ /* PDCCH DL + PDSCH */ @@ -149,7 +155,7 @@ void phch_worker::work_imp() /* Decode PDSCH if instructed to do so */ bool dl_ack = dl_action.default_ack; if (dl_action.decode_enabled) { - dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, dl_action.softbuffer, dl_action.rv); + dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, dl_action.softbuffer, dl_action.rv, dl_action.rnti); phy->mac->tb_decoded_ok(dl_mac_grant.pid); } if (dl_action.generate_ack) { @@ -164,7 +170,7 @@ void phch_worker::work_imp() /***** Uplink Processing + Transmission *******/ - + /* Generate UCI */ set_uci_sr(); set_uci_cqi(); @@ -188,10 +194,11 @@ void phch_worker::work_imp() /* Transmit PUSCH, PUCCH or SRS */ bool tx_signal = false; - if (ul_grant_available) { - if (ul_action.tx_enabled) { - encode_pusch(&ul_action.phy_grant.ul, ul_action.rv, ul_action.current_tx_nb, ul_action.softbuffer); - tx_signal = true; + if (ul_action.tx_enabled) { + encode_pusch(&ul_action.phy_grant.ul, ul_action.current_tx_nb, ul_action.softbuffer, ul_action.rv, ul_action.rnti); + tx_signal = true; + if (ul_action.expect_ack) { + phy->set_pending_ack(tti + 8, ue_ul.pusch_cfg.grant.n_prb_tilde[0], ul_action.phy_grant.ul.ncs_dmrs); } } else if (dl_action.generate_ack) { encode_pucch(); @@ -208,19 +215,21 @@ void phch_worker::work_imp() bool phch_worker::extract_fft_and_pdcch_llr() { bool decode_pdcch = false; - if (phy->get_ul_rnti(tti) || phy->get_dl_rnti(tti)) { + if (phy->get_ul_rnti(tti) || phy->get_dl_rnti(tti) || phy->get_pending_rar(tti)) { decode_pdcch = true; - } + } /* Without a grant, we might need to do fft processing if need to decode PHICH */ if (phy->get_pending_ack(tti) || decode_pdcch) { + Debug("Running FFT estimate\n"); if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { Error("Getting PDCCH FFT estimate\n"); return false; } } - + if (decode_pdcch) { /* and not in DRX mode */ + Debug("Extracting PDCCH LLR\n"); if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) { Error("Extracting PDCCH LLR\n"); return false; @@ -252,10 +261,12 @@ bool phch_worker::decode_pdcch_dl(srslte::ue::mac_interface_phy::mac_grant_t* gr srslte_ra_dl_dci_t dci_unpacked; if (srslte_ue_dl_find_dl_dci_type(&ue_dl, &dci_msg, cfi, tti%10, dl_rnti, type) != 1) { + Debug("Can't find DL DCI message\n"); return false; } if (srslte_dci_msg_to_dl_grant(&dci_msg, dl_rnti, cell.nof_prb, &dci_unpacked, &grant->phy_grant.dl)) { + Error("Converting DCI message to DL grant\n"); return false; } @@ -264,7 +275,8 @@ bool phch_worker::decode_pdcch_dl(srslte::ue::mac_interface_phy::mac_grant_t* gr grant->pid = dci_unpacked.harq_process; grant->tbs = grant->phy_grant.dl.mcs.tbs; grant->tti = tti; - grant->rnti_type = type; + grant->rv = dci_unpacked.rv_idx; + grant->rnti = dl_rnti; last_dl_pdcch_ncce = srslte_ue_dl_get_ncce(&ue_dl); @@ -277,16 +289,24 @@ bool phch_worker::decode_pdcch_dl(srslte::ue::mac_interface_phy::mac_grant_t* gr } } -bool phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t* softbuffer, uint32_t rv) +bool phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, + srslte_softbuffer_rx_t* softbuffer, uint32_t rv, uint16_t rnti) { Debug("DL Buffer TTI %d: Decoding PDSCH\n", tti); /* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */ - if (!srslte_ue_dl_cfg_grant(&ue_dl, grant, cfi, tti%10, dl_rnti, rv)) { + if (!srslte_ue_dl_cfg_grant(&ue_dl, grant, cfi, tti%10, rnti, rv)) { if (ue_dl.pdsch_cfg.grant.mcs.mod > 0 && ue_dl.pdsch_cfg.grant.mcs.tbs >= 0) { - return srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffer, ue_dl.sf_symbols, - ue_dl.ce, 0, dl_rnti, payload) == 0; + if (srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffer, ue_dl.sf_symbols, + ue_dl.ce, 0, rnti, payload) == 0) + { + Debug("TB decoded OK\n"); + return true; + } else { + Debug("TB decoded KO\n"); + return false; + } } else { Warning("Received grant for TBS=0\n"); } @@ -301,8 +321,10 @@ bool phch_worker::decode_phich(bool *ack) uint32_t I_lowest, n_dmrs; if (phy->get_pending_ack(tti, &I_lowest, &n_dmrs)) { if (ack) { + Debug("Decoding PHICH I_lowest=%d, n_dmrs=%d\n", I_lowest, n_dmrs); *ack = srslte_ue_dl_decode_phich(&ue_dl, tti%10, I_lowest, n_dmrs); } + phy->reset_pending_ack(tti); return true; } else { return false; @@ -317,6 +339,7 @@ bool phch_worker::decode_phich(bool *ack) bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) { phy->reset_pending_ack(tti + 4); + srslte_dci_msg_t dci_msg; srslte_ra_ul_dci_t dci_unpacked; srslte_dci_rar_grant_t rar_grant; @@ -324,9 +347,14 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) bool ret = false; if (phy->get_pending_rar(tti, &rar_grant)) { - if (srslte_dci_rar_to_ul_grant(&rar_grant, cell.nof_prb, pusch_hopping.hopping_offset, &dci_unpacked, &grant->phy_grant.ul)) { + Info("Pending RAR UL grant\n"); + if (srslte_dci_rar_to_ul_grant(&rar_grant, cell.nof_prb, pusch_hopping.hopping_offset, + &dci_unpacked, &grant->phy_grant.ul)) + { + Error("Converting RAR message to UL grant\n"); return false; } + Info("RAR grant found for TTI=%d\n", tti); rar_cqi_request = rar_grant.cqi_request; ret = true; } else { @@ -338,9 +366,14 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) if (srslte_ue_dl_find_ul_dci(&ue_dl, &dci_msg, cfi, tti%10, ul_rnti) != 1) { return false; } - if (srslte_dci_msg_to_ul_grant(&dci_msg, cell.nof_prb, pusch_hopping.hopping_offset, &dci_unpacked, &grant->phy_grant.ul)) { + if (srslte_dci_msg_to_ul_grant(&dci_msg, cell.nof_prb, pusch_hopping.hopping_offset, + &dci_unpacked, &grant->phy_grant.ul)) + { + Error("Converting DCI message to UL grant\n"); return false; } + ret = true; + Info("PDCCH: UL DCI Format0 cce_index=%d, n_data_bits=%d\n", ue_dl.last_n_cce, dci_msg.nof_bits); } } if (ret) { @@ -348,9 +381,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) grant->pid = 0; // This is computed by MAC from TTI grant->tbs = grant->phy_grant.ul.mcs.tbs; grant->tti = tti; - grant->rnti_type = type; - - Info("PDCCH: UL DCI Format0 cce_index=%d, n_data_bits=%d\n", ue_dl.last_n_cce, dci_msg.nof_bits); + grant->rnti = ul_rnti; if (SRSLTE_VERBOSE_ISINFO()) { srslte_ra_pusch_fprint(stdout, &dci_unpacked, cell.nof_prb); @@ -378,8 +409,8 @@ void phch_worker::set_uci_sr() uci_data.scheduling_request = false; if (phy->sr_enabled) { // Get I_sr parameter - if (srslte_ue_ul_sr_send_tti(I_sr, tti)) { - Info("SR transmission at TTI=%d\n", tti); + if (srslte_ue_ul_sr_send_tti(I_sr, tti+4)) { + Info("SR transmission at TTI=%d\n", tti+4); uci_data.scheduling_request = true; phy->sr_enabled = false; } @@ -389,7 +420,7 @@ void phch_worker::set_uci_sr() void phch_worker::set_uci_cqi() { if (cqi_cfg.configured || rar_cqi_request) { - if (srslte_cqi_send(cqi_cfg.pmi_idx, tti)) { + if (srslte_cqi_send(cqi_cfg.pmi_idx, tti+4)) { uci_data.uci_cqi_len = 4; uint8_t cqi[4] = {1, 1, 1, 1}; uci_data.uci_cqi = cqi; @@ -400,8 +431,8 @@ void phch_worker::set_uci_cqi() bool phch_worker::srs_is_ready_to_send() { if (srs_cfg.configured) { - if (srslte_refsignal_srs_send_cs(srs_cfg.subframe_config, tti%10) == 1 && - srslte_refsignal_srs_send_ue(srs_cfg.I_srs, tti) == 1) + if (srslte_refsignal_srs_send_cs(srs_cfg.subframe_config, (tti+4)%10) == 1 && + srslte_refsignal_srs_send_ue(srs_cfg.I_srs, tti+4) == 1) { return true; } @@ -418,30 +449,28 @@ void phch_worker::normalize() { srslte_vec_norm_cfc(signal_buffer, 0.9, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb)); } -void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t rv_idx, uint32_t current_tx_nb, srslte_softbuffer_tx_t* softbuffer) +void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t current_tx_nb, + srslte_softbuffer_tx_t* softbuffer, uint32_t rv, uint16_t rnti) { - if (srslte_ue_ul_cfg_grant(&ue_ul, grant, tti, rv_idx, current_tx_nb)) { + if (srslte_ue_ul_cfg_grant(&ue_ul, grant, tti+4, rv, current_tx_nb)) { Error("Configuring UL grant\n"); } - - phy->set_pending_ack(tti + 4, grant->n_prb_tilde[0], grant->ncs_dmrs); - - + if (srslte_ue_ul_pusch_encode_rnti_softbuffer(&ue_ul, ul_payload, uci_data, softbuffer, - ul_rnti, + rnti, signal_buffer)) { Error("Encoding PUSCH\n"); } Info("PUSCH: TTI=%d, CFO= %.1f KHz TBS=%d, mod=%s, rb_start=%d n_prb=%d, ack=%s, sr=%s, rnti=%d, shortened=%s\n", - tti, cfo*15e3, grant->mcs.tbs, srslte_mod_string(grant->mcs.mod), + tti+4, cfo*15e3, grant->mcs.tbs, srslte_mod_string(grant->mcs.mod), grant->n_prb[0], grant->L_prb, uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no", - ul_rnti, ue_ul.pusch.shortened?"yes":"no"); + rnti, ue_ul.pusch.shortened?"yes":"no"); normalize(); } @@ -449,13 +478,13 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t rv_idx, uin void phch_worker::encode_pucch() { - if (uci_data.scheduling_request || uci_data.uci_cqi_len > 0 || uci_data.uci_ack_len) + if (uci_data.scheduling_request || uci_data.uci_cqi_len > 0 || uci_data.uci_ack_len > 0) { - if (srslte_ue_ul_pucch_encode(&ue_ul, uci_data, last_dl_pdcch_ncce, tti, signal_buffer)) { + if (srslte_ue_ul_pucch_encode(&ue_ul, uci_data, last_dl_pdcch_ncce, tti+4, signal_buffer)) { Error("Encoding PUCCH\n"); } - Info("PUCCH: TTI=%d, CFO= %.1f KHz n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti, cfo*15e3, last_dl_pdcch_ncce, + Info("PUCCH: TTI=%d, CFO= %.1f KHz n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti+4, cfo*15e3, last_dl_pdcch_ncce, uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no", ue_ul.pucch.shortened?"yes":"no"); } @@ -464,12 +493,12 @@ void phch_worker::encode_pucch() void phch_worker::encode_srs() { - if (srslte_ue_ul_srs_encode(&ue_ul, tti, signal_buffer)) + if (srslte_ue_ul_srs_encode(&ue_ul, tti+4, signal_buffer)) { Error("Encoding SRS\n"); } - Info("SRS: TTI=%d, CFO= %.1f KHz \n", tti, cfo*15e3); + Info("SRS: TTI=%d, CFO= %.1f KHz \n", tti+4, cfo*15e3); normalize(); } @@ -479,6 +508,18 @@ void phch_worker::enable_pregen_signals(bool enabled) pregen_enabled = enabled; } +void phch_worker::reset_ul_params() +{ + bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); + bzero(&pusch_hopping, sizeof(srslte_pusch_hopping_cfg_t)); + bzero(&uci_cfg, sizeof(srslte_uci_cfg_t)); + bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t)); + bzero(&pucch_sched, sizeof(srslte_pucch_sched_t)); + bzero(&srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); + bzero(&cqi_cfg, sizeof(srslte_cqi_cfg_t)); + I_sr = 0; +} + void phch_worker::set_ul_params() { @@ -537,6 +578,7 @@ void phch_worker::set_ul_params() srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, &srs_cfg, &pucch_cfg, &pucch_sched, &uci_cfg, &pusch_hopping); /* CQI configuration */ + bzero(&cqi_cfg, sizeof(srslte_cqi_cfg_t)); cqi_cfg.configured = (bool) phy->params_db->get_param(phy_interface_params::CQI_PERIODIC_CONFIGURED)?true:false; cqi_cfg.pmi_idx = (uint32_t) phy->params_db->get_param(phy_interface_params::CQI_PERIODIC_PMI_IDX); diff --git a/srsapps/ue/phy/src/phy.cc b/srsapps/ue/phy/src/phy.cc index 3b00d5260..1f4ec65d4 100644 --- a/srsapps/ue/phy/src/phy.cc +++ b/srsapps/ue/phy/src/phy.cc @@ -69,17 +69,14 @@ bool phy::init_(radio* radio_handler_, mac_interface_phy *mac, log *log_h_, bool prach_buffer.init(¶ms_db, log_h); workers_common.init(¶ms_db, log_h, radio_handler, mac); - sf_recv.init(radio_handler, mac, &prach_buffer, &workers_pool, &workers_common, log_h, do_agc); // Add workers to workers pool and start threads for (int i=0;iget_param(phy_interface_params::PRACH_CONFIG_INDEX)), params_db->get_param(phy_interface_params::PRACH_ROOT_SEQ_IDX), params_db->get_param(phy_interface_params::PRACH_HIGH_SPEED_FLAG)?true:false, - params_db->get_param(phy_interface_params::PRACH_ZC_CONFIG))) { + params_db->get_param(phy_interface_params::PRACH_ZC_CONFIG))) + { + Error("Initiating PRACH library\n"); return false; } @@ -80,6 +83,7 @@ bool prach::init_cell(srslte_cell_t cell_) return false; } if(srslte_prach_gen(&prach_obj, i, params_db->get_param(phy_interface_params::PRACH_FREQ_OFFSET), buffer[i])) { + Error("Generating PRACH preamble %d\n", i); return false; } } @@ -87,6 +91,7 @@ bool prach::init_cell(srslte_cell_t cell_) signal_buffer = (cf_t*) srslte_vec_malloc(len*sizeof(cf_t)); initiated = signal_buffer?true:false; transmitted_tti = -1; + Info("PRACH Initiated %s\n", initiated?"OK":"KO"); return initiated; } @@ -97,6 +102,7 @@ bool prach::prepare_to_send(phy_interface::prach_cfg_t* cfg) if (ret) { memcpy(&prach_cfg, cfg, sizeof(phy_interface::prach_cfg_t)); } + return ret; } bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float target_power_dbm) @@ -105,9 +111,14 @@ bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float preamble_idx = preamble_idx_; allowed_subframe = allowed_subframe_; transmitted_tti = -1; - Info("PRACH Buffer: Prepare to send preamble %d\n", preamble_idx); + Info("PRACH prepare to send preamble %d\n", preamble_idx); return true; } else { + if (!initiated) { + Error("PRACH not initiated\n"); + } else if (preamble_idx_ >= 64) { + Error("Invalid preamble %d\n", preamble_idx_); + } return false; } } @@ -139,23 +150,18 @@ void prach::get_rar_cfg(uint16_t *rar_rnti, uint32_t *tti_start, uint32_t *tti_e } } -bool prach::send(radio *radio_handler, float cfo, srslte_timestamp_t rx_time) +bool prach::send(radio *radio_handler, float cfo, srslte_timestamp_t tx_time) { - // advance transmission time - srslte_timestamp_t tx_time; - srslte_timestamp_copy(&tx_time, &rx_time); - srslte_timestamp_add(&tx_time, 0, 1e-3*tx_advance_sf); - // Correct CFO before transmission srslte_cfo_correct(&cfo_h, buffer[preamble_idx], signal_buffer, cfo /srslte_symbol_sz(cell.nof_prb)); // Normalize signal amplitude srslte_vec_norm_cfc(signal_buffer, 0.9, signal_buffer, len); - radio_handler->tx(signal_buffer, len, tx_time); + radio_handler->tx(signal_buffer, len, tx_time); - Debug("PRACH transmitted CFO: %f, preamble=%d, len=%d rx_time=%f, tx_time=%f\n", - cfo*15000, preamble_idx, len, rx_time.frac_secs, tx_time.frac_secs); + Debug("PRACH transmitted CFO: %f, preamble=%d, len=%d tx_time=%f\n", + cfo*15000, preamble_idx, len, tx_time.frac_secs); preamble_idx = -1; } diff --git a/srsapps/ue/phy/test/CMakeLists.txt b/srsapps/ue/phy/test/CMakeLists.txt index fd74ce209..d5cc0af97 100644 --- a/srsapps/ue/phy/test/CMakeLists.txt +++ b/srsapps/ue/phy/test/CMakeLists.txt @@ -24,6 +24,6 @@ IF(UHD_FOUND) ADD_EXECUTABLE(ue_itf_test_sib1 ue_itf_test_sib1.cc) TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd) -# ADD_EXECUTABLE(ue_itf_test_prach ue_itf_test_prach.cc) -# TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd) + ADD_EXECUTABLE(ue_itf_test_prach ue_itf_test_prach.cc) + TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd) ENDIF(UHD_FOUND) diff --git a/srsapps/ue/phy/test/ue_itf_test_prach.cc b/srsapps/ue/phy/test/ue_itf_test_prach.cc index c9dc0e0e2..b363271ea 100644 --- a/srsapps/ue/phy/test/ue_itf_test_prach.cc +++ b/srsapps/ue/phy/test/ue_itf_test_prach.cc @@ -30,7 +30,6 @@ #include "srslte/utils/debug.h" #include "srsapps/ue/phy/phy.h" #include "srsapps/common/log_stdout.h" -#include "srsapps/common/tti_sync_cv.h" #include "srsapps/radio/radio_uhd.h" /********************************************************************** @@ -45,6 +44,7 @@ typedef struct { }prog_args_t; prog_args_t prog_args; +uint32_t srsapps_verbose = 0; void args_default(prog_args_t *args) { args->uhd_rx_freq = -1.0; @@ -83,7 +83,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) { args->continous = true; break; case 'v': - srslte_verbose++; + srsapps_verbose++; break; default: usage(args, argv[0]); @@ -98,18 +98,6 @@ void parse_args(prog_args_t *args, int argc, char **argv) { -typedef enum{ - rar_tpc_n6dB = 0, - rar_tpc_n4dB, - rar_tpc_n2dB, - rar_tpc_0dB, - rar_tpc_2dB, - rar_tpc_4dB, - rar_tpc_6dB, - rar_tpc_8dB, - rar_tpc_n_items, -}rar_tpc_command_t; -static const char tpc_command_text[rar_tpc_n_items][8] = {"-6dB", "-4dB", "-2dB", "0dB", "2dB", "4dB", "6dB", "8dB"}; typedef enum{ rar_header_type_bi = 0, rar_header_type_rapid, @@ -120,7 +108,7 @@ static const char rar_header_text[rar_header_type_n_items][8] = {"BI", "RAPID"}; typedef struct { rar_header_t hdr_type; bool hopping_flag; - rar_tpc_command_t tpc_command; + uint32_t tpc_command; bool ul_delay; bool csi_req; uint16_t rba; @@ -131,28 +119,6 @@ typedef struct { uint8_t BI; }rar_msg_t; -char *bool_to_string(bool x) { - if (x) { - return (char*) "Enabled"; - } else { - return (char*) "Disabled"; - } -} - -void rar_msg_fprint(FILE *stream, rar_msg_t *msg) -{ - fprintf(stream, "Header type: %s\n", rar_header_text[msg->hdr_type]); - fprintf(stream, "Hopping flag: %s\n", bool_to_string(msg->hopping_flag)); - fprintf(stream, "TPC command: %s\n", tpc_command_text[msg->tpc_command]); - fprintf(stream, "UL delay: %s\n", bool_to_string(msg->ul_delay)); - fprintf(stream, "CSI required: %s\n", bool_to_string(msg->csi_req)); - fprintf(stream, "RBA: %d\n", msg->rba); - fprintf(stream, "TA: %d\n", msg->timing_adv_cmd); - fprintf(stream, "T-CRNTI: %d\n", msg->temp_c_rnti); - fprintf(stream, "MCS: %d\n", msg->mcs); - fprintf(stream, "RAPID: %d\n", msg->RAPID); - fprintf(stream, "BI: %d\n", msg->BI); -} int rar_unpack(uint8_t *buffer, rar_msg_t *msg) { @@ -176,7 +142,7 @@ int rar_unpack(uint8_t *buffer, rar_msg_t *msg) msg->hopping_flag = *ptr++; msg->rba = srslte_bit_unpack(&ptr, 10); msg->mcs = srslte_bit_unpack(&ptr, 4); - msg->tpc_command = (rar_tpc_command_t) srslte_bit_unpack(&ptr, 3); + msg->tpc_command = srslte_bit_unpack(&ptr, 3); msg->ul_delay = *ptr++; msg->csi_req = *ptr++; msg->temp_c_rnti = srslte_bit_unpack(&ptr, 16); @@ -189,236 +155,155 @@ int rar_unpack(uint8_t *buffer, rar_msg_t *msg) -srslte::ue::phy phy; +srslte::ue::phy my_phy; +bool bch_decoded = false; -uint8_t payload[102400]; +uint8_t payload[10240]; const uint8_t conn_request_msg[] = {0x20, 0x06, 0x1F, 0x5C, 0x2C, 0x04, 0xB2, 0xAC, 0xF6, 0x00, 0x00, 0x00}; enum mac_state {RA, RAR, CONNREQUEST, CONNSETUP} state = RA; -uint32_t conreq_tti = 0; -uint32_t preamble_idx = 7; +uint32_t preamble_idx = 0; rar_msg_t rar_msg; -uint32_t nof_rx_connsetup = 0, nof_rx_rar = 0, nof_tx_ra = 0; uint32_t nof_rtx_connsetup = 0; uint32_t rv_value[4] = {0, 2, 3, 1}; void config_phy() { - phy.set_param(srslte::ue::phy_params::PRACH_CONFIG_INDEX, 0); - phy.set_param(srslte::ue::phy_params::PRACH_FREQ_OFFSET, 0); - phy.set_param(srslte::ue::phy_params::PRACH_HIGH_SPEED_FLAG, 0); - phy.set_param(srslte::ue::phy_params::PRACH_ROOT_SEQ_IDX, 0); - phy.set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG, 1); - - phy.set_param(srslte::ue::phy_params::PUSCH_BETA, 10); - phy.set_param(srslte::ue::phy_params::DMRS_GROUP_HOPPING_EN, 0); - phy.set_param(srslte::ue::phy_params::DMRS_SEQUENCE_HOPPING_EN, 0); - phy.set_param(srslte::ue::phy_params::PUSCH_RS_CYCLIC_SHIFT, 0); - phy.set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_ASSIGNMENT, 0); - phy.set_param(srslte::ue::phy_params::PUSCH_HOPPING_OFFSET, 0); - - phy.set_param(srslte::ue::phy_params::PUCCH_BETA, 10); - phy.set_param(srslte::ue::phy_params::PUCCH_DELTA_SHIFT, 1); - phy.set_param(srslte::ue::phy_params::PUCCH_CYCLIC_SHIFT, 0); - phy.set_param(srslte::ue::phy_params::PUCCH_N_PUCCH_1, 0); - phy.set_param(srslte::ue::phy_params::PUCCH_N_RB_2, 2); + my_phy.set_param(srslte::ue::phy_interface_params::PRACH_CONFIG_INDEX, 0); + my_phy.set_param(srslte::ue::phy_interface_params::PRACH_FREQ_OFFSET, 0); + my_phy.set_param(srslte::ue::phy_interface_params::PRACH_HIGH_SPEED_FLAG, 0); + my_phy.set_param(srslte::ue::phy_interface_params::PRACH_ROOT_SEQ_IDX, 0); + my_phy.set_param(srslte::ue::phy_interface_params::PRACH_ZC_CONFIG, 11); + + my_phy.set_param(srslte::ue::phy_interface_params::DMRS_GROUP_HOPPING_EN, 0); + my_phy.set_param(srslte::ue::phy_interface_params::DMRS_SEQUENCE_HOPPING_EN, 0); + my_phy.set_param(srslte::ue::phy_interface_params::PUSCH_HOPPING_N_SB, 2); + my_phy.set_param(srslte::ue::phy_interface_params::PUSCH_RS_CYCLIC_SHIFT, 0); + my_phy.set_param(srslte::ue::phy_interface_params::PUSCH_RS_GROUP_ASSIGNMENT, 0); + my_phy.set_param(srslte::ue::phy_interface_params::PUSCH_HOPPING_OFFSET, 0); + + my_phy.set_param(srslte::ue::phy_interface_params::PUCCH_DELTA_SHIFT, 2); + my_phy.set_param(srslte::ue::phy_interface_params::PUCCH_CYCLIC_SHIFT, 0); + my_phy.set_param(srslte::ue::phy_interface_params::PUCCH_N_PUCCH_1, 1); + my_phy.set_param(srslte::ue::phy_interface_params::PUCCH_N_RB_2, 2); + + my_phy.configure_prach_params(); + my_phy.configure_ul_params(); } -uint32_t interval(uint32_t x1, uint32_t x2) { - if (x1 > x2) { - return x1-x2; - } else { - return 10240-x2+x1; - } -} +srslte_softbuffer_rx_t softbuffer_rx; +srslte_softbuffer_tx_t softbuffer_tx; -srslte_softbuffer_rx_t softbuffer; +uint16_t temp_c_rnti; -// This is the MAC implementation -void run_tti(uint32_t tti) { - INFO("MAC running tti: %d\n", tti); +/******** MAC Interface implementation */ +class testmac : public srslte::ue::mac_interface_phy +{ +public: + void new_grant_ul(mac_grant_t grant, uint8_t *payload_ptr, tb_action_ul_t *action) { + printf("New grant UL\n"); + srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload_ptr, grant.tbs); + action->current_tx_nb = nof_rtx_connsetup; + action->rv = rv_value[nof_rtx_connsetup%4]; + action->softbuffer = &softbuffer_tx; + action->rnti = temp_c_rnti; + action->expect_ack = (nof_rtx_connsetup < 5)?true:false; + memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); + memcpy(&last_grant, &grant, sizeof(mac_grant_t)); + action->tx_enabled = true; + if (action->rv == 0) { + srslte_softbuffer_tx_reset(&softbuffer_tx); + } + my_phy.pdcch_dl_search(SRSLTE_RNTI_USER, temp_c_rnti); + } + + void new_grant_ul_ack(mac_grant_t grant, uint8_t *payload_ptr, bool ack, tb_action_ul_t *action) { + printf("New grant UL ACK\n"); + } - // Get buffer - srslte::ue::dl_buffer *dl_buffer = phy.get_dl_buffer(tti); + void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action) { + printf("harq recv hi=%d\n", ack?1:0); + if (!ack) { + nof_rtx_connsetup++; + action->current_tx_nb = nof_rtx_connsetup; + action->rv = rv_value[nof_rtx_connsetup%4]; + action->softbuffer = &softbuffer_tx; + action->rnti = temp_c_rnti; + action->expect_ack = true; + memcpy(&action->phy_grant, &last_grant.phy_grant, sizeof(srslte_phy_grant_t)); + action->tx_enabled = true; + if (action->rv == 0) { + srslte_softbuffer_tx_reset(&softbuffer_tx); + } + printf("Retransmission %d, rv=%d\n", nof_rtx_connsetup, action->rv); + } + } - if (state == RA) { - if (nof_tx_ra > 0 && !prog_args.continous) { - exit(0); - } - // Indicate PHY to transmit the PRACH when possible - if (phy.send_prach(preamble_idx)) { - nof_tx_ra++; - state = RAR; + void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) { + action->decode_enabled = true; + action->default_ack = false; + if (grant.rnti == 2) { + action->generate_ack = false; } else { - fprintf(stderr, "Error sending PRACH\n"); - exit(-1); + action->generate_ack = true; } - } - if (state == RAR) { - srslte::ue::dl_sched_grant rar_grant(2); - int ra_tti = phy.get_prach_transmitted_tti(); - if (ra_tti > 0) { - INFO("PRACH was transmitted at %d\n", ra_tti); - // Assume the maximum RA-window - uint32_t interval_ra = interval(tti, ra_tti); - INFO("Interval=%u\n", interval_ra); - if (interval_ra >= 3 && interval_ra <= 13) { - // Get DL grant for RA-RNTI=2 - if (dl_buffer->get_dl_grant(&rar_grant)) - { - srslte_softbuffer_rx_reset(&softbuffer); - // Decode packet - if (dl_buffer->decode_data(&rar_grant, &softbuffer, payload)) { - rar_unpack(payload, &rar_msg); - if (rar_msg.RAPID == preamble_idx) { - - INFO("Received RAR at TTI: %d\n", tti); - nof_rx_rar++; - - if (SRSLTE_VERBOSE_ISINFO()) { - rar_msg_fprint(stdout, &rar_msg); - } - - // Set time advance - phy.set_timeadv_rar(rar_msg.timing_adv_cmd); - - // Generate Msg3 grant - srslte::ue::ul_sched_grant connreq_grant(rar_msg.temp_c_rnti); - srslte_dci_rar_grant_t rar_grant; - rar_grant.rba = rar_msg.rba; - rar_grant.trunc_mcs = rar_msg.mcs; - rar_grant.hopping_flag = rar_msg.hopping_flag; - phy.rar_ul_grant(&rar_grant, &connreq_grant); - - // Pack Msg3 bits - srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload, connreq_grant.get_tbs()); - - // Get UL buffer - srslte::ue::ul_buffer *ul_buffer = phy.get_ul_buffer(tti+6); - - // Generate PUSCH - if (ul_buffer) { - connreq_grant.set_rv(0); - INFO("Generating PUSCH for TTI: %d\n", ul_buffer->tti); - ul_buffer->generate_data(&connreq_grant, payload); - - // Save transmission time - conreq_tti = ul_buffer->tti; - state = CONNREQUEST; - } else { - fprintf(stderr, "Error getting UL buffer for TTI %d\n", tti); - state = RA; - } - } - } - } - } else if (interval_ra > 13 && interval_ra < 100) { // avoid wrapping - INFO("RAR not received at TTI=%d (interval_ra=%d)\n", tti, interval_ra); - state = RA; - } + action->payload_ptr = payload; + action->rnti = grant.rnti; + memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); + memcpy(&last_grant, &grant, sizeof(mac_grant_t)); + action->rv = grant.rv; + action->softbuffer = &softbuffer_rx; + + if (action->rv == 0) { + srslte_softbuffer_rx_reset(&softbuffer_rx); } } - if (state == CONNREQUEST) { - uint32_t interval_conreq = interval(tti, conreq_tti); - if (interval_conreq == 4) { - - srslte::ue::ul_sched_grant connreq_grant(rar_msg.temp_c_rnti); - srslte_dci_rar_grant_t rar_grant; - rar_grant.rba = rar_msg.rba; - rar_grant.trunc_mcs = rar_msg.mcs; - rar_grant.hopping_flag = rar_msg.hopping_flag; - phy.rar_ul_grant(&rar_grant, &connreq_grant); - - // Decode PHICH from Connection Request - if (!dl_buffer->decode_ack(&connreq_grant)) { + + void tb_decoded_ok(uint32_t harq_pid) { + if (last_grant.rnti == 2) { + my_phy.pdcch_dl_search_reset(); + rar_unpack(payload, &rar_msg); + if (rar_msg.RAPID == preamble_idx) { + + printf("Received RAR at TTI: %d\n", last_grant.tti); + my_phy.set_timeadv_rar(rar_msg.timing_adv_cmd); - // Pack Msg3 bits - srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload, connreq_grant.get_tbs()); - - // Get UL buffer - srslte::ue::ul_buffer *ul_buffer = phy.get_ul_buffer(tti+4); + temp_c_rnti = rar_msg.temp_c_rnti; - // Generate PUSCH - if (ul_buffer) { - nof_rtx_connsetup++; - if (nof_rtx_connsetup >= 5) { - state = RA; - } else { - connreq_grant.set_current_tx_nb(nof_rtx_connsetup); - connreq_grant.set_rv(rv_value[nof_rtx_connsetup%4]); - INFO("Generating PUSCH for TTI: %d\n", ul_buffer->tti); - ul_buffer->generate_data(&connreq_grant, payload); - - // Save transmission time - conreq_tti = ul_buffer->tti; - } - } else { - fprintf(stderr, "Error getting UL buffer for TTI %d\n", tti); - state = RA; - } - } else { - srslte_softbuffer_rx_reset(&softbuffer); - state = CONNSETUP; - } - } - } - if (state == CONNSETUP) { - srslte::ue::dl_sched_grant conn_setup_grant(rar_msg.temp_c_rnti); - bool connsetup_recv = false; - // Get DL grant for tmp_rnti - if (dl_buffer->get_dl_grant(&conn_setup_grant)) - { - // Decode packet - if (dl_buffer->decode_data(&conn_setup_grant, &softbuffer, payload)) { - nof_rx_connsetup++; - state = RA; - nof_rtx_connsetup=0; - if (!prog_args.continous) { - printf("Connection Setup received (%d/%d)\n", nof_rx_connsetup, nof_tx_ra); + if (last_grant.tbs > 20 + SRSLTE_RAR_GRANT_LEN) { + uint8_t rar_grant[SRSLTE_RAR_GRANT_LEN]; + memcpy(rar_grant, &payload[20], sizeof(uint8_t)*SRSLTE_RAR_GRANT_LEN); + my_phy.set_rar_grant(last_grant.tti, rar_grant); } - connsetup_recv = true; } else { - INFO("Error decoding PDSCH for Connection Request at TTI=%d\n", tti); + printf("Received RAR RAPID=%d\n", rar_msg.RAPID); } - - // send ACK - INFO("Sending ack %d on TTI: %d\n", connsetup_recv, tti+4); - srslte::ue::ul_buffer *ul_buffer = phy.get_ul_buffer(tti+4); - ul_buffer->generate_ack(connsetup_recv, &conn_setup_grant); - if (!prog_args.continous) { - while(ul_buffer->uci_ready()) { - sleep(1); - } - } - state = RA; - } else { - INFO("DCI for Connection Request not found on PDCCH at TTI=%d\n", tti); - state = RA; - } - } - float gain = prog_args.uhd_rx_gain; - if (gain < 0) { - gain = phy.get_agc_gain(); + printf("Received Connection Setup\n"); + my_phy.pdcch_dl_search_reset(); + } } - if (srslte_verbose == SRSLTE_VERBOSE_NONE && prog_args.continous) { - printf("RECV RAR %2.1f \%% RECV ConnSetup %2.1f \%% (%5u/%5u) Gain: %.1f dB\r", - (float) 100*nof_rx_rar/nof_tx_ra, - (float) 100*nof_rx_connsetup/nof_tx_ra, - nof_rx_connsetup, nof_tx_ra, gain); + + void bch_decoded_ok(uint8_t *payload) { + printf("BCH decoded\n"); + bch_decoded = true; + srslte_cell_t cell; + my_phy.get_current_cell(&cell); + srslte_softbuffer_rx_init(&softbuffer_rx, cell); + srslte_softbuffer_tx_init(&softbuffer_tx, cell); } - - -} +private: + mac_grant_t last_grant; +}; + +testmac my_mac; +srslte::radio_uhd radio_uhd; + int main(int argc, char *argv[]) { - srslte_cell_t cell; - uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - srslte::ue::tti_sync_cv ttisync(10240); - srslte::radio_uhd radio_uhd; srslte::log_stdout log("PHY"); parse_args(&prog_args, argc, argv); @@ -428,56 +313,55 @@ int main(int argc, char *argv[]) radio_uhd.init(); radio_uhd.set_rx_gain(prog_args.uhd_rx_gain); radio_uhd.set_tx_gain(prog_args.uhd_tx_gain); - phy.init(&radio_uhd, &ttisync, &log); + my_phy.init(&radio_uhd, &my_mac, &log); } else { radio_uhd.init_agc(); - radio_uhd.set_tx_rx_gain_offset(-10); - phy.init_agc(&radio_uhd, &ttisync, &log); + radio_uhd.set_tx_rx_gain_offset(0); + my_phy.init_agc(&radio_uhd, &my_mac, &log); } + if (srsapps_verbose == 1) { + log.set_level_info(); + printf("Log level info\n"); + } + if (srsapps_verbose == 2) { + log.set_level_debug(); + printf("Log level debug\n"); + } + // Give it time to create thread sleep(1); - // Setup PHY parameters - config_phy(); - // Set RX freq radio_uhd.set_rx_freq(prog_args.uhd_rx_freq); radio_uhd.set_tx_freq(prog_args.uhd_tx_freq); - /* Instruct the PHY to decode BCH */ - if (!phy.decode_mib_best(&cell, bch_payload)) { - exit(-1); - } - // Print MIB - srslte_cell_fprint(stdout, &cell, phy.get_current_tti()/10); + // Instruct the PHY to configure PRACH parameters and sync to current cell + my_phy.sync_start(); - // Set the current PHY cell to the detected cell - if (!phy.set_cell(cell)) { - printf("Error setting cell\n"); - exit(-1); + while(!my_phy.status_is_sync()) { + usleep(20000); } - - if (!phy.init_prach()) { - printf("Error initiating PRACH\n"); - exit(-1); - } - - srslte_softbuffer_rx_init(&softbuffer, cell); - /* Instruct the PHY to start RX streaming and synchronize */ - if (!phy.start_rxtx()) { - printf("Could not start RX\n"); - exit(-1); - } - for (int i=0;i<100;i++) { - ttisync.wait(); - } + // Setup PHY parameters + config_phy(); + + /* Instruct PHY to send PRACH and prepare it for receiving RAR */ + srslte::ue::phy_interface::prach_cfg_t prach_cfg; + prach_cfg.allowed_subframe_enabled = false; + prach_cfg.preamble_idx = preamble_idx; + prach_cfg.rar_rnti = 2; + prach_cfg.rar_start = 3; + prach_cfg.rar_window = 10; + my_phy.prach_send(&prach_cfg); + /* go to idle and process each tti */ - while(1) { - uint32_t tti = ttisync.wait(); - run_tti(tti); + bool running = true; + while(running) { + sleep(1); } + my_phy.stop(); + radio_uhd.stop_rx(); } diff --git a/srsapps/ue/phy/test/ue_itf_test_sib1.cc b/srsapps/ue/phy/test/ue_itf_test_sib1.cc index 97d1d94ca..47326608c 100644 --- a/srsapps/ue/phy/test/ue_itf_test_sib1.cc +++ b/srsapps/ue/phy/test/ue_itf_test_sib1.cc @@ -43,6 +43,8 @@ typedef struct { float uhd_gain; }prog_args_t; +uint32_t srsapps_verbose = 0; + prog_args_t prog_args; void args_default(prog_args_t *args) { @@ -68,7 +70,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) { args->uhd_freq = atof(argv[optind]); break; case 'v': - srslte_verbose++; + srsapps_verbose++; break; default: usage(args, argv[0]); @@ -81,6 +83,13 @@ void parse_args(prog_args_t *args, int argc, char **argv) { } } +srslte::ue::phy my_phy; +bool bch_decoded = false; +uint32_t total_pkts=0; +uint32_t total_dci=0; +uint32_t total_oks=0; +uint8_t payload[1024]; +srslte_softbuffer_rx_t softbuffer; /******** MAC Interface implementation */ class testmac : public srslte::ue::mac_interface_phy @@ -98,70 +107,46 @@ public: } void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) { - printf("New grant DL\n"); + total_dci++; + + + action->decode_enabled = true; + action->default_ack = false; + action->generate_ack = false; + action->payload_ptr = payload; + memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); + action->rv = ((uint32_t) ceilf((float)3*((my_phy.tti_to_SFN(grant.tti)/2)%4)/2))%4; + action->softbuffer = &softbuffer; + + if (action->rv == 0) { + srslte_softbuffer_rx_reset(&softbuffer); + } } void tb_decoded_ok(uint32_t harq_pid) { - printf("TB decoded OK\n"); + total_oks++; } void bch_decoded_ok(uint8_t *payload) { printf("BCH decoded\n"); + bch_decoded = true; + srslte_cell_t cell; + my_phy.get_current_cell(&cell); + srslte_softbuffer_rx_init(&softbuffer, cell); + + } }; +testmac my_mac; +srslte::radio_uhd radio_uhd; -#ifdef kk -uint32_t total_pkts=0; -uint32_t total_dci=0; -uint32_t total_errors=0; -uint8_t payload[1024]; -// This is the MAC implementation -void run_tti(uint32_t tti) { - INFO("MAC running tti: %d\n", tti); - - // SIB1 is scheduled in subframe #5 of even frames - if ((phy.tti_to_SFN(tti)%2) == 0 && phy.tti_to_subf(tti) == 5) { - // Get buffer - srslte::ue::dl_buffer *buffer = phy.get_dl_buffer(tti); - - // Get DL grant - if (buffer->get_dl_grant(&grant)) - { - total_dci++; - // MAC sets RV - grant.set_rv(((uint32_t) ceilf((float)3*((phy.tti_to_SFN(tti)/2)%4)/2))%4); - - // Decode packet - if (!buffer->decode_data(&grant, payload)) { - total_errors++; - } - } - total_pkts++; - } - float gain = prog_args.uhd_gain; - if (gain < 0) { - gain = phy.get_agc_gain(); - } - if (srslte_verbose == SRSLTE_VERBOSE_NONE) { - printf("PDCCH BLER %.1f \%% PDSCH BLER %.1f \%% (total pkts: %5u) Gain: %.1f dB\r", - 100-(float) 100*total_dci/total_pkts, - (float) 100*total_errors/total_pkts, - total_pkts, gain); - } -} -#endif int main(int argc, char *argv[]) { - srslte::ue::phy phy; - testmac mac; - srslte_cell_t cell; - uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - srslte::radio_uhd radio_uhd; srslte::log_stdout log("PHY"); parse_args(&prog_args, argc, argv); @@ -170,28 +155,54 @@ int main(int argc, char *argv[]) if (prog_args.uhd_gain > 0) { radio_uhd.init(); radio_uhd.set_rx_gain(prog_args.uhd_gain); - phy.init(&radio_uhd, &mac, &log); + my_phy.init(&radio_uhd, &my_mac, &log); } else { radio_uhd.init_agc(); - phy.init_agc(&radio_uhd, &mac, &log); + my_phy.init_agc(&radio_uhd, &my_mac, &log); } + if (srsapps_verbose == 1) { + log.set_level_info(); + printf("Log level info\n"); + } + if (srsapps_verbose == 2) { + log.set_level_debug(); + printf("Log level debug\n"); + } + // Give it time to create thread sleep(1); - - // Set default parameters - phy.set_param(srslte::ue::phy_interface_params::PRACH_CONFIG_INDEX, 0); - phy.set_param(srslte::ue::phy_interface_params::PRACH_ROOT_SEQ_IDX, 0); - phy.set_param(srslte::ue::phy_interface_params::PRACH_HIGH_SPEED_FLAG, 0); - phy.set_param(srslte::ue::phy_interface_params::PRACH_ZC_CONFIG, 1); - + // Set RX freq and gain radio_uhd.set_rx_freq(prog_args.uhd_freq); - radio_uhd.set_rx_gain(prog_args.uhd_gain); - - phy.sync_start(); - while(1) { - usleep(1000); + my_phy.sync_start(); + + bool running = true; + while(running) { + if (bch_decoded && my_phy.status_is_sync()) { + uint32_t tti = my_phy.get_current_tti(); + + // SIB1 is scheduled in subframe #5 of even frames, try to decode next frame SIB1 + tti = (((tti/20)*20) + 25)%10240; + my_phy.pdcch_dl_search(SRSLTE_RNTI_SI, SRSLTE_SIRNTI, tti, tti+1); + + total_pkts++; + } + usleep(30000); + if (bch_decoded && my_phy.status_is_sync() && total_pkts > 0) { + if (srslte_verbose == SRSLTE_VERBOSE_NONE && srsapps_verbose == 0) { + float gain = prog_args.uhd_gain; + if (gain < 0) { + gain = radio_uhd.get_rx_gain(); + } + printf("PDCCH BLER %.1f \%% PDSCH BLER %.1f \%% (total pkts: %5u) Gain: %.1f dB\r", + 100-(float) 100*total_dci/total_pkts, + (float) 100*(1 - total_oks/total_pkts), + total_pkts, gain); + } + } } + my_phy.stop(); + radio_uhd.stop_rx(); } \ No newline at end of file diff --git a/srslte/lib/phch/src/prach.c b/srslte/lib/phch/src/prach.c index 3745c9ae2..62ff7fed1 100644 --- a/srslte/lib/phch/src/prach.c +++ b/srslte/lib/phch/src/prach.c @@ -411,15 +411,17 @@ int srslte_prach_init(srslte_prach_t *p, p->ifft_in = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t)); p->ifft_out = (cf_t*)srslte_vec_malloc(p->N_ifft_prach*sizeof(cf_t)); p->ifft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); - if(srslte_dft_plan(p->ifft, p->N_ifft_prach, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)){ - return -1; + if(srslte_dft_plan(p->ifft, p->N_ifft_prach, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { + fprintf(stderr, "Error creating DFT plan\n"); + return -1; } srslte_dft_plan_set_mirror(p->ifft, true); srslte_dft_plan_set_norm(p->ifft, true); p->fft = (srslte_dft_plan_t*)srslte_vec_malloc(sizeof(srslte_dft_plan_t)); if(srslte_dft_plan(p->fft, p->N_ifft_prach, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)){ - return -1; + fprintf(stderr, "Error creating DFT plan\n"); + return -1; } srslte_dft_plan_set_mirror(p->fft, true); srslte_dft_plan_set_norm(p->fft, true); @@ -428,6 +430,8 @@ int srslte_prach_init(srslte_prach_t *p, p->N_cp = prach_Tcp[p->f]*p->N_ifft_ul/2048; ret = SRSLTE_SUCCESS; + } else { + fprintf(stderr, "Invalid parameters\n"); } return ret; diff --git a/srslte/lib/ue/src/ue_dl.c b/srslte/lib/ue/src/ue_dl.c index d4fa63960..51ed1cd4c 100644 --- a/srslte/lib/ue/src/ue_dl.c +++ b/srslte/lib/ue/src/ue_dl.c @@ -379,7 +379,7 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr uint32_t Ngroups = srslte_phich_ngroups(&q->phich); uint32_t ngroup = (n_prb_lowest+n_dmrs)%Ngroups; uint32_t nseq = ((n_prb_lowest/Ngroups)+n_dmrs)%(2*srslte_phich_nsf(&q->phich)); - INFO("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, n_group=%d, n_seq=%d\n", + DEBUG("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, n_group=%d, n_seq=%d\n", sf_idx, n_prb_lowest, n_dmrs, ngroup, nseq); if (!srslte_phich_decode(&q->phich, q->sf_symbols, q->ce, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { INFO("Decoded PHICH %d with distance %f\n", ack_bit, distance); diff --git a/srslte/lib/ue/src/ue_sync.c b/srslte/lib/ue/src/ue_sync.c index 31efbcbe1..bc34a9c78 100644 --- a/srslte/lib/ue/src/ue_sync.c +++ b/srslte/lib/ue/src/ue_sync.c @@ -386,7 +386,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t track_idx; - if (q != NULL && + if (q != NULL && input_buffer != NULL) { diff --git a/srslte/lib/utils/src/convolution.c b/srslte/lib/utils/src/convolution.c index debeb253d..5891c5916 100644 --- a/srslte/lib/utils/src/convolution.c +++ b/srslte/lib/utils/src/convolution.c @@ -45,12 +45,15 @@ int srslte_conv_fft_cc_init(srslte_conv_fft_cc_t *q, uint32_t input_len, uint32_ return SRSLTE_ERROR; } if (srslte_dft_plan(&q->input_plan,q->output_len,SRSLTE_DFT_FORWARD,SRSLTE_DFT_COMPLEX)) { + fprintf(stderr, "Error initiating input plan\n"); return SRSLTE_ERROR; } if (srslte_dft_plan(&q->filter_plan,q->output_len,SRSLTE_DFT_FORWARD,SRSLTE_DFT_COMPLEX)) { + fprintf(stderr, "Error initiating filter plan\n"); return SRSLTE_ERROR; } if (srslte_dft_plan(&q->output_plan,q->output_len,SRSLTE_DFT_BACKWARD,SRSLTE_DFT_COMPLEX)) { + fprintf(stderr, "Error initiating output plan\n"); return SRSLTE_ERROR; } srslte_dft_plan_set_norm(&q->input_plan, true);