|
|
@ -18,11 +18,17 @@
|
|
|
|
* and at http://www.gnu.org/licenses/.
|
|
|
|
* and at http://www.gnu.org/licenses/.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <boost/program_options.hpp>
|
|
|
|
|
|
|
|
#include <boost/program_options/options_description.hpp>
|
|
|
|
|
|
|
|
#include <boost/program_options/parsers.hpp>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <mutex>
|
|
|
|
#include <mutex>
|
|
|
|
#include <srsenb/hdr/phy/phy.h>
|
|
|
|
#include <srsenb/hdr/phy/phy.h>
|
|
|
|
#include <srslte/common/test_common.h>
|
|
|
|
#include <srslte/common/test_common.h>
|
|
|
|
#include <srslte/common/threads.h>
|
|
|
|
#include <srslte/common/threads.h>
|
|
|
|
#include <srslte/common/tti_sync_cv.h>
|
|
|
|
#include <srslte/common/tti_sync_cv.h>
|
|
|
|
|
|
|
|
#include <srslte/interfaces/enb_interfaces.h>
|
|
|
|
|
|
|
|
#include <srslte/phy/common/phy_common.h>
|
|
|
|
#include <srslte/phy/phch/pusch_cfg.h>
|
|
|
|
#include <srslte/phy/phch/pusch_cfg.h>
|
|
|
|
#include <srslte/phy/utils/random.h>
|
|
|
|
#include <srslte/phy/utils/random.h>
|
|
|
|
#include <srslte/srslte.h>
|
|
|
|
#include <srslte/srslte.h>
|
|
|
@ -41,7 +47,7 @@ public:
|
|
|
|
if (reset_flag) { \
|
|
|
|
if (reset_flag) { \
|
|
|
|
received_##NAME = false; \
|
|
|
|
received_##NAME = false; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
while (!received_##NAME && !expired) { \
|
|
|
|
while (not received_##NAME and not expired) { \
|
|
|
|
expired = (cvar.wait_until(lock, expire_time) == std::cv_status::timeout); \
|
|
|
|
expired = (cvar.wait_until(lock, expire_time) == std::cv_status::timeout); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
if (expired) { \
|
|
|
|
if (expired) { \
|
|
|
@ -97,14 +103,14 @@ private:
|
|
|
|
CALLBACK(get_info);
|
|
|
|
CALLBACK(get_info);
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
explicit dummy_radio(uint32_t nof_channels) : log_h("RADIO")
|
|
|
|
explicit dummy_radio(uint32_t nof_channels, std::string log_level) : log_h("RADIO")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_h.set_level("info");
|
|
|
|
log_h.set_level(log_level);
|
|
|
|
|
|
|
|
|
|
|
|
// Allocate receive ring buffer
|
|
|
|
// Allocate receive ring buffer
|
|
|
|
for (uint32_t i = 0; i < nof_channels; i++) {
|
|
|
|
for (uint32_t i = 0; i < nof_channels; i++) {
|
|
|
|
auto* rb = (srslte_ringbuffer_t*)srslte_vec_malloc(sizeof(srslte_ringbuffer_t));
|
|
|
|
auto* rb = (srslte_ringbuffer_t*)srslte_vec_malloc(sizeof(srslte_ringbuffer_t));
|
|
|
|
if (!rb) {
|
|
|
|
if (not rb) {
|
|
|
|
ERROR("Allocating ring buffer\n");
|
|
|
|
ERROR("Allocating ring buffer\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -118,7 +124,7 @@ public:
|
|
|
|
// Allocate transmit ring buffer
|
|
|
|
// Allocate transmit ring buffer
|
|
|
|
for (uint32_t i = 0; i < nof_channels; i++) {
|
|
|
|
for (uint32_t i = 0; i < nof_channels; i++) {
|
|
|
|
auto* rb = (srslte_ringbuffer_t*)srslte_vec_malloc(sizeof(srslte_ringbuffer_t));
|
|
|
|
auto* rb = (srslte_ringbuffer_t*)srslte_vec_malloc(sizeof(srslte_ringbuffer_t));
|
|
|
|
if (!rb) {
|
|
|
|
if (not rb) {
|
|
|
|
ERROR("Allocating ring buffer\n");
|
|
|
|
ERROR("Allocating ring buffer\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -155,10 +161,10 @@ public:
|
|
|
|
|
|
|
|
|
|
|
|
log_h.debug("read_tx %d\n", nof_samples);
|
|
|
|
log_h.debug("read_tx %d\n", nof_samples);
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < ringbuffers_tx.size() && i < buffers.size(); i++) {
|
|
|
|
for (uint32_t i = 0; i < ringbuffers_tx.size() and i < buffers.size(); i++) {
|
|
|
|
do {
|
|
|
|
do {
|
|
|
|
err = srslte_ringbuffer_read_timed(ringbuffers_tx[i], buffers[i], nbytes, 1000);
|
|
|
|
err = srslte_ringbuffer_read_timed(ringbuffers_tx[i], buffers[i], nbytes, 1000);
|
|
|
|
} while (err < SRSLTE_SUCCESS && running);
|
|
|
|
} while (err < SRSLTE_SUCCESS and running);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
return err;
|
|
|
@ -170,7 +176,7 @@ public:
|
|
|
|
|
|
|
|
|
|
|
|
log_h.debug("write_rx %d\n", nof_samples);
|
|
|
|
log_h.debug("write_rx %d\n", nof_samples);
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < ringbuffers_rx.size() && i < buffers.size(); i++) {
|
|
|
|
for (uint32_t i = 0; i < ringbuffers_rx.size() and i < buffers.size(); i++) {
|
|
|
|
srslte_ringbuffer_write(ringbuffers_rx[i], buffers[i], nbytes);
|
|
|
|
srslte_ringbuffer_write(ringbuffers_rx[i], buffers[i], nbytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -186,7 +192,7 @@ public:
|
|
|
|
log_h.debug("tx %d\n", nof_samples);
|
|
|
|
log_h.debug("tx %d\n", nof_samples);
|
|
|
|
|
|
|
|
|
|
|
|
// Write ring buffer
|
|
|
|
// Write ring buffer
|
|
|
|
for (uint32_t i = 0; i < ringbuffers_tx.size() && err >= SRSLTE_SUCCESS; i++) {
|
|
|
|
for (uint32_t i = 0; i < ringbuffers_tx.size() and err >= SRSLTE_SUCCESS; i++) {
|
|
|
|
err = srslte_ringbuffer_write(ringbuffers_tx[i], buffer[i], nbytes);
|
|
|
|
err = srslte_ringbuffer_write(ringbuffers_tx[i], buffer[i], nbytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -208,10 +214,10 @@ public:
|
|
|
|
uint32_t nbytes = static_cast<uint32_t>(sizeof(cf_t)) * nof_samples;
|
|
|
|
uint32_t nbytes = static_cast<uint32_t>(sizeof(cf_t)) * nof_samples;
|
|
|
|
|
|
|
|
|
|
|
|
// Write ring buffer
|
|
|
|
// Write ring buffer
|
|
|
|
for (uint32_t i = 0; i < ringbuffers_rx.size() && err >= SRSLTE_SUCCESS; i++) {
|
|
|
|
for (uint32_t i = 0; i < ringbuffers_rx.size() and err >= SRSLTE_SUCCESS; i++) {
|
|
|
|
do {
|
|
|
|
do {
|
|
|
|
err = srslte_ringbuffer_read_timed(ringbuffers_rx[i], buffer[i], nbytes, 1000);
|
|
|
|
err = srslte_ringbuffer_read_timed(ringbuffers_rx[i], buffer[i], nbytes, 1000);
|
|
|
|
} while (err < SRSLTE_SUCCESS && running);
|
|
|
|
} while (err < SRSLTE_SUCCESS and running);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Copy new timestamp
|
|
|
|
// Copy new timestamp
|
|
|
@ -250,6 +256,8 @@ public:
|
|
|
|
srslte_rf_info_t* get_info(const uint32_t& radio_idx) override { return nullptr; }
|
|
|
|
srslte_rf_info_t* get_info(const uint32_t& radio_idx) override { return nullptr; }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::unique_ptr<dummy_radio> unique_dummy_radio_t;
|
|
|
|
|
|
|
|
|
|
|
|
class dummy_stack : public srsenb::stack_interface_phy_lte
|
|
|
|
class dummy_stack : public srsenb::stack_interface_phy_lte
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
private:
|
|
|
@ -262,7 +270,7 @@ private:
|
|
|
|
srslte::log_filter log_h;
|
|
|
|
srslte::log_filter log_h;
|
|
|
|
srslte::tti_sync_cv tti_sync;
|
|
|
|
srslte::tti_sync_cv tti_sync;
|
|
|
|
srslte_softbuffer_tx_t softbuffer_tx = {};
|
|
|
|
srslte_softbuffer_tx_t softbuffer_tx = {};
|
|
|
|
srslte_softbuffer_rx_t softbuffer_rx[SRSLTE_FDD_NOF_HARQ] = {};
|
|
|
|
srslte_softbuffer_rx_t softbuffer_rx[SRSLTE_MAX_CARRIERS][SRSLTE_FDD_NOF_HARQ] = {};
|
|
|
|
uint8_t* data = nullptr;
|
|
|
|
uint8_t* data = nullptr;
|
|
|
|
uint16_t ue_rnti = 0;
|
|
|
|
uint16_t ue_rnti = 0;
|
|
|
|
srslte_random_t random_gen = nullptr;
|
|
|
|
srslte_random_t random_gen = nullptr;
|
|
|
@ -312,16 +320,27 @@ private:
|
|
|
|
std::queue<tti_ul_info_t> tti_ul_info_ack_queue;
|
|
|
|
std::queue<tti_ul_info_t> tti_ul_info_ack_queue;
|
|
|
|
std::queue<tti_sr_info_t> tti_sr_info_queue;
|
|
|
|
std::queue<tti_sr_info_t> tti_sr_info_queue;
|
|
|
|
std::queue<tti_cqi_info_t> tti_cqi_info_queue;
|
|
|
|
std::queue<tti_cqi_info_t> tti_cqi_info_queue;
|
|
|
|
|
|
|
|
std::vector<uint32_t> active_cell_list;
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
explicit dummy_stack(uint16_t rnti_, srsenb::phy_cfg_t& phy_cfg_) :
|
|
|
|
explicit dummy_stack(srsenb::phy_cfg_t& phy_cfg_,
|
|
|
|
log_h("STACK"), ue_rnti(rnti_), random_gen(srslte_random_init(0)), phy_cfg(phy_cfg_)
|
|
|
|
std::string log_level,
|
|
|
|
|
|
|
|
uint16_t rnti_,
|
|
|
|
|
|
|
|
std::vector<uint32_t>& active_cell_list_) :
|
|
|
|
|
|
|
|
log_h("STACK"),
|
|
|
|
|
|
|
|
ue_rnti(rnti_),
|
|
|
|
|
|
|
|
random_gen(srslte_random_init(rnti_)),
|
|
|
|
|
|
|
|
phy_cfg(phy_cfg_),
|
|
|
|
|
|
|
|
active_cell_list(active_cell_list_)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_h.set_level("info");
|
|
|
|
log_h.set_level(log_level);
|
|
|
|
srslte_softbuffer_tx_init(&softbuffer_tx, SRSLTE_MAX_PRB);
|
|
|
|
srslte_softbuffer_tx_init(&softbuffer_tx, SRSLTE_MAX_PRB);
|
|
|
|
for (auto& sb : softbuffer_rx) {
|
|
|
|
for (uint32_t i = 0; i < active_cell_list.size(); i++) {
|
|
|
|
|
|
|
|
for (auto& sb : softbuffer_rx[i]) {
|
|
|
|
srslte_softbuffer_rx_init(&sb, SRSLTE_MAX_PRB);
|
|
|
|
srslte_softbuffer_rx_init(&sb, SRSLTE_MAX_PRB);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
data = srslte_vec_u8_malloc(150000);
|
|
|
|
data = srslte_vec_u8_malloc(150000);
|
|
|
|
memset(data, 0, 150000);
|
|
|
|
memset(data, 0, 150000);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -329,9 +348,11 @@ public:
|
|
|
|
~dummy_stack()
|
|
|
|
~dummy_stack()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
srslte_softbuffer_tx_free(&softbuffer_tx);
|
|
|
|
srslte_softbuffer_tx_free(&softbuffer_tx);
|
|
|
|
for (auto& sb : softbuffer_rx) {
|
|
|
|
for (auto& v : softbuffer_rx) {
|
|
|
|
|
|
|
|
for (auto& sb : v) {
|
|
|
|
srslte_softbuffer_rx_free(&sb);
|
|
|
|
srslte_softbuffer_rx_free(&sb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if (data) {
|
|
|
|
if (data) {
|
|
|
|
free(data);
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -421,15 +442,18 @@ public:
|
|
|
|
// Wait for UE
|
|
|
|
// Wait for UE
|
|
|
|
tti_sync.wait();
|
|
|
|
tti_sync.wait();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Make sure it works in the smallest PRB size
|
|
|
|
|
|
|
|
dl_sched_res[0].cfi = 2;
|
|
|
|
|
|
|
|
|
|
|
|
// Iterate for each carrier
|
|
|
|
// Iterate for each carrier
|
|
|
|
for (uint32_t cc_idx = 0; cc_idx < dl_sched_res.size(); cc_idx++) {
|
|
|
|
for (uint32_t& cc_idx : active_cell_list) {
|
|
|
|
auto& dl_sched = dl_sched_res[cc_idx];
|
|
|
|
auto& dl_sched = dl_sched_res[cc_idx];
|
|
|
|
|
|
|
|
|
|
|
|
// Required
|
|
|
|
// Required
|
|
|
|
dl_sched.cfi = 2; ///< Make sure it works in the smallest PRB size
|
|
|
|
dl_sched.cfi = 2;
|
|
|
|
|
|
|
|
|
|
|
|
// Random decision on whether transmit or not
|
|
|
|
// Random decision on whether transmit or not
|
|
|
|
if (srslte_random_bool(random_gen, prob_dl_grant)) {
|
|
|
|
if (ue_rnti and srslte_random_bool(random_gen, prob_dl_grant)) {
|
|
|
|
dl_sched.nof_grants = 1;
|
|
|
|
dl_sched.nof_grants = 1;
|
|
|
|
dl_sched.pdsch[0].softbuffer_tx[0] = &softbuffer_tx;
|
|
|
|
dl_sched.pdsch[0].softbuffer_tx[0] = &softbuffer_tx;
|
|
|
|
dl_sched.pdsch[0].softbuffer_tx[1] = &softbuffer_tx;
|
|
|
|
dl_sched.pdsch[0].softbuffer_tx[1] = &softbuffer_tx;
|
|
|
@ -476,12 +500,20 @@ public:
|
|
|
|
// Notify test engine
|
|
|
|
// Notify test engine
|
|
|
|
notify_get_ul_sched();
|
|
|
|
notify_get_ul_sched();
|
|
|
|
|
|
|
|
|
|
|
|
// Iterate for each carrier
|
|
|
|
// Iterate for each carrier following the eNb/Cell order
|
|
|
|
for (uint32_t cc_idx = 0; cc_idx < ul_sched_res.size(); cc_idx++) {
|
|
|
|
for (uint32_t cc_idx = 0; cc_idx < ul_sched_res.size(); cc_idx++) {
|
|
|
|
|
|
|
|
auto scell_idx = active_cell_list.size();
|
|
|
|
auto& ul_sched = ul_sched_res[cc_idx];
|
|
|
|
auto& ul_sched = ul_sched_res[cc_idx];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Checks if the eNb cell/carrier is enabled
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < active_cell_list.size() and scell_idx == active_cell_list.size(); i++) {
|
|
|
|
|
|
|
|
if (cc_idx == active_cell_list[i]) {
|
|
|
|
|
|
|
|
scell_idx = i;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Random decision on whether transmit or not (Do not give grants for TTI when SR shall be transmitted)
|
|
|
|
// Random decision on whether transmit or not (Do not give grants for TTI when SR shall be transmitted)
|
|
|
|
if (srslte_random_bool(random_gen, prob_ul_grant) && (tti % 20 != 0)) {
|
|
|
|
if (scell_idx < active_cell_list.size() and srslte_random_bool(random_gen, prob_ul_grant) and (tti % 20 != 0)) {
|
|
|
|
uint32_t nof_prb = phy_cfg.phy_cell_cfg[cc_idx].cell.nof_prb;
|
|
|
|
uint32_t nof_prb = phy_cfg.phy_cell_cfg[cc_idx].cell.nof_prb;
|
|
|
|
ul_sched.nof_grants = 1;
|
|
|
|
ul_sched.nof_grants = 1;
|
|
|
|
ul_sched.pusch[0] = {};
|
|
|
|
ul_sched.pusch[0] = {};
|
|
|
@ -503,7 +535,7 @@ public:
|
|
|
|
ul_sched.pusch[0].data = data;
|
|
|
|
ul_sched.pusch[0].data = data;
|
|
|
|
|
|
|
|
|
|
|
|
ul_sched.pusch[0].needs_pdcch = true;
|
|
|
|
ul_sched.pusch[0].needs_pdcch = true;
|
|
|
|
ul_sched.pusch[0].softbuffer_rx = &softbuffer_rx[tti % SRSLTE_FDD_NOF_HARQ];
|
|
|
|
ul_sched.pusch[0].softbuffer_rx = &softbuffer_rx[scell_idx][tti % SRSLTE_FDD_NOF_HARQ];
|
|
|
|
|
|
|
|
|
|
|
|
// Reset Rx softbuffer
|
|
|
|
// Reset Rx softbuffer
|
|
|
|
srslte_softbuffer_rx_reset(ul_sched.pusch[0].softbuffer_rx);
|
|
|
|
srslte_softbuffer_rx_reset(ul_sched.pusch[0].softbuffer_rx);
|
|
|
@ -521,7 +553,7 @@ public:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) override { notify_set_sched_dl_tti_mask(); }
|
|
|
|
void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) override { notify_set_sched_dl_tti_mask(); }
|
|
|
|
void rl_failure(uint16_t rnti) override { notify_rl_failure(); }
|
|
|
|
void rl_failure(uint16_t rnti) override { notify_rl_failure(); }
|
|
|
@ -534,13 +566,13 @@ public:
|
|
|
|
int run_tti()
|
|
|
|
int run_tti()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Check DL ACKs match with grants
|
|
|
|
// Check DL ACKs match with grants
|
|
|
|
while (!tti_dl_info_ack_queue.empty()) {
|
|
|
|
while (not tti_dl_info_ack_queue.empty()) {
|
|
|
|
// Get both Info
|
|
|
|
// Get both Info
|
|
|
|
tti_dl_info_t& tti_dl_sched = tti_dl_info_sched_queue.front();
|
|
|
|
tti_dl_info_t& tti_dl_sched = tti_dl_info_sched_queue.front();
|
|
|
|
tti_dl_info_t& tti_dl_ack = tti_dl_info_ack_queue.front();
|
|
|
|
tti_dl_info_t& tti_dl_ack = tti_dl_info_ack_queue.front();
|
|
|
|
|
|
|
|
|
|
|
|
// Calculate ACK TTI
|
|
|
|
// Calculate ACK TTI
|
|
|
|
tti_dl_sched.tti = (tti_dl_sched.tti + FDD_HARQ_DELAY_MS) % 10240;
|
|
|
|
tti_dl_sched.tti = TTI_ADD(tti_dl_sched.tti, FDD_HARQ_DELAY_MS);
|
|
|
|
|
|
|
|
|
|
|
|
// Assert that ACKs have been received
|
|
|
|
// Assert that ACKs have been received
|
|
|
|
TESTASSERT(tti_dl_sched.tti == tti_dl_ack.tti);
|
|
|
|
TESTASSERT(tti_dl_sched.tti == tti_dl_ack.tti);
|
|
|
@ -553,7 +585,7 @@ public:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check UL ACKs match with grants
|
|
|
|
// Check UL ACKs match with grants
|
|
|
|
while (!tti_ul_info_ack_queue.empty()) {
|
|
|
|
while (not tti_ul_info_ack_queue.empty()) {
|
|
|
|
// Get both Info
|
|
|
|
// Get both Info
|
|
|
|
tti_ul_info_t& tti_ul_sched = tti_ul_info_sched_queue.front();
|
|
|
|
tti_ul_info_t& tti_ul_sched = tti_ul_info_sched_queue.front();
|
|
|
|
tti_ul_info_t& tti_ul_ack = tti_ul_info_ack_queue.front();
|
|
|
|
tti_ul_info_t& tti_ul_ack = tti_ul_info_ack_queue.front();
|
|
|
@ -577,7 +609,7 @@ public:
|
|
|
|
// Get second, do not pop
|
|
|
|
// Get second, do not pop
|
|
|
|
tti_sr_info_t& tti_sr_info2 = tti_sr_info_queue.front();
|
|
|
|
tti_sr_info_t& tti_sr_info2 = tti_sr_info_queue.front();
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t elapsed_tti = ((tti_sr_info2.tti + 10240) - tti_sr_info1.tti) % 10240;
|
|
|
|
uint32_t elapsed_tti = TTI_SUB(tti_sr_info2.tti, tti_sr_info1.tti);
|
|
|
|
|
|
|
|
|
|
|
|
// Log SR info
|
|
|
|
// Log SR info
|
|
|
|
log_h.info("SR: tti1=%d; tti2=%d; elapsed %d;\n", tti_sr_info1.tti, tti_sr_info2.tti, elapsed_tti);
|
|
|
|
log_h.info("SR: tti1=%d; tti2=%d; elapsed %d;\n", tti_sr_info1.tti, tti_sr_info2.tti, elapsed_tti);
|
|
|
@ -593,6 +625,8 @@ public:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::unique_ptr<dummy_stack> unique_dummy_stack_t;
|
|
|
|
|
|
|
|
|
|
|
|
class dummy_ue
|
|
|
|
class dummy_ue
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
private:
|
|
|
@ -606,75 +640,79 @@ private:
|
|
|
|
srslte_ul_sf_cfg_t sf_ul_cfg = {};
|
|
|
|
srslte_ul_sf_cfg_t sf_ul_cfg = {};
|
|
|
|
srslte_softbuffer_tx_t softbuffer_tx = {};
|
|
|
|
srslte_softbuffer_tx_t softbuffer_tx = {};
|
|
|
|
uint8_t* tx_data = nullptr;
|
|
|
|
uint8_t* tx_data = nullptr;
|
|
|
|
srslte::phy_cfg_t dedicated = {};
|
|
|
|
srsenb::phy_interface_rrc_lte::phy_rrc_dedicated_list_t phy_rrc_cfg = {};
|
|
|
|
srslte::log_filter log_h;
|
|
|
|
srslte::log_filter log_h;
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
dummy_ue(dummy_radio& _radio,
|
|
|
|
dummy_ue(dummy_radio* _radio,
|
|
|
|
const srsenb::phy_cell_cfg_list_t& cell_list,
|
|
|
|
const srsenb::phy_cell_cfg_list_t& cell_list,
|
|
|
|
|
|
|
|
std::string log_level,
|
|
|
|
uint16_t rnti_,
|
|
|
|
uint16_t rnti_,
|
|
|
|
const srslte::phy_cfg_t& dedicated_) :
|
|
|
|
const srsenb::phy_interface_rrc_lte::phy_rrc_dedicated_list_t& phy_rrc_cfg_) :
|
|
|
|
radio(&_radio),
|
|
|
|
radio(_radio), log_h("UE PHY", nullptr, true), phy_rrc_cfg(phy_rrc_cfg_)
|
|
|
|
log_h("UE PHY", nullptr, true),
|
|
|
|
|
|
|
|
dedicated(dedicated_)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Calculate subframe length
|
|
|
|
// Calculate subframe length
|
|
|
|
sf_len = SRSLTE_SF_LEN_PRB(cell_list[0].cell.nof_prb);
|
|
|
|
sf_len = static_cast<uint32_t>(SRSLTE_SF_LEN_PRB(cell_list[0].cell.nof_prb));
|
|
|
|
rnti = rnti_;
|
|
|
|
rnti = rnti_;
|
|
|
|
|
|
|
|
|
|
|
|
log_h.set_level("info");
|
|
|
|
log_h.set_level(log_level);
|
|
|
|
|
|
|
|
|
|
|
|
// Initialise each cell
|
|
|
|
// Initialise one buffer per eNb
|
|
|
|
for (auto& cell : cell_list) {
|
|
|
|
for (auto& cell : cell_list) {
|
|
|
|
// Allocate buffers
|
|
|
|
// Allocate buffers
|
|
|
|
cf_t* buffer = srslte_vec_cf_malloc(sf_len);
|
|
|
|
cf_t* buffer = srslte_vec_cf_malloc(sf_len);
|
|
|
|
if (!buffer) {
|
|
|
|
if (not buffer) {
|
|
|
|
ERROR("Allocatin UE DL buffer\n");
|
|
|
|
ERROR("Allocatin UE DL buffer\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buffers.push_back(buffer);
|
|
|
|
buffers.push_back(buffer);
|
|
|
|
|
|
|
|
|
|
|
|
// Set buffer to zero
|
|
|
|
// Set buffer to zero
|
|
|
|
srslte_vec_cf_zero(buffer, sf_len);
|
|
|
|
srslte_vec_cf_zero(buffer, sf_len);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& q : phy_rrc_cfg) {
|
|
|
|
|
|
|
|
uint32_t cc_idx = q.cc_idx;
|
|
|
|
|
|
|
|
|
|
|
|
// Allocate UE DL
|
|
|
|
// Allocate UE DL
|
|
|
|
auto* ue_dl = (srslte_ue_dl_t*)srslte_vec_malloc(sizeof(srslte_ue_dl_t));
|
|
|
|
auto* ue_dl = (srslte_ue_dl_t*)srslte_vec_malloc(sizeof(srslte_ue_dl_t));
|
|
|
|
if (!ue_dl) {
|
|
|
|
if (not ue_dl) {
|
|
|
|
ERROR("Allocatin UE DL\n");
|
|
|
|
ERROR("Allocatin UE DL\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ue_dl_v.push_back(ue_dl);
|
|
|
|
ue_dl_v.push_back(ue_dl);
|
|
|
|
|
|
|
|
|
|
|
|
// Initialise UE DL
|
|
|
|
// Initialise UE DL
|
|
|
|
if (srslte_ue_dl_init(ue_dl, &buffer, cell.cell.nof_prb, 1)) {
|
|
|
|
if (srslte_ue_dl_init(
|
|
|
|
|
|
|
|
ue_dl, &buffers[cc_idx], cell_list[cc_idx].cell.nof_prb, cell_list[cc_idx].cell.nof_ports)) {
|
|
|
|
ERROR("Initiating UE DL\n");
|
|
|
|
ERROR("Initiating UE DL\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set Cell
|
|
|
|
// Set Cell
|
|
|
|
if (srslte_ue_dl_set_cell(ue_dl, cell.cell)) {
|
|
|
|
if (srslte_ue_dl_set_cell(ue_dl, cell_list[cc_idx].cell)) {
|
|
|
|
ERROR("Setting UE DL cell\n");
|
|
|
|
ERROR("Setting UE DL cell\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set RNTI
|
|
|
|
// Set RNTI
|
|
|
|
srslte_ue_dl_set_rnti(ue_dl, dedicated.dl_cfg.pdsch.rnti);
|
|
|
|
srslte_ue_dl_set_rnti(ue_dl, rnti);
|
|
|
|
|
|
|
|
|
|
|
|
// Allocate UE UL
|
|
|
|
// Allocate UE UL
|
|
|
|
auto* ue_ul = (srslte_ue_ul_t*)srslte_vec_malloc(sizeof(srslte_ue_ul_t));
|
|
|
|
auto* ue_ul = (srslte_ue_ul_t*)srslte_vec_malloc(sizeof(srslte_ue_ul_t));
|
|
|
|
if (!ue_ul) {
|
|
|
|
if (not ue_ul) {
|
|
|
|
ERROR("Allocatin UE UL\n");
|
|
|
|
ERROR("Allocatin UE UL\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ue_ul_v.push_back(ue_ul);
|
|
|
|
ue_ul_v.push_back(ue_ul);
|
|
|
|
|
|
|
|
|
|
|
|
// Initialise UE UL
|
|
|
|
// Initialise UE UL
|
|
|
|
if (srslte_ue_ul_init(ue_ul, buffer, cell.cell.nof_prb)) {
|
|
|
|
if (srslte_ue_ul_init(ue_ul, buffers[cc_idx], cell_list[cc_idx].cell.nof_prb)) {
|
|
|
|
ERROR("Setting UE UL cell\n");
|
|
|
|
ERROR("Setting UE UL cell\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set cell
|
|
|
|
// Set cell
|
|
|
|
if (srslte_ue_ul_set_cell(ue_ul, cell.cell)) {
|
|
|
|
if (srslte_ue_ul_set_cell(ue_ul, cell_list[cc_idx].cell)) {
|
|
|
|
ERROR("Setting UE DL cell\n");
|
|
|
|
ERROR("Setting UE DL cell\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set RNTI
|
|
|
|
// Set RNTI
|
|
|
|
srslte_ue_ul_set_rnti(ue_ul, dedicated.ul_cfg.pusch.rnti);
|
|
|
|
srslte_ue_ul_set_rnti(ue_ul, rnti);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Initialise softbuffer
|
|
|
|
// Initialise softbuffer
|
|
|
@ -684,7 +722,7 @@ public:
|
|
|
|
|
|
|
|
|
|
|
|
// Initialise dummy tx data
|
|
|
|
// Initialise dummy tx data
|
|
|
|
tx_data = srslte_vec_u8_malloc(SRSENB_MAX_BUFFER_SIZE_BYTES);
|
|
|
|
tx_data = srslte_vec_u8_malloc(SRSENB_MAX_BUFFER_SIZE_BYTES);
|
|
|
|
if (!tx_data) {
|
|
|
|
if (not tx_data) {
|
|
|
|
ERROR("Allocating Tx data\n");
|
|
|
|
ERROR("Allocating Tx data\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -727,34 +765,30 @@ public:
|
|
|
|
srslte_softbuffer_tx_free(&softbuffer_tx);
|
|
|
|
srslte_softbuffer_tx_free(&softbuffer_tx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int run_tti()
|
|
|
|
int work_dl(srslte_pdsch_ack_t& pdsch_ack, srslte_uci_data_t& uci_data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int ret = SRSLTE_SUCCESS;
|
|
|
|
// Read DL
|
|
|
|
srslte_uci_data_t uci_data = {};
|
|
|
|
TESTASSERT(radio->read_tx(buffers, sf_len) >= SRSLTE_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
// Set logging TTI
|
|
|
|
// Get grants DL/UL, we do not care about Decoding PDSCH
|
|
|
|
log_h.step(sf_dl_cfg.tti);
|
|
|
|
for (uint32_t i = 0; i < phy_rrc_cfg.size(); i++) {
|
|
|
|
|
|
|
|
uint32_t cc_idx = phy_rrc_cfg[i].cc_idx;
|
|
|
|
|
|
|
|
srslte::phy_cfg_t& dedicated = phy_rrc_cfg[i].phy_cfg;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Set UCI configuration from PCell only
|
|
|
|
|
|
|
|
if (i == 0) {
|
|
|
|
uci_data.cfg = dedicated.ul_cfg.pucch.uci_cfg;
|
|
|
|
uci_data.cfg = dedicated.ul_cfg.pucch.uci_cfg;
|
|
|
|
|
|
|
|
|
|
|
|
srslte_pdsch_ack_t pdsch_ack = {};
|
|
|
|
|
|
|
|
pdsch_ack.ack_nack_feedback_mode = dedicated.ul_cfg.pucch.ack_nack_feedback_mode;
|
|
|
|
pdsch_ack.ack_nack_feedback_mode = dedicated.ul_cfg.pucch.ack_nack_feedback_mode;
|
|
|
|
pdsch_ack.nof_cc = (uint32_t)buffers.size();
|
|
|
|
pdsch_ack.nof_cc = static_cast<uint32_t>(phy_rrc_cfg.size());
|
|
|
|
pdsch_ack.transmission_mode = dedicated.dl_cfg.tm;
|
|
|
|
pdsch_ack.transmission_mode = dedicated.dl_cfg.tm;
|
|
|
|
pdsch_ack.nof_cc = buffers.size();
|
|
|
|
|
|
|
|
pdsch_ack.ack_nack_feedback_mode = dedicated.ul_cfg.pucch.ack_nack_feedback_mode;
|
|
|
|
|
|
|
|
pdsch_ack.simul_cqi_ack = dedicated.ul_cfg.pucch.simul_cqi_ack;
|
|
|
|
pdsch_ack.simul_cqi_ack = dedicated.ul_cfg.pucch.simul_cqi_ack;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Read DL
|
|
|
|
|
|
|
|
TESTASSERT(radio->read_tx(buffers, sf_len) >= SRSLTE_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get grants DL/UL, we do not care about Decoding PDSCH
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < buffers.size(); i++) {
|
|
|
|
|
|
|
|
srslte_dci_dl_t dci_dl[SRSLTE_MAX_DCI_MSG] = {};
|
|
|
|
srslte_dci_dl_t dci_dl[SRSLTE_MAX_DCI_MSG] = {};
|
|
|
|
srslte_ue_dl_cfg_t ue_dl_cfg = {};
|
|
|
|
srslte_ue_dl_cfg_t ue_dl_cfg = {};
|
|
|
|
ue_dl_cfg.cfg = dedicated.dl_cfg;
|
|
|
|
ue_dl_cfg.cfg = dedicated.dl_cfg;
|
|
|
|
ue_dl_cfg.cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_12;
|
|
|
|
ue_dl_cfg.cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_12;
|
|
|
|
ue_dl_cfg.cfg.cqi_report.pmi_idx += i;
|
|
|
|
|
|
|
|
ue_dl_cfg.cfg.pdsch.rnti = rnti;
|
|
|
|
ue_dl_cfg.cfg.pdsch.rnti = rnti;
|
|
|
|
|
|
|
|
|
|
|
|
srslte_ue_dl_decode_fft_estimate(ue_dl_v[i], &sf_dl_cfg, &ue_dl_cfg);
|
|
|
|
srslte_ue_dl_decode_fft_estimate(ue_dl_v[i], &sf_dl_cfg, &ue_dl_cfg);
|
|
|
@ -771,12 +805,12 @@ public:
|
|
|
|
|
|
|
|
|
|
|
|
if (srslte_ue_dl_dci_to_pdsch_grant(ue_dl_v[i], &sf_dl_cfg, &ue_dl_cfg, dci_dl, &ue_dl_cfg.cfg.pdsch.grant)) {
|
|
|
|
if (srslte_ue_dl_dci_to_pdsch_grant(ue_dl_v[i], &sf_dl_cfg, &ue_dl_cfg, dci_dl, &ue_dl_cfg.cfg.pdsch.grant)) {
|
|
|
|
log_h.error("Converting DCI message to DL dci\n");
|
|
|
|
log_h.error("Converting DCI message to DL dci\n");
|
|
|
|
return -1;
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
srslte_pdsch_tx_info(&ue_dl_cfg.cfg.pdsch, str, 512);
|
|
|
|
srslte_pdsch_tx_info(&ue_dl_cfg.cfg.pdsch, str, 512);
|
|
|
|
|
|
|
|
|
|
|
|
log_h.info("[DL PDSCH %d] %s\n", i, str);
|
|
|
|
log_h.info("[DL PDSCH %d] cc=%d, %s\n", i, cc_idx, str);
|
|
|
|
|
|
|
|
|
|
|
|
pdsch_ack.cc[i].M = 1;
|
|
|
|
pdsch_ack.cc[i].M = 1;
|
|
|
|
pdsch_ack.cc[i].m[0].present = true;
|
|
|
|
pdsch_ack.cc[i].m[0].present = true;
|
|
|
@ -795,21 +829,31 @@ public:
|
|
|
|
srslte_ue_dl_gen_cqi_periodic(ue_dl_v[i], &ue_dl_cfg, 0x0f, sf_ul_cfg.tti, &uci_data);
|
|
|
|
srslte_ue_dl_gen_cqi_periodic(ue_dl_v[i], &ue_dl_cfg, 0x0f, sf_ul_cfg.tti, &uci_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Work UL
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
for (uint32_t i = 0; i < buffers.size(); i++) {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int work_ul(srslte_pdsch_ack_t& pdsch_ack, srslte_uci_data_t& uci_data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Zero all IQ UL buffers
|
|
|
|
|
|
|
|
for (auto& buffer : buffers) {
|
|
|
|
|
|
|
|
srslte_vec_cf_zero(buffer, SRSLTE_SF_LEN_PRB(ue_ul_v[0]->cell.nof_prb));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < phy_rrc_cfg.size(); i++) {
|
|
|
|
srslte_dci_ul_t dci_ul[SRSLTE_MAX_DCI_MSG] = {};
|
|
|
|
srslte_dci_ul_t dci_ul[SRSLTE_MAX_DCI_MSG] = {};
|
|
|
|
|
|
|
|
uint32_t cc_idx = phy_rrc_cfg[i].cc_idx;
|
|
|
|
|
|
|
|
srslte::phy_cfg_t& dedicated = phy_rrc_cfg[i].phy_cfg;
|
|
|
|
|
|
|
|
|
|
|
|
srslte_ue_ul_cfg_t ue_ul_cfg = {};
|
|
|
|
srslte_ue_ul_cfg_t ue_ul_cfg = {};
|
|
|
|
ue_ul_cfg.ul_cfg = dedicated.ul_cfg;
|
|
|
|
ue_ul_cfg.ul_cfg = dedicated.ul_cfg;
|
|
|
|
ue_ul_cfg.ul_cfg.pusch.softbuffers.tx = &softbuffer_tx;
|
|
|
|
ue_ul_cfg.ul_cfg.pusch.softbuffers.tx = &softbuffer_tx;
|
|
|
|
ue_ul_cfg.ul_cfg.pusch.rnti = rnti;
|
|
|
|
ue_ul_cfg.ul_cfg.pusch.rnti = rnti;
|
|
|
|
ue_ul_cfg.ul_cfg.pucch.rnti = rnti;
|
|
|
|
ue_ul_cfg.ul_cfg.pucch.rnti = rnti;
|
|
|
|
ue_ul_cfg.cc_idx = i;
|
|
|
|
ue_ul_cfg.cc_idx = i; // SCell index
|
|
|
|
|
|
|
|
|
|
|
|
srslte_ue_dl_cfg_t ue_dl_cfg = {};
|
|
|
|
srslte_ue_dl_cfg_t ue_dl_cfg = {};
|
|
|
|
ue_dl_cfg.cfg = dedicated.dl_cfg;
|
|
|
|
ue_dl_cfg.cfg = dedicated.dl_cfg;
|
|
|
|
ue_dl_cfg.cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_12;
|
|
|
|
ue_dl_cfg.cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_12;
|
|
|
|
ue_dl_cfg.cfg.cqi_report.pmi_idx += i;
|
|
|
|
|
|
|
|
ue_dl_cfg.cfg.pdsch.rnti = rnti;
|
|
|
|
ue_dl_cfg.cfg.pdsch.rnti = rnti;
|
|
|
|
|
|
|
|
|
|
|
|
// Get UL grants
|
|
|
|
// Get UL grants
|
|
|
@ -823,6 +867,8 @@ public:
|
|
|
|
TESTASSERT(srslte_ue_ul_dci_to_pusch_grant(
|
|
|
|
TESTASSERT(srslte_ue_ul_dci_to_pusch_grant(
|
|
|
|
ue_ul_v[i], &sf_ul_cfg, &ue_ul_cfg, dci_ul, &ue_ul_cfg.ul_cfg.pusch.grant) >= SRSLTE_SUCCESS);
|
|
|
|
ue_ul_v[i], &sf_ul_cfg, &ue_ul_cfg, dci_ul, &ue_ul_cfg.ul_cfg.pusch.grant) >= SRSLTE_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
srslte_softbuffer_tx_reset(&softbuffer_tx);
|
|
|
|
|
|
|
|
|
|
|
|
ue_ul_cfg.ul_cfg.pusch.softbuffers.tx = &softbuffer_tx;
|
|
|
|
ue_ul_cfg.ul_cfg.pusch.softbuffers.tx = &softbuffer_tx;
|
|
|
|
ue_ul_cfg.grant_available = true;
|
|
|
|
ue_ul_cfg.grant_available = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -843,172 +889,254 @@ public:
|
|
|
|
ue_ul_cfg.ul_cfg.pucch.uci_cfg = uci_data.cfg;
|
|
|
|
ue_ul_cfg.ul_cfg.pucch.uci_cfg = uci_data.cfg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Reset subframe
|
|
|
|
|
|
|
|
srslte_vec_cf_zero(buffers[i], sf_len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Work UL
|
|
|
|
// Work UL
|
|
|
|
TESTASSERT(srslte_ue_ul_encode(ue_ul_v[i], &sf_ul_cfg, &ue_ul_cfg, &pusch_data) >= SRSLTE_SUCCESS);
|
|
|
|
TESTASSERT(srslte_ue_ul_encode(ue_ul_v[i], &sf_ul_cfg, &ue_ul_cfg, &pusch_data) >= SRSLTE_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
char str[256] = {};
|
|
|
|
char str[256] = {};
|
|
|
|
srslte_ue_ul_info(&ue_ul_cfg, &sf_ul_cfg, &pusch_data.uci, str, sizeof(str));
|
|
|
|
srslte_ue_ul_info(&ue_ul_cfg, &sf_ul_cfg, &pusch_data.uci, str, sizeof(str));
|
|
|
|
log_h.info("[UL INFO] %s\n", str);
|
|
|
|
if (str[0]) {
|
|
|
|
|
|
|
|
log_h.info("[UL INFO %d] %s\n", i, str);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Write eNb Rx
|
|
|
|
// Write eNb Rx
|
|
|
|
radio->write_rx(buffers, sf_len);
|
|
|
|
radio->write_rx(buffers, sf_len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int run_tti()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
srslte_uci_data_t uci_data = {};
|
|
|
|
|
|
|
|
srslte_pdsch_ack_t pdsch_ack = {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set logging TTI
|
|
|
|
|
|
|
|
log_h.step(sf_dl_cfg.tti);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Work DL
|
|
|
|
|
|
|
|
TESTASSERT(work_dl(pdsch_ack, uci_data) == SRSLTE_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Work UL
|
|
|
|
|
|
|
|
TESTASSERT(work_ul(pdsch_ack, uci_data) == SRSLTE_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
// Increment TTI
|
|
|
|
// Increment TTI
|
|
|
|
sf_dl_cfg.tti = (sf_dl_cfg.tti + 1) % 10240;
|
|
|
|
sf_dl_cfg.tti = (sf_dl_cfg.tti + 1) % 10240;
|
|
|
|
sf_ul_cfg.tti = (sf_ul_cfg.tti + 1) % 10240;
|
|
|
|
sf_ul_cfg.tti = (sf_ul_cfg.tti + 1) % 10240;
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::unique_ptr<dummy_ue> unique_dummy_ue_phy_t;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::unique_ptr<srsenb::phy> unique_srsenb_phy_t;
|
|
|
|
|
|
|
|
|
|
|
|
class phy_test_bench
|
|
|
|
class phy_test_bench
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
struct args_t {
|
|
|
|
|
|
|
|
uint16_t rnti = 0x1234;
|
|
|
|
|
|
|
|
uint32_t duration = 10240;
|
|
|
|
|
|
|
|
uint32_t nof_enb_cells = 1;
|
|
|
|
|
|
|
|
srslte_cell_t cell = {};
|
|
|
|
|
|
|
|
std::vector<uint32_t> ue_cell_list = {0}; ///< First indicates PCell
|
|
|
|
|
|
|
|
std::string ack_mode = "normal";
|
|
|
|
|
|
|
|
std::string log_level = "none";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
args_t()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cell.nof_prb = 6;
|
|
|
|
|
|
|
|
cell.nof_ports = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
// Private classes
|
|
|
|
// Private classes
|
|
|
|
dummy_radio radio;
|
|
|
|
unique_dummy_radio_t radio;
|
|
|
|
dummy_stack stack;
|
|
|
|
unique_dummy_stack_t stack;
|
|
|
|
srsenb::phy enb_phy;
|
|
|
|
unique_srsenb_phy_t enb_phy;
|
|
|
|
dummy_ue ue_phy;
|
|
|
|
unique_dummy_ue_phy_t ue_phy;
|
|
|
|
srslte::log_filter log_h;
|
|
|
|
srslte::log_filter log_h;
|
|
|
|
srslte::logger_stdout logger_stdout;
|
|
|
|
srslte::logger_stdout logger_stdout;
|
|
|
|
uint32_t nof_carriers = 0;
|
|
|
|
|
|
|
|
srslte::phy_cfg_t common_dedicated = {};
|
|
|
|
args_t args = {}; ///< Test arguments
|
|
|
|
uint16_t rnti = 0;
|
|
|
|
srsenb::phy_args_t phy_args; ///< PHY arguments
|
|
|
|
|
|
|
|
srsenb::phy_cfg_t phy_cfg; ///< eNb Cell/Carrier configuration
|
|
|
|
|
|
|
|
srsenb::phy_interface_rrc_lte::phy_rrc_dedicated_list_t phy_rrc_cfg; ///< UE PHY configuration
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
phy_test_bench(srsenb::phy_args_t& phy_args,
|
|
|
|
explicit phy_test_bench(args_t& args_) : log_h("TEST BENCH")
|
|
|
|
srsenb::phy_cfg_t& phy_cfg,
|
|
|
|
|
|
|
|
uint16_t rnti_,
|
|
|
|
|
|
|
|
uint32_t pcell_index,
|
|
|
|
|
|
|
|
const srslte::phy_cfg_t& dedicated_) :
|
|
|
|
|
|
|
|
log_h("TEST BENCH"),
|
|
|
|
|
|
|
|
stack(rnti_, phy_cfg),
|
|
|
|
|
|
|
|
rnti(rnti_),
|
|
|
|
|
|
|
|
radio(phy_cfg.phy_cell_cfg.size()),
|
|
|
|
|
|
|
|
enb_phy(&logger_stdout),
|
|
|
|
|
|
|
|
ue_phy(radio, phy_cfg.phy_cell_cfg, rnti_, dedicated_),
|
|
|
|
|
|
|
|
nof_carriers(static_cast<uint32_t>(phy_cfg.phy_cell_cfg.size())),
|
|
|
|
|
|
|
|
common_dedicated(dedicated_)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
// Copy test arguments
|
|
|
|
|
|
|
|
args = args_;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Configure logger
|
|
|
|
|
|
|
|
log_h.set_level(args.log_level);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// PHY arguments
|
|
|
|
|
|
|
|
phy_args.log.phy_level = args.log_level;
|
|
|
|
|
|
|
|
phy_args.nof_phy_threads = 1; ///< Set number of phy threads to 1 for avoiding concurrency issues
|
|
|
|
|
|
|
|
|
|
|
|
// Always info
|
|
|
|
// Create cell configuration
|
|
|
|
log_h.set_level("info");
|
|
|
|
phy_cfg.phy_cell_cfg.resize(args.nof_enb_cells);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < args.nof_enb_cells; i++) {
|
|
|
|
|
|
|
|
auto& q = phy_cfg.phy_cell_cfg[i];
|
|
|
|
|
|
|
|
q.cell = args.cell;
|
|
|
|
|
|
|
|
q.cell.id = i;
|
|
|
|
|
|
|
|
q.cell_id = i;
|
|
|
|
|
|
|
|
q.dl_freq_hz = 0.0f; ///< Frequencies are irrelevant in this test
|
|
|
|
|
|
|
|
q.ul_freq_hz = 0.0f;
|
|
|
|
|
|
|
|
q.root_seq_idx = 25 + i; ///< Different PRACH root sequences
|
|
|
|
|
|
|
|
q.rf_port = i;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Initiate
|
|
|
|
phy_cfg.pucch_cnfg.delta_pucch_shift = asn1::rrc::pucch_cfg_common_s::delta_pucch_shift_e_::ds3;
|
|
|
|
enb_phy.init(phy_args, phy_cfg, &radio, &stack);
|
|
|
|
phy_cfg.prach_cnfg.root_seq_idx = 0;
|
|
|
|
|
|
|
|
phy_cfg.prach_cnfg.prach_cfg_info.high_speed_flag = false;
|
|
|
|
|
|
|
|
phy_cfg.prach_cnfg.prach_cfg_info.prach_cfg_idx = 3;
|
|
|
|
|
|
|
|
phy_cfg.prach_cnfg.prach_cfg_info.prach_freq_offset = 2;
|
|
|
|
|
|
|
|
phy_cfg.prach_cnfg.prach_cfg_info.zero_correlation_zone_cfg = 5;
|
|
|
|
|
|
|
|
|
|
|
|
// Add rnti to enb
|
|
|
|
// Create base UE dedicated configuration
|
|
|
|
enb_phy.add_rnti(rnti, pcell_index, false);
|
|
|
|
srslte::phy_cfg_t dedicated = {};
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.ack_nack_feedback_mode = srslte_string_ack_nack_feedback_mode(args.ack_mode.c_str());
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.delta_pucch_shift = 2;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n_rb_2 = 2;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.N_cs = 0;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n_pucch_sr = 1;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.N_pucch_1 = 2;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n_pucch_2 = 5;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.simul_cqi_ack = true;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.sr_configured = true;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.I_sr = 5;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[0][0] = 6;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[1][0] = 6;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[2][0] = 6;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[3][0] = 6;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[0][1] = 7;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[1][1] = 7;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[2][1] = 7;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[3][1] = 7;
|
|
|
|
|
|
|
|
dedicated.dl_cfg.cqi_report.periodic_configured = true;
|
|
|
|
|
|
|
|
dedicated.dl_cfg.cqi_report.pmi_idx = 25;
|
|
|
|
|
|
|
|
dedicated.dl_cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_20;
|
|
|
|
|
|
|
|
|
|
|
|
// Configure UE PHY
|
|
|
|
// Configure UE PHY
|
|
|
|
bool activation[SRSLTE_MAX_CARRIERS] = {};
|
|
|
|
bool activation[SRSLTE_MAX_CARRIERS] = {}; ///< Activation/Deactivation vector
|
|
|
|
uint32_t pcell_idx = 0;
|
|
|
|
uint32_t pcell_idx = 0;
|
|
|
|
srsenb::phy_interface_rrc_lte::phy_rrc_dedicated_list_t dedicated_list(4);
|
|
|
|
phy_rrc_cfg.resize(args.ue_cell_list.size());
|
|
|
|
for (uint32_t i = 0; i < phy_cfg.phy_cell_cfg.size(); i++) {
|
|
|
|
for (uint32_t i = 0; i < args.ue_cell_list.size(); i++) {
|
|
|
|
dedicated_list[i].cc_idx = (i + pcell_idx) % phy_cfg.phy_cell_cfg.size();
|
|
|
|
phy_rrc_cfg[i].cc_idx = args.ue_cell_list[i]; ///< First element is PCell
|
|
|
|
dedicated_list[i].configured = true;
|
|
|
|
phy_rrc_cfg[i].configured = true; ///< All configured by default
|
|
|
|
dedicated_list[i].phy_cfg = common_dedicated;
|
|
|
|
phy_rrc_cfg[i].phy_cfg = dedicated; ///< Load the same in all by default
|
|
|
|
dedicated_list[i].phy_cfg.dl_cfg.cqi_report.pmi_idx += i;
|
|
|
|
phy_rrc_cfg[i].phy_cfg.dl_cfg.cqi_report.pmi_idx += i; ///< CQI report depend on SCell index
|
|
|
|
|
|
|
|
|
|
|
|
// Disable SCell stuff
|
|
|
|
// Disable SCell stuff
|
|
|
|
if (i != pcell_index) {
|
|
|
|
if (i != 0) {
|
|
|
|
dedicated_list[i].phy_cfg.ul_cfg.pucch.sr_configured = false;
|
|
|
|
phy_rrc_cfg[i].phy_cfg.ul_cfg.pucch.sr_configured = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// All the cell/carriers are activated from the beggining
|
|
|
|
activation[i] = true;
|
|
|
|
activation[i] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
enb_phy.set_config_dedicated(rnti, dedicated_list);
|
|
|
|
|
|
|
|
enb_phy.set_activation_deactivation_scell(rnti, activation);
|
|
|
|
/// Create Radio instance
|
|
|
|
|
|
|
|
radio = unique_dummy_radio_t(new dummy_radio(args.nof_enb_cells, args.log_level));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Create Dummy Stack isntance
|
|
|
|
|
|
|
|
stack = unique_dummy_stack_t(new dummy_stack(phy_cfg, args.log_level, args.rnti, args.ue_cell_list));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// eNb PHY initialisation instance
|
|
|
|
|
|
|
|
enb_phy = unique_srsenb_phy_t(new srsenb::phy(&logger_stdout));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Initiate eNb PHY with the given RNTI
|
|
|
|
|
|
|
|
enb_phy->init(phy_args, phy_cfg, radio.get(), stack.get());
|
|
|
|
|
|
|
|
enb_phy->add_rnti(args.rnti, args.ue_cell_list[0], false);
|
|
|
|
|
|
|
|
enb_phy->set_config_dedicated(args.rnti, phy_rrc_cfg);
|
|
|
|
|
|
|
|
enb_phy->set_activation_deactivation_scell(args.rnti, activation);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Create dummy UE instance
|
|
|
|
|
|
|
|
ue_phy =
|
|
|
|
|
|
|
|
unique_dummy_ue_phy_t(new dummy_ue(radio.get(), phy_cfg.phy_cell_cfg, args.log_level, args.rnti, phy_rrc_cfg));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
~phy_test_bench()
|
|
|
|
~phy_test_bench()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
radio.stop();
|
|
|
|
radio->stop();
|
|
|
|
enb_phy.stop();
|
|
|
|
enb_phy->stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int run_tti()
|
|
|
|
int run_tti()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int ret = SRSLTE_SUCCESS;
|
|
|
|
int ret = SRSLTE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
stack.tti_clock();
|
|
|
|
stack->tti_clock();
|
|
|
|
|
|
|
|
|
|
|
|
TESTASSERT(!stack.get_received_rl_failure());
|
|
|
|
TESTASSERT(not stack->get_received_rl_failure());
|
|
|
|
TESTASSERT(ue_phy.run_tti() >= SRSLTE_SUCCESS);
|
|
|
|
TESTASSERT(ue_phy->run_tti() >= SRSLTE_SUCCESS);
|
|
|
|
TESTASSERT(stack.run_tti() >= SRSLTE_SUCCESS);
|
|
|
|
TESTASSERT(stack->run_tti() >= SRSLTE_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
|
|
typedef std::unique_ptr<phy_test_bench> unique_phy_test_bench;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace bpo = boost::program_options;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int parse_args(int argc, char** argv, phy_test_bench::args_t& args)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint32_t nof_carriers = 2;
|
|
|
|
int ret = SRSLTE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
srsenb::phy_args_t phy_args;
|
|
|
|
bpo::options_description options;
|
|
|
|
|
|
|
|
bpo::options_description common("Common execution options");
|
|
|
|
|
|
|
|
|
|
|
|
phy_args.log.phy_level = "info";
|
|
|
|
// clang-format off
|
|
|
|
phy_args.nof_phy_threads = 1; ///< Set number of phy threads to 1 for avoiding concurrency issues
|
|
|
|
common.add_options()
|
|
|
|
|
|
|
|
("duration", bpo::value<uint32_t>(&args.duration), "Duration of the execution in subframes")
|
|
|
|
|
|
|
|
("rnti", bpo::value<uint16_t>(&args.rnti), "UE RNTI, used for random seed")
|
|
|
|
|
|
|
|
("log_level", bpo::value<std::string>(&args.log_level), "General logging level")
|
|
|
|
|
|
|
|
("nof_enb_cells", bpo::value<uint32_t>(&args.nof_enb_cells), "Cell Number of PRB")
|
|
|
|
|
|
|
|
("ue_cell_list", bpo::value<std::vector<uint32_t> >(&args.ue_cell_list), "UE active cell list, the first is used as PCell")
|
|
|
|
|
|
|
|
("ack_mode", bpo::value<std::string>(&args.ack_mode), "HARQ ACK/NACK mode: normal, pucch3, cs")
|
|
|
|
|
|
|
|
("cell.nof_prb", bpo::value<uint32_t>(&args.cell.nof_prb)->default_value(args.cell.nof_prb), "eNb Cell/Carrier bandwidth")
|
|
|
|
|
|
|
|
("cell.nof_ports", bpo::value<uint32_t>(&args.cell.nof_ports)->default_value(args.cell.nof_ports), "eNb Cell/Carrier number of ports")
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
srsenb::phy_cfg_t phy_cfg = {};
|
|
|
|
options.add(common).add_options()("help", "Show this message");
|
|
|
|
for (uint32_t i = 0; i < nof_carriers; i++) {
|
|
|
|
// clang-format on
|
|
|
|
srsenb::phy_cell_cfg_t phy_cell_cfg = {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
phy_cell_cfg.cell.nof_prb = 6;
|
|
|
|
bpo::variables_map vm;
|
|
|
|
phy_cell_cfg.cell.id = i;
|
|
|
|
try {
|
|
|
|
phy_cell_cfg.cell.nof_ports = 1;
|
|
|
|
bpo::store(bpo::command_line_parser(argc, argv).options(options).run(), vm);
|
|
|
|
phy_cell_cfg.cell_id = i;
|
|
|
|
bpo::notify(vm);
|
|
|
|
phy_cell_cfg.dl_freq_hz = 2.6e9 + 10e6 * i;
|
|
|
|
} catch (bpo::error& e) {
|
|
|
|
phy_cell_cfg.ul_freq_hz = 2.6e9 + 10e6 * i - 100e6;
|
|
|
|
std::cerr << e.what() << std::endl;
|
|
|
|
phy_cell_cfg.rf_port = i;
|
|
|
|
ret = SRSLTE_ERROR;
|
|
|
|
phy_cell_cfg.root_seq_idx = 150 + i;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
phy_cfg.phy_cell_cfg.push_back(phy_cell_cfg);
|
|
|
|
// help option was given or error - print usage and exit
|
|
|
|
|
|
|
|
if (vm.count("help") || ret) {
|
|
|
|
|
|
|
|
std::cout << "Usage: " << argv[0] << " [OPTIONS] config_file" << std::endl << std::endl;
|
|
|
|
|
|
|
|
std::cout << options << std::endl << std::endl;
|
|
|
|
|
|
|
|
ret = SRSLTE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
phy_cfg.pucch_cnfg.delta_pucch_shift = asn1::rrc::pucch_cfg_common_s::delta_pucch_shift_e_::ds3;
|
|
|
|
return ret;
|
|
|
|
phy_cfg.prach_cnfg.root_seq_idx = 0;
|
|
|
|
}
|
|
|
|
phy_cfg.prach_cnfg.prach_cfg_info.high_speed_flag = false;
|
|
|
|
|
|
|
|
phy_cfg.prach_cnfg.prach_cfg_info.prach_cfg_idx = 3;
|
|
|
|
|
|
|
|
phy_cfg.prach_cnfg.prach_cfg_info.prach_freq_offset = 2;
|
|
|
|
|
|
|
|
phy_cfg.prach_cnfg.prach_cfg_info.zero_correlation_zone_cfg = 5;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set UE dedicated configuration
|
|
|
|
int main(int argc, char** argv)
|
|
|
|
srslte::phy_cfg_t dedicated = {};
|
|
|
|
{
|
|
|
|
dedicated.ul_cfg.pucch.ack_nack_feedback_mode = SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_CS;
|
|
|
|
phy_test_bench::args_t test_args;
|
|
|
|
dedicated.ul_cfg.pucch.delta_pucch_shift = 2;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n_rb_2 = 2;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.N_cs = 0;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n_pucch_sr = 1;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.N_pucch_1 = 2;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n_pucch_2 = 5;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.simul_cqi_ack = true;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.sr_configured = true;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.I_sr = 5;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[0][0] = 6;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[1][0] = 6;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[2][0] = 6;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[3][0] = 6;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[0][1] = 7;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[1][1] = 7;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[2][1] = 7;
|
|
|
|
|
|
|
|
dedicated.ul_cfg.pucch.n1_pucch_an_cs[3][1] = 7;
|
|
|
|
|
|
|
|
dedicated.dl_cfg.cqi_report.periodic_configured = true;
|
|
|
|
|
|
|
|
dedicated.dl_cfg.cqi_report.pmi_idx = 25;
|
|
|
|
|
|
|
|
dedicated.dl_cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_20;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Asssert PUCCH dedicated configuration has PUCCH 1b collisions
|
|
|
|
// Parse arguments
|
|
|
|
TESTASSERT(srslte_pucch_cfg_assert(&phy_cfg.phy_cell_cfg[0].cell, &dedicated.ul_cfg.pucch) == SRSLTE_SUCCESS);
|
|
|
|
parse_args(argc, argv, test_args);
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<phy_test_bench> test_bench =
|
|
|
|
// Create Test Bench
|
|
|
|
std::unique_ptr<phy_test_bench>(new phy_test_bench(phy_args, phy_cfg, 0x1234, 0, dedicated));
|
|
|
|
unique_phy_test_bench test_bench = unique_phy_test_bench(new phy_test_bench(test_args));
|
|
|
|
|
|
|
|
|
|
|
|
// Run Simulation
|
|
|
|
// Run Simulation
|
|
|
|
for (uint32_t i = 0; i < 256; i++) {
|
|
|
|
for (uint32_t i = 0; i < test_args.duration + 1; i++) {
|
|
|
|
TESTASSERT(test_bench->run_tti() >= SRSLTE_SUCCESS);
|
|
|
|
TESTASSERT(test_bench->run_tti() >= SRSLTE_SUCCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|