SRSUE PHY: unitialised values and attributes clean-tidy up

This commit is contained in:
Xavier Arteaga 2019-09-20 15:25:33 +02:00 committed by Xavier Arteaga
parent 78fcc11a30
commit 54974d935e
4 changed files with 180 additions and 269 deletions

View File

@ -69,15 +69,6 @@ private:
bool ul_grant_available, bool ul_grant_available,
mac_interface_phy_lte::mac_grant_ul_t* mac_grant); mac_interface_phy_lte::mac_grant_ul_t* mac_grant);
// Cross-carried grants scheduled from PCell
void set_dl_pending_grant(uint32_t cc_idx, srslte_dci_dl_t* dl_dci);
bool get_dl_pending_grant(uint32_t cc_idx, srslte_dci_dl_t* dl_dci);
typedef struct {
bool enable;
srslte_dci_dl_t dl_dci;
} pending_dl_grant_t;
pending_dl_grant_t pending_dl_grant[SRSLTE_MAX_CARRIERS]; // Only for the current TTI
/* Methods for DL... */ /* Methods for DL... */
int decode_pdcch_ul(); int decode_pdcch_ul();
int decode_pdcch_dl(); int decode_pdcch_dl();
@ -97,34 +88,34 @@ private:
uint32_t get_wideband_cqi(); uint32_t get_wideband_cqi();
/* Common objects */ /* Common objects */
phy_common* phy; phy_common* phy = nullptr;
srslte::log* log_h; srslte::log* log_h = nullptr;
srslte_cell_t cell; srslte_cell_t cell = {};
srslte_dl_sf_cfg_t sf_cfg_dl; srslte_dl_sf_cfg_t sf_cfg_dl = {};
srslte_ul_sf_cfg_t sf_cfg_ul; srslte_ul_sf_cfg_t sf_cfg_ul = {};
uint32_t cc_idx; uint32_t cc_idx = 0;
bool pregen_enabled = false; bool pregen_enabled = false;
bool cell_initiated; bool cell_initiated = false;
cf_t* signal_buffer_rx[SRSLTE_MAX_PORTS]; cf_t* signal_buffer_rx[SRSLTE_MAX_PORTS] = {};
cf_t* signal_buffer_tx[SRSLTE_MAX_PORTS]; cf_t* signal_buffer_tx[SRSLTE_MAX_PORTS] = {};
/* Objects for DL */ /* Objects for DL */
srslte_ue_dl_t ue_dl; srslte_ue_dl_t ue_dl = {};
srslte_ue_dl_cfg_t ue_dl_cfg; srslte_ue_dl_cfg_t ue_dl_cfg = {};
srslte_pmch_cfg_t pmch_cfg; srslte_pmch_cfg_t pmch_cfg = {};
srslte_chest_dl_cfg_t chest_mbsfn_cfg; srslte_chest_dl_cfg_t chest_mbsfn_cfg = {};
srslte_chest_dl_cfg_t chest_default_cfg; srslte_chest_dl_cfg_t chest_default_cfg = {};
/* Objects for UL */ /* Objects for UL */
srslte_ue_ul_t ue_ul; srslte_ue_ul_t ue_ul = {};
srslte_ue_ul_cfg_t ue_ul_cfg; srslte_ue_ul_cfg_t ue_ul_cfg = {};
// Metrics // Metrics
dl_metrics_t dl_metrics; dl_metrics_t dl_metrics = {};
ul_metrics_t ul_metrics; ul_metrics_t ul_metrics = {};
}; };
} // namespace srsue } // namespace srsue

View File

