merge develop, use Linux crypto library

This commit is contained in:
Laurent
2020-10-12 18:24:08 +02:00
58 changed files with 3064 additions and 4090 deletions
+1 -1
View File
@@ -211,7 +211,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
msi_pos++;
while((non_mbsfn_SubframeConfig & (0x100 >> msi_pos)) == (0x100>>msi_pos))
msi_pos++;
mbms_mch_i=0;
mbms_mch_i=0;
if((subframeP==0)){
x=0;
@@ -27,76 +27,70 @@
#include "common/utils/nr/nr_common.h"
#include <math.h>
#include "PHY/defs_nr_common.h"
//Table 5.1.2.2-2
uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824};
uint16_t NPRB_LBRM[7] = {32,66,107,135,162,217,273};
// Transport block size determination according to 6.1.4.2 of TS 38.214
// returns the TBS in bits
uint32_t nr_compute_tbs(uint16_t Qm,
uint16_t R,
uint16_t nb_rb,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
uint8_t tb_scaling,
uint8_t Nl)
uint8_t Nl)
{
uint16_t nbp_re, nb_re;
uint32_t nr_tbs=0;
uint32_t Ninfo, Np_info, C;
uint8_t n, scale;
uint16_t nbp_re, nb_re;
uint32_t nr_tbs=0;
uint32_t Ninfo, Np_info, C;
uint8_t n, scale;
nbp_re = 12 * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
nbp_re = NR_NB_SC_PER_RB * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
nb_re = min(156, nbp_re) * nb_rb;
scale = (R>1024)?11:10;
// Intermediate number of information bits
Ninfo = ((nb_re * R * Qm * Nl)>>scale)>>tb_scaling;
nb_re = min(156, nbp_re) * nb_rb;
scale = (R>1024)?11:10;
// Intermediate number of information bits
Ninfo = ((nb_re * R * Qm * Nl)>>scale)>>tb_scaling;
if (Ninfo <=3824) {
n = max(3, floor(log2(Ninfo)) - 6);
Np_info = max(24, (Ninfo>>n)<<n);
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
if (Tbstable_nr[i] >= Np_info){
nr_tbs = Tbstable_nr[i];
break;
}
if (Ninfo <=3824) {
n = max(3, floor(log2(Ninfo)) - 6);
Np_info = max(24, (Ninfo>>n)<<n);
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
if (Tbstable_nr[i] >= Np_info){
nr_tbs = Tbstable_nr[i];
break;
}
}
} else {
n = log2(Ninfo-24)-5;
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
if (R <= 256) {
C = CEILIDIV((Np_info+24),3816);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
} else {
if (Np_info > 8424){
C = CEILIDIV((Np_info+24),8424);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
} else {
nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
}
}
else {
n = log2(Ninfo-24)-5;
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
if (R <= 256) {
C = CEILIDIV((Np_info+24),3816);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
}
else {
if (Np_info > 8424){
C = CEILIDIV((Np_info+24),8424);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
}
else {
nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
}
}
}
//printf("Ninfo %d nbp_re %d nb_re %d Qm %d, R %d, tbs %d\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs);
return nr_tbs;
}
//printf("Ninfo %d nbp_re %d nb_re %d Qm %d, R %d, tbs %d\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs);
return nr_tbs;
}
//tbslbrm calculation according to 5.4.2.1 of 38.212
uint32_t nr_compute_tbslbrm(uint16_t table,
uint16_t nb_rb,
uint8_t Nl,
uint8_t C)
uint8_t Nl)
{
uint16_t R, nb_re;
@@ -104,14 +98,14 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
uint8_t Qm;
int i;
uint32_t nr_tbs=0;
uint32_t Ninfo, Np_info;
uint32_t Ninfo, Np_info, C;
uint8_t n;
for (i=0; i<7; i++) {
if (NPRB_LBRM[i] >= nb_rb){
nb_rb_lbrm = NPRB_LBRM[i];
break;
}
if (NPRB_LBRM[i] >= nb_rb){
nb_rb_lbrm = NPRB_LBRM[i];
break;
}
}
Qm = ((table == 1)? 8 : 6);
@@ -136,10 +130,12 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
if (R <= 256) {
C = CEILIDIV((Np_info+24),3816);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
}
else {
if (Np_info > 8424){
C = CEILIDIV((Np_info+24),8424);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
}
else {
@@ -150,5 +146,4 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
}
return nr_tbs;
}
+4 -2
View File
@@ -221,6 +221,10 @@ typedef struct {
uint32_t RA_tx_frame;
/// Random-access variable for window calculation (subframe of last change in window counter)
uint8_t RA_tx_subframe;
/// Scheduled TX frame for RA Msg3
frame_t msg3_frame;
/// Scheduled TX slot for RA Msg3
slot_t msg3_slot;
/// Random-access variable for backoff (frame of last change in backoff counter)
uint32_t RA_backoff_frame;
/// Random-access variable for backoff (subframe of last change in backoff counter)
@@ -243,13 +247,11 @@ typedef struct {
uint8_t generate_nr_prach;
//// FAPI-like interface message
fapi_nr_tx_request_t tx_request;
fapi_nr_ul_config_request_t ul_config_request;
fapi_nr_dl_config_request_t dl_config_request;
/// Interface module instances
nr_ue_if_module_t *if_module;
nr_scheduled_response_t scheduled_response;
nr_phy_config_t phy_config;
/// BSR report flag management
+42 -1
View File
@@ -88,6 +88,24 @@ NR_UE_MAC_INST_t *get_mac_inst(
\param ul_info UL indication*/
NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_indication_t *ul_info);
/**\brief fill nr_scheduled_response struct instance
@param nr_scheduled_response_t * pointer to scheduled_response instance to fill
@param fapi_nr_dl_config_request_t* pointer to dl_config,
@param fapi_nr_ul_config_request_t* pointer to ul_config,
@param fapi_nr_tx_request_t* pointer to tx_request;
@param module_id_t mod_id module ID
@param int cc_id CC ID
@param frame_t frame frame number
@param int slot reference number */
void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
fapi_nr_dl_config_request_t *dl_config,
fapi_nr_ul_config_request_t *ul_config,
fapi_nr_tx_request_t *tx_request,
module_id_t mod_id,
int cc_id,
frame_t frame,
int slot);
/* \brief Get SR payload (0,1) from UE MAC
@param Mod_id Instance id of UE in machine
@param CC_id Component Carrier index
@@ -156,7 +174,7 @@ int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index,
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot);
void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int dci_format,
uint8_t dci_length,
uint16_t rnti,
@@ -197,6 +215,17 @@ and fills the PRACH PDU per each FD occasion.
*/
void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
/* \brief This function schedules the Msg3 transmission
@param
@param
@param
@returns void
*/
void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac,
frame_t current_frame,
sub_frame_t current_slot,
uint8_t Msg3_tda_id);
/* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI.
@param Mod_id Index of UE instance
@param CC_id Index to a component carrier
@@ -212,6 +241,7 @@ random-access procedure
uint16_t nr_ue_process_rar(module_id_t mod_id,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
uint8_t * dlsch_buffer,
rnti_t * t_crnti,
uint8_t preamble_index,
@@ -264,5 +294,16 @@ void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
void nr_ue_msg2_scheduler(module_id_t mod_id, uint16_t rach_frame, uint16_t rach_slot, uint16_t *msg2_frame, uint16_t *msg2_slot);
int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
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
/** @}*/
+21 -1
View File
@@ -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;
}
+6 -2
View File
@@ -493,9 +493,13 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) {
// Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
// TbD Msg3 Retransmissions to be scheduled by DCI 0_0
mac->RA_active = 0;
mac->RA_window_cnt = -1;
mac->ra_state = RA_SUCCEEDED;
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR successfully received \n", mod_id, frame, nr_tti_tx);
mac->generate_nr_prach = 2;
LOG_I(MAC, "[MAC][UE %d][RAPROC]: RAR successfully received \n", mod_id);
} else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) {
@@ -578,7 +582,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
mac->RA_window_cnt--;
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR reception not successful, (RA window count %d) \n",
LOG_D(MAC, "[MAC][UE %d][RAPROC][%d.%d]: RAR not received yet (RA window count %d) \n",
mod_id,
frame,
nr_tti_tx,
@@ -64,11 +64,11 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd
}
void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id, uint8_t dci_format){
void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id){
uint16_t monitoringSymbolsWithinSlot;
uint16_t monitoringSymbolsWithinSlot = 0;
uint8_t bwp_id = 1, coreset_id = 1;
int sps;
int sps = 0;
def_dci_pdu_rel15 = calloc(1,sizeof(dci_pdu_rel15_t));
AssertFatal(mac->scc != NULL, "scc is null\n");
NR_ServingCellConfigCommon_t *scc = mac->scc;
@@ -76,9 +76,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP;
NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id];
// DCI format configuration
rel15->dci_format = dci_format;
// CORESET configuration
NR_ControlResourceSet_t *coreset = mac->coreset[bwp_id - 1][coreset_id - 1];
rel15->coreset.duration = coreset->duration;
@@ -123,7 +120,9 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, 275);
rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275);
rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
rel15->dci_length = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format, NR_RNTI_C, rel15->BWPSize, bwp_id);
for (int i = 0; i < rel15->num_dci_options; i++) {
rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id);
}
break;
case NR_RNTI_RA:
// we use the initial DL BWP
@@ -133,7 +132,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); //NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
rel15->dci_length = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format, NR_RNTI_RA, rel15->BWPSize, bwp_id);
rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id);
break;
case NR_RNTI_P:
break;
@@ -177,14 +176,13 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
#endif
// add DCI
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
dl_config->number_pdus = dl_config->number_pdus + 1;
dl_config->number_pdus += 1;
}
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot) {
int ss_id;
uint8_t bwp_id = 1, coreset_id = 1;
NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated;
NR_BWP_Downlink_t *bwp = mac->DLbwp[bwp_id - 1];
#ifdef DEBUG_DCI
@@ -215,7 +213,9 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space\n");
switch(mac->ra_state){
case WAIT_RAR:
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id, NR_DL_DCI_FORMAT_1_0);
rel15->num_dci_options = 1;
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id);
fill_dci_search_candidates(ss, rel15);
break;
case WAIT_CONTENTION_RESOLUTION:
@@ -286,7 +286,10 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
// Monitors DCI 01 and 11 scrambled with C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
if (get_softmodem_params()->phy_test == 1 && mac->crnti > 0) {
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in the user specific search space\n");
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id, NR_DL_DCI_FORMAT_1_1);
rel15->num_dci_options = 2;
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_1;
rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_1;
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id);
fill_dci_search_candidates(ss, rel15);
#ifdef DEBUG_DCI
+505 -190
View File
@@ -51,9 +51,10 @@
#include "NR_MAC_UE/mac_extern.h"
#include "common/utils/nr/nr_common.h"
/* PHY UE */
/* PHY */
#include "SCHED_NR_UE/defs.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
/*Openair Packet Tracer */
#include "UTIL/OPT/opt.h"
@@ -91,6 +92,24 @@ extern void mac_rlc_data_ind (
num_tb_t num_tbP,
crc_t *crcs_pP);
void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
fapi_nr_dl_config_request_t *dl_config,
fapi_nr_ul_config_request_t *ul_config,
fapi_nr_tx_request_t *tx_request,
module_id_t mod_id,
int cc_id,
frame_t frame,
int slot){
scheduled_response->dl_config = dl_config;
scheduled_response->ul_config = ul_config;
scheduled_response->tx_request = tx_request;
scheduled_response->module_id = mod_id;
scheduled_response->CC_id = cc_id;
scheduled_response->frame = frame;
scheduled_response->slot = slot;
}
uint32_t get_ssb_slot(uint32_t ssb_index){
// this function now only support f <= 3GHz
@@ -118,7 +137,7 @@ uint8_t table_9_2_2_1[16][8]={
{1,0, 14,26,0,3,0,0}
};
#if 0 // Not in use. In case of use, please adapt the schedule_response (no longer in MAC)
int8_t nr_ue_process_dlsch(module_id_t module_id,
int cc_id,
uint8_t gNB_index,
@@ -252,6 +271,7 @@ int8_t nr_ue_process_dlsch(module_id_t module_id,
}
return 0;
}
#endif
int8_t nr_ue_decode_mib(module_id_t module_id,
int cc_id,
@@ -719,7 +739,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP);
*/
dl_config->number_pdus = dl_config->number_pdus + 1;
mac->scheduled_response.dl_config = dl_config;
fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, 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);
}
} else { // we have an scg
@@ -728,17 +751,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
dcireq.cc_id = cc_id;
dcireq.frame = rx_frame;
dcireq.slot = rx_slot;
dcireq.dl_config_req.number_pdus = 0;
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
// we should have received a DL DCI here, so configure DL accordingly
scheduled_response.dl_config = &dcireq.dl_config_req;
scheduled_response.ul_config = NULL;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = mod_id;
scheduled_response.CC_id = cc_id;
scheduled_response.frame = rx_frame;
scheduled_response.slot = rx_slot;
fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, 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);
}
@@ -766,7 +782,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
uint8_t data_existing = 0;
uint16_t TBS_bytes;
uint32_t TBS;
int i;
int i, N_PRB_oh;
module_id_t mod_id = ul_info->module_id;
uint32_t gNB_index = ul_info->gNB_index;
@@ -778,57 +794,101 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
uint8_t access_mode = SCHEDULED_ACCESS;
// program PUSCH. this should actually be done upon reception of an UL DCI
// program PUSCH with UL DCI parameters
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
fapi_nr_tx_request_t tx_req;
fapi_nr_tx_request_body_t tx_req_body;
fapi_nr_ul_config_request_t *ul_config = &dcireq.ul_config_req;
nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
//--------------------------Temporary configuration-----------------------------//
uint16_t rnti = 0x1234;
uint32_t rb_size = 50;
uint32_t rb_start = 0;
uint8_t nr_of_symbols = 11;
uint8_t start_symbol_index = 0;
fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &mac->ul_config_request.ul_config_list[0];
uint16_t rnti = ulcfg_pdu->pusch_config_pdu.rnti;
uint32_t rb_size = ulcfg_pdu->pusch_config_pdu.rb_size;
uint32_t rb_start = ulcfg_pdu->pusch_config_pdu.rb_start;
uint8_t nr_of_symbols = ulcfg_pdu->pusch_config_pdu.nr_of_symbols;
uint8_t start_symbol_index = ulcfg_pdu->pusch_config_pdu.start_symbol_index;
uint8_t nrOfLayers = 1;
uint8_t mcs_index = 9;
uint8_t mcs_table = 0;
uint8_t harq_process_id = 0;
uint8_t rv_index = 0;
uint8_t mcs_index = ulcfg_pdu->pusch_config_pdu.mcs_index;
uint8_t mcs_table = ulcfg_pdu->pusch_config_pdu.mcs_table;
uint8_t harq_process_id = ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id;
uint8_t rv_index = ulcfg_pdu->pusch_config_pdu.pusch_data.rv_index;
uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
uint8_t dmrs_config_type = 0;
uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
// These should come from RRC config!!!
uint8_t ptrs_mcs1 = 2;
uint8_t ptrs_mcs2 = 4;
uint8_t ptrs_mcs3 = 10;
uint16_t n_rb0 = 25;
uint16_t n_rb1 = 75;
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;
//------------------------------------------------------------------------------//
for (i = start_symbol_index; i < start_symbol_index + nr_of_symbols; i++) {
if((ul_dmrs_symb_pos >> i) & 0x01)
number_dmrs_symbols += 1;
}
#ifdef DEBUG_DCI
LOG_I(MAC, " UL config params \n rnti: %x \n rb_size: %d \n",
rnti, rb_size);
LOG_I(MAC, "rb_start: %x \n nr_of_symbols: %d \n start_symbol_index: %d \n nrOfLayers: %d \n mcs_index: %d \n \
mcs_table: %d \n harq_process_id: %d \n ndi: %d \n num_cb: %d \n rv_index: %d \n",
rb_start, nr_of_symbols, start_symbol_index, nrOfLayers, mcs_index,
mcs_table, harq_process_id, ndi, num_cb, rv_index);
#endif
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);
// PTRS ports configuration
// TbD: ptrs_dmrs_port and ptrs_port_index are not initialised!
ptrs_ports_list.ptrs_re_offset = 0;
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;
// Num PRB Overhead from PUSCH-ServingCellConfig
if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL)
N_PRB_oh = 0;
else
N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead;
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);
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
}
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(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
@@ -876,8 +936,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
dcireq.frame = rx_frame;
dcireq.slot = rx_slot;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &dcireq.ul_config_req;
// Config UL TX PDU
tx_req.slot = slot_tx;
tx_req.sfn = frame_tx;
@@ -886,41 +944,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
tx_req_body.pdu_length = TBS_bytes;
tx_req_body.pdu_index = 0;
tx_req_body.pdu = ulsch_input_buffer;
tx_req.tx_request_body = &tx_req_body;
scheduled_response.tx_request = &tx_req;
scheduled_response.tx_request->tx_request_body = &tx_req_body;
scheduled_response.module_id = mod_id;
scheduled_response.CC_id = cc_id;
scheduled_response.frame = rx_frame;
scheduled_response.slot = rx_slot;
scheduled_response.ul_config->slot = ul_info->slot_tx;
scheduled_response.ul_config->number_pdus = 1;
scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
if (1 << ptrs_time_density >= nr_of_symbols) {
scheduled_response.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);
}
@@ -929,11 +955,116 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
// Note: Contention resolution is currently not active
if (mac->RA_contention_resolution_timer_active == 1)
ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx);
} else if (get_softmodem_params()->do_ra){
NR_UE_MAC_INST_t *mac = get_mac_inst(ul_info->module_id);
if (mac->RA_active && ul_info->slot_tx == mac->msg3_slot && ul_info->frame_tx == mac->msg3_frame){
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
nr_scheduled_response_t scheduled_response;
fapi_nr_tx_request_t tx_req;
fapi_nr_tx_request_body_t tx_req_body;
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus];
uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size;
//if (IS_SOFTMODEM_NOS1){
// // Getting IP traffic to be transmitted
// data_existing = nr_ue_get_sdu(mod_id,
// cc_id,
// frame_tx,
// slot_tx,
// 0,
// ulsch_input_buffer,
// TBS_bytes,
// &access_mode);
//}
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
//if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
//and block this traffic from being forwarded to the upper layers at the gNB
LOG_D(MAC, "Random data to be tranmsitted (TBS_bytes %d): \n", TBS_bytes);
//Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
//in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
//have a valid LCID (nr_process_mac_pdu function)
ulsch_input_buffer[0] = 0x31;
for (int i = 1; i < TBS_bytes; i++) {
ulsch_input_buffer[i] = (unsigned char) rand();
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
}
//}
LOG_D(MAC, "[UE %d] Frame %d, Subframe %d Adding Msg3 UL Config Request for rnti: %x\n",
ul_info->module_id,
ul_info->frame_tx,
ul_info->slot_tx,
mac->t_crnti);
// Config UL TX PDU
tx_req.slot = ul_info->slot_tx;
tx_req.sfn = ul_info->frame_tx;
tx_req.number_of_pdus = 1;
tx_req_body.pdu_length = TBS_bytes;
tx_req_body.pdu_index = 0;
tx_req_body.pdu = ulsch_input_buffer;
tx_req.tx_request_body = &tx_req_body;
ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
ul_config->number_pdus++;
// scheduled_response
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
}
}
}
}
return UE_CONNECTION_OK;
}
// PUSCH Msg3 scheduled by RAR UL grant according to 8.3 of TS 38.213
// Note: Msg3 tx in the uplink symbols of mixed slot
void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac,
frame_t current_frame,
sub_frame_t current_slot,
uint8_t Msg3_tda_id){
int delta = 0;
NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
struct NR_PUSCH_TimeDomainResourceAllocationList *pusch_TimeDomainAllocationList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
// k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1
// PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon
uint8_t k2 = *pusch_TimeDomainAllocationList->list.array[Msg3_tda_id]->k2;
switch (mu) {
case 0:
delta = 2;
break;
case 1:
delta = 3;
break;
case 2:
delta = 4;
break;
case 3:
delta = 6;
break;
}
mac->msg3_slot = (current_slot + k2 + delta) % nr_slots_per_frame[mu];
if (current_slot + k2 + delta > nr_slots_per_frame[mu])
mac->msg3_frame = (current_frame + 1) % 1024;
else
mac->msg3_frame = current_frame;
#ifdef DEBUG_MSG3
LOG_D(MAC, "[DEBUG_MSG3] current_slot %d k2 %d delta %d temp_slot %d mac->msg3_frame %d mac->msg3_slot %d \n", current_slot, k2, delta, current_slot + k2 + delta, mac->msg3_frame, mac->msg3_slot);
#endif
}
// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x
// It fills the PRACH PDU per each FD occasion.
// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3.
@@ -951,6 +1082,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
fapi_nr_ul_config_prach_pdu *prach_config_pdu;
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
fapi_nr_prach_config_t *prach_config = &cfg->prach_config;
nr_scheduled_response_t scheduled_response;
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
@@ -1081,10 +1213,11 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
}
}
}
} else if (mac->ra_state == RA_SUCCEEDED){
mac->generate_nr_prach = 2;
}
mac->scheduled_response.ul_config = ul_config;
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response);
}
}
@@ -2261,13 +2394,22 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
*/
if(pusch_config_pdu != NULL){
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
if (mac->ULbwp[0]->bwp_Dedicated->pusch_Config)
if (mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
}
else if (mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
}
if (pusch_TimeDomainAllocationList) {
AssertFatal(pusch_TimeDomainAllocationList->list.count > time_domain_ind,
"time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n",
time_domain_ind,pusch_TimeDomainAllocationList->list.count);
if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) {
LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n",
time_domain_ind, pusch_TimeDomainAllocationList->list.count);
pusch_config_pdu->start_symbol_index=0;
pusch_config_pdu->nr_of_symbols=0;
return -1;
}
int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[time_domain_ind]->startSymbolAndLength;
int S,L;
SLIV2SL(startSymbolAndLength,&S,&L);
@@ -2295,8 +2437,8 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits);
nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,def_dci_pdu_rel15);
return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci->dci_format));
int dci_format = nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,def_dci_pdu_rel15);
return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci_format));
}
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){
@@ -2317,6 +2459,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
LOG_D(MAC,"nr_ue_process_dci at MAC layer with dci_format=%d (DL BWP %d, UL BWP %d)\n",dci_format,n_RB_DLBWP,n_RB_ULBWP);
NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup;
NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
switch(dci_format){
case NR_UL_DCI_FORMAT_0_0:
@@ -2423,6 +2566,23 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
pusch_config_pdu_0_1->frequency_hopping = dci->frequency_hopping_flag.val;
/* MCS */
pusch_config_pdu_0_1->mcs_index = dci->mcs;
/* MCS TABLE */
if (pusch_config->transformPrecoder == NULL) {
if (mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_config_pdu_0_1->transform_precoding = 1;
else
pusch_config_pdu_0_1->transform_precoding = 0;
}
else
pusch_config_pdu_0_1->transform_precoding = *pusch_config->transformPrecoder;
if (pusch_config_pdu_0_1->transform_precoding == transform_precoder_disabled)
pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_Table, 0,
dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false);
else
pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_TableTransformPrecoder, 1,
dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false);
/* NDI */
pusch_config_pdu_0_1->pusch_data.new_data_indicator = dci->ndi;
/* RV */
@@ -3100,7 +3260,33 @@ void nr_ue_send_sdu(module_id_t module_idP,
}
void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
// N_RB configuration according to 7.3.1.0 (DCI size alignment) of TS 38.212
int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){
int N_RB = 0, start_RB;
switch(rnti_type) {
case NR_RNTI_RA:
case NR_RNTI_TC:
case NR_RNTI_P:
case NR_RNTI_SI:
if (mac->DLbwp[0]->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero) {
uint8_t bwp_id = 1;
uint8_t coreset_id = 0; // assuming controlResourceSetId is 0 for controlResourceSetZero
NR_ControlResourceSet_t *coreset = mac->coreset[bwp_id - 1][coreset_id];
get_coreset_rballoc(coreset->frequencyDomainResources.buf,&N_RB,&start_RB);
} else {
N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
}
break;
case NR_RNTI_C:
N_RB = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, 275);
break;
}
return N_RB;
}
int nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int dci_format,
uint8_t dci_size,
uint16_t rnti,
@@ -3117,21 +3303,45 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
AssertFatal(rnti_type!=-1,"no identified/handled rnti\n");
AssertFatal(mac->DLbwp[0] != NULL, "DLbwp[0] shouldn't be null here!\n");
AssertFatal(mac->ULbwp[0] != NULL, "ULbwp[0] shouldn't be null here!\n");
int N_RB = (mac->scg != NULL) ?
NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275) :
NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275);
int N_RB = get_n_rb(mac, rnti_type);
int N_RB_UL = (mac->scg != NULL) ?
NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275) :
NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275);
int pos=0;
int fsize=0;
if (rnti_type == NR_RNTI_C) {
// First find out the DCI format from the first bit (UE performed blind decoding)
pos++;
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
#ifdef DEBUG_EXTRACT_DCI
LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu);
#endif
if (dci_format == NR_UL_DCI_FORMAT_0_0 || dci_format == NR_DL_DCI_FORMAT_1_0) {
if (dci_pdu_rel15->format_indicator == 0)
dci_format = NR_UL_DCI_FORMAT_0_0;
else
dci_format = NR_DL_DCI_FORMAT_1_0;
}
else if (dci_format == NR_UL_DCI_FORMAT_0_1 || dci_format == NR_DL_DCI_FORMAT_1_1) {
// In case the sizes of formats 0_1 and 1_1 happen to be the same
if (dci_pdu_rel15->format_indicator == 0)
dci_format = NR_UL_DCI_FORMAT_0_1;
else
dci_format = NR_DL_DCI_FORMAT_1_1;
}
}
#ifdef DEBUG_EXTRACT_DCI
LOG_D(MAC, "DCI format is %d\n", dci_format);
#endif
switch(dci_format) {
case NR_DL_DCI_FORMAT_1_0:
switch(rnti_type) {
case NR_RNTI_RA:
N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); // TBR hotfix
// Freq domain assignment
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos=fsize;
@@ -3168,13 +3378,6 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
case NR_RNTI_C:
// indicating a DL DCI format 1bit
pos++;
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
#ifdef DEBUG_EXTRACT_DCI
LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu);
#endif
// Freq domain assignment (275rb >> fsize = 16)
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos+=fsize;
@@ -3375,18 +3578,16 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
switch(rnti_type)
{
case NR_RNTI_C:
// indicating a DL DCI format 1bit
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
// Freq domain assignment max 16 bit
fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
pos+=fsize;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
// Time domain assignment 4bit
pos+=4;
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
// Frequency hopping flag – 1 bit
pos++;
dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
// This is not supported yet - Skip for now
// Frequency hopping flag – 1 bit
//pos++;
//dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
// MCS 5 bit
pos+=5;
dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f;
@@ -3450,89 +3651,203 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
break;
case NR_DL_DCI_FORMAT_1_1:
// Format indicator
pos=1;
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
// Carrier indicator
pos+=dci_pdu_rel15->carrier_indicator.nbits;
dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
// BWP Indicator
pos+=dci_pdu_rel15->bwp_indicator.nbits;
dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1);
// Frequency domain resource assignment
pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->frequency_domain_assignment.nbits)-1);
// Time domain resource assignment
pos+=dci_pdu_rel15->time_domain_assignment.nbits;
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->time_domain_assignment.nbits)-1);
// VRB-to-PRB mapping
pos+=dci_pdu_rel15->vrb_to_prb_mapping.nbits;
dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->vrb_to_prb_mapping.nbits)-1);
// PRB bundling size indicator
pos+=dci_pdu_rel15->prb_bundling_size_indicator.nbits;
dci_pdu_rel15->prb_bundling_size_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->prb_bundling_size_indicator.nbits)-1);
// Rate matching indicator
pos+=dci_pdu_rel15->rate_matching_indicator.nbits;
dci_pdu_rel15->rate_matching_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rate_matching_indicator.nbits)-1);
// ZP CSI-RS trigger
pos+=dci_pdu_rel15->zp_csi_rs_trigger.nbits;
dci_pdu_rel15->zp_csi_rs_trigger.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->zp_csi_rs_trigger.nbits)-1);
//TB1
// MCS 5bit
pos+=5;
dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
// New data indicator 1bit
pos+=1;
dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&0x1;
// Redundancy version 2bit
pos+=2;
dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3;
//TB2
// MCS 5bit
pos+=dci_pdu_rel15->mcs2.nbits;
dci_pdu_rel15->mcs2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->mcs2.nbits)-1);
// New data indicator 1bit
pos+=dci_pdu_rel15->ndi2.nbits;
dci_pdu_rel15->ndi2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ndi2.nbits)-1);
// Redundancy version 2bit
pos+=dci_pdu_rel15->rv2.nbits;
dci_pdu_rel15->rv2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rv2.nbits)-1);
// HARQ process number 4bit
pos+=4;
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
// Downlink assignment index
pos+=dci_pdu_rel15->dai[0].nbits;
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1);
// TPC command for scheduled PUCCH 2bit
pos+=2;
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&0x3;
// PUCCH resource indicator 3bit
pos+=3;
dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x3;
// PDSCH-to-HARQ_feedback timing indicator
pos+=dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits;
dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits)-1);
// Antenna ports
pos+=dci_pdu_rel15->antenna_ports.nbits;
dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1);
// TCI
pos+=dci_pdu_rel15->transmission_configuration_indication.nbits;
dci_pdu_rel15->transmission_configuration_indication.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->transmission_configuration_indication.nbits)-1);
// SRS request
pos+=dci_pdu_rel15->srs_request.nbits;
dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1);
// CBG transmission information
pos+=dci_pdu_rel15->cbgti.nbits;
dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1);
// CBG flushing out information
pos+=dci_pdu_rel15->cbgfi.nbits;
dci_pdu_rel15->cbgfi.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgfi.nbits)-1);
// DMRS sequence init
pos+=1;
dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&0x1;
break;
switch(rnti_type)
{
case NR_RNTI_C:
// Carrier indicator
pos+=dci_pdu_rel15->carrier_indicator.nbits;
dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
// BWP Indicator
pos+=dci_pdu_rel15->bwp_indicator.nbits;
dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1);
// Frequency domain resource assignment
pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->frequency_domain_assignment.nbits)-1);
// Time domain resource assignment
pos+=dci_pdu_rel15->time_domain_assignment.nbits;
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->time_domain_assignment.nbits)-1);
// VRB-to-PRB mapping
pos+=dci_pdu_rel15->vrb_to_prb_mapping.nbits;
dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->vrb_to_prb_mapping.nbits)-1);
// PRB bundling size indicator
pos+=dci_pdu_rel15->prb_bundling_size_indicator.nbits;
dci_pdu_rel15->prb_bundling_size_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->prb_bundling_size_indicator.nbits)-1);
// Rate matching indicator
pos+=dci_pdu_rel15->rate_matching_indicator.nbits;
dci_pdu_rel15->rate_matching_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rate_matching_indicator.nbits)-1);
// ZP CSI-RS trigger
pos+=dci_pdu_rel15->zp_csi_rs_trigger.nbits;
dci_pdu_rel15->zp_csi_rs_trigger.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->zp_csi_rs_trigger.nbits)-1);
//TB1
// MCS 5bit
pos+=5;
dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
// New data indicator 1bit
pos+=1;
dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&0x1;
// Redundancy version 2bit
pos+=2;
dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3;
//TB2
// MCS 5bit
pos+=dci_pdu_rel15->mcs2.nbits;
dci_pdu_rel15->mcs2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->mcs2.nbits)-1);
// New data indicator 1bit
pos+=dci_pdu_rel15->ndi2.nbits;
dci_pdu_rel15->ndi2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ndi2.nbits)-1);
// Redundancy version 2bit
pos+=dci_pdu_rel15->rv2.nbits;
dci_pdu_rel15->rv2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rv2.nbits)-1);
// HARQ process number 4bit
pos+=4;
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
// Downlink assignment index
pos+=dci_pdu_rel15->dai[0].nbits;
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1);
// TPC command for scheduled PUCCH 2bit
pos+=2;
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&0x3;
// PUCCH resource indicator 3bit
pos+=3;
dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x3;
// PDSCH-to-HARQ_feedback timing indicator
pos+=dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits;
dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits)-1);
// Antenna ports
pos+=dci_pdu_rel15->antenna_ports.nbits;
dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1);
// TCI
pos+=dci_pdu_rel15->transmission_configuration_indication.nbits;
dci_pdu_rel15->transmission_configuration_indication.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->transmission_configuration_indication.nbits)-1);
// SRS request
pos+=dci_pdu_rel15->srs_request.nbits;
dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1);
// CBG transmission information
pos+=dci_pdu_rel15->cbgti.nbits;
dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1);
// CBG flushing out information
pos+=dci_pdu_rel15->cbgfi.nbits;
dci_pdu_rel15->cbgfi.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgfi.nbits)-1);
// DMRS sequence init
pos+=1;
dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&0x1;
break;
}
break;
}
case NR_UL_DCI_FORMAT_0_1:
switch(rnti_type)
{
case NR_RNTI_C:
// Carrier indicator
pos+=dci_pdu_rel15->carrier_indicator.nbits;
dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
// UL/SUL Indicator
pos+=dci_pdu_rel15->ul_sul_indicator.nbits;
dci_pdu_rel15->ul_sul_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ul_sul_indicator.nbits)-1);
// BWP Indicator
pos+=dci_pdu_rel15->bwp_indicator.nbits;
dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1);
// Freq domain assignment max 16 bit
fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
//pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
pos+=fsize;
//pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
// Time domain assignment 4bit
//pos+=4;
pos+=dci_pdu_rel15->time_domain_assignment.nbits;
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0x3;
// Not supported yet - skip for now
// Frequency hopping flag – 1 bit
//pos++;
//dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
// MCS 5 bit
pos+=5;
dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f;
// New data indicator 1bit
pos++;
dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1;
// Redundancy version 2bit
pos+=2;
dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3;
// HARQ process number 4bit
pos+=4;
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
// 1st Downlink assignment index
pos+=dci_pdu_rel15->dai[0].nbits;
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1);
// 2nd Downlink assignment index
pos+=dci_pdu_rel15->dai[1].nbits;
dci_pdu_rel15->dai[1].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[1].nbits)-1);
// TPC command for scheduled PUSCH – 2 bits
pos+=2;
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3;
// SRS resource indicator
pos+=dci_pdu_rel15->srs_resource_indicator.nbits;
dci_pdu_rel15->srs_resource_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_resource_indicator.nbits)-1);
// Precoding info and n. of layers
pos+=dci_pdu_rel15->precoding_information.nbits;
dci_pdu_rel15->precoding_information.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->precoding_information.nbits)-1);
// Antenna ports
pos+=dci_pdu_rel15->antenna_ports.nbits;
dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1);
// SRS request
pos+=dci_pdu_rel15->srs_request.nbits;
dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1);
// CSI request
pos+=dci_pdu_rel15->csi_request.nbits;
dci_pdu_rel15->csi_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->csi_request.nbits)-1);
// CBG transmission information
pos+=dci_pdu_rel15->cbgti.nbits;
dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1);
// PTRS DMRS association
pos+=dci_pdu_rel15->ptrs_dmrs_association.nbits;
dci_pdu_rel15->ptrs_dmrs_association.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ptrs_dmrs_association.nbits)-1);
// Beta offset indicator
pos+=dci_pdu_rel15->beta_offset_indicator.nbits;
dci_pdu_rel15->beta_offset_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->beta_offset_indicator.nbits)-1);
// DMRS sequence initialization
pos+=dci_pdu_rel15->dmrs_sequence_initialization.nbits;
dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dmrs_sequence_initialization.nbits)-1);
// UL-SCH indicator
pos+=1;
dci_pdu_rel15->ulsch_indicator = (*dci_pdu>>(dci_size-pos))&0x1;
// UL/SUL indicator – 1 bit
/* commented for now (RK): need to get this from BWP descriptor
if (cfg->pucch_config.pucch_GroupHopping.value)
dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ul_sul_indicator&1)<<(dci_size-pos++);
*/
break;
}
break;
}
return dci_format;
}
+168 -30
View File
@@ -46,7 +46,8 @@
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include <common/utils/nr/nr_common.h>
#define DEBUG_RAR
// #define DEBUG_RAR
// #define DEBUG_MSG3
// table 7.2-1 TS 38.321
uint16_t table_7_2_1[16] = {
@@ -66,6 +67,135 @@ uint16_t table_7_2_1[16] = {
1920, // row index 13
};
void nr_config_Msg3_pdu(NR_UE_MAC_INST_t *mac,
int Msg3_f_alloc,
uint8_t Msg3_t_alloc,
uint8_t mcs,
uint8_t freq_hopping){
int f_alloc, mask, StartSymbolIndex, NrOfSymbols;
uint8_t nb_dmrs_re_per_rb;
uint16_t number_dmrs_symbols = 0;
int N_PRB_oh;
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;
NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
NR_BWP_UplinkDedicated_t *ibwp = mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP;
NR_PUSCH_Config_t *pusch_Config = ibwp->pusch_Config->choice.setup;
int startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[Msg3_t_alloc]->startSymbolAndLength;
#ifdef DEBUG_MSG3
printf("[DEBUG_MSG3] Configuring 1 Msg3 PDU of %d UL pdus \n", ul_config->number_pdus);
#endif
// Num PRB Overhead from PUSCH-ServingCellConfig
if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL)
N_PRB_oh = 0;
else
N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead;
// active BWP start
int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
// initial BWP start
int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275);
int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275);
// BWP start selection according to 8.3 of TS 38.213
pusch_config_pdu->bwp_size = ibwp_size;
if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
pusch_config_pdu->bwp_start = abwp_start;
else
pusch_config_pdu->bwp_start = ibwp_start;
//// Resource assignment from RAR
// Frequency domain allocation according to 8.3 of TS 38.213
if (ibwp_size < 180)
mask = (1 << ((int) ceil(log2((ibwp_size*(ibwp_size+1))>>1)))) - 1;
else
mask = (1 << (28 - (int)(ceil(log2((ibwp_size*(ibwp_size+1))>>1))))) - 1;
f_alloc = Msg3_f_alloc & mask;
nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, ibwp_size, 0, f_alloc);
// virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211)
pusch_config_pdu->rb_start += ibwp_start - abwp_start;
// Time domain allocation
SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
pusch_config_pdu->ul_dmrs_symb_pos = 1<<StartSymbolIndex;
pusch_config_pdu->start_symbol_index = StartSymbolIndex;
pusch_config_pdu->nr_of_symbols = NrOfSymbols;
#ifdef DEBUG_MSG3
printf("[DEBUG_MSG3] Freq assignment (RB start %d size %d) BWP (start %d, size %d), Time assignment (sliv_S %d sliv_L %d) \n",
pusch_config_pdu->rb_start,
pusch_config_pdu->rb_size,
pusch_config_pdu->bwp_start,
pusch_config_pdu->bwp_size,
StartSymbolIndex,
NrOfSymbols);
#endif
// MCS
pusch_config_pdu->mcs_index = mcs;
// Frequency hopping
pusch_config_pdu->frequency_hopping = freq_hopping;
// TC-RNTI
pusch_config_pdu->rnti = mac->t_crnti;
// DM-RS configuration according to 6.2.2 UE DM-RS transmission procedure in 38.214
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;
// Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_config_pdu->transform_precoding = 1;
else
pusch_config_pdu->transform_precoding = 0;
// Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214
pusch_config_pdu->resource_alloc = pusch_Config->resourceAllocation;
//// Completing PUSCH PDU
pusch_config_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_config_pdu->mcs_table = 0;
pusch_config_pdu->nrOfLayers = 1;
pusch_config_pdu->cyclic_prefix = 0;
pusch_config_pdu->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
pusch_config_pdu->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
pusch_config_pdu->data_scrambling_id = *scc->physCellId;
pusch_config_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
pusch_config_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
pusch_config_pdu->vrb_to_prb_mapping = 0;
pusch_config_pdu->uplink_frequency_shift_7p5khz = 0;
//Optional Data only included if indicated in pduBitmap
pusch_config_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213
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;
// 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)/8;
}
/////////////////////////////////////
// Random Access Response PDU //
// TS 38.213 ch 8.2 //
@@ -90,12 +220,13 @@ uint16_t table_7_2_1[16] = {
//| F_alloc |Time allocation|//
//| MCS | TPC |CSI|//
/////////////////////////////////////
// WIP todo:
// TbD WIP Msg3 development ongoing
// - apply UL grant freq alloc & time alloc as per 8.2 TS 38.213
// - apply tpc command, csi req, mcs
// - apply tpc command
uint16_t nr_ue_process_rar(module_id_t mod_id,
int CC_id,
frame_t frameP,
frame_t frame,
sub_frame_t slot,
uint8_t * dlsch_buffer,
rnti_t * t_crnti,
uint8_t preamble_index,
@@ -106,11 +237,7 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer
uint8_t n_subPDUs = 0; // number of RAR payloads
uint8_t n_subheaders = 0; // number of MAC RAR subheaders
//uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs
//unsigned char freq_hopping, msg3_t_alloc, mcs, tpc_command, csi_req; // WIP
//uint16_t ta_command = 0, msg3_f_alloc, bwp_size; // WIP
uint16_t ta_command = 0;
//int f_alloc, mask; // WIP
AssertFatal(CC_id == 0, "RAR reception on secondary CCs is not supported yet\n");
@@ -126,7 +253,7 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ue_mac->RA_backoff_indicator);
}
if (rarh->RAPID == preamble_index) {
LOG_D(PHY, "[UE %d][RAPROC] Found RAR with the intended RAPID %d\n", mod_id, rarh->RAPID);
LOG_I(PHY, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR));
ue_mac->RA_RAPID_found = 1;
break;
@@ -139,17 +266,19 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
}
};
LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", n_subheaders, n_subPDUs);
#ifdef DEBUG_RAR
LOG_D(MAC, "[DEBUG_RAR] (%d,%d) number of RAR subheader %d; number of RAR pyloads %d\n", frame, slot, n_subheaders, n_subPDUs);
LOG_D(MAC, "[DEBUG_RAR] Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
#endif
// LOG_I(MAC, "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
// mod_id, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
#if 0 // TbD WIP Msg3 development ongoing
if (ue_mac->RA_RAPID_found) {
uint8_t freq_hopping, mcs, Msg3_t_alloc, Msg3_f_alloc;
unsigned char tpc_command, csi_req;
// TC-RNTI
*t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
ue_mac->t_crnti = *t_crnti;
ue_mac->rnti_type = NR_RNTI_TC;
// TA command
ta_command = rar->TA2 + (rar->TA1 << 5);
// CSI
@@ -182,27 +311,36 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
ue_mac->Msg3_TPC = 8;
break;
}
//MCS
// MCS
mcs = (unsigned char) (rar->UL_GRANT_4 >> 4);
// time and frequency alloc
bwp_size = NRRIV2BW(ue_mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07);
msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12));
if (bwp_size < 180)
mask = (1 << ((int) ceil(log2((bwp_size*(bwp_size+1))>>1)))) - 1;
else
mask = (1 << (28 - (int)(ceil(log2((bwp_size*(bwp_size+1))>>1))))) - 1;
f_alloc = msg3_f_alloc & mask;
// frequency hopping flag
// time alloc
Msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07);
// frequency alloc
Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12));
// frequency hopping
freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2);
#ifdef DEBUG_RAR
LOG_D(MAC, "[DEBUG_RAR] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n",
Msg3_t_alloc,
Msg3_f_alloc,
ta_command,
mcs,
freq_hopping,
tpc_command,
csi_req,
ue_mac->t_crnti);
#endif
// Config Msg3 PDU
nr_config_Msg3_pdu(ue_mac, Msg3_f_alloc, Msg3_t_alloc, mcs, freq_hopping);
// Schedule Msg3
nr_ue_msg3_scheduler(ue_mac, frame, slot, Msg3_t_alloc);
} else {
ue_mac->t_crnti = 0;
ta_command = (0xffff);
}
#endif
// move the selected RAR to the front of the RA_PDSCH buffer
memcpy((void *) (selected_rar_buffer + 0), (void *) rarh, 1);
+30 -15
View File
@@ -46,6 +46,9 @@
#include "NR_MIB.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
/* Softmodem params */
#include "executables/softmodem-common.h"
extern RAN_CONTEXT_t RC;
//extern int l2_init_gNB(void);
extern void mac_top_init_gNB(void);
@@ -346,22 +349,34 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
if (secondaryCellGroup) {
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
int UE_id;
if (add_ue == 1) {
UE_id = add_new_nr_ue(Mod_idP,rnti);
UE_list->secondaryCellGroup[UE_id] = secondaryCellGroup;
uint8_t num_preamble = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.count;
UE_list->preambles[UE_id].num_preambles = num_preamble;
UE_list->preambles[UE_id].preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
for (int i=0; i<num_preamble; i++) {
UE_list->preambles[UE_id].preamble_list[i] = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex;
}
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
if (add_ue == 1 && get_softmodem_params()->phy_test) {
const int UE_id = add_new_nr_ue(Mod_idP,rnti);
UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
AssertFatal(bwpList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
bwpList->list.count);
const int bwp_id = 1;
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
}
else { // secondaryCellGroup has been updated
UE_id = find_nr_UE_id(Mod_idP,rnti);
UE_list->secondaryCellGroup[UE_id] = secondaryCellGroup;
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
/* TODO: should check for free RA process */
const int CC_id = 0;
NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0];
ra->state = RA_IDLE;
ra->secondaryCellGroup = secondaryCellGroup;
ra->crnti = rnti;
uint8_t num_preamble = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.count;
ra->preambles.num_preambles = num_preamble;
ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
for (int i = 0; i < num_preamble; i++)
ra->preambles.preamble_list[i] = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex;
LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti);
} else { // secondaryCellGroup has been updated
const int UE_id = find_nr_UE_id(Mod_idP,rnti);
UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
LOG_I(PHY,"Modified UE_id %d/%x with secondaryCellGroup\n",UE_id,rnti);
}
}
+75 -121
View File
@@ -63,19 +63,19 @@ const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
void clear_mac_stats(gNB_MAC_INST *gNB) {
memset((void*)gNB->UE_list.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
}
void dump_mac_stats(gNB_MAC_INST *gNB) {
NR_UE_list_t *UE_list = &gNB->UE_list;
NR_UE_info_t *UE_info = &gNB->UE_info;
NR_mac_stats_t *stats;
int lc_id;
for (int UE_id=0;UE_id<MAX_MOBILES_PER_GNB;UE_id++) {
if (UE_list->active[UE_id] == TRUE) {
LOG_I(MAC,"UE %x\n",UE_list->rnti[UE_id]);
stats = &UE_list->mac_stats[UE_id];
if (UE_info->active[UE_id]) {
LOG_I(MAC, "UE %x\n", UE_info->rnti[UE_id]);
stats = &UE_info->mac_stats[UE_id];
LOG_I(MAC,"dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",stats->dlsch_rounds[0],stats->dlsch_rounds[1],stats->dlsch_rounds[2],stats->dlsch_rounds[3],stats->dlsch_errors);
LOG_I(MAC,"dlsch_total_bytes %d\n",stats->dlsch_total_bytes);
LOG_I(MAC,"ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",stats->ulsch_rounds[0],stats->ulsch_rounds[1],stats->ulsch_rounds[2],stats->ulsch_rounds[3],stats->ulsch_errors);
@@ -130,18 +130,18 @@ void check_nr_ul_failure(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP) {
UE_list_t *UE_list = &RC.nrmac[module_idP]->UE_list;
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
nfapi_nr_dl_dci_request_t *DL_req = &RC.nrmac[module_idP]->DL_req[0];
uint16_t rnti = UE_RNTI(module_idP, UE_id);
NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels;
// check uplink failure
if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
(UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
(UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti,
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
if (UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
// add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
nfapi_nr_dl_dci_request_pdu_t *dl_config_pdu = &DL_req[CC_id].dl_tti_request_body.dl_config_pdu_list[DL_req[CC_id].dl_tti_request_body.number_pdu];
@@ -151,7 +151,7 @@ void check_nr_ul_failure(module_id_t module_idP,
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_DCI_REQUEST_DCI_DL_PDU_REL8_TAG;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id),
UE_list->UE_sched_ctrl[UE_id].
UE_info->UE_sched_ctrl[UE_id].
dl_cqi[CC_id], format1A);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
@@ -167,27 +167,27 @@ void check_nr_ul_failure(module_id_t module_idP,
LOG_I(MAC,
"UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",
UE_id, rnti,
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer,
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer,
dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.resource_block_coding);
} else { // ra_pdcch_sent==1
LOG_I(MAC,
"UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",
UE_id, rnti,
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames
}
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer++;
// check threshold
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
// inform RRC of failure and clear timer
LOG_I(MAC,
"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
UE_id, rnti);
mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti);
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1;
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync = 1;
//Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
if (rrc_agent_registered[module_idP]) {
@@ -204,7 +204,7 @@ void check_nr_ul_failure(module_id_t module_idP,
void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
UE_list_t *UE_list = &gNB->UE_list;
NR_UE_info_t *UE_info = &gNB->UE_info;
nfapi_ul_config_request_body_t *ul_req;
int CC_id, UE_id;
NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels;
@@ -238,16 +238,16 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
if ((1 << tmp) & deltaTSFC) {
// This is an SRS subframe, loop over UEs
for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) {
if (!RC.nrmac[module_idP]->UE_list.active[UE_id]) continue;
if (!RC.nrmac[module_idP]->UE_info.active[UE_id]) continue;
ul_req = &RC.nrmac[module_idP]->UL_req[CC_id].ul_config_request_body;
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue;
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
"physicalConfigDedicated is null for UE %d\n",
UE_id);
if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
get_srs_pos(&cc[CC_id],
soundingRS_UL_ConfigDedicated->choice.
@@ -262,7 +262,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu));
ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti;
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_info->UE_template[CC_id][UE_id].rnti;
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;;
@@ -275,7 +275,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
ul_req->number_of_pdus++;
} // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset)
} // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup)
} // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
} // if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
} // for (UE_id ...
} // if((1<<tmp) & deltaTSFC)
@@ -322,9 +322,9 @@ void nr_schedule_pusch(int Mod_idP,
sub_frame_t slotP) {
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
int k = slotP + ul_slots - num_slots_per_tdd;
NR_sched_pusch *pusch = &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k];
NR_sched_pusch *pusch = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k];
if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) {
UL_tti_req->SFN = pusch->frame;
UL_tti_req->Slot = pusch->slot;
@@ -332,7 +332,7 @@ void nr_schedule_pusch(int Mod_idP,
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu;
UL_tti_req->n_pdus+=1;
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k],
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
0, sizeof(NR_sched_pusch));
}
}
@@ -348,10 +348,10 @@ void nr_schedule_pucch(int Mod_idP,
uint16_t O_ack;
uint8_t SR_flag = 0; // no SR in PUCCH implemented for now
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id);
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
int bwp_id=1;
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
@@ -359,7 +359,7 @@ void nr_schedule_pucch(int Mod_idP,
NR_sched_pucch *curr_pucch;
for (int k=0; k<nr_ulmix_slots; k++) {
curr_pucch = &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k];
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k];
if ((curr_pucch->dai_c > 0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
UL_tti_req->SFN = curr_pucch->frame;
UL_tti_req->Slot = curr_pucch->ul_slot;
@@ -381,60 +381,48 @@ void nr_schedule_pucch(int Mod_idP,
O_ack,
SR_flag);
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k],
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k],
0,
sizeof(NR_sched_pucch));
}
}
}
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot){
if((bitmap>>slot)&0x01)
return true;
else
return false;
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
return (bitmap >> slot) & 0x01;
}
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
frame_t frame,
sub_frame_t slot){
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
int CC_id;
int UE_id;
uint64_t *dlsch_in_slot_bitmap=NULL;
uint64_t *ulsch_in_slot_bitmap=NULL;
int pucch_sched;
UE_id=0;
int bwp_id = 1;
const int UE_id = 0;
const int bwp_id = 1;
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_UE_list_t *UE_list = &gNB->UE_list;
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
NR_UE_info_t *UE_info = &gNB->UE_info;
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])>>(7-scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0)
nr_ulmix_slots++;
NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity);
const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
if (slot== 0 && (UE_list->UEcontext[UE_id].fiveG_connected || get_softmodem_params()->phy_test)) {
if (slot == 0 && UE_info->active[UE_id]) {
for (int k=0; k<nr_ulmix_slots; k++) {
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k],
/* Seems to be covered 384? */
/*memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k],
0,
sizeof(NR_sched_pucch));
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k],
sizeof(NR_sched_pucch));*/
/* Seems to be covered in line 335? */
/*memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
0,
sizeof(NR_sched_pusch));
sizeof(NR_sched_pusch));*/
}
}
@@ -442,9 +430,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
pdcp_run(&ctxt);
nr_rrc_rx_tx(); //&ctxt, CC_id);
/* send tick to RLC every ms */
/* send tick to RLC and RRC every ms */
if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
void nr_rlc_tick(int frame, int subframe);
@@ -452,57 +437,21 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
}
dlsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch
ulsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch
// hardcoding dlsch to be in slot 1
if (!(slot%num_slots_per_tdd)) {
if(slot==0) {
*dlsch_in_slot_bitmap = 0x02;
*ulsch_in_slot_bitmap = 0x100;
}
else {
*dlsch_in_slot_bitmap = 0x00;
*ulsch_in_slot_bitmap = 0x00;
}
}
const uint64_t dlsch_in_slot_bitmap = (1 << 1);
const uint64_t ulsch_in_slot_bitmap = (1 << 8);
memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
//mbsfn_status[CC_id] = 0;
// clear vrb_maps
memset(cc[CC_id].vrb_map, 0, 100);
memset(cc[CC_id].vrb_map_UL, 0, 100);
memset(cc[CC_id].vrb_map, 0, 275);
memset(cc[CC_id].vrb_map_UL, 0, 275);
clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot);
}
// refresh UE list based on UEs dropped by PHY in previous subframe
/*
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if (UE_list->active[i]) {
nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id];
rnti = 0;//UE_RNTI(module_idP, i);
CC_id = 0;//UE_PCCID(module_idP, i);
} //END if (UE_list->active[i])
} //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
*/
// This schedules MIB
if((slot == 0) && (frame & 7) == 0){
schedule_nr_mib(module_idP, frame, slot);
}
if (get_softmodem_params()->phy_test == 0)
nr_schedule_RA(module_idP, frame, slot);
else
UE_list->UEcontext[UE_id].fiveG_connected = true;
if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]);
@@ -527,10 +476,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
if (get_softmodem_params()->phy_test == 0) {
nr_schedule_RA(module_idP, frame, slot);
nr_schedule_reception_msg3(module_idP, 0, frame, slot);
} else
UE_list->UEcontext[UE_id].fiveG_connected = true;
if (UE_list->UEcontext[UE_id].fiveG_connected ) {
}
if (UE_info->active[UE_id]) {
// TbD once RACH is available, start ta_timer when UE is connected
if (ue_sched_ctl->ta_timer)
ue_sched_ctl->ta_timer--;
@@ -543,29 +492,34 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
// This schedules the DCI for Uplink and subsequently PUSCH
if (UE_list->UEcontext[UE_id].fiveG_connected) {
// The decision about whether to schedule is done for each UE independently
// inside
if (UE_info->active[UE_id] && slot < 10) {
int tda = 1; // time domain assignment hardcoded for now
schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda);
schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda, ulsch_in_slot_bitmap);
nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot);
}
if (UE_list->UEcontext[UE_id].fiveG_connected && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot%num_slots_per_tdd))) {
if (UE_info->active[UE_id]
&& (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd))
&& (!get_softmodem_params()->phy_test || slot == 1)
&& slot < 10) {
ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd;
nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched);
nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
//int pucch_sched;
//nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched);
//nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_info->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd);
ue_sched_ctl->ta_apply = false;
}
if (UE_list->UEcontext[UE_id].fiveG_connected )
if (UE_info->active[UE_id])
nr_schedule_pucch(module_idP, UE_id, nr_ulmix_slots, frame, slot);
/*
// Allocate CCEs for good after scheduling is done
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
allocate_CCEs(module_idP, CC_id, subframeP, 0);
*/
stop_meas(&RC.nrmac[module_idP]->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
+52 -32
View File
@@ -247,14 +247,11 @@ void nr_initiate_ra_proc(module_id_t module_idP,
uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL
NR_SearchSpace_t *ss;
int UE_id = 0;
// ra_rnti from 5.1.3 in 38.321
uint16_t ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8);
uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset;
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_UE_list_t *UE_list = &nr_mac->UE_list;
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_RA_t *ra = &cc->ra[0];
@@ -262,23 +259,23 @@ void nr_initiate_ra_proc(module_id_t module_idP,
// if the preamble received correspond to one of the listed
// the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries
int pr_found=0;
for (int i=0;i<UE_list->preambles[UE_id].num_preambles;i++) {
if (preamble_index == UE_list->preambles[UE_id].preamble_list[i]) {
for (int i = 0; i < ra->preambles.num_preambles; i++) {
if (preamble_index == ra->preambles.preamble_list[i]) {
pr_found=1;
break;
}
}
if (pr_found)
UE_list->UEcontext[UE_id].fiveG_connected = false;
else {
LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated for UE_id %d\n",
module_idP, preamble_index, UE_id);
if (!pr_found) {
LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
module_idP, preamble_index);
return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
}
// This should be handled differently when we use the initialBWP for RA
ra->bwp_id=1;
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
NR_BWP_Downlink_t *bwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
@@ -325,7 +322,6 @@ void nr_initiate_ra_proc(module_id_t module_idP,
ra->RA_rnti = ra_rnti;
ra->preamble_index = preamble_index;
UE_list->tc_rnti[UE_id] = ra->rnti;
LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x\n",
module_idP,
@@ -423,7 +419,6 @@ void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frame
ul_req->pdus_list[ul_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
ul_req->pdus_list[ul_req->n_pdus].pusch_pdu = ra->pusch_pdu;
ul_req->n_pdus+=1;
ra->state = RA_IDLE;
}
}
}
@@ -434,8 +429,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_RA_t *ra = &cc->ra[0];
NR_UE_list_t *UE_list = &mac->UE_list;
int UE_id = 0;
if (ra->state == RA_IDLE) {
LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
@@ -447,13 +440,12 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
nfapi_nr_pusch_pdu_t *pusch_pdu = &ra->pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n", UE_id);
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
AssertFatal(ra->secondaryCellGroup,
"no secondaryCellGroup for RNTI %04x\n",
ra->crnti);
AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Uplink_t *ubwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
LOG_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
frameP,
slotP,
@@ -542,17 +534,15 @@ void nr_generate_Msg2(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP){
int UE_id = 0, dci_formats[2], rnti_types[2], mcsIndex;
int dci_formats[2], rnti_types[2], mcsIndex;
int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0;
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[0];
NR_RA_t *ra = &cc->ra[0];
NR_UE_list_t *UE_list = &nr_mac->UE_list;
NR_SearchSpace_t *ss = ra->ra_ss;
uint16_t RA_rnti = ra->RA_rnti;
long locationAndBandwidth;
// uint8_t *vrb_map = cc[CC_id].vrb_map, CC_id;
// check if UE is doing RA on CORESET0 , InitialBWP or configured BWP from SCD
// get the BW of the PDCCH for PDCCH size and RAR PDSCH size
@@ -597,11 +587,13 @@ void nr_generate_Msg2(module_id_t module_idP,
// This code from this point on will not work on initialBWP or CORESET0
AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n");
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
AssertFatal(ra->secondaryCellGroup,
"no secondaryCellGroup for RNTI %04x\n",
ra->crnti);
AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
@@ -681,7 +673,30 @@ void nr_generate_Msg2(module_id_t module_idP,
dci_pdu_rel15[0].mcs,
dci_pdu_rel15[0].tb_scaling);
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, RA_rnti, 0, ss, scc, bwp);
uint8_t nr_of_candidates, aggregation_level;
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 0 /* common */);
int CCEIndex = allocate_nr_CCEs(
nr_mac,
bwp,
coreset,
aggregation_level,
0, /* n_RNTI 0: common search space */
0); // m
if (CCEIndex < 0) {
LOG_E(MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
return;
}
nr_configure_pdcch(nr_mac,
pdcch_pdu_rel15,
RA_rnti,
ss,
coreset,
scc,
bwp,
aggregation_level,
CCEIndex);
LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x\n", frameP, slotP, RA_rnti);
@@ -696,7 +711,7 @@ void nr_generate_Msg2(module_id_t module_idP,
pdcch_pdu_rel15->StartSymbolIndex,
pdcch_pdu_rel15->DurationSymbols);
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id);
fill_dci_pdu_rel15(scc,ra->secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id);
dl_req->nPDUs+=2;
@@ -719,6 +734,11 @@ void nr_generate_Msg2(module_id_t module_idP,
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].Slot = slotP;
memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length);
/* mark the corresponding RBs as used */
uint8_t *vrb_map = cc[CC_id].vrb_map;
for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++)
vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
}
}
@@ -82,7 +82,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
if (mib_sdu_length > 0) {
LOG_I(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->nPDUs, mib_sdu_length);
LOG_D(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->nPDUs, mib_sdu_length);
if ((frameP & 1023) < 80){
LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length);
@@ -137,6 +137,11 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
dl_req->nPDUs++;
uint8_t *vrb_map = cc[CC_id].vrb_map;
const int rbStart = dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA;
for (int rb = 0; rb < 20; rb++)
vrb_map[rbStart + rb] = 1;
}
}
}
+410 -12
View File
@@ -32,6 +32,7 @@
/*PHY*/
#include "PHY/CODING/coding_defs.h"
#include "PHY/defs_nr_common.h"
#include "common/utils/nr/nr_common.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
/*MAC*/
#include "NR_MAC_COMMON/nr_mac.h"
@@ -45,6 +46,9 @@
/*TAG*/
#include "NR_TAG-Id.h"
/*Softmodem params*/
#include "executables/softmodem-common.h"
////////////////////////////////////////////////////////
/////* DLSCH MAC PDU generation (6.1.2 TS 38.321) */////
////////////////////////////////////////////////////////
@@ -54,6 +58,7 @@
//#define SIZE_OF_POINTER sizeof (void *)
int nr_generate_dlsch_pdu(module_id_t module_idP,
NR_UE_sched_ctrl_t *ue_sched_ctl,
unsigned char *sdus_payload,
unsigned char *mac_pdu,
unsigned char num_sdus,
@@ -70,14 +75,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
// MAC CEs
uint8_t mac_header_control_elements[16], *ce_ptr;
ce_ptr = &mac_header_control_elements[0];
uint16_t UE_id = 0; //TODO need to get as a function parameter or need to invoke api to UE_id using module Id and RNTI
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
NR_UE_list_t *UE_list = &gNB_mac->UE_list;
NR_UE_sched_ctrl_t *ue_sched_ctl = NULL;
//NR_CellGroupConfig_t *config = UE_list->secondaryCellGroup[UE_id];
ue_sched_ctl = &(UE_list->UE_sched_ctrl[UE_id]);
NR_mac_stats_t *mac_stats = &(UE_list->mac_stats[UE_id]);
// 1) Compute MAC CE and related subheaders
@@ -329,8 +326,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]);
dlsch_buffer_ptr += sdu_lengths[i];
mac_pdu_ptr += sdu_lengths[i];
mac_stats->lc_bytes_tx[sdu_lcids[i]] += sdu_lengths[i];
}
// 4) Compute final offset for padding
@@ -412,6 +407,409 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_
UL_info->uci_ind.num_ucis = 0;
}
/* functionalities of this function have been moved to nr_schedule_uss_dlsch_phytest */
void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) {
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
AssertFatal(tda < tdaList->list.count,
"time_domain_allocation %d>=%d\n",
tda,
tdaList->list.count);
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
int startSymbolIndex, nrOfSymbols;
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
return nrOfSymbols;
}
nfapi_nr_dmrs_type_e getDmrsConfigType(NR_BWP_Downlink_t *bwp) {
return bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
}
uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData) {
const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(bwp);
if (dmrsConfigType == NFAPI_NR_DMRS_TYPE1) {
// if no data in dmrs cdm group is 1 only even REs have no data
// if no data in dmrs cdm group is 2 both odd and even REs have no data
return numDmrsCdmGrpsNoData * 6;
} else {
return numDmrsCdmGrpsNoData * 4;
}
}
void nr_simple_dlsch_preprocessor(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd) {
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
AssertFatal(UE_info->num_UEs <= 1,
"%s() cannot handle more than one UE, but found %d\n",
__func__,
UE_info->num_UEs);
if (UE_info->num_UEs == 0)
return;
const int UE_id = 0;
const int CC_id = 0;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
sched_ctrl->rbSize = 0;
/* Retrieve amount of data to send for this UE */
sched_ctrl->num_total_bytes = 0;
const int lcid = DL_SCH_LCID_DTCH;
const uint16_t rnti = UE_info->rnti[UE_id];
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
rnti,
module_id,
frame,
slot,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
0,
0);
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
if (sched_ctrl->num_total_bytes == 0 && !get_softmodem_params()->phy_test)
return;
LOG_D(MAC,
"%d.%d, DTCH%d->DLSCH, RLC status %d bytes\n",
frame,
slot,
lcid,
sched_ctrl->rlc_status[lcid].bytes_in_buffer);
/* Find a free CCE */
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
uint8_t nr_of_candidates;
find_aggregation_candidates(&sched_ctrl->aggregation_level,
&nr_of_candidates,
sched_ctrl->search_space);
sched_ctrl->coreset = get_coreset(
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
sched_ctrl->active_bwp,
sched_ctrl->coreset,
sched_ctrl->aggregation_level,
UE_info->rnti[UE_id],
0); // m
if (sched_ctrl->cce_index < 0) {
LOG_E(MAC, "%s(): could not find CCE for UE %d\n", __func__, UE_id);
return;
}
/* Find PUCCH occasion */
nr_update_pucch_scheduling(
module_id, UE_id, frame, slot, num_slots_per_tdd, &sched_ctrl->pucch_sched_idx);
AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n");
uint8_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
const int current_harq_pid = sched_ctrl->current_harq_pid;
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
if (harq->round != 0) { /* retransmission */
sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation;
/* ensure that there is a free place for RB allocation */
int rbSize = 0;
while (rbSize < retInfo->rbSize) {
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
rbSize = 0;
while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++;
if (rbStart >= bwpSize) {
LOG_E(MAC,
"cannot allocate retransmission for UE %d/RNTI %04x: no resources\n",
UE_id,
rnti);
return;
}
while (rbStart + rbSize < bwpSize
&& !vrb_map[rbStart + rbSize]
&& rbSize < retInfo->rbSize)
rbSize++;
}
sched_ctrl->rbSize = retInfo->rbSize;
sched_ctrl->rbStart = rbStart;
/* MCS etc: just reuse from previous scheduling opportunity */
sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx;
sched_ctrl->mcs = retInfo->mcs;
sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData;
} else {
// Time-domain allocation
sched_ctrl->time_domain_allocation = 2;
// modulation scheme
sched_ctrl->mcsTableIdx = 0;
sched_ctrl->mcs = 9;
sched_ctrl->numDmrsCdmGrpsNoData = 1;
// Freq-demain allocation
while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++;
uint8_t N_PRB_DMRS =
getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp,
sched_ctrl->time_domain_allocation);
int rbSize = 0;
uint32_t TBS = 0;
do {
rbSize++;
TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
rbSize,
nrOfSymbols,
N_PRB_DMRS, // FIXME // This should be multiplied by the
// number of dmrs symbols
0 /* N_PRB_oh, 0 for initialBWP */,
0 /* tb_scaling */,
1 /* nrOfLayers */)
>> 3;
} while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes);
sched_ctrl->rbSize = rbSize;
sched_ctrl->rbStart = rbStart;
}
/* mark the corresponding RBs as used */
for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
vrb_map[rb + sched_ctrl->rbStart] = 1;
}
void nr_schedule_ue_spec(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd) {
/* PREPROCESSOR */
nr_simple_dlsch_preprocessor(module_id, frame, slot, num_slots_per_tdd);
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
const int CC_id = 0;
NR_UE_list_t *UE_list = &UE_info->list;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
if (sched_ctrl->rbSize <= 0 && !get_softmodem_params()->phy_test)
continue;
const rnti_t rnti = UE_info->rnti[UE_id];
/* POST processing */
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
AssertFatal(sched_ctrl->time_domain_allocation < tdaList->list.count,
"time_domain_allocation %d>=%d\n",
sched_ctrl->time_domain_allocation,
tdaList->list.count);
const int startSymbolAndLength =
tdaList->list.array[sched_ctrl->time_domain_allocation]->startSymbolAndLength;
int startSymbolIndex, nrOfSymbols;
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
uint8_t N_PRB_DMRS =
getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
const uint32_t TBS =
nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
sched_ctrl->rbSize,
nrOfSymbols,
N_PRB_DMRS, // FIXME // This should be multiplied by the
// number of dmrs symbols
0 /* N_PRB_oh, 0 for initialBWP */,
0 /* tb_scaling */,
1 /* nrOfLayers */)
>> 3;
const int current_harq_pid = sched_ctrl->current_harq_pid;
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx];
harq->feedback_slot = pucch->ul_slot;
harq->is_waiting = 1;
UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
nr_fill_nfapi_dl_pdu(module_id,
UE_id,
sched_ctrl->active_bwp->bwp_Id,
sched_ctrl->search_space,
sched_ctrl->coreset,
dl_req,
pucch,
1 /* nrOfLayers */,
sched_ctrl->mcs,
sched_ctrl->rbSize,
sched_ctrl->rbStart,
sched_ctrl->numDmrsCdmGrpsNoData,
getDmrsConfigType(sched_ctrl->active_bwp),
sched_ctrl->mcsTableIdx,
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
TBS,
sched_ctrl->time_domain_allocation,
startSymbolIndex,
nrOfSymbols,
sched_ctrl->aggregation_level,
sched_ctrl->cce_index,
current_harq_pid,
harq->ndi,
harq->round);
NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
if (harq->round != 0) { /* retransmission */
if (sched_ctrl->rbSize != retInfo->rbSize)
LOG_W(MAC,
"retransmission uses different rbSize (%d vs. orig %d)\n",
sched_ctrl->rbSize,
retInfo->rbSize);
if (sched_ctrl->time_domain_allocation != retInfo->time_domain_allocation)
LOG_W(MAC,
"retransmission uses different time_domain_allocation (%d vs. orig %d)\n",
sched_ctrl->time_domain_allocation,
retInfo->time_domain_allocation);
if (sched_ctrl->mcs != retInfo->mcs
|| sched_ctrl->mcsTableIdx != retInfo->mcsTableIdx
|| sched_ctrl->numDmrsCdmGrpsNoData != retInfo->numDmrsCdmGrpsNoData)
LOG_W(MAC,
"retransmission uses different table/MCS/numDmrsCdmGrpsNoData (%d/%d/%d vs. orig %d/%d/%d)\n",
sched_ctrl->mcsTableIdx,
sched_ctrl->mcs,
sched_ctrl->numDmrsCdmGrpsNoData,
retInfo->mcsTableIdx,
retInfo->mcs,
retInfo->numDmrsCdmGrpsNoData);
/* we do not have to do anything, since we do not require to get data
* from RLC, encode MAC CEs, or copy data to FAPI structures */
LOG_W(MAC, "%d.%2d retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
} else { /* initial transmission */
/* reserve space for timing advance of UE if necessary,
* nr_generate_dlsch_pdu() checks for ta_apply and add TA CE if necessary */
const int ta_len = (sched_ctrl->ta_apply) ? 2 : 0;
/* Get RLC data TODO: remove random data retrieval */
int header_length_total = 0;
int header_length_last = 0;
int sdu_length_total = 0;
int num_sdus = 0;
uint16_t sdu_lengths[NB_RB_MAX] = {0};
uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES];
unsigned char sdu_lcids[NB_RB_MAX] = {0};
const int lcid = DL_SCH_LCID_DTCH;
if (sched_ctrl->num_total_bytes > 0) {
LOG_D(MAC,
"[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting "
"%d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n",
module_id,
frame,
TBS - ta_len - header_length_total - sdu_length_total - 3,
lcid,
header_length_total,
TBS);
sdu_lengths[num_sdus] = mac_rlc_data_req(module_id,
rnti,
module_id,
frame,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
TBS - ta_len - header_length_total - sdu_length_total - 3,
(char *)&mac_sdus[sdu_length_total],
0,
0);
LOG_D(MAC,
"[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
module_id,
sdu_lengths[num_sdus],
lcid);
sdu_lcids[num_sdus] = lcid;
sdu_length_total += sdu_lengths[num_sdus];
header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
header_length_total += header_length_last;
num_sdus++;
//ue_sched_ctl->uplane_inactivity_timer = 0;
}
else if (get_softmodem_params()->phy_test) {
LOG_D(MAC, "Configuring DL_TX in %d.%d: random data\n", frame, slot);
// fill dlsch_buffer with random data
for (int i = 0; i < TBS; i++)
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
sdu_lcids[0] = 0x3f; // DRB
sdu_lengths[0] = TBS - ta_len - 3;
header_length_total += 2 + (sdu_lengths[0] >= 128);
sdu_length_total += sdu_lengths[0];
num_sdus +=1;
}
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total;
// Check if there is data from RLC or CE
const int post_padding = TBS >= 2 + header_length_total + sdu_length_total + ta_len;
// padding param currently not in use
//padding = TBS - header_length_total - sdu_length_total - ta_len - 1;
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
/* pointer to directly generate the PDU into the nFAPI structure */
uint32_t *buf = tx_req->TLVs[0].value.direct;
const int offset = nr_generate_dlsch_pdu(
module_id,
sched_ctrl,
(unsigned char *)mac_sdus,
(unsigned char *)buf,
num_sdus, // num_sdus
sdu_lengths,
sdu_lcids,
255, // no drx
NULL, // contention res id
post_padding);
// Padding: fill remainder of DLSCH with 0
if (post_padding > 0) {
for (int j = 0; j < TBS - offset; j++)
buf[offset + j] = 0;
}
/* the buffer has been filled by nr_generate_dlsch_pdu(), below we simply
* fill the remaining information */
tx_req->PDU_length = TBS;
tx_req->PDU_index = gNB_mac->pdu_index[0]++;
tx_req->num_TLV = 1;
tx_req->TLVs[0].length = TBS + 2;
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
gNB_mac->TX_req[CC_id].SFN = frame;
gNB_mac->TX_req[CC_id].Slot = slot;
retInfo->rbSize = sched_ctrl->rbSize;
retInfo->time_domain_allocation = sched_ctrl->time_domain_allocation;
retInfo->mcsTableIdx = sched_ctrl->mcsTableIdx;
retInfo->mcs = sched_ctrl->mcs;
retInfo->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData;
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
if (frame%100 == 0) {
LOG_I(MAC,
"%d.%d, first 10 payload bytes, TBS size: %d \n",
frame,
slot,
TBS);
for(int i = 0; i < 10; i++)
LOG_I(MAC, "byte %d: %x\n", i, ((uint8_t *) buf)[i]);
}
#endif
}
}
}
@@ -252,14 +252,12 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
}
}
int configure_fapi_dl_pdu(int Mod_idP,
nfapi_nr_dl_tti_request_body_t *dl_req,
NR_sched_pucch *pucch_sched,
uint8_t *mcsIndex,
uint16_t *rbSize,
uint16_t *rbStart) {
int configure_fapi_dl_pdu_phytest(int Mod_idP,
nfapi_nr_dl_tti_request_body_t *dl_req,
NR_sched_pucch *pucch_sched,
uint8_t *mcsIndex,
uint16_t *rbSize,
uint16_t *rbStart) {
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -271,9 +269,9 @@ int configure_fapi_dl_pdu(int Mod_idP,
int bwp_id=1;
int UE_id = 0;
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
@@ -298,7 +296,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
pdsch_pdu_rel15->pduBitmap = 0;
pdsch_pdu_rel15->rnti = UE_list->rnti[UE_id];
pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id];
pdsch_pdu_rel15->pduIndex = 0;
// BWP
@@ -310,17 +308,17 @@ int configure_fapi_dl_pdu(int Mod_idP,
pdsch_pdu_rel15->NrOfCodewords = 1;
int mcs = (mcsIndex!=NULL) ? *mcsIndex : 9;
int current_harq_pid = UE_list->UE_sched_ctrl[UE_id].current_harq_pid;
int current_harq_pid = UE_info->UE_sched_ctrl[UE_id].current_harq_pid;
pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0);
pdsch_pdu_rel15->qamModOrder[0] = 2;
pdsch_pdu_rel15->mcsIndex[0] = mcs;
pdsch_pdu_rel15->mcsTable[0] = 0;
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round];
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round];
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
pdsch_pdu_rel15->nrOfLayers = 1;
pdsch_pdu_rel15->transmissionScheme = 0;
pdsch_pdu_rel15->refPoint = 0; // Point A
UE_list->mac_stats[UE_id].dlsch_rounds[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++;
UE_info->mac_stats[UE_id].dlsch_rounds[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++;
pdsch_pdu_rel15->dmrsConfigType = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
pdsch_pdu_rel15->SCID = 0;
@@ -368,18 +366,18 @@ int configure_fapi_dl_pdu(int Mod_idP,
dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0];
// harq pid and ndi
dci_pdu_rel15[0].harq_pid = current_harq_pid;
dci_pdu_rel15[0].ndi = UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi;
dci_pdu_rel15[0].ndi = UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi;
// DAI
dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3;
// TPC for PUCCH
dci_pdu_rel15[0].tpc = UE_list->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213
dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213
// PUCCH resource indicator
dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator;
// PDSCH to HARQ TI
dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator;
UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].feedback_slot = pucch_sched->ul_slot;
UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1;
UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].feedback_slot = pucch_sched->ul_slot;
UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1;
// antenna ports
dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0
// dmrs sequence initialization
@@ -416,18 +414,30 @@ int configure_fapi_dl_pdu(int Mod_idP,
}
AssertFatal(found==1,"Couldn't find an adequate searchspace\n");
int ret = nr_configure_pdcch(nr_mac,
pdcch_pdu_rel15,
UE_list->rnti[UE_id],
1, // ue-specific
ss,
scc,
bwp);
if (ret < 0) {
LOG_I(MAC,"CCE list not empty, couldn't schedule PDSCH\n");
free(dci_pdu_rel15);
return (0);
uint8_t nr_of_candidates, aggregation_level;
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */);
int CCEIndex = allocate_nr_CCEs(
nr_mac,
bwp,
coreset,
aggregation_level,
UE_info->rnti[UE_id],
0); // m
if (CCEIndex < 0) {
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PDSCH\n", __func__);
free(dci_pdu_rel15);
return 0;
}
nr_configure_pdcch(nr_mac,
pdcch_pdu_rel15,
UE_info->rnti[UE_id],
ss,
coreset,
scc,
bwp,
aggregation_level,
CCEIndex);
int dci_formats[2];
int rnti_types[2];
@@ -455,8 +465,8 @@ int configure_fapi_dl_pdu(int Mod_idP,
// Hardcode it for now
TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0];
if (UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0)
UE_list->mac_stats[UE_id].dlsch_total_bytes += TBS;
if (UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0)
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d startSymbolAndLength %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n",
pdsch_pdu_rel15->rbStart,
@@ -581,7 +591,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP,
tx_req->num_TLV = 1;
tx_req->TLVs[0].length = tbs_bytes +2;
memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_list.DLSCH_pdu[0][0].payload[0], tbs_bytes);
memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_info.DLSCH_pdu[0][0].payload[0], tbs_bytes);
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].SFN = frameP;
@@ -608,14 +618,14 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
mac_rlc_status_resp_t rlc_status;
NR_UE_list_t *UE_list = &gNB_mac->UE_list;
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
if (UE_list->num_UEs ==0) return;
if (UE_info->num_UEs ==0) return;
unsigned char sdu_lcids[NB_RB_MAX] = {0};
uint16_t sdu_lengths[NB_RB_MAX] = {0};
uint16_t rnti = UE_list->rnti[UE_id];
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
uint16_t rnti = UE_info->rnti[UE_id];
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES];
@@ -623,12 +633,13 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
int ta_len = (ue_sched_ctl->ta_apply)?2:0;
TBS_bytes = configure_fapi_dl_pdu(module_idP,
dl_req,
pucch_sched,
dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL,
dlsch_config!=NULL ? &dlsch_config->rbSize : NULL,
dlsch_config!=NULL ? &dlsch_config->rbStart : NULL);
TBS_bytes = configure_fapi_dl_pdu_phytest(
module_idP,
dl_req,
pucch_sched,
dlsch_config != NULL ? dlsch_config->mcsIndex : NULL,
dlsch_config != NULL ? &dlsch_config->rbSize : NULL,
dlsch_config != NULL ? &dlsch_config->rbStart : NULL);
if (TBS_bytes == 0)
return;
@@ -693,7 +704,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
// fill dlsch_buffer with random data
for (i = 0; i < TBS_bytes; i++){
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
//((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff);
//((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff);
}
//Sending SDUs with size 1
//Initialize elements of sdu_lcids and sdu_lengths
@@ -707,13 +718,15 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
if (frameP%100 == 0){
LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes);
for(int i = 0; i < 10; i++) {
LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]);
LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[CC_id][0][0].payload[0])[i]);
}
}
#endif
}
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total;
// there is at least one SDU or TA command
// if (num_sdus > 0 ){
if (ta_len + sdu_length_total + header_length_total > 0) {
@@ -730,8 +743,9 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
}
offset = nr_generate_dlsch_pdu(module_idP,
&UE_info->UE_sched_ctrl[UE_id],
(unsigned char *) mac_sdus,
(unsigned char *) gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0],
(unsigned char *) gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0],
num_sdus, //num_sdus
sdu_lengths,
sdu_lcids,
@@ -742,7 +756,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
// Padding: fill remainder of DLSCH with 0
if (post_padding > 0){
for (int j = 0; j < (TBS_bytes - offset); j++)
gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0][offset + j] = 0; // mac_pdu[offset + j] = 0;
gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0][offset + j] = 0; // mac_pdu[offset + j] = 0;
}
configure_fapi_dl_Tx(module_idP, frameP, slotP, dl_req, tx_req, TBS_bytes, gNB_mac->pdu_index[CC_id]);
@@ -759,7 +773,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
if (frameP%100 == 0){
LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes);
for(int i = 0; i < 10; i++) {
LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]);
LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]);
}
}
#endif
@@ -800,12 +814,26 @@ int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) {
return -1;
}
long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
DevAssert(ubwp);
const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
if (tda_list->k2)
return *tda_list->k2;
else if (mu < 2)
return 1;
else if (mu == 2)
return 2;
else
return 3;
}
void schedule_fapi_ul_pdu(int Mod_idP,
frame_t frameP,
sub_frame_t slotP,
int num_slots_per_tdd,
int ul_slots,
int time_domain_assignment) {
int time_domain_assignment,
uint64_t ulsch_in_slot_bitmap) {
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
@@ -814,10 +842,10 @@ void schedule_fapi_ul_pdu(int Mod_idP,
int bwp_id=1;
int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
int UE_id = 0;
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id);
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
@@ -829,18 +857,14 @@ void schedule_fapi_ul_pdu(int Mod_idP,
AssertFatal(time_domain_assignment<ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count,
"time_domain_assignment %d>=%d\n",time_domain_assignment,ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count);
int K2;
if (ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2 != NULL)
K2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2;
else {
if (mu<2) K2=1;
else if(mu==2) K2=2;
else K2=3;
}
if (is_xlsch_in_slot(UE_list->UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap,(slotP+K2)%num_slots_per_tdd)) {
//nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
int K2 = get_K2(ubwp, time_domain_assignment,mu);
/* check if slot is UL, and for phy test verify that it is in first TDD
* period, slot 8 (for K2=2, this is at slot 6 in the gNB; because of UE
* limitations). Note that if K2 or the TDD configuration is changed, below
* conditions might exclude each other and never be true */
const int slot_idx = (slotP + K2) % num_slots_per_tdd;
if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot_idx)
&& (!get_softmodem_params()->phy_test || slot_idx == 8)) {
nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0];
UL_dci_req->SFN = frameP;
UL_dci_req->Slot = slotP;
@@ -850,10 +874,10 @@ void schedule_fapi_ul_pdu(int Mod_idP,
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
uint16_t rnti = UE_list->rnti[UE_id];
uint16_t rnti = UE_info->rnti[UE_id];
int first_ul_slot = num_slots_per_tdd - ul_slots;
NR_sched_pusch *pusch_sched = &UE_list->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot];
NR_sched_pusch *pusch_sched = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot];
pusch_sched->frame = frameP;
pusch_sched->slot = slotP + K2;
pusch_sched->active = true;
@@ -952,7 +976,7 @@ void schedule_fapi_ul_pdu(int Mod_idP,
if (get_softmodem_params()->phy_test==1)
pusch_pdu->rb_size = 50;
else
pusch_pdu->rb_size = 5;
pusch_pdu->rb_size = pusch_pdu->bwp_size;
}
else
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
@@ -1045,9 +1069,9 @@ void schedule_fapi_ul_pdu(int Mod_idP,
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
//Optional Data only included if indicated in pduBitmap
int8_t harq_id = select_ul_harq_pid(&UE_list->UE_sched_ctrl[UE_id]);
int8_t harq_id = select_ul_harq_pid(&UE_info->UE_sched_ctrl[UE_id]);
if (harq_id < 0) return;
NR_UE_ul_harq_t *cur_harq = &UE_list->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id];
NR_UE_ul_harq_t *cur_harq = &UE_info->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id];
pusch_pdu->pusch_data.harq_process_id = harq_id;
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
@@ -1077,8 +1101,8 @@ void schedule_fapi_ul_pdu(int Mod_idP,
0,
pusch_pdu->nrOfLayers)>>3;
UE_list->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
if (cur_harq->round == 0) UE_list->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size;
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
if (cur_harq->round == 0) UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size;
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
//pusch_pdu->pusch_data.cb_present_and_position;
@@ -1099,22 +1123,34 @@ void schedule_fapi_ul_pdu(int Mod_idP,
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP);
int ret = nr_configure_pdcch(nr_mac,
pdcch_pdu_rel15,
UE_list->rnti[UE_id],
1, // ue-specific,
ss,
scc,
bwp);
if (ret < 0) {
LOG_I(MAC,"CCE list not empty, couldn't schedule PUSCH\n");
uint8_t nr_of_candidates, aggregation_level;
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */);
int CCEIndex = allocate_nr_CCEs(
nr_mac,
bwp,
coreset,
aggregation_level,
UE_info->rnti[UE_id],
0); // m
if (CCEIndex < 0) {
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
pusch_sched->active = false;
return;
}
else {
nr_configure_pdcch(nr_mac,
pdcch_pdu_rel15,
UE_info->rnti[UE_id],
ss,
coreset,
scc,
bwp,
aggregation_level,
CCEIndex);
dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t));
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_list->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id);
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_info->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id);
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id);
free(dci_pdu_rel15);
}
@@ -63,7 +63,6 @@
#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_gNB_SCHEDULER 1
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
@@ -127,37 +126,60 @@ static inline uint8_t get_max_cces(uint8_t scs) {
return (nr_max_number_of_cces_per_slot[scs]);
}
NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp,
NR_SearchSpace_t *ss,
int ss_type) {
NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId;
if (ss_type == 0) { // common search space
AssertFatal(coreset_id != 0, "coreset0 currently not supported\n");
NR_ControlResourceSet_t *coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
AssertFatal(coreset_id == coreset->controlResourceSetId,
"ID of common ss coreset does not correspond to id set in the "
"search space\n");
return coreset;
} else {
const int n = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count;
for (int i = 0; i < n; i++) {
NR_ControlResourceSet_t *coreset =
bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i];
if (coreset_id == coreset->controlResourceSetId) {
return coreset;
}
}
AssertFatal(0, "Couldn't find coreset with id %ld\n", coreset_id);
}
}
NR_SearchSpace_t *get_searchspace(
NR_BWP_Downlink_t *bwp,
NR_SearchSpace__searchSpaceType_PR target_ss) {
DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList);
DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count > 0);
const int n = bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;
for (int i=0;i<n;i++) {
NR_SearchSpace_t *ss = bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n");
if (ss->searchSpaceType->present == target_ss) {
return ss;
}
}
AssertFatal(0, "Couldn't find an adequate searchspace\n");
}
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int bwp_id,
int list_id,
int aggregation,
int search_space, // 0 common, 1 ue-specific
int UE_id,
int m) {
NR_BWP_Downlink_t *bwp,
NR_ControlResourceSet_t *coreset,
int aggregation,
uint16_t n_RNTI,
int m) {
// uncomment these when we allocate for common search space
// NR_COMMON_channels_t *cc = nr_mac->common_channels;
// NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_UE_list_t *UE_list = &nr_mac->UE_list;
NR_BWP_Downlink_t *bwp;
NR_CellGroupConfig_t *secondaryCellGroup;
NR_ControlResourceSet_t *coreset;
AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id);
secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
if (search_space == 1) {
coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[list_id];
}
else {
coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
}
int coreset_id = coreset->controlResourceSetId;
int *cce_list = nr_mac->cce_list[bwp_id][coreset_id];
int *cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id];
int n_rb=0;
for (int i=0;i<6;i++)
@@ -167,17 +189,14 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
n_rb*=6;
uint16_t N_reg = n_rb * coreset->duration;
uint16_t Y=0, N_cce, M_s_max, n_CI=0;
uint16_t n_RNTI = search_space == 1 ? UE_list->rnti[UE_id]:0;
uint32_t A[3]={39827,39829,39839};
uint16_t n_CI=0;
const uint32_t A[3]={39827,39829,39839};
/* if n_RNTI is zero, this results in zero, too! */
uint16_t Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0
N_cce = N_reg / NR_NB_REG_PER_CCE;
uint16_t N_cce = N_reg / NR_NB_REG_PER_CCE;
M_s_max = (aggregation==4)?4:(aggregation==8)?2:1;
if (search_space == 1) {
Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0
}
uint16_t M_s_max = (aggregation==4)?4:(aggregation==8)?2:1;
int first_cce = aggregation * (( Y + (m*N_cce)/(aggregation*M_s_max) + n_CI ) % CEILIDIV(N_cce,aggregation));
for (int i=0;i<aggregation;i++)
@@ -407,44 +426,229 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
}
int nr_configure_pdcch(gNB_MAC_INST *nr_mac,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
uint16_t rnti,
int ss_type,
NR_SearchSpace_t *ss,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp){
void nr_fill_nfapi_dl_pdu(int Mod_idP,
int UE_id,
int bwp_id,
NR_SearchSpace_t *ss,
NR_ControlResourceSet_t *coreset,
nfapi_nr_dl_tti_request_body_t *dl_req,
NR_sched_pucch *pucch_sched,
int nrOfLayers,
uint8_t mcs,
uint16_t rbSize,
uint16_t rbStart,
uint8_t numDmrsCdmGrpsNoData,
nfapi_nr_dmrs_type_e dmrsConfigType,
uint8_t table_idx,
uint16_t R,
uint8_t Qm,
uint32_t TBS,
int time_domain_assignment,
int StartSymbolIndex,
int NrOfSymbols,
uint8_t aggregation_level,
int CCEIndex,
int harq_pid,
int ndi,
int round) {
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
int CCEIndex = -1;
int cid = 0;
NR_ControlResourceSet_t *coreset = NULL;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
pdsch_pdu_rel15->pduBitmap = 0;
pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id];
pdsch_pdu_rel15->pduIndex = nr_mac->pdu_index[0]++;
// BWP
pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
if (bwp->bwp_Common->genericParameters.cyclicPrefix)
pdsch_pdu_rel15->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix;
else
pdsch_pdu_rel15->CyclicPrefix = 0;
pdsch_pdu_rel15->NrOfCodewords = 1;
pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0);
pdsch_pdu_rel15->qamModOrder[0] = 2;
pdsch_pdu_rel15->mcsIndex[0] = mcs;
pdsch_pdu_rel15->mcsTable[0] = 0;
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[round];
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
pdsch_pdu_rel15->nrOfLayers = nrOfLayers;
pdsch_pdu_rel15->transmissionScheme = 0;
pdsch_pdu_rel15->refPoint = 0; // Point A
pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType;
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
pdsch_pdu_rel15->SCID = 0;
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = numDmrsCdmGrpsNoData;
pdsch_pdu_rel15->dmrsPorts = 1;
pdsch_pdu_rel15->resourceAlloc = 1;
pdsch_pdu_rel15->rbStart = rbStart;
pdsch_pdu_rel15->rbSize = rbSize;
pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
pdsch_pdu_rel15->targetCodeRate[0] = R;
pdsch_pdu_rel15->qamModOrder[0] = Qm;
pdsch_pdu_rel15->TBSize[0] = TBS;
pdsch_pdu_rel15->mcsTable[0] = table_idx;
pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
// k0 = *bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0;
pdsch_pdu_rel15->dlDmrsSymbPos =
fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup,
scc->dmrs_TypeA_Position,
pdsch_pdu_rel15->NrOfSymbols);
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
memset(dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t) * MAX_DCI_CORESET);
// bwp indicator
int n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
if (n_dl_bwp < 4)
dci_pdu_rel15[0].bwp_indicator.val = bwp_id;
else
dci_pdu_rel15[0].bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212
// frequency domain assignment
if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation==NR_PDSCH_Config__resourceAllocation_resourceAllocationType1)
dci_pdu_rel15[0].frequency_domain_assignment.val =
PRBalloc_to_locationandbandwidth0(
pdsch_pdu_rel15->rbSize,
pdsch_pdu_rel15->rbStart,
NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,
275));
else
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
// time domain assignment
dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV;
// mcs and rv
dci_pdu_rel15[0].mcs = mcs;
dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0];
// harq pid and ndi
dci_pdu_rel15[0].harq_pid = harq_pid;
dci_pdu_rel15[0].ndi = ndi;
// DAI
dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3;
// TPC for PUCCH
dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213
// PUCCH resource indicator
dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator;
// PDSCH to HARQ TI
dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator;
// antenna ports
dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0
// dmrs sequence initialization
dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID;
LOG_D(MAC,
"[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), "
"time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n",
dci_pdu_rel15[0].frequency_domain_assignment.val,
pdsch_pdu_rel15->rbStart,
pdsch_pdu_rel15->rbSize,
NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, 275),
dci_pdu_rel15[0].time_domain_assignment.val,
dci_pdu_rel15[0].vrb_to_prb_mapping.val,
dci_pdu_rel15[0].mcs,
dci_pdu_rel15[0].tb_scaling,
dci_pdu_rel15[0].ndi,
dci_pdu_rel15[0].rv);
nr_configure_pdcch(nr_mac,
pdcch_pdu_rel15,
UE_info->rnti[UE_id],
ss,
coreset,
scc,
bwp,
aggregation_level,
CCEIndex);
int dci_formats[2];
int rnti_types[2];
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
dci_formats[0] = NR_DL_DCI_FORMAT_1_1;
else
dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
rnti_types[0] = NR_RNTI_C;
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id);
LOG_D(MAC,
"DCI params: rnti %x, rnti_type %d, dci_format %d\n",
pdcch_pdu_rel15->dci_pdu.RNTI[0],
rnti_types[0],
dci_formats[0]);
LOG_D(MAC,
"coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
(unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
pdcch_pdu_rel15->StartSymbolIndex,
pdcch_pdu_rel15->DurationSymbols);
// I don't know why the following is not needed, but in this case we don't
// need additional calculations:
//const uint16_t N_RE_prime = NR_NB_SC_PER_RB * N_sh_symb - N_PRB_DMRS - N_PRB_oh;
//LOG_D(MAC,
// "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n",
// N_RE_prime,
// N_sh_symb,
// N_PRB_DMRS,
// N_PRB_oh);
//pdsch_pdu_rel15->nb_mod_symbols = N_RE_prime*pdsch_pdu_rel15->n_prb*pdsch_pdu_rel15->nb_codewords;
LOG_D(MAC,
"DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d "
"nb_layers %d nb_codewords %d mcs %d TBS: %d\n",
pdsch_pdu_rel15->rbStart,
pdsch_pdu_rel15->rbSize,
pdsch_pdu_rel15->StartSymbolIndex,
pdsch_pdu_rel15->NrOfSymbols,
pdsch_pdu_rel15->nrOfLayers,
pdsch_pdu_rel15->NrOfCodewords,
pdsch_pdu_rel15->mcsIndex[0],
TBS);
dl_req->nPDUs += 2;
}
void nr_configure_pdcch(gNB_MAC_INST *nr_mac,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
uint16_t rnti,
NR_SearchSpace_t *ss,
NR_ControlResourceSet_t *coreset,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp,
uint8_t aggregation_level,
int CCEIndex) {
if (bwp) { // This is not the InitialBWP
NR_ControlResourceSet_t *temp_coreset;
NR_ControlResourceSetId_t coresetid = *ss->controlResourceSetId;
if (ss_type == 0) { // common search space
if (coresetid == 0){
AssertFatal(1==0,"coreset0 currently not supported\n");
}
else {
coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
AssertFatal(coresetid==coreset->controlResourceSetId,"ID of common ss coreset does not correspond to id set in the search space\n");
}
}
else {
int n_list = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count;
for (int i=0; i<n_list; i++) {
temp_coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i];
if (coresetid==temp_coreset->controlResourceSetId) {
coreset = temp_coreset;
cid = i;
break;
}
}
if(coreset==NULL)
AssertFatal(1==0,"Couldn't find coreset with id %ld\n",coresetid);
}
pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdcch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
@@ -507,22 +711,6 @@ int nr_configure_pdcch(gNB_MAC_INST *nr_mac,
pdcch_pdu->dci_pdu.ScramblingRNTI[pdcch_pdu->numDlDci]=0;
}
uint8_t nr_of_candidates,aggregation_level;
find_aggregation_candidates(&aggregation_level,
&nr_of_candidates,
ss);
CCEIndex = allocate_nr_CCEs(nr_mac,
1, // bwp_id
cid,
aggregation_level,
ss->searchSpaceType->present-1, // search_space, 0 common, 1 ue-specific
0, // UE-id
0); // m
if (CCEIndex<0)
return (CCEIndex);
pdcch_pdu->dci_pdu.AggregationLevel[pdcch_pdu->numDlDci] = aggregation_level;
pdcch_pdu->dci_pdu.CceIndex[pdcch_pdu->numDlDci] = CCEIndex;
@@ -531,7 +719,6 @@ int nr_configure_pdcch(gNB_MAC_INST *nr_mac,
pdcch_pdu->dci_pdu.powerControlOffsetSS[pdcch_pdu->numDlDci]=1;
pdcch_pdu->numDlDci++;
return (0);
}
else { // this is for InitialBWP
AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n");
@@ -1396,39 +1583,34 @@ int extract_length(int startSymbolAndLength) {
}
/*
* Dump the UL or DL UE_list into LOG_T(MAC)
* Dump the UL or DL UE_info into LOG_T(MAC)
*/
void
dump_nr_ue_list(NR_UE_list_t *listP,
int ul_flag)
//------------------------------------------------------------------------------
{
if (ul_flag == 0) {
for (int j = listP->head; j >= 0; j = listP->next[j]) {
LOG_T(MAC, "DL list node %d => %d\n",
j,
listP->next[j]);
}
} else {
for (int j = listP->head_ul; j >= 0; j = listP->next_ul[j]) {
LOG_T(MAC, "UL list node %d => %d\n",
j,
listP->next_ul[j]);
}
}
void dump_nr_ue_list(NR_UE_list_t *listP) {
for (int j = listP->head; j >= 0; j = listP->next[j])
LOG_T(MAC, "DL list node %d => %d\n", j, listP->next[j]);
}
return;
/*
* Add a UE to NR_UE_list listP
*/
inline void add_nr_ue_list(NR_UE_list_t *listP, int UE_id) {
int *cur = &listP->head;
while (*cur >= 0) {
AssertFatal(*cur != UE_id, "UE_id %d already in NR_UE_list!\n", UE_id);
cur = &listP->next[*cur];
}
*cur = UE_id;
}
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP)
//------------------------------------------------------------------------------
{
int UE_id;
NR_UE_list_t *UE_list = &RC.nrmac[mod_idP]->UE_list;
NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) {
if (UE_list->active[UE_id] == TRUE) {
if (UE_list->rnti[UE_id] == rntiP) {
if (UE_info->active[UE_id]) {
if (UE_info->rnti[UE_id] == rntiP) {
return UE_id;
}
}
@@ -1439,42 +1621,40 @@ int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP)
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
int UE_id;
int i;
NR_UE_list_t *UE_list = &RC.nrmac[mod_idP]->UE_list;
NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
NR_COMMON_channels_t *cc = RC.nrmac[mod_idP]->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
int num_slots_ul = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0)
num_slots_ul++;
LOG_I(MAC, "[gNB %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",
LOG_W(MAC, "[gNB %d] Adding UE with rnti %x (num_UEs %d)\n",
mod_idP,
rntiP,
UE_list->avail,
UE_list->num_UEs);
dump_nr_ue_list(UE_list, 0);
UE_info->num_UEs);
dump_nr_ue_list(&UE_info->list);
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if (UE_list->active[i] == TRUE)
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if (UE_info->active[i])
continue;
UE_id = i;
UE_list->num_UEs++;
UE_list->active[UE_id] = TRUE;
UE_list->rnti[UE_id] = rntiP;
memset((void *) &UE_list->UE_sched_ctrl[UE_id],
int UE_id = i;
UE_info->num_UEs++;
UE_info->active[UE_id] = true;
UE_info->rnti[UE_id] = rntiP;
add_nr_ue_list(&UE_info->list, UE_id);
memset((void *) &UE_info->UE_sched_ctrl[UE_id],
0,
sizeof(NR_UE_sched_ctrl_t));
UE_list->UE_sched_ctrl[UE_id].ta_timer = 100;
UE_list->UE_sched_ctrl[UE_id].ta_update = 31;
UE_list->UE_sched_ctrl[UE_id].ul_rssi = 0;
UE_list->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch));
UE_list->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch));
UE_info->UE_sched_ctrl[UE_id].ta_timer = 100;
UE_info->UE_sched_ctrl[UE_id].ta_update = 31;
UE_info->UE_sched_ctrl[UE_id].ul_rssi = 0;
UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch));
UE_info->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch));
for (int k=0; k<num_slots_ul; k++) {
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k],
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k],
0,
sizeof(NR_sched_pucch));
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k],
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
0,
sizeof(NR_sched_pusch));
}
@@ -1482,15 +1662,13 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
mod_idP,
UE_id,
rntiP);
dump_nr_ue_list(UE_list,
0);
dump_nr_ue_list(&UE_info->list);
return (UE_id);
}
// printf("MAC: cannot add new UE for rnti %x\n", rntiP);
LOG_E(MAC, "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n");
dump_nr_ue_list(UE_list,
0);
LOG_E(MAC, "error in add_new_ue(), could not find space in UE_info, Dumping UE list\n");
dump_nr_ue_list(&UE_info->list);
return -1;
}
@@ -1503,23 +1681,23 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
{
int UE_id;
int i;
NR_UE_list_t *UE_list = &RC.nrmac[mod_id]->UE_list;
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if (UE_list->active[i] != TRUE)
if (UE_info->active[i] != TRUE)
continue;
if (UE_list->rnti[i] != rnti)
if (UE_info->rnti[i] != rnti)
continue;
/* UE found, remove it */
UE_id = i;
UE_list->num_UEs--;
UE_list->UEcontext[UE_id].fiveG_connected = FALSE;
UE_list->active[UE_id] = FALSE;
UE_list->rnti[UE_id] = 0;
free(UE_list->UE_sched_ctrl[UE_id].sched_pucch);
free(UE_list->UE_sched_ctrl[UE_id].sched_pusch);
memset((void *) &UE_list->UE_sched_ctrl[UE_id],
UE_info->num_UEs--;
UE_info->active[UE_id] = FALSE;
UE_info->rnti[UE_id] = 0;
free(UE_info->UE_sched_ctrl[UE_id].sched_pucch);
free(UE_info->UE_sched_ctrl[UE_id].sched_pusch);
memset((void *) &UE_info->UE_sched_ctrl[UE_id],
0,
sizeof(NR_UE_sched_ctrl_t));
LOG_I(MAC, "[gNB %d] Remove NR UE_id %d : rnti %x\n",
@@ -1554,8 +1732,8 @@ void get_pdsch_to_harq_feedback(int Mod_idP,
uint8_t *pdsch_to_harq_feedback) {
int bwp_id=1;
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
@@ -1607,7 +1785,7 @@ void nr_update_pucch_scheduling(int Mod_idP,
int *pucch_id) {
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
NR_sched_pucch *curr_pucch;
int first_ul_slot_tdd,k,i;
uint8_t pdsch_to_harq_feedback[8];
@@ -1622,7 +1800,7 @@ void nr_update_pucch_scheduling(int Mod_idP,
// for each possible ul or mixed slot
for (k=0; k<nr_ulmix_slots; k++) {
curr_pucch = &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k];
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k];
// if there is free room in current pucch structure
if (curr_pucch->dai_c<MAX_ACK_BITS) {
curr_pucch->frame = frameP;
@@ -212,7 +212,7 @@ void nr_process_mac_pdu(
LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len);
int UE_id = find_nr_UE_id(module_idP, rnti);
RC.nrmac[module_idP]->UE_list.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
RC.nrmac[module_idP]->UE_info.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n");
@@ -309,19 +309,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const uint16_t rssi){
int current_rnti = 0, UE_id = -1, harq_pid = 0;
gNB_MAC_INST *gNB_mac = NULL;
NR_UE_list_t *UE_list = NULL;
NR_UE_info_t *UE_info = NULL;
NR_UE_sched_ctrl_t *UE_scheduling_control = NULL;
current_rnti = rntiP;
UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti);
gNB_mac = RC.nrmac[gnb_mod_idP];
UE_list = &gNB_mac->UE_list;
UE_info = &gNB_mac->UE_info;
int target_snrx10 = gNB_mac->pusch_target_snrx10;
if (UE_id != -1) {
UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]);
UE_list->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
gnb_mod_idP,
harq_pid,
@@ -364,20 +364,46 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
}
}
else {
else if (sduP != NULL) { // if the CRC passed
// random access pusch with TC-RNTI
if (sduP != NULL) { // if the CRC passed
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if (UE_list->active[i] == TRUE) {
if (UE_list->tc_rnti[i] == current_rnti) {
// for now the only thing we are doing is set the UE as 5G connected
UE_list->UEcontext[i].fiveG_connected = true;
LOG_I(MAC, "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly and UE_id %d is now 5G connected\n",
gnb_mod_idP, current_rnti, i);
}
}
}
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[0];
if (ra->state != WAIT_Msg3) {
LOG_E(MAC,
"expected RA state WAIT_Msg3/%d (but is %d) for RA-RNTI %04x\n",
WAIT_Msg3,
ra->state,
ra->rnti);
return;
}
if (ra->rnti != current_rnti) {
LOG_E(MAC,
"expected RA-RNTI %04x (C-RNTI %04x) to match current RNTI %04x\n",
ra->rnti,
ra->crnti,
current_rnti);
return;
}
free(ra->preambles.preamble_list);
ra->state = RA_IDLE;
LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti);
const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->crnti);
UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup;
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
AssertFatal(bwpList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
bwpList->list.count);
const int bwp_id = 1;
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
LOG_W(MAC,
"[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
"adding UE MAC Context UE_id %d/RNTI %04x\n",
gnb_mod_idP,
current_rnti,
UE_id,
ra->crnti);
}
}
+64 -22
View File
@@ -67,6 +67,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
frame_t frame_rxP, sub_frame_t slot_rxP);
int nr_generate_dlsch_pdu(module_id_t Mod_idP,
NR_UE_sched_ctrl_t *ue_sched_ctl,
unsigned char *sdus_payload,
unsigned char *mac_pdu,
unsigned char num_sdus,
@@ -76,7 +77,10 @@ int nr_generate_dlsch_pdu(module_id_t Mod_idP,
unsigned char *ue_cont_res_id,
unsigned short post_padding);
void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
void nr_schedule_ue_spec(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd);
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
@@ -126,12 +130,38 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP);
int configure_fapi_dl_pdu(int Mod_id,
nfapi_nr_dl_tti_request_body_t *dl_req,
NR_sched_pucch *pucch_sched,
uint8_t *mcsIndex,
uint16_t *rbSize,
uint16_t *rbStart);
void nr_fill_nfapi_dl_pdu(int Mod_id,
int UE_id,
int bwp_id,
NR_SearchSpace_t *ss,
NR_ControlResourceSet_t *coreset,
nfapi_nr_dl_tti_request_body_t *dl_req,
NR_sched_pucch *pucch_sched,
int nrOfLayers,
uint8_t mcs,
uint16_t rbSize,
uint16_t rbStart,
uint8_t numDmrsCdmGrpsNoData,
nfapi_nr_dmrs_type_e dmrsConfigType,
uint8_t table_idx,
uint16_t R,
uint8_t Qm,
uint32_t tbs,
int time_domain_assignment,
int StartSymbolIndex,
int NrOfSymbols,
uint8_t aggregation_level,
int CCEIndex,
int harq_pid,
int ndi,
int round);
int configure_fapi_dl_pdu_phytest(int Mod_id,
nfapi_nr_dl_tti_request_body_t *dl_req,
NR_sched_pucch *pucch_sched,
uint8_t *mcsIndex,
uint16_t *rbSize,
uint16_t *rbStart);
void config_uldci(NR_BWP_Uplink_t *ubwp,
nfapi_nr_pusch_pdu_t *pusch_pdu,
@@ -211,13 +241,15 @@ void find_search_space(int ss_type,
NR_BWP_Downlink_t *bwp,
NR_SearchSpace_t *ss);
int nr_configure_pdcch(gNB_MAC_INST *nr_mac,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
uint16_t rnti,
int ss_type,
NR_SearchSpace_t *ss,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp);
void nr_configure_pdcch(gNB_MAC_INST *nr_mac,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
uint16_t rnti,
NR_SearchSpace_t *ss,
NR_ControlResourceSet_t *coreset,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp,
uint8_t aggregation_level,
int CCEIndex);
void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc,
NR_CellGroupConfig_t *secondaryCellGroup,
@@ -233,6 +265,16 @@ void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup,
nr_dci_format_t format,
int bwp_id);
/* find coreset within the search space */
NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp,
NR_SearchSpace_t *ss,
int ss_type);
/* find a search space within a BWP */
NR_SearchSpace_t *get_searchspace(
NR_BWP_Downlink_t *bwp,
NR_SearchSpace__searchSpaceType_PR target_ss);
void find_aggregation_candidates(uint8_t *aggregation_level,
uint8_t *nr_of_candidates,
NR_SearchSpace_t *ss);
@@ -259,7 +301,8 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB);
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
void dump_nr_ue_list(NR_UE_list_t *listP, int ul_flag);
void dump_nr_ue_list(NR_UE_list_t *listP);
void add_nr_ue_list(NR_UE_list_t *listP, int UE_id);
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
@@ -268,13 +311,11 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP);
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti);
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int bwp_id,
int coreset_id,
NR_BWP_Downlink_t *bwp,
NR_ControlResourceSet_t *coreset,
int aggregation,
int search_space, // 0 common, 1 ue-specific
int UE_id,
int m
);
uint16_t n_RNTI,
int m);
int get_dlscs(nfapi_nr_config_request_t *cfg);
@@ -307,7 +348,8 @@ void schedule_fapi_ul_pdu(int Mod_idP,
sub_frame_t slotP,
int num_slots_per_tdd,
int ul_slots,
int time_domain_assignment);
int time_domain_assignment,
uint64_t ulsch_in_slot_bitmap);
void nr_process_mac_pdu(
module_id_t module_idP,
+13 -21
View File
@@ -50,7 +50,7 @@ void mac_top_init_gNB(void)
{
module_id_t i;
int list_el;
NR_UE_list_t *UE_list;
NR_UE_info_t *UE_info;
gNB_MAC_INST *nrmac;
LOG_I(MAC, "[MAIN] Init function start:nb_nr_macrlc_inst=%d\n",RC.nb_nr_macrlc_inst);
@@ -104,29 +104,21 @@ void mac_top_init_gNB(void)
nrmac = RC.nrmac[i];
nrmac->if_inst = NR_IF_Module_init(i);
UE_list = &nrmac->UE_list;
UE_list->num_UEs = 0;
UE_list->head = -1;
UE_list->head_ul = -1;
UE_list->avail = 0;
for (list_el = 0; list_el < MAX_MOBILES_PER_GNB - 1; list_el++) {
UE_list->next[list_el] = list_el + 1;
UE_list->next_ul[list_el] = list_el + 1;
UE_list->active[list_el] = FALSE;
UE_info = &nrmac->UE_info;
UE_info->num_UEs = 0;
UE_info->list.head = -1;
for (list_el = 0; list_el < MAX_MOBILES_PER_GNB; list_el++) {
UE_info->list.next[list_el] = -1;
UE_info->active[list_el] = false;
for (int list_harq = 0; list_harq < NR_MAX_NB_HARQ_PROCESSES; list_harq++) {
UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0;
UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].ndi = 0;
UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].is_waiting = 0;
UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].round = 0;
UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].ndi = 0;
UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].state = 0;
UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0;
UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].ndi = 0;
UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].is_waiting = 0;
UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].round = 0;
UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].ndi = 0;
UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].state = 0;
}
}
UE_list->next[list_el] = -1;
UE_list->next_ul[list_el] = -1;
UE_list->active[list_el] = FALSE;
}
srand48(0);
+66 -20
View File
@@ -86,6 +86,11 @@ typedef enum {
WAIT_Msg4_ACK = 4
} RA_gNB_state_t;
typedef struct NR_preamble_ue {
uint8_t num_preambles;
uint8_t *preamble_list;
} NR_preamble_ue_t;
/*! \brief gNB template for the Random access information */
typedef struct {
/// Flag to indicate this process is active
@@ -144,6 +149,12 @@ typedef struct {
int msg4_mcs;
/// RA search space
NR_SearchSpace_t *ra_ss;
/// secondaryCellGroup for UE in NSA that is to come
NR_CellGroupConfig_t *secondaryCellGroup;
/// Preambles for contention-free access
NR_preamble_ue_t preambles;
/// NSA: the UEs C-RNTI to use
rnti_t crnti;
} NR_RA_t;
/*! \brief gNB common channels */
@@ -175,9 +186,9 @@ typedef struct {
/// Template for RA computations
NR_RA_t ra[NR_NB_RA_PROC_MAX];
/// VRB map for common channels
uint8_t vrb_map[100];
uint8_t vrb_map[275];
/// VRB map for common channels and retransmissions by PHICH
uint8_t vrb_map_UL[100];
uint8_t vrb_map_UL[275];
/// number of subframe allocation pattern available for MBSFN sync area
uint8_t num_sf_allocation_pattern;
} NR_COMMON_channels_t;
@@ -271,6 +282,14 @@ typedef struct NR_UE_harq {
uint16_t feedback_slot;
} NR_UE_harq_t;
typedef struct NR_UE_old_sched {
uint16_t rbSize;
int time_domain_allocation;
uint8_t mcsTableIdx;
uint8_t mcs;
uint8_t numDmrsCdmGrpsNoData;
} NR_UE_ret_info_t;
typedef enum {
INACTIVE = 0,
ACTIVE_NOT_SCHED,
@@ -286,10 +305,39 @@ typedef struct NR_UE_ul_harq {
/*! \brief scheduling control information set through an API */
typedef struct {
uint64_t dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch
uint64_t ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch
/// total amount of data awaiting for this UE
uint32_t num_total_bytes;
/// per-LC status data
mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID];
/// the currently active BWP in DL
NR_BWP_Downlink_t *active_bwp;
NR_sched_pucch *sched_pucch;
/// selected PUCCH index, if scheduled
int pucch_sched_idx;
NR_sched_pusch *sched_pusch;
/// CCE index and aggregation, should be coherent with cce_list
NR_SearchSpace_t *search_space;
NR_ControlResourceSet_t *coreset;
int cce_index;
uint8_t aggregation_level;
/// RB allocation within active BWP
uint16_t rbSize;
uint16_t rbStart;
// time-domain allocation for scheduled RBs
int time_domain_allocation;
/// MCS-related infos
uint8_t mcsTableIdx;
uint8_t mcs;
uint8_t numDmrsCdmGrpsNoData;
/// Retransmission-related information
NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES];
uint16_t ta_timer;
int16_t ta_update;
bool ta_apply;
@@ -303,11 +351,6 @@ typedef struct {
NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information
} NR_UE_sched_ctrl_t;
typedef struct NR_preamble_ue {
uint8_t num_preambles;
uint8_t *preamble_list;
} NR_preamble_ue;
typedef struct {
boolean_t fiveG_connected;
uicc_t *uicc;
@@ -326,25 +369,28 @@ typedef struct {
} NR_mac_stats_t;
/*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in
* the scheduler and to keep "classes" of users. */
typedef struct {
int head;
int next[MAX_MOBILES_PER_GNB];
} NR_UE_list_t;
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
typedef struct {
DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
/// scheduling control info
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB];
int next[MAX_MOBILES_PER_GNB];
int head;
int next_ul[MAX_MOBILES_PER_GNB];
int head_ul;
int avail;
NR_UE_list_t list;
int num_UEs;
boolean_t active[MAX_MOBILES_PER_GNB];
NRUEcontext_t UEcontext[MAX_MOBILES_PER_GNB];
bool active[MAX_MOBILES_PER_GNB];
rnti_t rnti[MAX_MOBILES_PER_GNB];
rnti_t tc_rnti[MAX_MOBILES_PER_GNB];
NR_preamble_ue preambles[MAX_MOBILES_PER_GNB];
NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB];
} NR_UE_list_t;
} NR_UE_info_t;
/*! \brief top level eNB MAC structure */
typedef struct gNB_MAC_INST_s {
@@ -378,7 +424,7 @@ typedef struct gNB_MAC_INST_s {
/// NFAPI DL PDU structure
nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX];
NR_UE_list_t UE_list;
NR_UE_info_t UE_info;
/// UL handle
uint32_t ul_handle;
+7 -7
View File
@@ -431,9 +431,9 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4;
printf("!!!!!!! deliver_sdu_drb (drb %d) sending message to gtp size %d: ", rb_id, size);
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]);
printf("\n");
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size);
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]);
//printf("\n");
itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
}
@@ -474,9 +474,9 @@ rb_found:
memblock = get_free_mem_block(size, __FUNCTION__);
memcpy(memblock->data, buf, size);
printf("!!!!!!! deliver_pdu_drb (srb %d) calling rlc_data_req size %d: ", rb_id, size);
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
printf("\n");
LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, rb_id, size);
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
//printf("\n");
enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock, NULL, NULL);
}
@@ -877,7 +877,7 @@ static boolean_t pdcp_data_req_drb(
const sdu_size_t sdu_buffer_size,
unsigned char *const sdu_buffer)
{
printf("pdcp_data_req called size %d\n", sdu_buffer_size);
LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size);
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
int rnti = ctxt_pP->rnti;
+2 -2
View File
@@ -181,10 +181,10 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot);
handle_nr_rach(UL_info);
handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0],mac->pucch_target_snrx10);
handle_nr_uci(UL_info,&mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0],mac->pucch_target_snrx10);
// clear HI prior to handling ULSCH
mac->UL_dci_req[CC_id].numPdus = 0;
handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0]);
handle_nr_ulsch(UL_info, &mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0]);
if (nfapi_mode != 1) {
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
+11 -33
View File
@@ -107,17 +107,10 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
module_id_t module_id = ul_info->module_id;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
// clean previous FAPI messages
mac->tx_request.number_of_pdus = 0;
mac->ul_config_request.number_pdus = 0;
mac->dl_config_request.number_pdus = 0;
// clean previous FAPI messages
ret = nr_ue_scheduler(NULL, ul_info);
if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra){
if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra)
nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx);
}
switch(ret){
case UE_CONNECTION_OK:
@@ -132,8 +125,6 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
break;
}
mac->if_module->scheduled_response(&mac->scheduled_response);
return 0;
}
@@ -151,22 +142,11 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
nr_ue_scheduler(dl_info, NULL);
} else {
// UL indication after reception of DCI or DL PDU
dl_config->number_pdus = 0;
ul_config->number_pdus = 0;
//hook up pointers
mac->scheduled_response.dl_config = dl_config;
mac->scheduled_response.ul_config = ul_config;
mac->scheduled_response.tx_request = &mac->tx_request;
mac->scheduled_response.module_id = dl_info->module_id;
mac->scheduled_response.CC_id = dl_info->cc_id;
mac->scheduled_response.frame = dl_info->frame;
mac->scheduled_response.slot = dl_info->slot;
if(dl_info->dci_ind != NULL){
LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
for(i=0; i<dl_info->dci_ind->number_of_dcis; ++i){
LOG_D(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
nr_scheduled_response_t scheduled_response;
int8_t ret = handle_dci(dl_info->module_id,
dl_info->cc_id,
dl_info->gNB_index,
@@ -174,8 +154,10 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
ret_mask |= (ret << FAPI_NR_DCI_IND);
if (ret >= 0) {
AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is void!\n" );
nr_ue_if_module_inst[module_id]->scheduled_response(&mac->scheduled_response);
AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" );
AssertFatal( nr_ue_if_module_inst[module_id]->scheduled_response != NULL, "scheduled_response is NULL!\n" );
fill_scheduled_response(&scheduled_response, dl_config, ul_config, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot);
nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response);
}
}
}
@@ -266,20 +248,16 @@ int nr_ue_if_module_kill(uint32_t module_id) {
if (nr_ue_if_module_inst[module_id] != NULL){
free(nr_ue_if_module_inst[module_id]);
}
}
return 0;
}
int nr_ue_dcireq(nr_dcireq_t *dcireq) {
fapi_nr_dl_config_request_t *dl_config=&dcireq->dl_config_req;
fapi_nr_dl_config_request_t *dl_config = &dcireq->dl_config_req;
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
dl_config->sfn=UE_mac->dl_config_request.sfn;
dl_config->slot=UE_mac->dl_config_request.slot;
dl_config->number_pdus=0;
//printf(" UE_mac->dl_config_request.slot %d VS dcireq->slot %d \n", UE_mac->dl_config_request.slot, dcireq->slot);
dl_config->sfn = UE_mac->dl_config_request.sfn;
dl_config->slot = UE_mac->dl_config_request.slot;
LOG_D(PHY, "Entering UE DCI configuration frame %d slot %d \n", dcireq->frame, dcireq->slot);
+3 -3
View File
@@ -399,9 +399,9 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(
}
for(i=0; i<buffer_len; ++i){
printf("[RRC] MIB PDU : %d\n", bufferP[i]);
}
//for(i=0; i<buffer_len; ++i){
// printf("[RRC] MIB PDU : %d\n", bufferP[i]);
//}
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_NR_BCCH_BCH_Message,