SRSUE Added RAR unpacking and other fixes

master
Xavier Arteaga 4 years ago committed by David Rupprecht
parent 82a8dcc77a
commit b768002a93

@ -61,7 +61,8 @@ public:
/// Indicate reception of UL grant (only TBS is provided). Buffer for resulting MAC PDU is provided by MAC and is
/// passed as pointer to PHY during tx_reuqest
virtual void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, srslte::unique_byte_buffer_t phy_tx_pdu) = 0;
virtual void
new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, srslte::unique_byte_buffer_t phy_tx_pdu) = 0;
/**
* @brief Indicate the successful transmission of a PRACH.
@ -124,7 +125,9 @@ public:
} tx_request_t;
// MAC informs PHY about UL grant included in RAR PDU
virtual int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> packed_ul_grant) = 0;
virtual int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> packed_ul_grant,
uint16_t rnti,
srslte_rnti_type_t rnti_type) = 0;
// MAC instructs PHY to transmit MAC TB at the given TTI
virtual int tx_request(const tx_request_t& request) = 0;

@ -147,7 +147,9 @@ typedef enum SRSLTE_API {
srslte_search_space_type_common_1, ///< configured by ra-SearchSpace in PDCCH-ConfigCommon
srslte_search_space_type_common_2, ///< configured by pagingSearchSpace in PDCCH-ConfigCommon
srslte_search_space_type_common_3, ///< configured by SearchSpace in PDCCH-Config with searchSpaceType = common
srslte_search_space_type_ue ///< configured by SearchSpace in PDCCH-Config with searchSpaceType = ue-Specific
srslte_search_space_type_ue, ///< configured by SearchSpace in PDCCH-Config with searchSpaceType = ue-Specific
srslte_search_space_type_rar, ///< Indicates that a grant was given by MAC RAR as described in TS 38.213 clause 8.2
srslte_search_space_type_cg ///< Indicates that a grant was given by Configured Grant from the upper layers
} srslte_search_space_type_t;
/**
@ -172,16 +174,17 @@ typedef enum SRSLTE_API {
/**
* @brief RNTI types
* @remark Usage described in TS 38.321 Table 7.1-2: RNTI usage.
*/
typedef enum SRSLTE_API {
srslte_rnti_type_c = 0,
srslte_rnti_type_p,
srslte_rnti_type_si,
srslte_rnti_type_ra,
srslte_rnti_type_tc,
srslte_rnti_type_cs,
srslte_rnti_type_sp_csi,
srslte_rnti_type_mcs_c,
srslte_rnti_type_p, ///< @brief Paging and System Information change notification (PCH)
srslte_rnti_type_si, ///< @brief Broadcast of System Information (DL-SCH)
srslte_rnti_type_ra, ///< @brief Random Access Response (DL-SCH)
srslte_rnti_type_tc, ///< @brief Contention Resolution (when no valid C-RNTI is available) (DL-SCH)
srslte_rnti_type_cs, ///< @brief Configured scheduled unicast transmission (DL-SCH, UL-SCH)
srslte_rnti_type_sp_csi, ///< @brief Activation of Semi-persistent CSI reporting on PUSCH
srslte_rnti_type_mcs_c, ///< @brief Dynamically scheduled unicast transmission (DL-SCH)
} srslte_rnti_type_t;
/**

@ -89,6 +89,8 @@ typedef struct SRSLTE_API {
// Frequency hopping
uint32_t frequency_offset; ///< frequency offset
// Random Access Response Grant
uint32_t csi_request;
} srslte_dci_ul_nr_t;
/**
@ -118,6 +120,15 @@ SRSLTE_API int srslte_dci_nr_format_0_0_unpack(const srslte_carrier_nr_t* carrie
srslte_dci_msg_nr_t* msg,
srslte_dci_ul_nr_t* dci);
/**
* @brief Unpacks DCI from Random Access Response Grant
* @remark Described in TS 38.213 Table 8.2-1: Random Access Response Grant Content field size
* @param msg
* @param dci
* @return SRSLTE_SUCCESS if unpacked correctly, SRSLTE_ERROR code otherwise
*/
SRSLTE_API int srslte_dci_nr_rar_unpack(srslte_dci_msg_nr_t* msg, srslte_dci_ul_nr_t* dci);
SRSLTE_API int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
srslte_rnti_type_t rnti_type);