@ -22,8 +22,6 @@
#ifndef SRSUE_PHCH_COMMON_H #ifndef SRSUE_PHCH_COMMON_H
#define SRSUE_PHCH_COMMON_H #define SRSUE_PHCH_COMMON_H
#define TX_MODE_CONTINUOUS 1
#include "phy_metrics.h" #include "phy_metrics.h"
#include "srslte/common/gen_mch_tables.h" #include "srslte/common/gen_mch_tables.h"
#include "srslte/common/log.h" #include "srslte/common/log.h"
@ -31,7 +29,8 @@
#include "srslte/interfaces/ue_interfaces.h" #include "srslte/interfaces/ue_interfaces.h"
#include "srslte/radio/radio.h" #include "srslte/radio/radio.h"
#include "srslte/srslte.h" #include "srslte/srslte.h"
#include <pthread.h> #include <condition_variable>
#include <mutex>
#include <semaphore.h> #include <semaphore.h>
#include <string.h> #include <string.h>
#include <vector> #include <vector>
@ -53,30 +52,23 @@ class phy_common
{ {
public: public:
/* Common variables used by all phy workers */ /* Common variables used by all phy workers */
phy_args_t* args; phy_args_t* args = nullptr;
stack_interface_phy_lte* stack; stack_interface_phy_lte* stack = nullptr;
phy_interface_rrc_lte::phy_cfg_mbsfn_t mbsfn_config; phy_interface_rrc_lte::phy_cfg_mbsfn_t mbsfn_config;
/* Power control variables */ /* Power control variables */
float pathloss[SRSLTE_MAX_CARRIERS]; float pathloss[SRSLTE_MAX_CARRIERS] = {};
float cur_pathloss; float cur_pathloss = 0.0f;
float p0_preamble; float cur_pusch_power = 0.0f;
float cur_radio_power; float avg_rsrp[SRSLTE_MAX_CARRIERS] = {};
float cur_pusch_power; float avg_rsrp_dbm[SRSLTE_MAX_CARRIERS] = {};
float avg_rsrp[SRSLTE_MAX_CARRIERS]; float avg_rsrq_db = 0.0f;
float avg_rsrp_dbm[SRSLTE_MAX_CARRIERS]; float avg_rssi_dbm = 0.0f;
float avg_rsrq_db; float rx_gain_offset = 0.0f;
float avg_rssi_dbm; float avg_snr_db_cqi[SRSLTE_MAX_CARRIERS] = {};
float rx_gain_offset; float avg_noise[SRSLTE_MAX_CARRIERS] = {};
float avg_snr_db_cqi[SRSLTE_MAX_CARRIERS]; uint32_t pcell_report_period = 0;
float avg_snr_db_sync;
float avg_noise[SRSLTE_MAX_CARRIERS];
bool pcell_meas_enabled;
uint32_t pcell_report_period;
bool pcell_first_measurement;
// SCell EARFCN, PCI, configured and enabled list // SCell EARFCN, PCI, configured and enabled list
typedef struct { typedef struct {
@ -93,7 +85,7 @@ public:
// Save last TBS for DL (Format1C) // Save last TBS for DL (Format1C)
int last_dl_tbs[SRSLTE_MAX_HARQ_PROC][SRSLTE_MAX_CARRIERS][SRSLTE_MAX_CODEWORDS] = {}; int last_dl_tbs[SRSLTE_MAX_HARQ_PROC][SRSLTE_MAX_CARRIERS][SRSLTE_MAX_CODEWORDS] = {};
phy_common(uint32_t max_workers); explicit phy_common(uint32_t max_workers);
~phy_common(); ~phy_common();
@ -108,6 +100,9 @@ public:
void set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN], uint16_t rnti, srslte_tdd_config_t tdd_config); void set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN], uint16_t rnti, srslte_tdd_config_t tdd_config);
void set_dl_pending_grant(uint32_t tti, uint32_t cc_idx, const srslte_dci_dl_t* dl_dci);
bool get_dl_pending_grant(uint32_t tti, uint32_t cc_idx, srslte_dci_dl_t* dl_dci);
void set_ul_pending_ack(srslte_ul_sf_cfg_t* sf, void set_ul_pending_ack(srslte_ul_sf_cfg_t* sf,
uint32_t cc_idx, uint32_t cc_idx,
srslte_phich_grant_t phich_grant, srslte_phich_grant_t phich_grant,
@ -139,19 +134,17 @@ public:
uint32_t nof_samples[SRSLTE_MAX_RADIOS], uint32_t nof_samples[SRSLTE_MAX_RADIOS],
srslte_timestamp_t tx_time[SRSLTE_MAX_RADIOS]); srslte_timestamp_t tx_time[SRSLTE_MAX_RADIOS]);
void set_cell(const srslte_cell_t& c);
void set_nof_workers(uint32_t nof_workers); void set_nof_workers(uint32_t nof_workers);
bool sr_enabled; bool sr_enabled = false;
int sr_last_tx_tti; int sr_last_tx_tti = -1;
srslte::radio_interface_phy* get_radio(); srslte::radio_interface_phy* get_radio();
void set_cell(const srslte_cell_t& c); void set_dl_metrics(dl_metrics_t m, uint32_t cc_idx);
uint32_t get_nof_prb();
void set_dl_metrics(const dl_metrics_t m, uint32_t cc_idx);
void get_dl_metrics(dl_metrics_t m[SRSLTE_MAX_CARRIERS]); void get_dl_metrics(dl_metrics_t m[SRSLTE_MAX_CARRIERS]);
void set_ul_metrics(const ul_metrics_t m, uint32_t cc_idx); void set_ul_metrics(ul_metrics_t m, uint32_t cc_idx);
void get_ul_metrics(ul_metrics_t m[SRSLTE_MAX_CARRIERS]); void get_ul_metrics(ul_metrics_t m[SRSLTE_MAX_CARRIERS]);
void set_sync_metrics(const uint32_t& cc_idx, const sync_metrics_t& m); void set_sync_metrics(const uint32_t& cc_idx, const sync_metrics_t& m);
void get_sync_metrics(sync_metrics_t m[SRSLTE_MAX_CARRIERS]); void get_sync_metrics(sync_metrics_t m[SRSLTE_MAX_CARRIERS]);
@ -169,76 +162,83 @@ public:
void set_mch_period_stop(uint32_t stop); void set_mch_period_stop(uint32_t stop);
private: private:
bool have_mtch_stop; bool have_mtch_stop = false;
pthread_mutex_t mtch_mutex; std::mutex mtch_mutex;
pthread_cond_t mtch_cvar; std::condition_variable mtch_cvar;
std::vector<sem_t> tx_sem; std::vector<sem_t> tx_sem;
uint32_t nof_workers; uint32_t nof_workers = 0;
uint32_t max_workers; uint32_t max_workers = 0;
bool is_pending_tx_end = false; bool is_pending_tx_end = false;
srslte::radio_interface_phy* radio_h; srslte::radio_interface_phy* radio_h = nullptr;
float cfo; float cfo = 0.0f;
srslte::log* log_h; srslte::log* log_h = nullptr;
srslte::channel_ptr ul_channel = nullptr; srslte::channel_ptr ul_channel = nullptr;
int rar_grant_tti; int rar_grant_tti = -1;
typedef struct { typedef struct {
bool enable; bool enable;
srslte_phich_grant_t phich_grant; srslte_phich_grant_t phich_grant;
srslte_dci_ul_t dci_ul; srslte_dci_ul_t dci_ul;
} pending_ul_ack_t; } pending_ul_ack_t;
pending_ul_ack_t pending_ul_ack[TTIMOD_SZ][SRSLTE_MAX_CARRIERS][2]; pending_ul_ack_t pending_ul_ack[TTIMOD_SZ][SRSLTE_MAX_CARRIERS][2] = {};
pthread_mutex_t pending_ul_ack_mutex; std::mutex pending_ul_ack_mutex;
typedef struct { typedef struct {
bool hi_value; bool hi_value;
bool hi_present; bool hi_present;
srslte_dci_ul_t dci_ul; srslte_dci_ul_t dci_ul;
} received_ul_ack_t; } received_ul_ack_t;
received_ul_ack_t received_ul_ack[TTIMOD_SZ][SRSLTE_MAX_CARRIERS]; received_ul_ack_t received_ul_ack[TTIMOD_SZ][SRSLTE_MAX_CARRIERS] = {};
pthread_mutex_t received_ul_ack_mutex; std::mutex received_ul_ack_mutex;
typedef struct { typedef struct {
bool enable; bool enable;
uint32_t pid; uint32_t pid;
srslte_dci_ul_t dci; srslte_dci_ul_t dci;
} pending_ul_grant_t; } pending_ul_grant_t;
pending_ul_grant_t pending_ul_grant[TTIMOD_SZ][SRSLTE_MAX_CARRIERS]; pending_ul_grant_t pending_ul_grant[TTIMOD_SZ][SRSLTE_MAX_CARRIERS] = {};
pthread_mutex_t pending_ul_grant_mutex; std::mutex pending_ul_grant_mutex;
typedef struct { typedef struct {
bool enable; bool enable;
uint8_t value[SRSLTE_MAX_CODEWORDS]; // 0/1 or 2 for DTX uint8_t value[SRSLTE_MAX_CODEWORDS]; // 0/1 or 2 for DTX
srslte_pdsch_ack_resource_t resource; srslte_pdsch_ack_resource_t resource;
} received_ack_t; } received_ack_t;
received_ack_t pending_dl_ack[TTIMOD_SZ][SRSLTE_MAX_CARRIERS]; received_ack_t pending_dl_ack[TTIMOD_SZ][SRSLTE_MAX_CARRIERS] = {};
uint32_t pending_dl_dai[TTIMOD_SZ][SRSLTE_MAX_CARRIERS]; uint32_t pending_dl_dai[TTIMOD_SZ][SRSLTE_MAX_CARRIERS] = {};
pthread_mutex_t pending_dl_ack_mutex; std::mutex pending_dl_ack_mutex;
bool is_first_tx; // Cross-carried grants scheduled from PCell
typedef struct {
bool enable;
srslte_dci_dl_t dl_dci;
} pending_dl_grant_t;
pending_dl_grant_t pending_dl_grant[FDD_HARQ_DELAY_MS][SRSLTE_MAX_CARRIERS] = {};
srslte_cell_t cell; bool is_first_tx = true;
dl_metrics_t dl_metrics[SRSLTE_MAX_CARRIERS]; srslte_cell_t cell = {};
uint32_t dl_metrics_count;
bool dl_metrics_read; dl_metrics_t dl_metrics[SRSLTE_MAX_CARRIERS] = {};
ul_metrics_t ul_metrics[SRSLTE_MAX_CARRIERS]; uint32_t dl_metrics_count = 0;
uint32_t ul_metrics_count; bool dl_metrics_read = true;
bool ul_metrics_read; ul_metrics_t ul_metrics[SRSLTE_MAX_CARRIERS] = {};
sync_metrics_t sync_metrics[SRSLTE_MAX_CARRIERS]; uint32_t ul_metrics_count = 0;
uint32_t sync_metrics_count; bool ul_metrics_read = true;
bool sync_metrics_read; sync_metrics_t sync_metrics[SRSLTE_MAX_CARRIERS] = {};
uint32_t sync_metrics_count = 0;
bool sync_metrics_read = true;
// MBSFN // MBSFN
bool sib13_configured; bool sib13_configured = false;
bool mcch_configured; bool mcch_configured = false;
uint32_t mch_period_stop; uint32_t mch_period_stop = 0;
uint8_t mch_table[40]; uint8_t mch_table[40] = {};
uint8_t mcch_table[10]; uint8_t mcch_table[10] = {};
bool is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); bool is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti);

