NR UE PUSCH procedures fixes
- moved remaining PUSCH PDU configuration from ULSCH procedures entirely to MAC - introduced a function for DMRS RE configuration - cleaned up redundant code in ULSCH procedures - fixed TBS computation for Msg3
This commit is contained in:
@@ -101,13 +101,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
|
||||
|
||||
uint32_t available_bits;
|
||||
uint8_t mod_order, cwd_index, l;
|
||||
uint8_t cwd_index, l;
|
||||
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
|
||||
int16_t **tx_layers;
|
||||
int32_t **txdataF;
|
||||
int8_t Wf[2], Wt[2], l_prime[2], delta;
|
||||
uint16_t rnti, code_rate, nb_rb;
|
||||
uint8_t nb_dmrs_re_per_rb,mcs, Nl;
|
||||
uint8_t nb_dmrs_re_per_rb;
|
||||
int ap, i;
|
||||
int sample_offsetF, N_RE_prime;
|
||||
|
||||
@@ -124,49 +123,31 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index];
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu;
|
||||
|
||||
int start_symbol = harq_process_ul_ue->pusch_pdu.start_symbol_index;
|
||||
uint16_t ul_dmrs_symb_pos = harq_process_ul_ue->pusch_pdu.ul_dmrs_symb_pos;
|
||||
uint8_t number_of_symbols = harq_process_ul_ue->pusch_pdu.nr_of_symbols;
|
||||
uint8_t dmrs_type = harq_process_ul_ue->pusch_pdu.dmrs_config_type;
|
||||
uint16_t start_rb = harq_process_ul_ue->pusch_pdu.rb_start;
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
|
||||
int start_symbol = pusch_pdu->start_symbol_index;
|
||||
uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
|
||||
uint8_t number_of_symbols = pusch_pdu->nr_of_symbols;
|
||||
uint8_t dmrs_type = pusch_pdu->dmrs_config_type;
|
||||
uint16_t start_rb = pusch_pdu->rb_start;
|
||||
uint16_t nb_rb = pusch_pdu->rb_size;
|
||||
uint8_t Nl = pusch_pdu->nrOfLayers;
|
||||
uint8_t mod_order = pusch_pdu->qam_mod_order;
|
||||
uint16_t rnti = pusch_pdu->rnti;
|
||||
uint8_t cdm_grps_no_data = pusch_pdu->num_dmrs_cdm_grps_no_data;
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
|
||||
|
||||
if (start_sc >= frame_parms->ofdm_symbol_size)
|
||||
start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
for (i = start_symbol; i < start_symbol + number_of_symbols; i++) {
|
||||
|
||||
if((ul_dmrs_symb_pos >> i) & 0x01)
|
||||
number_dmrs_symbols += 1;
|
||||
|
||||
}
|
||||
|
||||
rnti = harq_process_ul_ue->pusch_pdu.rnti;
|
||||
ulsch_ue->Nid_cell = Nid_cell;
|
||||
|
||||
nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*harq_process_ul_ue->pusch_pdu.num_dmrs_cdm_grps_no_data;
|
||||
get_num_re_dmrs(pusch_pdu, &nb_dmrs_re_per_rb, &number_dmrs_symbols);
|
||||
|
||||
// TbD num_of_mod_symbols is set but never used
|
||||
N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh;
|
||||
|
||||
nb_rb = harq_process_ul_ue->pusch_pdu.rb_size;
|
||||
|
||||
harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*num_of_codewords;
|
||||
|
||||
mcs = harq_process_ul_ue->pusch_pdu.mcs_index;
|
||||
Nl = harq_process_ul_ue->pusch_pdu.nrOfLayers;
|
||||
mod_order = nr_get_Qm_ul(mcs, 0);
|
||||
code_rate = nr_get_code_rate_ul(mcs, 0);
|
||||
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = nr_compute_tbs(mod_order,
|
||||
code_rate,
|
||||
nb_rb,
|
||||
number_of_symbols,
|
||||
nb_dmrs_re_per_rb*number_dmrs_symbols,
|
||||
0,
|
||||
0,
|
||||
harq_process_ul_ue->pusch_pdu.nrOfLayers);
|
||||
|
||||
/////////////////////////ULSCH coding/////////////////////////
|
||||
///////////
|
||||
|
||||
@@ -224,10 +205,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
uint8_t L_ptrs, K_ptrs = 0;
|
||||
uint16_t beta_ptrs = 1; // temp value until power control is implemented
|
||||
|
||||
if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
|
||||
K_ptrs = (harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density)?4:2;
|
||||
L_ptrs = 1<<harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_time_density;
|
||||
K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
|
||||
L_ptrs = 1<<pusch_pdu->pusch_ptrs.ptrs_time_density;
|
||||
|
||||
ulsch_ue->ptrs_symbols = 0;
|
||||
|
||||
@@ -312,7 +293,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
if ((ul_dmrs_symb_pos >> l) & 0x01) {
|
||||
is_dmrs_sym = 1;
|
||||
|
||||
if (harq_process_ul_ue->pusch_pdu.transform_precoding == 1){ // if transform precoding is disabled
|
||||
if (pusch_pdu->transform_precoding == 1){ // if transform precoding is disabled
|
||||
if (dmrs_type == pusch_dmrs_type1)
|
||||
dmrs_idx = start_rb*6;
|
||||
else
|
||||
@@ -323,7 +304,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
} else if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
} else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
|
||||
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
|
||||
is_ptrs_sym = 1;
|
||||
@@ -348,7 +329,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
dmrs_type,
|
||||
K_ptrs,
|
||||
nb_rb,
|
||||
harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
|
||||
start_sc,
|
||||
frame_parms->ofdm_symbol_size);
|
||||
}
|
||||
@@ -377,7 +358,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
ptrs_idx++;
|
||||
|
||||
} else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,harq_process_ul_ue->pusch_pdu.num_dmrs_cdm_grps_no_data,dmrs_type)) {
|
||||
} else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, cdm_grps_no_data, dmrs_type)) {
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1];
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1];
|
||||
|
||||
@@ -300,5 +300,10 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
|
||||
uint16_t n_RB_ULBWP,
|
||||
uint16_t n_RB_DLBWP,
|
||||
uint16_t riv);
|
||||
|
||||
void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
uint8_t *nb_dmrs_re_per_rb,
|
||||
uint16_t *number_dmrs_symbols);
|
||||
|
||||
#endif
|
||||
/** @}*/
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*! \file nr_l1_helper.c
|
||||
* \brief PHY helper functions for PRACH adapted to NR
|
||||
* \brief PHY/MAC helper functions
|
||||
* \author Guido Casati
|
||||
* \date 2019
|
||||
* \version 2.0
|
||||
@@ -151,3 +151,23 @@ int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t m
|
||||
|
||||
return receivedTargerPower;
|
||||
}
|
||||
|
||||
void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
uint8_t *nb_dmrs_re_per_rb,
|
||||
uint16_t *number_dmrs_symbols){
|
||||
|
||||
int start_symbol = pusch_pdu->start_symbol_index;
|
||||
uint8_t number_of_symbols = pusch_pdu->nr_of_symbols;
|
||||
uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
|
||||
uint8_t dmrs_type = pusch_pdu->dmrs_config_type;
|
||||
uint8_t cdm_grps_no_data = pusch_pdu->num_dmrs_cdm_grps_no_data;
|
||||
|
||||
*number_dmrs_symbols = 0;
|
||||
for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) {
|
||||
if((ul_dmrs_symb_pos >> i) & 0x01)
|
||||
*number_dmrs_symbols += 1;
|
||||
}
|
||||
|
||||
*nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data;
|
||||
|
||||
}
|
||||
|
||||
@@ -822,34 +822,56 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
|
||||
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table);
|
||||
uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size);
|
||||
uint8_t no_data_in_dmrs = 1;
|
||||
uint16_t number_dmrs_symbols = 0;
|
||||
uint16_t ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
|
||||
int N_PRB_oh = 0; // TBR higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
|
||||
//------------------------------------------------------------------------------//
|
||||
// PTRS ports configuration
|
||||
// TbD: ptrs_dmrs_port and ptrs_port_index are not initialised!
|
||||
ptrs_ports_list.ptrs_re_offset = 0;
|
||||
|
||||
ul_config->slot = ul_info->slot_tx;
|
||||
ul_config->number_pdus = 1;
|
||||
ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = &ptrs_ports_list;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate = nr_get_code_rate_ul(mcs_index, mcs_table);
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order = nr_get_Qm_ul(mcs_index, mcs_table);
|
||||
|
||||
for (i = start_symbol_index; i < start_symbol_index + nr_of_symbols; i++) {
|
||||
if((ul_dmrs_symb_pos >> i) & 0x01)
|
||||
number_dmrs_symbols += 1;
|
||||
}
|
||||
if (1 << ptrs_time_density >= nr_of_symbols) {
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
|
||||
}
|
||||
|
||||
if(no_data_in_dmrs)
|
||||
nb_dmrs_re_per_rb = 12;
|
||||
else
|
||||
nb_dmrs_re_per_rb = ((dmrs_config_type == pusch_dmrs_type1) ? 6:4);
|
||||
get_num_re_dmrs(&ul_config->ul_config_list[0].pusch_config_pdu,
|
||||
&nb_dmrs_re_per_rb,
|
||||
&number_dmrs_symbols);
|
||||
|
||||
TBS = nr_compute_tbs(nr_get_Qm_ul(mcs_index, 0),
|
||||
nr_get_code_rate_ul(mcs_index, 0),
|
||||
rb_size,
|
||||
nr_of_symbols,
|
||||
nb_dmrs_re_per_rb*number_dmrs_symbols,
|
||||
0,
|
||||
0,
|
||||
nrOfLayers);
|
||||
TBS_bytes = TBS/8;
|
||||
TBS = nr_compute_tbs(ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order,
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate,
|
||||
rb_size,
|
||||
nr_of_symbols,
|
||||
nb_dmrs_re_per_rb*number_dmrs_symbols,
|
||||
N_PRB_oh,
|
||||
0,
|
||||
nrOfLayers);
|
||||
TBS_bytes = TBS/8;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS_bytes;
|
||||
|
||||
if (IS_SOFTMODEM_NOS1){
|
||||
// Getting IP traffic to be transmitted
|
||||
@@ -907,31 +929,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
tx_req_body.pdu = ulsch_input_buffer;
|
||||
tx_req.tx_request_body = &tx_req_body;
|
||||
|
||||
ul_config->slot = ul_info->slot_tx;
|
||||
ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = &ptrs_ports_list;
|
||||
|
||||
if (1 << ptrs_time_density >= nr_of_symbols) {
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
|
||||
}
|
||||
|
||||
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
|
||||
@@ -74,7 +74,9 @@ void nr_config_Msg3_pdu(NR_UE_MAC_INST_t *mac,
|
||||
uint8_t freq_hopping){
|
||||
|
||||
int f_alloc, mask, StartSymbolIndex, NrOfSymbols;
|
||||
uint16_t TBS_bytes;
|
||||
uint8_t nb_dmrs_re_per_rb;
|
||||
uint16_t number_dmrs_symbols = 0;
|
||||
int N_PRB_oh = 0; // TBR higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
|
||||
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
@@ -138,6 +140,10 @@ void nr_config_Msg3_pdu(NR_UE_MAC_INST_t *mac,
|
||||
pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1;
|
||||
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2;
|
||||
pusch_config_pdu->dmrs_ports = 1;
|
||||
get_num_re_dmrs(pusch_config_pdu,
|
||||
&nb_dmrs_re_per_rb,
|
||||
&number_dmrs_symbols);
|
||||
|
||||
// DMRS sequence initialization [TS 38.211, sec 6.4.1.1.1].
|
||||
// Should match what is sent in DCI 0_1, otherwise set to 0.
|
||||
pusch_config_pdu->scid = 0;
|
||||
@@ -168,15 +174,16 @@ void nr_config_Msg3_pdu(NR_UE_MAC_INST_t *mac,
|
||||
pusch_config_pdu->pusch_data.harq_process_id = 0;
|
||||
pusch_config_pdu->pusch_data.new_data_indicator = 1; // new data
|
||||
pusch_config_pdu->pusch_data.num_cb = 0;
|
||||
TBS_bytes = nr_compute_tbs(pusch_config_pdu->qam_mod_order,
|
||||
pusch_config_pdu->target_code_rate,
|
||||
pusch_config_pdu->rb_size,
|
||||
pusch_config_pdu->nr_of_symbols,
|
||||
12, // TBR compute accordingly - nb dmrs set for no data in dmrs symbol
|
||||
0, // nb_rb_oh
|
||||
0, // to verify tb scaling
|
||||
pusch_config_pdu->nrOfLayers = 1)/8;
|
||||
pusch_config_pdu->pusch_data.tb_size = TBS_bytes;
|
||||
|
||||
// Compute TBS
|
||||
pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order,
|
||||
pusch_config_pdu->target_code_rate,
|
||||
pusch_config_pdu->rb_size,
|
||||
pusch_config_pdu->nr_of_symbols,
|
||||
nb_dmrs_re_per_rb*number_dmrs_symbols,
|
||||
N_PRB_oh,
|
||||
0, // TBR to verify tb scaling
|
||||
pusch_config_pdu->nrOfLayers);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user