@ -349,6 +349,71 @@ static int dci_nr_format_0_0_to_str(const srslte_dci_ul_nr_t* dci, char* str, ui
return len;
}
int srslte_dci_nr_rar_unpack(srslte_dci_msg_nr_t* msg, srslte_dci_ul_nr_t* dci)
{
if (msg == NULL || dci == NULL) {
return SRSLTE_ERROR;
}
uint8_t* y = msg->payload;
// Copy DCI MSG fields
dci->location = msg->location;
dci->search_space = msg->search_space;
dci->coreset_id = msg->coreset_id;
dci->rnti_type = msg->rnti_type;
dci->rnti = msg->rnti;
dci->format = msg->format;
// Frequency hopping flag - 1 bit
dci->freq_hopping_flag = srslte_bit_pack(&y, 1);
// PUSCH frequency resource allocation - 14 bits
dci->freq_domain_assigment = srslte_bit_pack(&y, 14);
// PUSCH time resource allocation - 4 bits
dci->time_domain_assigment = srslte_bit_pack(&y, 4);
// MCS -4 bits
dci->mcs = srslte_bit_pack(&y, 4);
// TPC command for PUSCH - 3 bits
dci->tpc = srslte_bit_pack(&y, 3);
// CSI request - 1 bits
dci->csi_request = srslte_bit_pack(&y, 3);
return SRSLTE_SUCCESS;
}
static int dci_nr_rar_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len)
{
uint32_t len = 0;
// Print format
len = srslte_print_check(str, str_len, len, "rnti=%04x dci=rar ", dci->rnti);
// Frequency hopping flag
len = srslte_print_check(str, str_len, len, "hop=%d ", dci->freq_hopping_flag);
// PUSCH frequency resource allocation
len = srslte_print_check(str, str_len, len, "f_alloc=0x%x ", dci->freq_domain_assigment);
// PUSCH time resource allocation
len = srslte_print_check(str, str_len, len, "t_alloc=0x%x ", dci->time_domain_assigment);
// Modulation and coding scheme
len = srslte_print_check(str, str_len, len, "mcs=%d ", dci->mcs);
// TPC command for scheduled PUSCH
len = srslte_print_check(str, str_len, len, "tpc=%d ", dci->tpc);
// CSI request
len = srslte_print_check(str, str_len, len, "csi=%d ", dci->csi_request);
return len;
}
int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
const srslte_dci_dl_nr_t* dci,
@ -758,6 +823,8 @@ int srslte_dci_ul_nr_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t s
switch (dci->format) {
case srslte_dci_format_nr_0_0:
return dci_nr_format_0_0_to_str(dci, str, str_len);
case srslte_dci_format_nr_rar:
return dci_nr_rar_to_str(dci, str, str_len);
default:; // Do nothing
}