View File

@ -49,30 +49,11 @@ namespace srsue {
* *
*/ */
cc_worker::cc_worker(uint32_t cc_idx, uint32_t max_prb, srsue::phy_common* phy, srslte::log* log_h) cc_worker::cc_worker(uint32_t cc_idx_, uint32_t max_prb, srsue::phy_common* phy_, srslte::log* log_h_)
{ {
ZERO_OBJECT(signal_buffer_rx); cc_idx = cc_idx_;
ZERO_OBJECT(signal_buffer_tx); phy = phy_;
ZERO_OBJECT(pending_dl_grant); log_h = log_h_;
ZERO_OBJECT(cell);
ZERO_OBJECT(sf_cfg_dl);
ZERO_OBJECT(sf_cfg_ul);
ZERO_OBJECT(ue_dl);
ZERO_OBJECT(ue_dl_cfg);
ZERO_OBJECT(ue_dl_cfg.cfg.pdsch);
ZERO_OBJECT(pmch_cfg);
ZERO_OBJECT(chest_mbsfn_cfg);
ZERO_OBJECT(chest_default_cfg);
ZERO_OBJECT(ue_ul);
ZERO_OBJECT(ue_ul_cfg);
ZERO_OBJECT(dl_metrics);
ZERO_OBJECT(ul_metrics);
cell_initiated = false;
this->cc_idx = cc_idx;
this->phy = phy;
this->log_h = log_h;
for (uint32_t i = 0; i < phy->args->nof_rx_ant; i++) { for (uint32_t i = 0; i < phy->args->nof_rx_ant; i++) {
signal_buffer_rx[i] = (cf_t*)srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(max_prb)); signal_buffer_rx[i] = (cf_t*)srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(max_prb));
@ -143,10 +124,10 @@ void cc_worker::reset()
set_config(empty_cfg); set_config(empty_cfg);
} }
bool cc_worker::set_cell(srslte_cell_t cell) bool cc_worker::set_cell(srslte_cell_t cell_)
{ {
if (this->cell.id != cell.id || !cell_initiated) { if (cell.id != cell_.id || !cell_initiated) {
this->cell = cell; cell = cell_;
if (srslte_ue_dl_set_cell(&ue_dl, cell)) { if (srslte_ue_dl_set_cell(&ue_dl, cell)) {
Error("Initiating UE DL\n"); Error("Initiating UE DL\n");
@ -216,27 +197,6 @@ void cc_worker::enable_pregen_signals(bool enabled)
this->pregen_enabled = enabled; this->pregen_enabled = enabled;
} }
void cc_worker::set_dl_pending_grant(uint32_t cc_idx, srslte_dci_dl_t* dl_dci)
{
if (!pending_dl_grant[cc_idx].enable) {
pending_dl_grant[cc_idx].dl_dci = *dl_dci;
pending_dl_grant[cc_idx].enable = true;
} else {
Warning("set_dl_pending_grant: cc=%d already exists\n", cc_idx);
}
}
bool cc_worker::get_dl_pending_grant(uint32_t cc_idx, srslte_dci_dl_t* dl_dci)
{
if (pending_dl_grant[cc_idx].enable) {
*dl_dci = pending_dl_grant[cc_idx].dl_dci;
pending_dl_grant[cc_idx].enable = false;
return true;
} else {
return false;
}
}
/************ /************
* *
* Downlink Functions * Downlink Functions
@ -245,9 +205,9 @@ bool cc_worker::get_dl_pending_grant(uint32_t cc_idx, srslte_dci_dl_t* dl_dci)
bool cc_worker::work_dl_regular() bool cc_worker::work_dl_regular()
{ {
bool dl_ack[SRSLTE_MAX_CODEWORDS]; bool dl_ack[SRSLTE_MAX_CODEWORDS] = {};
mac_interface_phy_lte::tb_action_dl_t dl_action; mac_interface_phy_lte::tb_action_dl_t dl_action = {};
bool found_dl_grant = false; bool found_dl_grant = false;
@ -288,8 +248,8 @@ bool cc_worker::work_dl_regular()
} }
} }
srslte_dci_dl_t dci_dl; srslte_dci_dl_t dci_dl = {};
bool has_dl_grant = get_dl_pending_grant(cc_idx, &dci_dl); bool has_dl_grant = phy->get_dl_pending_grant(CURRENT_TTI, cc_idx, &dci_dl);
// If found a dci for this carrier, generate a grant, pass it to MAC and decode the associated PDSCH // If found a dci for this carrier, generate a grant, pass it to MAC and decode the associated PDSCH
if (has_dl_grant) { if (has_dl_grant) {
@ -313,7 +273,7 @@ bool cc_worker::work_dl_regular()
ue_dl_cfg.cfg.pdsch.rnti = dci_dl.rnti; ue_dl_cfg.cfg.pdsch.rnti = dci_dl.rnti;
// Generate MAC grant // Generate MAC grant
mac_interface_phy_lte::mac_grant_dl_t mac_grant; mac_interface_phy_lte::mac_grant_dl_t mac_grant = {};
dl_phy_to_mac_grant(&ue_dl_cfg.cfg.pdsch.grant, &dci_dl, &mac_grant); dl_phy_to_mac_grant(&ue_dl_cfg.cfg.pdsch.grant, &dci_dl, &mac_grant);
// Save ACK resource configuration // Save ACK resource configuration
@ -333,7 +293,7 @@ bool cc_worker::work_dl_regular()
bool cc_worker::work_dl_mbsfn(srslte_mbsfn_cfg_t mbsfn_cfg) bool cc_worker::work_dl_mbsfn(srslte_mbsfn_cfg_t mbsfn_cfg)
{ {
mac_interface_phy_lte::tb_action_dl_t dl_action; mac_interface_phy_lte::tb_action_dl_t dl_action = {};
// Configure MBSFN settings // Configure MBSFN settings
srslte_ue_dl_set_mbsfn_area_id(&ue_dl, mbsfn_cfg.mbsfn_area_id); srslte_ue_dl_set_mbsfn_area_id(&ue_dl, mbsfn_cfg.mbsfn_area_id);
@ -400,8 +360,7 @@ int cc_worker::decode_pdcch_dl()
{ {
int nof_grants = 0; int nof_grants = 0;
srslte_dci_dl_t dci[SRSLTE_MAX_CARRIERS]; srslte_dci_dl_t dci[SRSLTE_MAX_CARRIERS] = {};
ZERO_OBJECT(dci);
uint16_t dl_rnti = phy->stack->get_dl_sched_rnti(CURRENT_TTI); uint16_t dl_rnti = phy->stack->get_dl_sched_rnti(CURRENT_TTI);
if (dl_rnti) { if (dl_rnti) {
@ -424,10 +383,10 @@ int cc_worker::decode_pdcch_dl()
for (int k = 0; k < nof_grants; k++) { for (int k = 0; k < nof_grants; k++) {
// Save dci to CC index // Save dci to CC index
set_dl_pending_grant(dci[k].cif_present ? dci[k].cif : cc_idx, &dci[k]); phy->set_dl_pending_grant(CURRENT_TTI, dci[k].cif_present ? dci[k].cif : cc_idx, &dci[k]);
// Logging // Logging
char str[512]; char str[512] = {};
srslte_dci_dl_info(&dci[k], str, 512); srslte_dci_dl_info(&dci[k], str, 512);
Info("PDCCH: cc=%d, %s, snr=%.1f dB\n", cc_idx, str, ue_dl.chest_res.snr_db); Info("PDCCH: cc=%d, %s, snr=%.1f dB\n", cc_idx, str, ue_dl.chest_res.snr_db);
} }
@ -440,12 +399,11 @@ int cc_worker::decode_pdsch(srslte_pdsch_ack_resource_t ack_resource,
bool mac_acks[SRSLTE_MAX_CODEWORDS]) bool mac_acks[SRSLTE_MAX_CODEWORDS])
{ {
srslte_pdsch_res_t pdsch_dec[SRSLTE_MAX_CODEWORDS]; srslte_pdsch_res_t pdsch_dec[SRSLTE_MAX_CODEWORDS] = {};
ZERO_OBJECT(pdsch_dec);
// See if at least 1 codeword needs to be decoded. If not need to be decode, resend ACK // See if at least 1 codeword needs to be decoded. If not need to be decode, resend ACK
bool decode_enable = false; bool decode_enable = false;
bool tb_enable[SRSLTE_MAX_CODEWORDS]; bool tb_enable[SRSLTE_MAX_CODEWORDS] = {};
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
tb_enable[tb] = ue_dl_cfg.cfg.pdsch.grant.tb[tb].enabled; tb_enable[tb] = ue_dl_cfg.cfg.pdsch.grant.tb[tb].enabled;
if (action->tb[tb].enabled) { if (action->tb[tb].enabled) {
@ -472,7 +430,7 @@ int cc_worker::decode_pdsch(srslte_pdsch_ack_resource_t ack_resource,
} }
// Generate ACKs for MAC and PUCCH // Generate ACKs for MAC and PUCCH
uint8_t pending_acks[SRSLTE_MAX_CODEWORDS]; uint8_t pending_acks[SRSLTE_MAX_CODEWORDS] = {};
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
// For MAC, set to true if it's a duplicate // For MAC, set to true if it's a duplicate
mac_acks[tb] = action->tb[tb].enabled ? pdsch_dec[tb].crc : true; mac_acks[tb] = action->tb[tb].enabled ? pdsch_dec[tb].crc : true;
@ -492,7 +450,7 @@ int cc_worker::decode_pdsch(srslte_pdsch_ack_resource_t ack_resource,
dl_metrics.turbo_iters = pdsch_dec->avg_iterations_block / 2; dl_metrics.turbo_iters = pdsch_dec->avg_iterations_block / 2;
// Logging // Logging
char str[512]; char str[512] = {};
srslte_pdsch_rx_info(&ue_dl_cfg.cfg.pdsch, pdsch_dec, str, 512); srslte_pdsch_rx_info(&ue_dl_cfg.cfg.pdsch, pdsch_dec, str, 512);
Info("PDSCH: cc=%d, %s, snr=%.1f dB\n", cc_idx, str, ue_dl.chest_res.snr_db); Info("PDSCH: cc=%d, %s, snr=%.1f dB\n", cc_idx, str, ue_dl.chest_res.snr_db);
} }
@ -502,7 +460,7 @@ int cc_worker::decode_pdsch(srslte_pdsch_ack_resource_t ack_resource,
int cc_worker::decode_pmch(mac_interface_phy_lte::tb_action_dl_t* action, srslte_mbsfn_cfg_t* mbsfn_cfg) int cc_worker::decode_pmch(mac_interface_phy_lte::tb_action_dl_t* action, srslte_mbsfn_cfg_t* mbsfn_cfg)
{ {
srslte_pdsch_res_t pmch_dec; srslte_pdsch_res_t pmch_dec = {};
pmch_cfg.area_id = mbsfn_cfg->mbsfn_area_id; pmch_cfg.area_id = mbsfn_cfg->mbsfn_area_id;
pmch_cfg.pdsch_cfg.softbuffers.rx[0] = action->tb[0].softbuffer.rx; pmch_cfg.pdsch_cfg.softbuffers.rx[0] = action->tb[0].softbuffer.rx;
@ -576,7 +534,7 @@ void cc_worker::update_measurements()
// Average RSRQ over DEFAULT_MEAS_PERIOD_MS then sent to RRC // Average RSRQ over DEFAULT_MEAS_PERIOD_MS then sent to RRC
float rsrq_db = ue_dl.chest_res.rsrq_db; float rsrq_db = ue_dl.chest_res.rsrq_db;
if (std::isnormal(rsrq_db)) { if (std::isnormal(rsrq_db)) {
if (!(CURRENT_TTI % phy->pcell_report_period) || !phy->avg_rsrq_db) { if (!(CURRENT_TTI % phy->pcell_report_period) || !std::isnormal(phy->avg_rsrq_db)) {
phy->avg_rsrq_db = rsrq_db; phy->avg_rsrq_db = rsrq_db;
} else { } else {
phy->avg_rsrq_db = SRSLTE_VEC_CMA(rsrq_db, phy->avg_rsrq_db, CURRENT_TTI % phy->pcell_report_period); phy->avg_rsrq_db = SRSLTE_VEC_CMA(rsrq_db, phy->avg_rsrq_db, CURRENT_TTI % phy->pcell_report_period);
@ -586,10 +544,10 @@ void cc_worker::update_measurements()
// Average RSRP taken from CRS // Average RSRP taken from CRS
float rsrp_lin = ue_dl.chest_res.rsrp; float rsrp_lin = ue_dl.chest_res.rsrp;
if (std::isnormal(rsrp_lin)) { if (std::isnormal(rsrp_lin)) {
if (!phy->avg_rsrp[cc_idx] && !std::isnan(phy->avg_rsrp[cc_idx])) { if (!std::isnormal(phy->avg_rsrp[cc_idx])) {
phy->avg_rsrp[cc_idx] = SRSLTE_VEC_EMA(rsrp_lin, phy->avg_rsrp[cc_idx], snr_ema_coeff);
} else {
phy->avg_rsrp[cc_idx] = rsrp_lin; phy->avg_rsrp[cc_idx] = rsrp_lin;
} else {
phy->avg_rsrp[cc_idx] = SRSLTE_VEC_EMA(rsrp_lin, phy->avg_rsrp[cc_idx], snr_ema_coeff);
} }
} }
@ -598,7 +556,7 @@ void cc_worker::update_measurements()
// Serving cell RSRP measurements are averaged over DEFAULT_MEAS_PERIOD_MS then sent to RRC // Serving cell RSRP measurements are averaged over DEFAULT_MEAS_PERIOD_MS then sent to RRC
if (std::isnormal(rsrp_dbm)) { if (std::isnormal(rsrp_dbm)) {
if (!(CURRENT_TTI % phy->pcell_report_period) || !phy->avg_rsrp_dbm[cc_idx]) { if (!(CURRENT_TTI % phy->pcell_report_period) || !std::isnormal(phy->avg_rsrp_dbm[cc_idx])) {
phy->avg_rsrp_dbm[cc_idx] = rsrp_dbm; phy->avg_rsrp_dbm[cc_idx] = rsrp_dbm;
} else { } else {
phy->avg_rsrp_dbm[cc_idx] = phy->avg_rsrp_dbm[cc_idx] =
@ -613,7 +571,7 @@ void cc_worker::update_measurements()
// Average noise // Average noise
float cur_noise = ue_dl.chest_res.noise_estimate; float cur_noise = ue_dl.chest_res.noise_estimate;
if (std::isnormal(cur_noise)) { if (std::isnormal(cur_noise)) {
if (!phy->avg_noise) { if (!std::isnormal(phy->avg_noise[cc_idx])) {
phy->avg_noise[cc_idx] = cur_noise; phy->avg_noise[cc_idx] = cur_noise;
} else { } else {
phy->avg_noise[cc_idx] = SRSLTE_VEC_EMA(cur_noise, phy->avg_noise[cc_idx], snr_ema_coeff); phy->avg_noise[cc_idx] = SRSLTE_VEC_EMA(cur_noise, phy->avg_noise[cc_idx], snr_ema_coeff);
@ -622,7 +580,7 @@ void cc_worker::update_measurements()
// Average snr in the log domain // Average snr in the log domain
if (std::isnormal(ue_dl.chest_res.snr_db)) { if (std::isnormal(ue_dl.chest_res.snr_db)) {
if (!phy->avg_noise) { if (!std::isnormal(phy->avg_snr_db_cqi[cc_idx])) {
phy->avg_snr_db_cqi[cc_idx] = ue_dl.chest_res.snr_db; phy->avg_snr_db_cqi[cc_idx] = ue_dl.chest_res.snr_db;
} else { } else {
phy->avg_snr_db_cqi[cc_idx] = SRSLTE_VEC_EMA(ue_dl.chest_res.snr_db, phy->avg_snr_db_cqi[cc_idx], snr_ema_coeff); phy->avg_snr_db_cqi[cc_idx] = SRSLTE_VEC_EMA(ue_dl.chest_res.snr_db, phy->avg_snr_db_cqi[cc_idx], snr_ema_coeff);
@ -660,7 +618,7 @@ bool cc_worker::work_ul(srslte_uci_data_t* uci_data)
bool ul_grant_available = phy->get_ul_pending_grant(&sf_cfg_ul, cc_idx, &pid, &dci_ul); bool ul_grant_available = phy->get_ul_pending_grant(&sf_cfg_ul, cc_idx, &pid, &dci_ul);
ul_mac_grant.phich_available = ul_mac_grant.phich_available =
phy->get_ul_received_ack(&sf_cfg_ul, cc_idx, &ul_mac_grant.hi_value, ul_grant_available ? NULL : &dci_ul); phy->get_ul_received_ack(&sf_cfg_ul, cc_idx, &ul_mac_grant.hi_value, ul_grant_available ? nullptr : &dci_ul);
// If there is no grant, pid is from current TX TTI // If there is no grant, pid is from current TX TTI
if (!ul_grant_available) { if (!ul_grant_available) {
@ -717,7 +675,7 @@ bool cc_worker::work_ul(srslte_uci_data_t* uci_data)
} }
// Generate uplink signal, include uci data on only PCell // Generate uplink signal, include uci data on only PCell
signal_ready = encode_uplink(&ul_action, (cc_idx == 0) ? uci_data : NULL); signal_ready = encode_uplink(&ul_action, (cc_idx == 0) ? uci_data : nullptr);
// Prepare to receive ACK through PHICH // Prepare to receive ACK through PHICH
if (ul_action.expect_ack) { if (ul_action.expect_ack) {
@ -803,6 +761,12 @@ bool cc_worker::encode_uplink(mac_interface_phy_lte::tb_action_ul_t* action, srs
if (action) { if (action) {
data.ptr = action->tb.payload; data.ptr = action->tb.payload;
ue_ul_cfg.ul_cfg.pusch.softbuffers.tx = action->tb.softbuffer.tx; ue_ul_cfg.ul_cfg.pusch.softbuffers.tx = action->tb.softbuffer.tx;
// Use RV from higher layers
ue_ul_cfg.ul_cfg.pusch.grant.tb.rv = action->tb.rv;
// Setup PUSCH grant
ue_ul_cfg.grant_available = action->tb.enabled;
} }
// Set UCI data and configuration // Set UCI data and configuration
@ -815,12 +779,6 @@ bool cc_worker::encode_uplink(mac_interface_phy_lte::tb_action_ul_t* action, srs
ZERO_OBJECT(ue_ul_cfg.ul_cfg.pucch.uci_cfg); ZERO_OBJECT(ue_ul_cfg.ul_cfg.pucch.uci_cfg);
} }
// Use RV from higher layers
ue_ul_cfg.ul_cfg.pusch.grant.tb.rv = action->tb.rv;
// Setup PUSCH grant
ue_ul_cfg.grant_available = action->tb.enabled;
// Set UL RNTI // Set UL RNTI
ue_ul_cfg.ul_cfg.pucch.rnti = phy->stack->get_ul_sched_rnti(CURRENT_TTI_TX); ue_ul_cfg.ul_cfg.pucch.rnti = phy->stack->get_ul_sched_rnti(CURRENT_TTI_TX);
@ -896,9 +854,9 @@ void cc_worker::set_uci_ack(srslte_uci_data_t* uci_data,
uint32_t nof_configured_carriers = 0; uint32_t nof_configured_carriers = 0;
// Only PCell generates ACK for all SCell // Only PCell generates ACK for all SCell
for (uint32_t cc_idx = 0; cc_idx < phy->args->nof_carriers; cc_idx++) { for (uint32_t i = 0; i < phy->args->nof_carriers; i++) {
if (cc_idx == 0 || phy->scell_cfg[cc_idx].configured) { if (i == 0 || phy->scell_cfg[i].configured) {
phy->get_dl_pending_ack(&sf_cfg_ul, cc_idx, &ack_info.cc[cc_idx]); phy->get_dl_pending_ack(&sf_cfg_ul, i, &ack_info.cc[i]);
nof_configured_carriers++; nof_configured_carriers++;
} }
} }

View File

@ -42,48 +42,12 @@ using namespace asn1::rrc;
namespace srsue { namespace srsue {
static cf_t zeros[50000]; static cf_t zeros[50000] = {};
static cf_t* zeros_multi[SRSLTE_MAX_PORTS]; static cf_t* zeros_multi[SRSLTE_MAX_PORTS] = {zeros, zeros, zeros, zeros};
phy_common::phy_common(uint32_t max_workers) : tx_sem(max_workers) phy_common::phy_common(uint32_t max_workers_) : tx_sem(max_workers_)
{ {
args = NULL; max_workers = max_workers_;
log_h = NULL;
radio_h = NULL;
stack = NULL;
this->max_workers = max_workers;
rx_gain_offset = 0;
// have_mtch_stop = false;
pthread_mutex_init(&pending_ul_ack_mutex, NULL);
pthread_mutex_init(&pending_dl_ack_mutex, NULL);
pthread_mutex_init(&pending_ul_grant_mutex, NULL);
pthread_mutex_init(&received_ul_ack_mutex, NULL);
pthread_mutex_init(&mtch_mutex, NULL);
pthread_cond_init(&mtch_cvar, NULL);
bzero(&dl_metrics, sizeof(dl_metrics_t) * SRSLTE_MAX_CARRIERS);
dl_metrics_read = true;
dl_metrics_count = 0;
bzero(&ul_metrics, sizeof(ul_metrics_t) * SRSLTE_MAX_CARRIERS);
ul_metrics_read = true;
ul_metrics_count = 0;
ZERO_OBJECT(sync_metrics);
sync_metrics_read = true;
sync_metrics_count = 0;
rar_grant_tti = -1;
bzero(zeros, 50000 * sizeof(cf_t));
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
zeros_multi[p] = zeros;
}
for (int i = 0; i < TTIMOD_SZ; i++) {
for (int j = 0; j < SRSLTE_MAX_CARRIERS; j++) {
bzero(&received_ul_ack[i][j], sizeof(received_ul_ack_t));
}
}
for (uint32_t i = 0; i < max_workers; i++) { for (uint32_t i = 0; i < max_workers; i++) {
sem_init(&tx_sem[i], 0, 0); // All semaphores start blocked sem_init(&tx_sem[i], 0, 0); // All semaphores start blocked
@ -97,10 +61,6 @@ phy_common::phy_common(uint32_t max_workers) : tx_sem(max_workers)
phy_common::~phy_common() phy_common::~phy_common()
{ {
pthread_mutex_destroy(&pending_ul_ack_mutex);
pthread_mutex_destroy(&pending_dl_ack_mutex);
pthread_mutex_destroy(&pending_ul_grant_mutex);
pthread_mutex_destroy(&received_ul_ack_mutex);
for (uint32_t i = 0; i < max_workers; i++) { for (uint32_t i = 0; i < max_workers; i++) {
sem_post(&tx_sem[i]); sem_post(&tx_sem[i]);
} }
@ -109,9 +69,9 @@ phy_common::~phy_common()
} }
} }
void phy_common::set_nof_workers(uint32_t nof_workers) void phy_common::set_nof_workers(uint32_t nof_workers_)
{ {
this->nof_workers = nof_workers; nof_workers = nof_workers_;
} }
void phy_common::init(phy_args_t* _args, void phy_common::init(phy_args_t* _args,
@ -150,9 +110,9 @@ void phy_common::set_ue_dl_cfg(srslte_ue_dl_cfg_t* ue_dl_cfg)
} }
chest_cfg->filter_type = SRSLTE_CHEST_FILTER_GAUSS; chest_cfg->filter_type = SRSLTE_CHEST_FILTER_GAUSS;
if (!args->snr_estim_alg.compare("refs")) { if (args->snr_estim_alg == "refs") {
chest_cfg->noise_alg = SRSLTE_NOISE_ALG_REFS; chest_cfg->noise_alg = SRSLTE_NOISE_ALG_REFS;
} else if (!args->snr_estim_alg.compare("empty")) { } else if (args->snr_estim_alg == "empty") {
chest_cfg->noise_alg = SRSLTE_NOISE_ALG_EMPTY; chest_cfg->noise_alg = SRSLTE_NOISE_ALG_EMPTY;
} else { } else {
chest_cfg->noise_alg = SRSLTE_NOISE_ALG_PSS; chest_cfg->noise_alg = SRSLTE_NOISE_ALG_PSS;
@ -170,7 +130,7 @@ void phy_common::set_pdsch_cfg(srslte_pdsch_cfg_t* pdsch_cfg)
bzero(pdsch_cfg, sizeof(srslte_pdsch_cfg_t)); bzero(pdsch_cfg, sizeof(srslte_pdsch_cfg_t));
pdsch_cfg->csi_enable = args->pdsch_csi_enabled; pdsch_cfg->csi_enable = args->pdsch_csi_enabled;
pdsch_cfg->max_nof_iterations = args->pdsch_max_its; pdsch_cfg->max_nof_iterations = args->pdsch_max_its;
pdsch_cfg->decoder_type = !args->equalizer_mode.compare("zf") ? SRSLTE_MIMO_DECODER_ZF : SRSLTE_MIMO_DECODER_MMSE; pdsch_cfg->decoder_type = (args->equalizer_mode == "zf") ? SRSLTE_MIMO_DECODER_ZF : SRSLTE_MIMO_DECODER_MMSE;
} }
void phy_common::set_ue_ul_cfg(srslte_ue_ul_cfg_t* ue_ul_cfg) void phy_common::set_ue_ul_cfg(srslte_ue_ul_cfg_t* ue_ul_cfg)
@ -198,9 +158,9 @@ void phy_common::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRAN
srslte_tdd_config_t tdd_config) srslte_tdd_config_t tdd_config)
{ {
if (MSG3_DELAY_MS < 0) { #if MSG3_DELAY_MS < 0
ERROR("Error MSG3_DELAY_MS can't be negative\n"); #error "Error MSG3_DELAY_MS can't be negative"
} #endif /* MSG3_DELAY_MS < 0 */
if (rar_grant_tti < 0) { if (rar_grant_tti < 0) {
Error("Must call set_rar_grant_tti before set_rar_grant\n"); Error("Must call set_rar_grant_tti before set_rar_grant\n");
@ -230,7 +190,7 @@ void phy_common::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRAN
} }
// Save Msg3 UL dci // Save Msg3 UL dci
pthread_mutex_lock(&pending_ul_grant_mutex); std::lock_guard<std::mutex> lock(pending_ul_grant_mutex);
if (!pending_ul_grant[TTIMOD(msg3_tx_tti)][0].enable) { if (!pending_ul_grant[TTIMOD(msg3_tx_tti)][0].enable) {
Debug("RAR grant rar_grant=%d, msg3_tti=%d, stored in index=%d\n", rar_grant_tti, msg3_tx_tti, TTIMOD(msg3_tx_tti)); Debug("RAR grant rar_grant=%d, msg3_tti=%d, stored in index=%d\n", rar_grant_tti, msg3_tx_tti, TTIMOD(msg3_tx_tti));
pending_ul_grant[TTIMOD(msg3_tx_tti)][0].pid = ul_pidof(msg3_tx_tti, &tdd_config); pending_ul_grant[TTIMOD(msg3_tx_tti)][0].pid = ul_pidof(msg3_tx_tti, &tdd_config);
@ -239,7 +199,6 @@ void phy_common::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRAN
} else { } else {
Warning("set_rar_grant: sf->tti=%d, cc=%d already in use\n", msg3_tx_tti, 0); Warning("set_rar_grant: sf->tti=%d, cc=%d already in use\n", msg3_tx_tti, 0);
} }
pthread_mutex_unlock(&pending_ul_grant_mutex);
rar_grant_tti = -1; rar_grant_tti = -1;
} }
@ -324,7 +283,7 @@ void phy_common::set_ul_pending_ack(srslte_ul_sf_cfg_t* sf,
srslte_dci_ul_t* dci_ul) srslte_dci_ul_t* dci_ul)
{ {
// Use a lock here because subframe 4 and 9 of TDD config 0 accept multiple PHICH from multiple frames // Use a lock here because subframe 4 and 9 of TDD config 0 accept multiple PHICH from multiple frames
pthread_mutex_lock(&pending_ul_ack_mutex); std::lock_guard<std::mutex> lock(pending_ul_ack_mutex);
if (!pending_ul_ack[TTIMOD(tti_phich(sf))][cc_idx][phich_grant.I_phich].enable) { if (!pending_ul_ack[TTIMOD(tti_phich(sf))][cc_idx][phich_grant.I_phich].enable) {
pending_ul_ack[TTIMOD(tti_phich(sf))][cc_idx][phich_grant.I_phich].dci_ul = *dci_ul; pending_ul_ack[TTIMOD(tti_phich(sf))][cc_idx][phich_grant.I_phich].dci_ul = *dci_ul;
@ -338,7 +297,6 @@ void phy_common::set_ul_pending_ack(srslte_ul_sf_cfg_t* sf,
} else { } else {
Warning("set_ul_pending_ack: sf->tti=%d, cc=%d already in use\n", sf->tti, cc_idx); Warning("set_ul_pending_ack: sf->tti=%d, cc=%d already in use\n", sf->tti, cc_idx);
} }
pthread_mutex_unlock(&pending_ul_ack_mutex);
} }
// Here SF->TTI is when PHICH is being transmitted so that's DL subframe // Here SF->TTI is when PHICH is being transmitted so that's DL subframe
@ -347,7 +305,7 @@ bool phy_common::get_ul_pending_ack(srslte_dl_sf_cfg_t* sf,
srslte_phich_grant_t* phich_grant, srslte_phich_grant_t* phich_grant,
srslte_dci_ul_t* dci_ul) srslte_dci_ul_t* dci_ul)
{ {
pthread_mutex_lock(&pending_ul_ack_mutex); std::lock_guard<std::mutex> lock(pending_ul_ack_mutex);
bool ret = false; bool ret = false;
if (pending_ul_ack[TTIMOD(sf->tti)][cc_idx][phich_grant->I_phich].enable) { if (pending_ul_ack[TTIMOD(sf->tti)][cc_idx][phich_grant->I_phich].enable) {
*phich_grant = pending_ul_ack[TTIMOD(sf->tti)][cc_idx][phich_grant->I_phich].phich_grant; *phich_grant = pending_ul_ack[TTIMOD(sf->tti)][cc_idx][phich_grant->I_phich].phich_grant;
@ -356,26 +314,20 @@ bool phy_common::get_ul_pending_ack(srslte_dl_sf_cfg_t* sf,
pending_ul_ack[TTIMOD(sf->tti)][cc_idx][phich_grant->I_phich].enable = false; pending_ul_ack[TTIMOD(sf->tti)][cc_idx][phich_grant->I_phich].enable = false;
Debug("Get pending ACK for sf->tti=%d n_dmrs=%d, I_phich=%d\n", sf->tti, phich_grant->n_dmrs, phich_grant->I_phich); Debug("Get pending ACK for sf->tti=%d n_dmrs=%d, I_phich=%d\n", sf->tti, phich_grant->n_dmrs, phich_grant->I_phich);
} }
pthread_mutex_unlock(&pending_ul_ack_mutex);
return ret; return ret;
} }
bool phy_common::is_any_ul_pending_ack() bool phy_common::is_any_ul_pending_ack()
{ {
pthread_mutex_lock(&pending_ul_ack_mutex); std::lock_guard<std::mutex> lock(pending_ul_ack_mutex);
bool ret = false; bool ret = false;
for (int i = 0; i < TTIMOD_SZ; i++) { for (int i = 0; i < TTIMOD_SZ && !ret; i++) {
for (int n = 0; n < SRSLTE_MAX_CARRIERS; n++) { for (int n = 0; n < SRSLTE_MAX_CARRIERS && !ret; n++) {
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2 && !ret; j++) {
if (pending_ul_ack[i][n][j].enable) { ret = pending_ul_ack[i][n][j].enable;
ret = true;
goto unlock_exit;
}
} }
} }
} }
unlock_exit:
pthread_mutex_unlock(&pending_ul_ack_mutex);
return ret; return ret;
} }
@ -394,8 +346,7 @@ unlock_exit:
// SF->TTI is at which Format0 dci is received // SF->TTI is at which Format0 dci is received
void phy_common::set_ul_pending_grant(srslte_dl_sf_cfg_t* sf, uint32_t cc_idx, srslte_dci_ul_t* dci) void phy_common::set_ul_pending_grant(srslte_dl_sf_cfg_t* sf, uint32_t cc_idx, srslte_dci_ul_t* dci)
{ {
std::lock_guard<std::mutex> lock(pending_ul_grant_mutex);
pthread_mutex_lock(&pending_ul_grant_mutex);
// Calculate PID for this SF->TTI // Calculate PID for this SF->TTI
uint32_t pid = ul_pidof(tti_pusch_gr(sf), &sf->tdd_config); uint32_t pid = ul_pidof(tti_pusch_gr(sf), &sf->tdd_config);
@ -408,13 +359,12 @@ void phy_common::set_ul_pending_grant(srslte_dl_sf_cfg_t* sf, uint32_t cc_idx, s
} else { } else {
Warning("set_ul_pending_grant: sf->tti=%d, cc=%d already in use\n", sf->tti, cc_idx); Warning("set_ul_pending_grant: sf->tti=%d, cc=%d already in use\n", sf->tti, cc_idx);
} }
pthread_mutex_unlock(&pending_ul_grant_mutex);
} }
// SF->TTI at which PUSCH should be transmitted // SF->TTI at which PUSCH should be transmitted
bool phy_common::get_ul_pending_grant(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, uint32_t* pid, srslte_dci_ul_t* dci) bool phy_common::get_ul_pending_grant(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, uint32_t* pid, srslte_dci_ul_t* dci)
{ {
pthread_mutex_lock(&pending_ul_grant_mutex); std::lock_guard<std::mutex> lock(pending_ul_grant_mutex);
bool ret = false; bool ret = false;
if (pending_ul_grant[TTIMOD(sf->tti)][cc_idx].enable) { if (pending_ul_grant[TTIMOD(sf->tti)][cc_idx].enable) {
Debug("Reading grant sf->tti=%d idx=%d\n", sf->tti, TTIMOD(sf->tti)); Debug("Reading grant sf->tti=%d idx=%d\n", sf->tti, TTIMOD(sf->tti));
@ -427,7 +377,7 @@ bool phy_common::get_ul_pending_grant(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, u
pending_ul_grant[TTIMOD(sf->tti)][cc_idx].enable = false; pending_ul_grant[TTIMOD(sf->tti)][cc_idx].enable = false;
ret = true; ret = true;
} }
pthread_mutex_unlock(&pending_ul_grant_mutex);
return ret; return ret;
} }
@ -435,18 +385,17 @@ bool phy_common::get_ul_pending_grant(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, u
void phy_common::set_ul_received_ack( void phy_common::set_ul_received_ack(
srslte_dl_sf_cfg_t* sf, uint32_t cc_idx, bool ack_value, uint32_t I_phich, srslte_dci_ul_t* dci_ul) srslte_dl_sf_cfg_t* sf, uint32_t cc_idx, bool ack_value, uint32_t I_phich, srslte_dci_ul_t* dci_ul)
{ {
pthread_mutex_lock(&received_ul_ack_mutex); std::lock_guard<std::mutex> lock(received_ul_ack_mutex);
received_ul_ack[TTIMOD(tti_pusch_hi(sf))][cc_idx].hi_present = true; received_ul_ack[TTIMOD(tti_pusch_hi(sf))][cc_idx].hi_present = true;
received_ul_ack[TTIMOD(tti_pusch_hi(sf))][cc_idx].hi_value = ack_value; received_ul_ack[TTIMOD(tti_pusch_hi(sf))][cc_idx].hi_value = ack_value;
received_ul_ack[TTIMOD(tti_pusch_hi(sf))][cc_idx].dci_ul = *dci_ul; received_ul_ack[TTIMOD(tti_pusch_hi(sf))][cc_idx].dci_ul = *dci_ul;
Debug("Set ul received ack for sf->tti=%d, current_tti=%d\n", tti_pusch_hi(sf), sf->tti); Debug("Set ul received ack for sf->tti=%d, current_tti=%d\n", tti_pusch_hi(sf), sf->tti);
pthread_mutex_unlock(&received_ul_ack_mutex);
} }
// SF->TTI at which PUSCH will be transmitted // SF->TTI at which PUSCH will be transmitted
bool phy_common::get_ul_received_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, bool* ack_value, srslte_dci_ul_t* dci_ul) bool phy_common::get_ul_received_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, bool* ack_value, srslte_dci_ul_t* dci_ul)
{ {
pthread_mutex_lock(&received_ul_ack_mutex); std::lock_guard<std::mutex> lock(received_ul_ack_mutex);
bool ret = false; bool ret = false;
if (received_ul_ack[TTIMOD(sf->tti)][cc_idx].hi_present) { if (received_ul_ack[TTIMOD(sf->tti)][cc_idx].hi_present) {
if (ack_value) { if (ack_value) {
@ -459,7 +408,6 @@ bool phy_common::get_ul_received_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, bo
received_ul_ack[TTIMOD(sf->tti)][cc_idx].hi_present = false; received_ul_ack[TTIMOD(sf->tti)][cc_idx].hi_present = false;
ret = true; ret = true;
} }
pthread_mutex_unlock(&received_ul_ack_mutex);
return ret; return ret;
} }
@ -469,7 +417,7 @@ void phy_common::set_dl_pending_ack(srslte_dl_sf_cfg_t* sf,
uint8_t value[SRSLTE_MAX_CODEWORDS], uint8_t value[SRSLTE_MAX_CODEWORDS],
srslte_pdsch_ack_resource_t resource) srslte_pdsch_ack_resource_t resource)
{ {
pthread_mutex_lock(&pending_dl_ack_mutex); std::lock_guard<std::mutex> lock(pending_dl_ack_mutex);
if (!pending_dl_ack[TTIMOD(sf->tti)][cc_idx].enable) { if (!pending_dl_ack[TTIMOD(sf->tti)][cc_idx].enable) {
pending_dl_ack[TTIMOD(sf->tti)][cc_idx].enable = true; pending_dl_ack[TTIMOD(sf->tti)][cc_idx].enable = true;
pending_dl_ack[TTIMOD(sf->tti)][cc_idx].resource = resource; pending_dl_ack[TTIMOD(sf->tti)][cc_idx].resource = resource;
@ -478,7 +426,6 @@ void phy_common::set_dl_pending_ack(srslte_dl_sf_cfg_t* sf,
} else { } else {
Warning("pending_dl_ack: sf->tti=%d, cc=%d already in use\n", sf->tti, cc_idx); Warning("pending_dl_ack: sf->tti=%d, cc=%d already in use\n", sf->tti, cc_idx);
} }
pthread_mutex_unlock(&pending_dl_ack_mutex);
} }
void phy_common::set_rar_grant_tti(uint32_t tti) void phy_common::set_rar_grant_tti(uint32_t tti)
@ -486,6 +433,30 @@ void phy_common::set_rar_grant_tti(uint32_t tti)
rar_grant_tti = tti; rar_grant_tti = tti;
} }
void phy_common::set_dl_pending_grant(uint32_t tti, uint32_t cc_idx, const srslte_dci_dl_t* dl_dci)
{
if (!pending_dl_grant[tti % FDD_HARQ_DELAY_MS][cc_idx].enable) {
pending_dl_grant[tti % FDD_HARQ_DELAY_MS][cc_idx].dl_dci = *dl_dci;
pending_dl_grant[tti % FDD_HARQ_DELAY_MS][cc_idx].enable = true;
} else {
Warning("set_dl_pending_grant: cc=%d already exists\n", cc_idx);
}
}
bool phy_common::get_dl_pending_grant(uint32_t tti, uint32_t cc_idx, srslte_dci_dl_t* dl_dci)
{
if (pending_dl_grant[tti % FDD_HARQ_DELAY_MS][cc_idx].enable) {
// Read grant
*dl_dci = pending_dl_grant[tti % FDD_HARQ_DELAY_MS][cc_idx].dl_dci;
// Reset read flag
pending_dl_grant[tti % FDD_HARQ_DELAY_MS][cc_idx].enable = false;
return true;
} else {
return false;
}
}
typedef struct { typedef struct {
uint32_t M; uint32_t M;
uint32_t K[9]; uint32_t K[9];
@ -513,7 +484,7 @@ das_index_t das_table[7][10] = {
// SF->TTI at which ACK/NACK would be transmitted // SF->TTI at which ACK/NACK would be transmitted
bool phy_common::get_dl_pending_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, srslte_pdsch_ack_cc_t* ack) bool phy_common::get_dl_pending_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, srslte_pdsch_ack_cc_t* ack)
{ {
pthread_mutex_lock(&pending_dl_ack_mutex); std::lock_guard<std::mutex> lock(pending_dl_ack_mutex);
bool ret = false; bool ret = false;
uint32_t M; uint32_t M;
if (cell.frame_type == SRSLTE_FDD) { if (cell.frame_type == SRSLTE_FDD) {
@ -544,7 +515,6 @@ bool phy_common::get_dl_pending_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, srs
bzero(&pending_dl_ack[TTIMOD(pdsch_tti)][cc_idx], sizeof(received_ack_t)); bzero(&pending_dl_ack[TTIMOD(pdsch_tti)][cc_idx], sizeof(received_ack_t));
} }
ack->M = ret ? M : 0; ack->M = ret ? M : 0;
pthread_mutex_unlock(&pending_dl_ack_mutex);
return ret; return ret;
} }
@ -619,11 +589,6 @@ void phy_common::set_cell(const srslte_cell_t& c)
} }
} }
uint32_t phy_common::get_nof_prb()
{
return cell.nof_prb;
}
void phy_common::set_dl_metrics(const dl_metrics_t m, uint32_t cc_idx) void phy_common::set_dl_metrics(const dl_metrics_t m, uint32_t cc_idx)
{ {
if (dl_metrics_read) { if (dl_metrics_read) {
@ -713,8 +678,6 @@ void phy_common::reset()
sr_enabled = false; sr_enabled = false;
cur_pathloss = 0; cur_pathloss = 0;
cur_pusch_power = 0; cur_pusch_power = 0;
p0_preamble = 0;
cur_radio_power = 0;
sr_last_tx_tti = -1; sr_last_tx_tti = -1;
cur_pusch_power = 0; cur_pusch_power = 0;
ZERO_OBJECT(pathloss); ZERO_OBJECT(pathloss);
@ -782,11 +745,10 @@ void phy_common::set_mcch()
void phy_common::set_mch_period_stop(uint32_t stop) void phy_common::set_mch_period_stop(uint32_t stop)
{ {
pthread_mutex_lock(&mtch_mutex); std::lock_guard<std::mutex> lock(mtch_mutex);
have_mtch_stop = true; have_mtch_stop = true;
mch_period_stop = stop; mch_period_stop = stop;
pthread_cond_signal(&mtch_cvar); mtch_cvar.notify_one();
pthread_mutex_unlock(&mtch_mutex);
} }
bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti) bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti)
@ -830,11 +792,11 @@ bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti)
mcch->pmch_info_list_r9[0].pmch_cfg_r9.mch_sched_period_r9.to_number(); mcch->pmch_info_list_r9[0].pmch_cfg_r9.mch_sched_period_r9.to_number();
uint32_t frame_alloc_idx = sfn % mcch->common_sf_alloc_period_r9.to_number(); uint32_t frame_alloc_idx = sfn % mcch->common_sf_alloc_period_r9.to_number();
uint32_t sf_alloc_idx = frame_alloc_idx * mbsfn_per_frame + ((sf < 4) ? sf - 1 : sf - 3); uint32_t sf_alloc_idx = frame_alloc_idx * mbsfn_per_frame + ((sf < 4) ? sf - 1 : sf - 3);
pthread_mutex_lock(&mtch_mutex); std::unique_lock<std::mutex> lock(mtch_mutex);
while (!have_mtch_stop) { while (!have_mtch_stop) {
pthread_cond_wait(&mtch_cvar, &mtch_mutex); mtch_cvar.wait(lock);
} }
pthread_mutex_unlock(&mtch_mutex); mtch_mutex.unlock();
for (uint32_t i = 0; i < mcch->pmch_info_list_r9.size(); i++) { for (uint32_t i = 0; i < mcch->pmch_info_list_r9.size(); i++) {
if (sf_alloc_idx <= mch_period_stop) { if (sf_alloc_idx <= mch_period_stop) {