Merge remote-tracking branch 'origin/ul-phr' into integration_2022_wk36b
This commit is contained in:
@@ -724,3 +724,4 @@ void SLIV2SL(int SLIV,int *S,int *L) {
|
|||||||
*S=13-SLIVmod14;
|
*S=13-SLIVmod14;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,10 +56,9 @@ typedef enum frequency_range_e {
|
|||||||
} frequency_range_t;
|
} frequency_range_t;
|
||||||
|
|
||||||
extern const nr_bandentry_t nr_bandtable[];
|
extern const nr_bandentry_t nr_bandtable[];
|
||||||
|
|
||||||
static inline int get_num_dmrs(uint16_t dmrs_mask ) {
|
static inline int get_num_dmrs(uint16_t dmrs_mask ) {
|
||||||
|
|
||||||
int num_dmrs=0;
|
int num_dmrs=0;
|
||||||
|
|
||||||
for (int i=0;i<16;i++) num_dmrs+=((dmrs_mask>>i)&1);
|
for (int i=0;i<16;i++) num_dmrs+=((dmrs_mask>>i)&1);
|
||||||
return(num_dmrs);
|
return(num_dmrs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -777,6 +777,7 @@ typedef struct {
|
|||||||
} nfapi_nr_dl_tti_pdcch_pdu_rel15_t;
|
} nfapi_nr_dl_tti_pdcch_pdu_rel15_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint8_t ldpcBaseGraph;
|
||||||
uint32_t tbSizeLbrmBytes;
|
uint32_t tbSizeLbrmBytes;
|
||||||
}nfapi_v3_pdsch_maintenance_parameters_t;
|
}nfapi_v3_pdsch_maintenance_parameters_t;
|
||||||
|
|
||||||
@@ -1193,6 +1194,7 @@ typedef struct
|
|||||||
#define PUSCH_PDU_BITMAP_DFTS_OFDM 0x8
|
#define PUSCH_PDU_BITMAP_DFTS_OFDM 0x8
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint8_t ldpcBaseGraph;
|
||||||
uint32_t tbSizeLbrmBytes;
|
uint32_t tbSizeLbrmBytes;
|
||||||
}nfapi_v3_pusch_maintenance_parameters_t;
|
}nfapi_v3_pusch_maintenance_parameters_t;
|
||||||
|
|
||||||
|
|||||||
@@ -375,14 +375,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
|||||||
memcpy(harq->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc
|
memcpy(harq->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc
|
||||||
}
|
}
|
||||||
|
|
||||||
// target_code_rate is in 0.1 units
|
impp.BG = rel15->maintenance_parms_v3.ldpcBaseGraph;
|
||||||
float Coderate = (float) rel15->targetCodeRate[0] / 10240.0f;
|
|
||||||
LOG_D(PHY,"DLSCH Coderate %f\n",Coderate);
|
|
||||||
|
|
||||||
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
|
|
||||||
impp.BG = 2;
|
|
||||||
else
|
|
||||||
impp.BG = 1;
|
|
||||||
|
|
||||||
start_meas(dlsch_segmentation_stats);
|
start_meas(dlsch_segmentation_stats);
|
||||||
impp.Kb = nr_segmentation(harq->b, harq->c, harq->B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG);
|
impp.Kb = nr_segmentation(harq->b, harq->c, harq->B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG);
|
||||||
|
|||||||
@@ -380,7 +380,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
|||||||
uint32_t r;
|
uint32_t r;
|
||||||
uint32_t r_offset;
|
uint32_t r_offset;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
int kc;
|
|
||||||
int E;
|
int E;
|
||||||
int8_t llrProcBuf[22*384];
|
int8_t llrProcBuf[22*384];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -462,8 +461,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
|||||||
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d\n",
|
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d\n",
|
||||||
harq_pid, A, G, mcs, n_layers, nb_rb, Qm, Coderate, pusch_pdu->pusch_data.rv_index, harq_process->round);
|
harq_pid, A, G, mcs, n_layers, nb_rb, Qm, Coderate, pusch_pdu->pusch_data.rv_index, harq_process->round);
|
||||||
|
|
||||||
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
|
p_decParams->BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph;
|
||||||
p_decParams->BG = 2;
|
int kc;
|
||||||
|
if (p_decParams->BG == 2){
|
||||||
kc = 52;
|
kc = 52;
|
||||||
if (Coderate < 0.3333) {
|
if (Coderate < 0.3333) {
|
||||||
p_decParams->R = 15;
|
p_decParams->R = 15;
|
||||||
@@ -475,7 +475,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
|||||||
p_decParams->R = 23;
|
p_decParams->R = 23;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p_decParams->BG = 1;
|
|
||||||
kc = 68;
|
kc = 68;
|
||||||
if (Coderate < 0.6667) {
|
if (Coderate < 0.6667) {
|
||||||
p_decParams->R = 13;
|
p_decParams->R = 13;
|
||||||
|
|||||||
@@ -84,45 +84,45 @@ nrUE_params_t *get_nrUE_params(void) {
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
int i; //,j,l,aa;
|
int i; //,j,l,aa;
|
||||||
double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0;
|
double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0;
|
||||||
double snr_step = 0.1;
|
double snr_step = 0.1;
|
||||||
uint8_t snr1set = 0;
|
uint8_t snr1set = 0;
|
||||||
int **txdata;
|
int **txdata;
|
||||||
double **s_re, **s_im, **r_re, **r_im;
|
double **s_re, **s_im, **r_re, **r_im;
|
||||||
// int sync_pos, sync_pos_slot;
|
// int sync_pos, sync_pos_slot;
|
||||||
// FILE *rx_frame_file;
|
// FILE *rx_frame_file;
|
||||||
FILE *output_fd = NULL;
|
FILE *output_fd = NULL;
|
||||||
//uint8_t write_output_file = 0;
|
//uint8_t write_output_file = 0;
|
||||||
// int subframe_offset;
|
// int subframe_offset;
|
||||||
// char fname[40], vname[40];
|
// char fname[40], vname[40];
|
||||||
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
|
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
|
||||||
uint8_t n_tx = 1, n_rx = 1;
|
uint8_t n_tx = 1, n_rx = 1;
|
||||||
//uint8_t transmission_mode = 1;
|
//uint8_t transmission_mode = 1;
|
||||||
uint16_t Nid_cell = 0;
|
uint16_t Nid_cell = 0;
|
||||||
channel_desc_t *gNB2UE;
|
channel_desc_t *gNB2UE;
|
||||||
uint8_t extended_prefix_flag = 0;
|
uint8_t extended_prefix_flag = 0;
|
||||||
//int8_t interf1 = -21, interf2 = -21;
|
//int8_t interf1 = -21, interf2 = -21;
|
||||||
FILE *input_fd = NULL, *pbch_file_fd = NULL;
|
FILE *input_fd = NULL, *pbch_file_fd = NULL;
|
||||||
//char input_val_str[50],input_val_str2[50];
|
//char input_val_str[50],input_val_str2[50];
|
||||||
//uint16_t NB_RB=25;
|
//uint16_t NB_RB=25;
|
||||||
SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
|
SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
|
||||||
uint16_t N_RB_DL = 106, mu = 1;
|
uint16_t N_RB_DL = 106, mu = 1;
|
||||||
//unsigned char frame_type = 0;
|
//unsigned char frame_type = 0;
|
||||||
unsigned char pbch_phase = 0;
|
unsigned char pbch_phase = 0;
|
||||||
int frame = 0, slot = 0;
|
int frame = 0, slot = 0;
|
||||||
int frame_length_complex_samples;
|
int frame_length_complex_samples;
|
||||||
//int frame_length_complex_samples_no_prefix;
|
//int frame_length_complex_samples_no_prefix;
|
||||||
NR_DL_FRAME_PARMS *frame_parms;
|
NR_DL_FRAME_PARMS *frame_parms;
|
||||||
uint8_t Kmimo = 0;
|
uint8_t Kmimo = 0;
|
||||||
uint32_t Nsoft = 0;
|
uint32_t Nsoft = 0;
|
||||||
double sigma;
|
double sigma;
|
||||||
unsigned char qbits = 8;
|
unsigned char qbits = 8;
|
||||||
int ret;
|
int ret;
|
||||||
//int run_initial_sync=0;
|
//int run_initial_sync=0;
|
||||||
int loglvl = OAILOG_WARNING;
|
int loglvl = OAILOG_WARNING;
|
||||||
uint8_t dlsch_threads = 0;
|
uint8_t dlsch_threads = 0;
|
||||||
float target_error_rate = 0.01;
|
float target_error_rate = 0.01;
|
||||||
uint64_t SSB_positions=0x01;
|
uint64_t SSB_positions=0x01;
|
||||||
uint16_t nb_symb_sch = 12;
|
uint16_t nb_symb_sch = 12;
|
||||||
@@ -468,6 +468,7 @@ int main(int argc, char **argv)
|
|||||||
rel15->mcsIndex[0] = Imcs;
|
rel15->mcsIndex[0] = Imcs;
|
||||||
rel15->numDmrsCdmGrpsNoData = 1;
|
rel15->numDmrsCdmGrpsNoData = 1;
|
||||||
rel15->maintenance_parms_v3.tbSizeLbrmBytes = Tbslbrm;
|
rel15->maintenance_parms_v3.tbSizeLbrmBytes = Tbslbrm;
|
||||||
|
rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, rate);
|
||||||
double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc
|
double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc
|
||||||
short channel_output_fixed[16 * 68 * 384];
|
short channel_output_fixed[16 * 68 * 384];
|
||||||
//unsigned char *estimated_output;
|
//unsigned char *estimated_output;
|
||||||
|
|||||||
@@ -327,6 +327,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
|
|||||||
sched_pdsch->rbStart = g_rbStart;
|
sched_pdsch->rbStart = g_rbStart;
|
||||||
sched_pdsch->rbSize = g_rbSize;
|
sched_pdsch->rbSize = g_rbSize;
|
||||||
sched_pdsch->mcs = g_mcsIndex;
|
sched_pdsch->mcs = g_mcsIndex;
|
||||||
|
sched_pdsch->nrOfLayers = g_nrOfLayers;
|
||||||
/* the following might override the table that is mandated by RRC
|
/* the following might override the table that is mandated by RRC
|
||||||
* configuration */
|
* configuration */
|
||||||
current_BWP->mcsTableIdx = g_mcsTableIdx;
|
current_BWP->mcsTableIdx = g_mcsTableIdx;
|
||||||
|
|||||||
@@ -472,6 +472,7 @@ int main(int argc, char **argv)
|
|||||||
rel15_ul->nrOfLayers = Nl;
|
rel15_ul->nrOfLayers = Nl;
|
||||||
rel15_ul->target_code_rate = code_rate;
|
rel15_ul->target_code_rate = code_rate;
|
||||||
rel15_ul->pusch_data.tb_size = TBS>>3;
|
rel15_ul->pusch_data.tb_size = TBS>>3;
|
||||||
|
rel15_ul->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, code_rate);
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc
|
double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc
|
||||||
|
|||||||
@@ -1135,7 +1135,7 @@ int main(int argc, char **argv)
|
|||||||
pusch_pdu->bwp_size = abwp_size;
|
pusch_pdu->bwp_size = abwp_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
pusch_pdu->pusch_data.tb_size = TBS/8;
|
pusch_pdu->pusch_data.tb_size = TBS>>3;
|
||||||
pusch_pdu->pdu_bit_map = pdu_bit_map;
|
pusch_pdu->pdu_bit_map = pdu_bit_map;
|
||||||
pusch_pdu->rnti = n_rnti;
|
pusch_pdu->rnti = n_rnti;
|
||||||
pusch_pdu->mcs_index = Imcs;
|
pusch_pdu->mcs_index = Imcs;
|
||||||
@@ -1168,6 +1168,7 @@ int main(int argc, char **argv)
|
|||||||
pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
|
pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
|
||||||
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
|
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
|
||||||
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
|
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
|
||||||
|
pusch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, code_rate);
|
||||||
|
|
||||||
// if transform precoding is enabled
|
// if transform precoding is enabled
|
||||||
if (transform_precoding == transformPrecoder_enabled) {
|
if (transform_precoding == transformPrecoder_enabled) {
|
||||||
|
|||||||
@@ -3498,6 +3498,15 @@ void csi_period_offset(NR_CSI_ReportConfig_t *csirep,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t get_BG(uint32_t A, uint16_t R) {
|
||||||
|
|
||||||
|
float code_rate = (float) R / 10240.0f;
|
||||||
|
if ((A <=292) || ((A<=3824) && (code_rate <= 0.6667)) || code_rate <= 0.25)
|
||||||
|
return 2;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t get_Y(NR_SearchSpace_t *ss, int slot, rnti_t rnti) {
|
uint32_t get_Y(NR_SearchSpace_t *ss, int slot, rnti_t rnti) {
|
||||||
|
|
||||||
if(ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common)
|
if(ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common)
|
||||||
|
|||||||
@@ -40,6 +40,8 @@
|
|||||||
|
|
||||||
uint32_t get_Y(NR_SearchSpace_t *ss, int slot, rnti_t rnti);
|
uint32_t get_Y(NR_SearchSpace_t *ss, int slot, rnti_t rnti);
|
||||||
|
|
||||||
|
uint8_t get_BG(uint32_t A, uint16_t R);
|
||||||
|
|
||||||
uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
|
uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
|
||||||
|
|
||||||
uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
|
uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
|
||||||
|
|||||||
@@ -1057,6 +1057,8 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
|
|||||||
|
|
||||||
pusch_pdu->mcs_index = mcsindex;
|
pusch_pdu->mcs_index = mcsindex;
|
||||||
pusch_pdu->pusch_data.tb_size = TBS;
|
pusch_pdu->pusch_data.tb_size = TBS;
|
||||||
|
pusch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS<<3,R);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1322,6 +1324,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
|||||||
pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx,
|
pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx,
|
||||||
bw_tbslbrm,
|
bw_tbslbrm,
|
||||||
1);
|
1);
|
||||||
|
pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS<<3,R);
|
||||||
|
|
||||||
// Fill PDCCH DL DCI PDU
|
// Fill PDCCH DL DCI PDU
|
||||||
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
|
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
|
||||||
@@ -1703,6 +1706,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
|||||||
pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx,
|
pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx,
|
||||||
bw_tbslbrm,
|
bw_tbslbrm,
|
||||||
1);
|
1);
|
||||||
|
pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(harq->tb_size<<3,R);
|
||||||
|
|
||||||
pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=1;
|
pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=1;
|
||||||
pdsch_pdu_rel15->precodingAndBeamforming.prg_size=275;
|
pdsch_pdu_rel15->precodingAndBeamforming.prg_size=275;
|
||||||
|
|||||||
@@ -465,6 +465,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
|||||||
pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(0,
|
pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(0,
|
||||||
pdsch_pdu_rel15->BWPSize,
|
pdsch_pdu_rel15->BWPSize,
|
||||||
1);
|
1);
|
||||||
|
pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS<<3,pdsch_pdu_rel15->targetCodeRate[0]);
|
||||||
|
|
||||||
/* Fill PDCCH DL DCI PDU */
|
/* Fill PDCCH DL DCI PDU */
|
||||||
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
|
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
|
||||||
|
|||||||
@@ -1071,6 +1071,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(current_BWP->mcsTableIdx,
|
pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(current_BWP->mcsTableIdx,
|
||||||
bw_tbslbrm,
|
bw_tbslbrm,
|
||||||
nl_tbslbrm);
|
nl_tbslbrm);
|
||||||
|
pdsch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS<<3,R);
|
||||||
|
|
||||||
NR_PDSCH_Config_t *pdsch_Config = current_BWP->pdsch_Config;
|
NR_PDSCH_Config_t *pdsch_Config = current_BWP->pdsch_Config;
|
||||||
|
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx)
|
|||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) {
|
void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) {
|
||||||
|
|
||||||
//TODO first basic implementation of dmrs port selection
|
//TODO first basic implementation of dmrs port selection
|
||||||
|
|||||||
@@ -53,6 +53,32 @@ const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon
|
|||||||
return 0; // if FDD or not mixed slot in TDD, for now use default TDA (TODO handle CSI-RS slots)
|
return 0; // if FDD or not mixed slot in TDD, for now use default TDA (TODO handle CSI-RS slots)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int compute_bw_factor(int mu, int rb) {
|
||||||
|
// 38.213 7.1.1
|
||||||
|
return (10 * log10(rb << mu));
|
||||||
|
}
|
||||||
|
|
||||||
|
int compute_delta_tf(int tbs_bits,
|
||||||
|
int rb,
|
||||||
|
int n_layers,
|
||||||
|
int n_symbols,
|
||||||
|
int n_dmrs,
|
||||||
|
long *deltaMCS) {
|
||||||
|
|
||||||
|
// 38.213 7.1.1
|
||||||
|
// if the PUSCH transmission is over more than one layer delta_tf = 0
|
||||||
|
if(deltaMCS == NULL || n_layers>1)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
AssertFatal(1==0,"Compute DeltaTF not yet fully supported\n");
|
||||||
|
|
||||||
|
const int n_re = (NR_NB_SC_PER_RB * n_symbols - n_dmrs) * rb;
|
||||||
|
const int BPRE = tbs_bits/n_re; //TODO change for PUSCH with CSI
|
||||||
|
const float f = pow(2, (float) BPRE * 1.25);
|
||||||
|
const float beta = 1.0f; //TODO change for PUSCH with CSI
|
||||||
|
return(10 * log10((f - 1) * beta));
|
||||||
|
}
|
||||||
|
|
||||||
// For both UL-SCH except:
|
// For both UL-SCH except:
|
||||||
// - UL-SCH: fixed-size MAC CE(known by LCID)
|
// - UL-SCH: fixed-size MAC CE(known by LCID)
|
||||||
// - UL-SCH: padding
|
// - UL-SCH: padding
|
||||||
@@ -77,320 +103,321 @@ const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon
|
|||||||
// F: length of L is 0:8 or 1:16 bits wide
|
// F: length of L is 0:8 or 1:16 bits wide
|
||||||
// R: Reserved bit, set to zero.
|
// R: Reserved bit, set to zero.
|
||||||
|
|
||||||
int nr_process_mac_pdu( instance_t module_idP,
|
int nr_process_mac_pdu(instance_t module_idP,
|
||||||
NR_UE_info_t* UE,
|
NR_UE_info_t* UE,
|
||||||
uint8_t CC_id,
|
uint8_t CC_id,
|
||||||
frame_t frameP,
|
frame_t frameP,
|
||||||
sub_frame_t slot,
|
sub_frame_t slot,
|
||||||
uint8_t *pduP,
|
uint8_t *pduP,
|
||||||
int pdu_len)
|
int pdu_len,
|
||||||
|
const int8_t harq_pid)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
uint8_t done = 0;
|
||||||
|
|
||||||
uint8_t done = 0;
|
int sdus = 0;
|
||||||
int sdus = 0;
|
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
||||||
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
|
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
if (pduP[0] != UL_SCH_LCID_PADDING)
|
||||||
|
trace_NRpdu(DIRECTION_UPLINK, pduP, pdu_len, WS_C_RNTI, UE->rnti, frameP, 0, 0, 0);
|
||||||
|
|
||||||
if ( pduP[0] != UL_SCH_LCID_PADDING )
|
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
||||||
trace_NRpdu(DIRECTION_UPLINK, pduP, pdu_len, WS_C_RNTI, UE->rnti, frameP, 0, 0, 0);
|
LOG_I(NR_MAC, "In %s: dumping MAC PDU in %d.%d:\n", __func__, frameP, slot);
|
||||||
|
log_dump(NR_MAC, pduP, pdu_len, LOG_DUMP_CHAR, "\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
while (!done && pdu_len > 0){
|
||||||
LOG_I(NR_MAC, "In %s: dumping MAC PDU in %d.%d:\n", __func__, frameP, slot);
|
uint16_t mac_len=0;
|
||||||
log_dump(NR_MAC, pduP, pdu_len, LOG_DUMP_CHAR, "\n");
|
uint16_t mac_subheader_len=sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||||
#endif
|
uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
||||||
|
|
||||||
while (!done && pdu_len > 0){
|
LOG_D(NR_MAC, "In %s: received UL-SCH sub-PDU with LCID 0x%x in %d.%d (remaining PDU length %d)\n", __func__, rx_lcid, frameP, slot, pdu_len);
|
||||||
uint16_t mac_len=0;
|
|
||||||
uint16_t mac_subheader_len=sizeof(NR_MAC_SUBHEADER_FIXED);
|
|
||||||
uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
|
||||||
|
|
||||||
LOG_D(NR_MAC, "In %s: received UL-SCH sub-PDU with LCID 0x%x in %d.%d (remaining PDU length %d)\n", __func__, rx_lcid, frameP, slot, pdu_len);
|
unsigned char *ce_ptr;
|
||||||
|
int n_Lcg = 0;
|
||||||
|
|
||||||
unsigned char *ce_ptr;
|
switch(rx_lcid){
|
||||||
int n_Lcg = 0;
|
// MAC CE
|
||||||
|
/*#ifdef DEBUG_HEADER_PARSING
|
||||||
switch(rx_lcid){
|
LOG_D(NR_MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID, pdu_len);
|
||||||
// MAC CE
|
#endif*/
|
||||||
|
case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
|
||||||
/*#ifdef DEBUG_HEADER_PARSING
|
// 38.321 Ch6.1.3.20
|
||||||
LOG_D(NR_MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID, pdu_len);
|
mac_len = 2;
|
||||||
#endif*/
|
break;
|
||||||
case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
|
case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION:
|
||||||
// 38.321 Ch6.1.3.20
|
// 38.321 Ch6.1.3.7
|
||||||
mac_len = 2;
|
break;
|
||||||
break;
|
case UL_SCH_LCID_S_BSR:
|
||||||
case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION:
|
case UL_SCH_LCID_S_TRUNCATED_BSR:
|
||||||
// 38.321 Ch6.1.3.7
|
//38.321 section 6.1.3.1
|
||||||
break;
|
//fixed length
|
||||||
|
mac_len =1;
|
||||||
case UL_SCH_LCID_S_BSR:
|
/* Extract short BSR value */
|
||||||
case UL_SCH_LCID_S_TRUNCATED_BSR:
|
ce_ptr = &pduP[mac_subheader_len];
|
||||||
//38.321 section 6.1.3.1
|
NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr;
|
||||||
//fixed length
|
sched_ctrl->estimated_ul_buffer = 0;
|
||||||
mac_len =1;
|
sched_ctrl->estimated_ul_buffer = NR_SHORT_BSR_TABLE[bsr_s->Buffer_size];
|
||||||
/* Extract short BSR value */
|
LOG_D(NR_MAC,
|
||||||
ce_ptr = &pduP[mac_subheader_len];
|
"SHORT BSR at %4d.%2d, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n",
|
||||||
NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr;
|
frameP,
|
||||||
sched_ctrl->estimated_ul_buffer = 0;
|
slot,
|
||||||
sched_ctrl->estimated_ul_buffer = NR_SHORT_BSR_TABLE[bsr_s->Buffer_size];
|
bsr_s->LcgID,
|
||||||
LOG_D(NR_MAC,
|
bsr_s->Buffer_size,
|
||||||
"SHORT BSR at %4d.%2d, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n",
|
NR_SHORT_BSR_TABLE[bsr_s->Buffer_size],
|
||||||
frameP,
|
sched_ctrl->estimated_ul_buffer);
|
||||||
slot,
|
break;
|
||||||
bsr_s->LcgID,
|
case UL_SCH_LCID_L_BSR:
|
||||||
bsr_s->Buffer_size,
|
case UL_SCH_LCID_L_TRUNCATED_BSR:
|
||||||
NR_SHORT_BSR_TABLE[bsr_s->Buffer_size],
|
//38.321 section 6.1.3.1
|
||||||
sched_ctrl->estimated_ul_buffer);
|
//variable length
|
||||||
break;
|
/* Several checks have been added to this function to
|
||||||
|
ensure that the casting of the pduP is possible. There seems
|
||||||
case UL_SCH_LCID_L_BSR:
|
to be a partial PDU at the end of this buffer, so here
|
||||||
case UL_SCH_LCID_L_TRUNCATED_BSR:
|
we gracefully ignore that by returning 0. See:
|
||||||
//38.321 section 6.1.3.1
|
https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues/534 */
|
||||||
//variable length
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
/* Several checks have been added to this function to
|
|
||||||
ensure that the casting of the pduP is possible. There seems
|
|
||||||
to be a partial PDU at the end of this buffer, so here
|
|
||||||
we gracefully ignore that by returning 0. See:
|
|
||||||
https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues/534 */
|
|
||||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
|
||||||
return 0;
|
|
||||||
/* Extract long BSR value */
|
|
||||||
ce_ptr = &pduP[mac_subheader_len];
|
|
||||||
NR_BSR_LONG *bsr_l = (NR_BSR_LONG *) ce_ptr;
|
|
||||||
sched_ctrl->estimated_ul_buffer = 0;
|
|
||||||
|
|
||||||
n_Lcg = bsr_l->LcgID7 + bsr_l->LcgID6 + bsr_l->LcgID5 + bsr_l->LcgID4 +
|
|
||||||
bsr_l->LcgID3 + bsr_l->LcgID2 + bsr_l->LcgID1 + bsr_l->LcgID0;
|
|
||||||
|
|
||||||
LOG_D(NR_MAC, "LONG BSR, LCG ID(7-0) %d/%d/%d/%d/%d/%d/%d/%d\n",
|
|
||||||
bsr_l->LcgID7, bsr_l->LcgID6, bsr_l->LcgID5, bsr_l->LcgID4,
|
|
||||||
bsr_l->LcgID3, bsr_l->LcgID2, bsr_l->LcgID1, bsr_l->LcgID0);
|
|
||||||
|
|
||||||
for (int n = 0; n < n_Lcg; n++){
|
|
||||||
LOG_D(NR_MAC, "LONG BSR, %d/%d (n/n_Lcg), BS Index %d, BS value < %d",
|
|
||||||
n, n_Lcg, pduP[mac_subheader_len + 1 + n],
|
|
||||||
NR_LONG_BSR_TABLE[pduP[mac_subheader_len + 1 + n]]);
|
|
||||||
sched_ctrl->estimated_ul_buffer +=
|
|
||||||
NR_LONG_BSR_TABLE[pduP[mac_subheader_len + 1 + n]];
|
|
||||||
LOG_D(NR_MAC,
|
|
||||||
"LONG BSR at %4d.%2d, %d/%d (n/n_Lcg), BS Index %d, BS value < %d, total %d\n",
|
|
||||||
frameP,
|
|
||||||
slot,
|
|
||||||
n,
|
|
||||||
n_Lcg,
|
|
||||||
pduP[mac_subheader_len + 1 + n],
|
|
||||||
NR_LONG_BSR_TABLE[pduP[mac_subheader_len + 1 + n]],
|
|
||||||
sched_ctrl->estimated_ul_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UL_SCH_LCID_C_RNTI:
|
|
||||||
|
|
||||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
|
||||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
|
||||||
if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) {
|
|
||||||
ra->crnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF);
|
|
||||||
ra->msg3_dcch_dtch = true;
|
|
||||||
LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x\n", ra->crnti);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//38.321 section 6.1.3.2
|
|
||||||
//fixed length
|
|
||||||
mac_len = 2;
|
|
||||||
/* Extract CRNTI value */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UL_SCH_LCID_SINGLE_ENTRY_PHR:
|
|
||||||
//38.321 section 6.1.3.8
|
|
||||||
//fixed length
|
|
||||||
mac_len = 2;
|
|
||||||
/* Extract SINGLE ENTRY PHR elements for PHR calculation */
|
|
||||||
ce_ptr = &pduP[mac_subheader_len];
|
|
||||||
NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
|
|
||||||
/* Save the phr info */
|
|
||||||
const int PH = phr->PH;
|
|
||||||
const int PCMAX = phr->PCMAX;
|
|
||||||
/* 38.133 Table10.1.17.1-1 */
|
|
||||||
if (PH < 55)
|
|
||||||
sched_ctrl->ph = PH - 32;
|
|
||||||
else
|
|
||||||
sched_ctrl->ph = PH - 32 + (PH - 54);
|
|
||||||
/* 38.133 Table10.1.18.1-1 */
|
|
||||||
sched_ctrl->pcmax = PCMAX - 29;
|
|
||||||
LOG_D(NR_MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
|
|
||||||
phr->R1, PH, sched_ctrl->ph, phr->R2, PCMAX, sched_ctrl->pcmax);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT:
|
|
||||||
//38.321 section 6.1.3.9
|
|
||||||
// varialbe length
|
|
||||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
|
||||||
return 0;
|
|
||||||
/* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT:
|
|
||||||
//38.321 section 6.1.3.9
|
|
||||||
// varialbe length
|
|
||||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
|
||||||
return 0;
|
|
||||||
/* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UL_SCH_LCID_PADDING:
|
|
||||||
done = 1;
|
|
||||||
// end of MAC PDU, can ignore the rest.
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UL_SCH_LCID_SRB1:
|
|
||||||
case UL_SCH_LCID_SRB2:
|
|
||||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
rnti_t crnti = UE->rnti;
|
|
||||||
NR_UE_info_t* UE_idx = UE;
|
|
||||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
|
||||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
|
||||||
if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) {
|
|
||||||
uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len;
|
|
||||||
if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
|
|
||||||
crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF);
|
|
||||||
LOG_W(NR_MAC, " UL_SCH_LCID_SRB for rnti %04x\n", crnti);
|
|
||||||
UE_idx = find_nr_UE(&RC.nrmac[module_idP]->UE_info, crnti);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UE_idx->CellGroup) {
|
|
||||||
LOG_D(NR_MAC, "Frame %d : ULSCH -> UL-DCCH %d (gNB %ld, %d bytes), rnti: 0x%04x \n", frameP, rx_lcid, module_idP, mac_len, crnti);
|
|
||||||
mac_rlc_data_ind(module_idP,
|
|
||||||
crnti,
|
|
||||||
module_idP,
|
|
||||||
frameP,
|
|
||||||
ENB_FLAG_YES,
|
|
||||||
MBMS_FLAG_NO,
|
|
||||||
rx_lcid,
|
|
||||||
(char *) (pduP + mac_subheader_len),
|
|
||||||
mac_len,
|
|
||||||
1,
|
|
||||||
NULL);
|
|
||||||
} else {
|
|
||||||
AssertFatal(1==0,"[UE %04x] Frame/Slot %d.%d : Received LCID %d which is not configured, dropping packet\n",UE->rnti,frameP,slot,rx_lcid);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UL_SCH_LCID_SRB3:
|
|
||||||
// todo
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UL_SCH_LCID_CCCH:
|
|
||||||
case UL_SCH_LCID_CCCH1:
|
|
||||||
// fixed length
|
|
||||||
mac_subheader_len = 1;
|
|
||||||
|
|
||||||
if ( rx_lcid == UL_SCH_LCID_CCCH1 ) {
|
|
||||||
// RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes
|
|
||||||
mac_len = 8;
|
|
||||||
|
|
||||||
// Check if it is a valid CCCH1 message, we get all 00's messages very often
|
|
||||||
int i = 0;
|
|
||||||
for(i=0; i<(mac_subheader_len+mac_len); i++) {
|
|
||||||
if(pduP[i] != 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == (mac_subheader_len+mac_len)) {
|
|
||||||
LOG_D(NR_MAC, "%s() Invalid CCCH1 message!, pdu_len: %d\n", __func__, pdu_len);
|
|
||||||
done = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// fixed length of 6 bytes
|
|
||||||
mac_len = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_initial_ul_rrc_message(module_idP,
|
|
||||||
CC_id,
|
|
||||||
UE,
|
|
||||||
CCCH,
|
|
||||||
pduP + mac_subheader_len,
|
|
||||||
mac_len);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UL_SCH_LCID_DTCH ... (UL_SCH_LCID_DTCH + 28):
|
|
||||||
// check if LCID is valid at current time.
|
|
||||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n",
|
|
||||||
UE->rnti,
|
|
||||||
frameP,
|
|
||||||
slot,
|
|
||||||
rx_lcid<4?"DCCH":"DTCH",
|
|
||||||
rx_lcid,
|
|
||||||
module_idP,
|
|
||||||
mac_len);
|
|
||||||
UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len;
|
|
||||||
|
|
||||||
mac_rlc_data_ind(module_idP,
|
|
||||||
UE->rnti,
|
|
||||||
module_idP,
|
|
||||||
frameP,
|
|
||||||
ENB_FLAG_YES,
|
|
||||||
MBMS_FLAG_NO,
|
|
||||||
rx_lcid,
|
|
||||||
(char *)(pduP + mac_subheader_len),
|
|
||||||
mac_len,
|
|
||||||
1,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
sdus += 1;
|
|
||||||
/* Updated estimated buffer when receiving data */
|
|
||||||
if (sched_ctrl->estimated_ul_buffer >= mac_len) {
|
|
||||||
sched_ctrl->estimated_ul_buffer -= mac_len;
|
|
||||||
} else {
|
|
||||||
sched_ctrl->estimated_ul_buffer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
sdus += 1;
|
|
||||||
|
|
||||||
default:
|
|
||||||
LOG_E(NR_MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid);
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
|
||||||
if (rx_lcid < 45 || rx_lcid == 52 || rx_lcid == 63) {
|
|
||||||
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU sub-header with length %d (LCID = 0x%02x):\n", __func__, mac_subheader_len, rx_lcid);
|
|
||||||
log_dump(NR_MAC, pduP, mac_subheader_len, LOG_DUMP_CHAR, "\n");
|
|
||||||
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
|
|
||||||
log_dump(NR_MAC, pduP + mac_subheader_len, mac_len, LOG_DUMP_CHAR, "\n");
|
|
||||||
} else {
|
|
||||||
LOG_I(NR_MAC, "In %s: dumping UL MAC CE with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
|
|
||||||
log_dump(NR_MAC, pduP + mac_subheader_len + mac_len, mac_len, LOG_DUMP_CHAR, "\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pduP += ( mac_subheader_len + mac_len );
|
|
||||||
pdu_len -= ( mac_subheader_len + mac_len );
|
|
||||||
|
|
||||||
if (pdu_len < 0) {
|
|
||||||
LOG_E(NR_MAC, "In %s: residual UL MAC PDU in %d.%d with length < 0!, pdu_len %d \n", __func__, frameP, slot, pdu_len);
|
|
||||||
LOG_E(NR_MAC, "MAC PDU ");
|
|
||||||
for (int i = 0; i < 20; i++) // Only printf 1st - 20nd bytes
|
|
||||||
printf("%02x ", pduP[i]);
|
|
||||||
printf("\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
|
/* Extract long BSR value */
|
||||||
|
ce_ptr = &pduP[mac_subheader_len];
|
||||||
|
NR_BSR_LONG *bsr_l = (NR_BSR_LONG *) ce_ptr;
|
||||||
|
sched_ctrl->estimated_ul_buffer = 0;
|
||||||
|
|
||||||
|
n_Lcg = bsr_l->LcgID7 + bsr_l->LcgID6 + bsr_l->LcgID5 + bsr_l->LcgID4 +
|
||||||
|
bsr_l->LcgID3 + bsr_l->LcgID2 + bsr_l->LcgID1 + bsr_l->LcgID0;
|
||||||
|
|
||||||
|
LOG_D(NR_MAC, "LONG BSR, LCG ID(7-0) %d/%d/%d/%d/%d/%d/%d/%d\n",
|
||||||
|
bsr_l->LcgID7, bsr_l->LcgID6, bsr_l->LcgID5, bsr_l->LcgID4,
|
||||||
|
bsr_l->LcgID3, bsr_l->LcgID2, bsr_l->LcgID1, bsr_l->LcgID0);
|
||||||
|
|
||||||
|
for (int n = 0; n < n_Lcg; n++){
|
||||||
|
LOG_D(NR_MAC, "LONG BSR, %d/%d (n/n_Lcg), BS Index %d, BS value < %d",
|
||||||
|
n, n_Lcg, pduP[mac_subheader_len + 1 + n],
|
||||||
|
NR_LONG_BSR_TABLE[pduP[mac_subheader_len + 1 + n]]);
|
||||||
|
sched_ctrl->estimated_ul_buffer += NR_LONG_BSR_TABLE[pduP[mac_subheader_len + 1 + n]];
|
||||||
|
LOG_D(NR_MAC,
|
||||||
|
"LONG BSR at %4d.%2d, %d/%d (n/n_Lcg), BS Index %d, BS value < %d, total %d\n",
|
||||||
|
frameP,
|
||||||
|
slot,
|
||||||
|
n,
|
||||||
|
n_Lcg,
|
||||||
|
pduP[mac_subheader_len + 1 + n],
|
||||||
|
NR_LONG_BSR_TABLE[pduP[mac_subheader_len + 1 + n]],
|
||||||
|
sched_ctrl->estimated_ul_buffer);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UL_SCH_LCID_C_RNTI:
|
||||||
|
|
||||||
|
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||||
|
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
||||||
|
if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) {
|
||||||
|
ra->crnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF);
|
||||||
|
ra->msg3_dcch_dtch = true;
|
||||||
|
LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x\n", ra->crnti);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//38.321 section 6.1.3.2
|
||||||
|
//fixed length
|
||||||
|
mac_len = 2;
|
||||||
|
/* Extract CRNTI value */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UL_SCH_LCID_SINGLE_ENTRY_PHR:
|
||||||
|
AssertFatal(harq_pid>-1,"Invalid HARQ PID %d\n",harq_pid);
|
||||||
|
NR_sched_pusch_t *sched_pusch = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;;
|
||||||
|
//38.321 section 6.1.3.8
|
||||||
|
//fixed length
|
||||||
|
mac_len = 2;
|
||||||
|
/* Extract SINGLE ENTRY PHR elements for PHR calculation */
|
||||||
|
ce_ptr = &pduP[mac_subheader_len];
|
||||||
|
NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
|
||||||
|
/* Save the phr info */
|
||||||
|
int PH;
|
||||||
|
const int PCMAX = phr->PCMAX;
|
||||||
|
/* 38.133 Table10.1.17.1-1 */
|
||||||
|
if (phr->PH < 55)
|
||||||
|
PH = phr->PH - 32;
|
||||||
|
else
|
||||||
|
PH = phr->PH - 32 + (phr->PH - 54);
|
||||||
|
// in sched_ctrl we set normalized PH wrt MCS and PRBs
|
||||||
|
long *deltaMCS = ul_bwp->pusch_Config ? ul_bwp->pusch_Config->pusch_PowerControl->deltaMCS : NULL;
|
||||||
|
sched_ctrl->ph = PH +
|
||||||
|
compute_bw_factor(sched_pusch->mu, sched_pusch->rbSize) +
|
||||||
|
compute_delta_tf(sched_pusch->tb_size<<3,
|
||||||
|
sched_pusch->rbSize,
|
||||||
|
0, //n_layers
|
||||||
|
0, //n_symbols
|
||||||
|
0, //n_dmrs
|
||||||
|
deltaMCS);
|
||||||
|
/* 38.133 Table10.1.18.1-1 */
|
||||||
|
sched_ctrl->pcmax = PCMAX - 29;
|
||||||
|
LOG_D(NR_MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
|
||||||
|
phr->R1, PH, sched_ctrl->ph, phr->R2, PCMAX, sched_ctrl->pcmax);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT:
|
||||||
|
//38.321 section 6.1.3.9
|
||||||
|
// varialbe length
|
||||||
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
|
return 0;
|
||||||
|
/* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT:
|
||||||
|
//38.321 section 6.1.3.9
|
||||||
|
// varialbe length
|
||||||
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
|
return 0;
|
||||||
|
/* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UL_SCH_LCID_PADDING:
|
||||||
|
done = 1;
|
||||||
|
// end of MAC PDU, can ignore the rest.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UL_SCH_LCID_SRB1:
|
||||||
|
case UL_SCH_LCID_SRB2:
|
||||||
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rnti_t crnti = UE->rnti;
|
||||||
|
NR_UE_info_t* UE_idx = UE;
|
||||||
|
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||||
|
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
||||||
|
if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) {
|
||||||
|
uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len;
|
||||||
|
if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
|
||||||
|
crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF);
|
||||||
|
LOG_W(NR_MAC, " UL_SCH_LCID_SRB for rnti %04x\n", crnti);
|
||||||
|
UE_idx = find_nr_UE(&RC.nrmac[module_idP]->UE_info, crnti);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UE_idx->CellGroup) {
|
||||||
|
LOG_D(NR_MAC, "Frame %d : ULSCH -> UL-DCCH %d (gNB %ld, %d bytes), rnti: 0x%04x \n", frameP, rx_lcid, module_idP, mac_len, crnti);
|
||||||
|
mac_rlc_data_ind(module_idP,
|
||||||
|
crnti,
|
||||||
|
module_idP,
|
||||||
|
frameP,
|
||||||
|
ENB_FLAG_YES,
|
||||||
|
MBMS_FLAG_NO,
|
||||||
|
rx_lcid,
|
||||||
|
(char *) (pduP + mac_subheader_len),
|
||||||
|
mac_len,
|
||||||
|
1,
|
||||||
|
NULL);
|
||||||
|
} else {
|
||||||
|
AssertFatal(1==0,"[UE %04x] Frame/Slot %d.%d : Received LCID %d which is not configured, dropping packet\n",UE->rnti,frameP,slot,rx_lcid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UL_SCH_LCID_CCCH:
|
||||||
|
case UL_SCH_LCID_CCCH1:
|
||||||
|
// fixed length
|
||||||
|
mac_subheader_len = 1;
|
||||||
|
|
||||||
|
if ( rx_lcid == UL_SCH_LCID_CCCH1 ) {
|
||||||
|
// RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes
|
||||||
|
mac_len = 8;
|
||||||
|
|
||||||
|
// Check if it is a valid CCCH1 message, we get all 00's messages very often
|
||||||
|
int i = 0;
|
||||||
|
for(i=0; i<(mac_subheader_len+mac_len); i++) {
|
||||||
|
if(pduP[i] != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == (mac_subheader_len+mac_len)) {
|
||||||
|
LOG_D(NR_MAC, "%s() Invalid CCCH1 message!, pdu_len: %d\n", __func__, pdu_len);
|
||||||
|
done = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// fixed length of 6 bytes
|
||||||
|
mac_len = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_initial_ul_rrc_message(module_idP,
|
||||||
|
CC_id,
|
||||||
|
UE,
|
||||||
|
CCCH,
|
||||||
|
pduP + mac_subheader_len,
|
||||||
|
mac_len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UL_SCH_LCID_DTCH ... (UL_SCH_LCID_DTCH + 28):
|
||||||
|
// check if LCID is valid at current time.
|
||||||
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n",
|
||||||
|
UE->rnti,
|
||||||
|
frameP,
|
||||||
|
slot,
|
||||||
|
rx_lcid<4?"DCCH":"DTCH",
|
||||||
|
rx_lcid,
|
||||||
|
module_idP,
|
||||||
|
mac_len);
|
||||||
|
UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len;
|
||||||
|
|
||||||
|
mac_rlc_data_ind(module_idP,
|
||||||
|
UE->rnti,
|
||||||
|
module_idP,
|
||||||
|
frameP,
|
||||||
|
ENB_FLAG_YES,
|
||||||
|
MBMS_FLAG_NO,
|
||||||
|
rx_lcid,
|
||||||
|
(char *)(pduP + mac_subheader_len),
|
||||||
|
mac_len,
|
||||||
|
1,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
sdus += 1;
|
||||||
|
/* Updated estimated buffer when receiving data */
|
||||||
|
if (sched_ctrl->estimated_ul_buffer >= mac_len)
|
||||||
|
sched_ctrl->estimated_ul_buffer -= mac_len;
|
||||||
|
else
|
||||||
|
sched_ctrl->estimated_ul_buffer = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_E(NR_MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid);
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
||||||
|
if (rx_lcid < 45 || rx_lcid == 52 || rx_lcid == 63) {
|
||||||
|
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU sub-header with length %d (LCID = 0x%02x):\n", __func__, mac_subheader_len, rx_lcid);
|
||||||
|
log_dump(NR_MAC, pduP, mac_subheader_len, LOG_DUMP_CHAR, "\n");
|
||||||
|
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
|
||||||
|
log_dump(NR_MAC, pduP + mac_subheader_len, mac_len, LOG_DUMP_CHAR, "\n");
|
||||||
|
} else {
|
||||||
|
LOG_I(NR_MAC, "In %s: dumping UL MAC CE with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
|
||||||
|
log_dump(NR_MAC, pduP + mac_subheader_len + mac_len, mac_len, LOG_DUMP_CHAR, "\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pduP += ( mac_subheader_len + mac_len );
|
||||||
|
pdu_len -= ( mac_subheader_len + mac_len );
|
||||||
|
|
||||||
|
if (pdu_len < 0) {
|
||||||
|
LOG_E(NR_MAC, "In %s: residual UL MAC PDU in %d.%d with length < 0!, pdu_len %d \n", __func__, frameP, slot, pdu_len);
|
||||||
|
LOG_E(NR_MAC, "MAC PDU ");
|
||||||
|
for (int i = 0; i < 20; i++) // Only printf 1st - 20nd bytes
|
||||||
|
printf("%02x ", pduP[i]);
|
||||||
|
printf("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UE->mac_stats.ul.num_mac_sdu += sdus;
|
UE->mac_stats.ul.num_mac_sdu += sdus;
|
||||||
|
|
||||||
@@ -547,9 +574,9 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|||||||
|
|
||||||
LOG_I(NR_MAC, "Printing received UL MAC payload at gNB side: %d \n");
|
LOG_I(NR_MAC, "Printing received UL MAC payload at gNB side: %d \n");
|
||||||
for (int i = 0; i < sdu_lenP ; i++) {
|
for (int i = 0; i < sdu_lenP ; i++) {
|
||||||
//harq_process_ul_ue->a[i] = (unsigned char) rand();
|
//harq_process_ul_ue->a[i] = (unsigned char) rand();
|
||||||
//printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
|
//printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
|
||||||
printf("%02x ",(unsigned char)sduP[i]);
|
printf("%02x ",(unsigned char)sduP[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
@@ -564,7 +591,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|||||||
if (UE_scheduling_control->sched_ul_bytes < 0)
|
if (UE_scheduling_control->sched_ul_bytes < 0)
|
||||||
UE_scheduling_control->sched_ul_bytes = 0;
|
UE_scheduling_control->sched_ul_bytes = 0;
|
||||||
|
|
||||||
nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP);
|
nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, harq_pid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
|
NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
|
||||||
@@ -663,14 +690,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|||||||
current_rnti,
|
current_rnti,
|
||||||
ra->rnti);
|
ra->rnti);
|
||||||
|
|
||||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
|
||||||
|
|
||||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
|
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
|
||||||
if (timing_advance != 0xffff)
|
if (timing_advance != 0xffff)
|
||||||
UE_scheduling_control->ta_update = timing_advance;
|
UE_scheduling_control->ta_update = timing_advance;
|
||||||
UE_scheduling_control->raw_rssi = rssi;
|
UE_scheduling_control->raw_rssi = rssi;
|
||||||
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
||||||
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
||||||
if(ra->cfra) {
|
if(ra->cfra) {
|
||||||
|
|
||||||
LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti);
|
LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti);
|
||||||
@@ -691,8 +718,9 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|||||||
// Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to fill in Msg4
|
// Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to fill in Msg4
|
||||||
// First byte corresponds to R/LCID MAC sub-header
|
// First byte corresponds to R/LCID MAC sub-header
|
||||||
memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
|
memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
|
||||||
|
// harq_pid set a non valid value because it is not used in this call
|
||||||
if (nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP) == 0) {
|
// the function is only called to decode the contention resolution sub-header
|
||||||
|
if (nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) {
|
||||||
ra->state = Msg4;
|
ra->state = Msg4;
|
||||||
ra->Msg4_frame = (frameP + 2) % 1024;
|
ra->Msg4_frame = (frameP + 2) % 1024;
|
||||||
ra->Msg4_slot = 1;
|
ra->Msg4_slot = 1;
|
||||||
@@ -864,6 +892,65 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc,
|
|||||||
return has_data || sched_ctrl->SR || high_inactivity;
|
return has_data || sched_ctrl->SR || high_inactivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_ul_ue_R_Qm(int mcs, int mcs_table, const NR_PUSCH_Config_t *pusch_Config, uint16_t *R, uint8_t *Qm)
|
||||||
|
{
|
||||||
|
*R = nr_get_code_rate_ul(mcs, mcs_table);
|
||||||
|
*Qm = nr_get_Qm_ul(mcs, mcs_table);
|
||||||
|
|
||||||
|
if (pusch_Config && pusch_Config->tp_pi2BPSK && ((mcs_table == 3 && mcs < 2) || (mcs_table == 4 && mcs < 6))) {
|
||||||
|
*R >>= 1;
|
||||||
|
*Qm <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void nr_ue_max_mcs_min_rb(int mu, int ph_limit, NR_pusch_semi_static_t *ps, NR_UE_UL_BWP_t *ul_bwp, uint16_t minRb, uint32_t tbs, uint16_t *Rb, uint8_t *mcs)
|
||||||
|
{
|
||||||
|
AssertFatal(*Rb >= minRb, "illegal Rb %d < minRb %d\n", *Rb, minRb);
|
||||||
|
AssertFatal(*mcs >= 0 && *mcs <= 28, "illegal MCS %d\n", *mcs);
|
||||||
|
|
||||||
|
const int tbs_bits = tbs << 3;
|
||||||
|
uint16_t R;
|
||||||
|
uint8_t Qm;
|
||||||
|
update_ul_ue_R_Qm(*mcs, ul_bwp->mcs_table, ul_bwp->pusch_Config, &R, &Qm);
|
||||||
|
|
||||||
|
long *deltaMCS = ul_bwp->pusch_Config ? ul_bwp->pusch_Config->pusch_PowerControl->deltaMCS : NULL;
|
||||||
|
int tx_power = compute_bw_factor(mu, *Rb) +
|
||||||
|
compute_delta_tf(tbs_bits,
|
||||||
|
*Rb,
|
||||||
|
ps->nrOfLayers,
|
||||||
|
ps->nrOfSymbols,
|
||||||
|
ps->N_PRB_DMRS*ps->num_dmrs_symb,
|
||||||
|
deltaMCS);
|
||||||
|
|
||||||
|
while (ph_limit < tx_power && *Rb >= minRb) {
|
||||||
|
(*Rb)--;
|
||||||
|
tx_power = compute_bw_factor(mu, *Rb) +
|
||||||
|
compute_delta_tf(tbs_bits,
|
||||||
|
*Rb,
|
||||||
|
ps->nrOfLayers,
|
||||||
|
ps->nrOfSymbols,
|
||||||
|
ps->N_PRB_DMRS*ps->num_dmrs_symb,
|
||||||
|
deltaMCS);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ph_limit < tx_power && *mcs > 6) {
|
||||||
|
(*mcs)--;
|
||||||
|
update_ul_ue_R_Qm(*mcs, ul_bwp->mcs_table, ul_bwp->pusch_Config, &R, &Qm);
|
||||||
|
tx_power = compute_bw_factor(mu, *Rb) +
|
||||||
|
compute_delta_tf(tbs_bits,
|
||||||
|
*Rb,
|
||||||
|
ps->nrOfLayers,
|
||||||
|
ps->nrOfSymbols,
|
||||||
|
ps->N_PRB_DMRS*ps->num_dmrs_symb,
|
||||||
|
deltaMCS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ph_limit < tx_power)
|
||||||
|
LOG_W(NR_MAC, "Normalized power %d based on current resources (RBs %d, MCS %d) exceed reported PHR %d (normalized value)\n",
|
||||||
|
tx_power, *Rb, *mcs, ph_limit);
|
||||||
|
}
|
||||||
|
|
||||||
static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||||
frame_t frame,
|
frame_t frame,
|
||||||
sub_frame_t slot,
|
sub_frame_t slot,
|
||||||
@@ -1006,18 +1093,6 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_PUSCH_Config_t *pusch_Config, const int mcs_table) {
|
|
||||||
|
|
||||||
const int mcs = sched_pusch->mcs;
|
|
||||||
sched_pusch->R = nr_get_code_rate_ul(mcs, mcs_table);
|
|
||||||
sched_pusch->Qm = nr_get_Qm_ul(mcs, mcs_table);
|
|
||||||
|
|
||||||
if (pusch_Config && pusch_Config->tp_pi2BPSK && ((mcs_table == 3 && mcs < 2) || (mcs_table == 4 && mcs < 6))) {
|
|
||||||
sched_pusch->R >>= 1;
|
|
||||||
sched_pusch->Qm <<= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ul_pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
|
uint32_t ul_pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
|
||||||
typedef struct UEsched_s {
|
typedef struct UEsched_s {
|
||||||
float coef;
|
float coef;
|
||||||
@@ -1188,7 +1263,7 @@ void pf_ul(module_id_t module_id,
|
|||||||
|
|
||||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||||
sched_pusch->mcs = min(nrmac->min_grant_mcs, sched_pusch->mcs);
|
sched_pusch->mcs = min(nrmac->min_grant_mcs, sched_pusch->mcs);
|
||||||
update_ul_ue_R_Qm(sched_pusch, current_BWP->pusch_Config, current_BWP->mcs_table);
|
update_ul_ue_R_Qm(sched_pusch->mcs, current_BWP->mcs_table, current_BWP->pusch_Config, &sched_pusch->R, &sched_pusch->Qm);
|
||||||
sched_pusch->rbStart = rbStart;
|
sched_pusch->rbStart = rbStart;
|
||||||
sched_pusch->rbSize = min_rb;
|
sched_pusch->rbSize = min_rb;
|
||||||
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
|
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
|
||||||
@@ -1274,7 +1349,7 @@ void pf_ul(module_id_t module_id,
|
|||||||
nrOfLayers,
|
nrOfLayers,
|
||||||
ps);
|
ps);
|
||||||
}
|
}
|
||||||
update_ul_ue_R_Qm(sched_pusch, current_BWP->pusch_Config, current_BWP->mcs_table);
|
update_ul_ue_R_Qm(sched_pusch->mcs, current_BWP->mcs_table, current_BWP->pusch_Config, &sched_pusch->R, &sched_pusch->Qm);
|
||||||
|
|
||||||
int rbStart = 0;
|
int rbStart = 0;
|
||||||
const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||||
@@ -1293,8 +1368,17 @@ void pf_ul(module_id_t module_id,
|
|||||||
else
|
else
|
||||||
LOG_D(NR_MAC,"allocating UL data for RNTI %04x (rbStsart %d, min_rb %d, bwpSize %d)\n", iterator->UE->rnti,rbStart,min_rb,bwpSize);
|
LOG_D(NR_MAC,"allocating UL data for RNTI %04x (rbStsart %d, min_rb %d, bwpSize %d)\n", iterator->UE->rnti,rbStart,min_rb,bwpSize);
|
||||||
|
|
||||||
/* Calculate the current scheduling bytes and the necessary RBs */
|
/* Calculate the current scheduling bytes */
|
||||||
const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0);
|
const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0);
|
||||||
|
/* adjust rbSize and MCS according to PHR and BPRE */
|
||||||
|
sched_pusch->mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||||
|
if(sched_ctrl->pcmax!=0 ||
|
||||||
|
sched_ctrl->ph!=0) // verify if the PHR related parameter have been initialized
|
||||||
|
nr_ue_max_mcs_min_rb(sched_pusch->mu, sched_ctrl->ph, ps, current_BWP, min_rbSize, B, &max_rbSize, &sched_pusch->mcs);
|
||||||
|
|
||||||
|
if (sched_pusch->mcs < sched_ctrl->ul_bler_stats.mcs)
|
||||||
|
sched_ctrl->ul_bler_stats.mcs = sched_pusch->mcs; /* force estimated MCS down */
|
||||||
|
|
||||||
uint16_t rbSize = 0;
|
uint16_t rbSize = 0;
|
||||||
uint32_t TBS = 0;
|
uint32_t TBS = 0;
|
||||||
|
|
||||||
@@ -1308,6 +1392,7 @@ void pf_ul(module_id_t module_id,
|
|||||||
max_rbSize,
|
max_rbSize,
|
||||||
&TBS,
|
&TBS,
|
||||||
&rbSize);
|
&rbSize);
|
||||||
|
|
||||||
sched_pusch->rbSize = rbSize;
|
sched_pusch->rbSize = rbSize;
|
||||||
sched_pusch->tb_size = TBS;
|
sched_pusch->tb_size = TBS;
|
||||||
LOG_D(NR_MAC,"rbSize %d (max_rbSize %d), TBS %d, est buf %d, sched_ul %d, B %d, CCE %d, num_dmrs_symb %d, N_PRB_DMRS %d\n",
|
LOG_D(NR_MAC,"rbSize %d (max_rbSize %d), TBS %d, est buf %d, sched_ul %d, B %d, CCE %d, num_dmrs_symb %d, N_PRB_DMRS %d\n",
|
||||||
@@ -1692,6 +1777,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
|||||||
pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size;
|
pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size;
|
||||||
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
|
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
|
||||||
|
|
||||||
|
pusch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(sched_pusch->tb_size<<3,sched_pusch->R);
|
||||||
if(current_BWP->pusch_servingcellconfig &&
|
if(current_BWP->pusch_servingcellconfig &&
|
||||||
current_BWP->pusch_servingcellconfig->rateMatching) {
|
current_BWP->pusch_servingcellconfig->rateMatching) {
|
||||||
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
||||||
|
|||||||
@@ -469,7 +469,6 @@ uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl,
|
|||||||
int codebook_mode);
|
int codebook_mode);
|
||||||
|
|
||||||
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx);
|
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx);
|
||||||
|
|
||||||
uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl);
|
uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||||
|
|
||||||
const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
|
const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
|
||||||
|
|||||||
@@ -394,6 +394,7 @@ typedef struct NR_pusch_semi_static_t {
|
|||||||
typedef struct NR_sched_pusch {
|
typedef struct NR_sched_pusch {
|
||||||
int frame;
|
int frame;
|
||||||
int slot;
|
int slot;
|
||||||
|
int mu;
|
||||||
|
|
||||||
/// RB allocation within active uBWP
|
/// RB allocation within active uBWP
|
||||||
uint16_t rbSize;
|
uint16_t rbSize;
|
||||||
|
|||||||
@@ -1664,12 +1664,7 @@ void fill_initial_cellGroupConfig(int uid,
|
|||||||
tag->tag_Id = 0;
|
tag->tag_Id = 0;
|
||||||
tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity;
|
tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity;
|
||||||
ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag);
|
ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag);
|
||||||
mac_CellGroupConfig->phr_Config = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config));
|
set_phr_config(mac_CellGroupConfig);
|
||||||
mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config->choice.setup));
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf10;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf10;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1;
|
|
||||||
|
|
||||||
mac_CellGroupConfig->schedulingRequestConfig = calloc(1, sizeof(*mac_CellGroupConfig->schedulingRequestConfig));
|
mac_CellGroupConfig->schedulingRequestConfig = calloc(1, sizeof(*mac_CellGroupConfig->schedulingRequestConfig));
|
||||||
mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList));
|
mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList));
|
||||||
|
|||||||
@@ -1147,4 +1147,13 @@ void config_uplinkBWP(NR_BWP_Uplink_t *ubwp,
|
|||||||
ubwp->bwp_Dedicated->beamFailureRecoveryConfig = NULL;
|
ubwp->bwp_Dedicated->beamFailureRecoveryConfig = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_phr_config(NR_MAC_CellGroupConfig_t *mac_CellGroupConfig)
|
||||||
|
{
|
||||||
|
mac_CellGroupConfig->phr_Config = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config));
|
||||||
|
mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup;
|
||||||
|
mac_CellGroupConfig->phr_Config->choice.setup = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config->choice.setup));
|
||||||
|
mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf10;
|
||||||
|
mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf10;
|
||||||
|
mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ typedef struct physicalcellgroup_s{
|
|||||||
long RNTI_Value[MAX_NUM_CCs];
|
long RNTI_Value[MAX_NUM_CCs];
|
||||||
}physicalcellgroup_t;
|
}physicalcellgroup_t;
|
||||||
|
|
||||||
|
void set_phr_config(NR_MAC_CellGroupConfig_t *mac_CellGroupConfig);
|
||||||
uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc);
|
uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc);
|
||||||
void rrc_coreset_config(NR_ControlResourceSet_t *coreset,
|
void rrc_coreset_config(NR_ControlResourceSet_t *coreset,
|
||||||
int bwp_id,
|
int bwp_id,
|
||||||
|
|||||||
@@ -133,16 +133,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
|||||||
tag->tag_Id = 0;
|
tag->tag_Id = 0;
|
||||||
tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity;
|
tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity;
|
||||||
ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag);
|
ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag);
|
||||||
mac_CellGroupConfig->phr_Config = calloc(1,sizeof(*mac_CellGroupConfig->phr_Config));
|
set_phr_config(mac_CellGroupConfig);
|
||||||
mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup = calloc(1,sizeof(*mac_CellGroupConfig->phr_Config->choice.setup));
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf20;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf0;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB3;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->multiplePHR=false;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->dummy=false;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->phr_Type2OtherCell = false;
|
|
||||||
mac_CellGroupConfig->phr_Config->choice.setup->phr_ModeOtherCG = NR_PHR_Config__phr_ModeOtherCG_real;
|
|
||||||
mac_CellGroupConfig->skipUplinkTxDynamic=false;
|
mac_CellGroupConfig->skipUplinkTxDynamic=false;
|
||||||
mac_CellGroupConfig->ext1 = NULL;
|
mac_CellGroupConfig->ext1 = NULL;
|
||||||
secondaryCellGroup->physicalCellGroupConfig = calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig));
|
secondaryCellGroup->physicalCellGroupConfig = calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig));
|
||||||
|
|||||||
Reference in New Issue
Block a user