@ -601,7 +601,7 @@ int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
srslte_sch_grant_nr_t* pusch_grant)
{
// 5.2.1.1 Resource allocation in time domain
if (srslte_ra_dl_nr_time(pusch_hl_cfg,
if (srslte_ra_ul_nr_time(pusch_hl_cfg,
dci_ul->rnti_type,
dci_ul->search_space,
dci_ul->coreset_id,

@ -137,12 +137,16 @@ int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg,
}
// Determine which PUSCH Time domain RA configuration to apply (TS 38.214 Table 6.1.2.1.1-1:)
if (rnti_type == srslte_rnti_type_ra) {
if (ss_type == srslte_search_space_type_rar) {
// Row 1
if (cfg->nof_common_time_ra == 0) {
srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant);
} else if (m < SRSLTE_MAX_NOF_DL_ALLOCATION) {
} else if (m < SRSLTE_MAX_NOF_DL_ALLOCATION && m < cfg->nof_common_time_ra) {
ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant);
} else {
ERROR("Time domain resource selection (m=%d) exceeds the maximum value (%d)",
m,
SRSLTE_MIN(cfg->nof_common_time_ra, SRSLTE_MAX_NOF_DL_ALLOCATION));
}
} else if ((rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_mcs_c ||
rnti_type == srslte_rnti_type_tc || rnti_type == srslte_rnti_type_cs) &&
@ -172,7 +176,7 @@ int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg,
// Table 6.1.2.1.1-5 defines the additional subcarrier spacing specific slot delay value for the first transmission of
// PUSCH scheduled by the RAR. When the UE transmits a PUSCH scheduled by RAR, the Δ value specific to the PUSCH
// subcarrier spacing μ PUSCH is applied in addition to the K 2 value.
if (rnti_type == srslte_rnti_type_ra) {
if (ss_type == srslte_search_space_type_rar) {
uint32_t delta[4] = {2, 3, 4, 6};
if (cfg->scs_cfg >= 4) {
ERROR("Invalid numerology");
@ -460,4 +464,4 @@ int srslte_ra_ul_nr_pucch_resource(const srslte_pucch_nr_hl_cfg_t* pucch_cfg,
return ra_ul_nr_pucch_resource_default(r_pucch, resource);
}
return ra_ul_nr_pucch_resource_hl(pucch_cfg, O_uci, uci_cfg->pucch_resource_id, resource);
}
}

@ -73,7 +73,9 @@ public:
// Convert UL DCI to grant
srslte_sch_cfg_nr_t pusch_cfg = {};
if (srslte_ra_ul_dci_to_grant_nr(&carrier, &cfg.pusch, &dci_ul, &pusch_cfg, &pusch_cfg.grant)) {
ERROR("Computing UL grant");
std::array<char, 512> str;
srslte_dci_ul_nr_to_str(&dci_ul, str.data(), str.size());
ERROR("Computing UL grant %s", str.data());
return;
}

@ -23,6 +23,8 @@ namespace nr {
class worker_pool
{
private:
srslog::sink& log_sink;
srslog::basic_logger& logger;
srslte::thread_pool pool;
std::vector<std::unique_ptr<sf_worker> > workers;
state phy_state;
@ -31,18 +33,14 @@ private:
public:
sf_worker* operator[](std::size_t pos) { return workers.at(pos).get(); }
worker_pool(uint32_t max_workers);
bool init(const phy_args_nr_t& args_,
phy_common* common,
stack_interface_phy_nr* stack_,
srslog::sink& log_sink,
int prio);
worker_pool(uint32_t max_workers, srslog::sink& log_sink_);
bool init(const phy_args_nr_t& args_, phy_common* common, stack_interface_phy_nr* stack_, int prio);
sf_worker* wait_worker(uint32_t tti);
void start_worker(sf_worker* w);
void stop();
void send_prach(uint32_t prach_occasion, uint32_t preamble_index, int preamble_received_target_power);
int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> array);
bool set_config(const srslte::phy_cfg_nr_t& cfg);
int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> array, uint16_t rnti, srslte_rnti_type_t rnti_type);
bool set_config(const srslte::phy_cfg_nr_t& cfg);
};
} // namespace nr

@ -76,7 +76,7 @@ public:
logger_phy(srslog::fetch_basic_logger("PHY", log_sink)),
logger_phy_lib(srslog::fetch_basic_logger("PHY_LIB", log_sink)),
lte_workers(MAX_WORKERS),
nr_workers(MAX_WORKERS),
nr_workers(MAX_WORKERS, log_sink),
common(logger_phy),
sfsync(logger_phy, logger_phy_lib),
prach_buffer(logger_phy),
@ -175,7 +175,9 @@ public:
int init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srslte::radio_interface_phy* radio_) final;
bool set_config(const srslte::phy_cfg_nr_t& cfg) final;
int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> packed_ul_grant) final;
int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> packed_ul_grant,
uint16_t rnti,
srslte_rnti_type_t rnti_type) final;
void send_prach(const uint32_t prach_occasion,
const int preamble_index,
const float preamble_received_target_power,

@ -50,8 +50,11 @@ public:
bool set_config(const srslte::phy_cfg_nr_t& cfg) override;
// MAC interface
int tx_request(const tx_request_t& request) override;
int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS>) override { return SRSLTE_SUCCESS; };
int tx_request(const tx_request_t& request) override;
int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS>, uint16_t rnti, srslte_rnti_type_t rnti_type) override
{
return SRSLTE_SUCCESS;
};
void send_prach(const uint32_t preamble_idx,
const int prach_occasion,
const float target_power_dbm,

@ -14,13 +14,11 @@
namespace srsue {
namespace nr {
worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers) {}
worker_pool::worker_pool(uint32_t max_workers, srslog::sink& log_sink_) :
pool(max_workers), log_sink(log_sink_), logger(srslog::fetch_basic_logger("NR-PHY", log_sink))
{}
bool worker_pool::init(const phy_args_nr_t& args,
phy_common* common,
stack_interface_phy_nr* stack_,
srslog::sink& log_sink,
int prio)
bool worker_pool::init(const phy_args_nr_t& args, phy_common* common, stack_interface_phy_nr* stack_, int prio)
{
phy_state.stack = stack_;
phy_state.args = args;
@ -101,23 +99,32 @@ void worker_pool::send_prach(uint32_t prach_occasion, uint32_t preamble_index, i
prach_buffer->prepare_to_send(preamble_index);
}
int worker_pool::set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> packed_ul_grant)
int worker_pool::set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> packed_ul_grant,
uint16_t rnti,
srslte_rnti_type_t rnti_type)
{
// Copy DCI bits and setup DCI context
srslte_dci_msg_nr_t dci_msg = {};
dci_msg.format = srslte_dci_format_nr_rar;
dci_msg.rnti_type = srslte_rnti_type_ra;
dci_msg.rnti = phy_state.ra_rnti;
dci_msg.format = srslte_dci_format_nr_0_0; // MAC RAR grant shall be unpacked as DCI 0_0 format
dci_msg.rnti_type = rnti_type;
dci_msg.search_space = srslte_search_space_type_rar; // This indicates it is a MAC RAR
dci_msg.rnti = rnti;
dci_msg.nof_bits = SRSLTE_RAR_UL_GRANT_NBITS;
srslte_vec_u8_copy(dci_msg.payload, packed_ul_grant.data(), SRSLTE_RAR_UL_GRANT_NBITS);
srslte_dci_ul_nr_t dci_ul = {};
if (srslte_dci_nr_format_0_0_unpack(&phy_state.carrier, &phy_state.cfg.pdcch.coreset[1], &dci_msg, &dci_ul) <
SRSLTE_SUCCESS) {
if (srslte_dci_nr_rar_unpack(&dci_msg, &dci_ul) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
if (logger.info.enabled()) {
std::array<char, 512> str;
srslte_dci_ul_nr_to_str(&dci_ul, str.data(), str.size());
logger.set_context(phy_state.rar_grant_tti);
logger.info("Setting RAR Grant %s", str.data());
}
phy_state.set_ul_pending_grant(phy_state.rar_grant_tti, dci_ul);
return SRSLTE_SUCCESS;
@ -128,4 +135,4 @@ bool worker_pool::set_config(const srslte::phy_cfg_nr_t& cfg)
return true;
}
} // namespace nr
} // namespace srsue
} // namespace srsue

@ -607,16 +607,18 @@ void phy::set_mch_period_stop(uint32_t stop)
int phy::init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srslte::radio_interface_phy* radio_)
{
if (!nr_workers.init(args_, &common, stack_, log_sink, WORKERS_THREAD_PRIO)) {
if (!nr_workers.init(args_, &common, stack_, WORKERS_THREAD_PRIO)) {
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
int phy::set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> packed_ul_grant)
int phy::set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> packed_ul_grant,
uint16_t rnti,
srslte_rnti_type_t rnti_type)
{
return nr_workers.set_ul_grant(packed_ul_grant);
return nr_workers.set_ul_grant(packed_ul_grant, rnti, rnti_type);
}
void phy::send_prach(const uint32_t prach_occasion,

@ -11,8 +11,8 @@
*/
#include "srsue/hdr/stack/mac_nr/proc_ra_nr.h"
#include "srsue/hdr/stack/mac_nr/mac_nr.h"
#include "srslte/mac/mac_rar_pdu_nr.h"
#include "srsue/hdr/stack/mac_nr/mac_nr.h"
namespace srsue {
@ -32,8 +32,8 @@ int delta_preamble_db_table_nr[5] = {0, -3, -6, 0};
proc_ra_nr::proc_ra_nr(srslog::basic_logger& logger_) : logger(logger_) {}
void proc_ra_nr::init(phy_interface_mac_nr* phy_,
mac_interface_proc_ra_nr* mac_,
srslte::ext_task_sched_handle* task_sched_)
mac_interface_proc_ra_nr* mac_,
srslte::ext_task_sched_handle* task_sched_)
{
phy = phy_;
mac = mac_;
@ -164,7 +164,7 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::mac_nr_grant_
return;
}
// Stop rar timer
// Stop rar timer
rar_timeout_timer.stop();
for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; ++i) {
if (grant.tb[i] != nullptr) {
@ -178,11 +178,14 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::mac_nr_grant_
for (auto& subpdu : pdu.get_subpdus()) {
if (subpdu.has_rapid() && subpdu.get_rapid() == preamble_index) {
logger.info("PROC RA NR: Setting ul grant and prepare msg3");
phy->set_ul_grant(subpdu.get_ul_grant());
temp_rnti = subpdu.get_temp_crnti();
// Set Temporary-C-RNTI if provided, otherwise C-RNTI is ok
phy->set_ul_grant(subpdu.get_ul_grant(), temp_rnti, srslte_rnti_type_c);
// reset all parameters that are used before rar
rar_rnti = SRSLTE_INVALID_RNTI;
mac->msg3_prepare();
temp_rnti = subpdu.get_temp_crnti();
current_ta = subpdu.get_ta();
}
}
@ -314,4 +317,4 @@ void proc_ra_nr::reset()
rar_timeout_timer.stop();
contention_resolution_timer.stop();
}
} // namespace srsue
} // namespace srsue

@ -20,14 +20,20 @@ class dummy_phy : public phy_interface_mac_nr
{
public:
dummy_phy() {}
void send_prach(const uint32_t prach_occasion_, const int preamble_index_, const float preamble_received_target_power_, const float ta_base_sec_ = 0.0f)
void send_prach(const uint32_t prach_occasion_,
const int preamble_index_,
const float preamble_received_target_power_,
const float ta_base_sec_ = 0.0f)
{
prach_occasion = prach_occasion_;
preamble_index = preamble_index_;
preamble_received_target_power = preamble_received_target_power_;
}
int tx_request(const tx_request_t& request) {return 0;}
int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS>) { return 0; }
int tx_request(const tx_request_t& request) { return 0; }
int set_ul_grant(std::array<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS>, uint16_t rnti, srslte_rnti_type_t rnti_type)
{
return 0;
}
void get_last_send_prach(uint32_t* prach_occasion_, uint32_t* preamble_index_, int* preamble_received_target_power_)
{
@ -110,12 +116,12 @@ int main()
TESTASSERT(proc_ra_nr.get_rar_rnti() == 0x16);
}
}
mac_interface_phy_nr::mac_nr_grant_dl_t grant;
mac_interface_phy_nr::mac_nr_grant_dl_t grant;
grant.rnti = 0x16;
grant.tti = rach_cfg.ra_responseWindow + tti_start + 3;
grant.pid = 0x0123;
uint8_t mac_dl_rar_pdu[] = {0x40, 0x06, 0x68, 0x03, 0x21, 0x46, 0x46, 0x02, 0x00, 0x00, 0x00};
grant.tb[0] = srslte::make_byte_buffer();
grant.tb[0] = srslte::make_byte_buffer();
grant.tb[0].get()->append_bytes(mac_dl_rar_pdu, sizeof(mac_dl_rar_pdu));
proc_ra_nr.handle_rar_pdu(grant);

Loading…
Cancel
Save