Merge branch 'develop' of https://gitlab.eurecom.fr/oai/openairinterface5g into NR_UE_thread_improvement_IDCC
This commit is contained in:
@@ -233,6 +233,7 @@ typedef uint8_t pdusessionid_t;
|
||||
//-----------------------------------------------------------------------------
|
||||
// may be ITTI not enabled, but type instance is useful also for OTG,
|
||||
typedef intptr_t instance_t;
|
||||
|
||||
typedef struct protocol_ctxt_s {
|
||||
module_id_t module_id; /*!< \brief Virtualized module identifier */
|
||||
eNB_flag_t enb_flag; /*!< \brief Flag to indicate eNB (1) or UE (0) */
|
||||
|
||||
@@ -427,6 +427,7 @@ typedef struct NRRrcConfigurationReq_s {
|
||||
bool force_256qam_off;
|
||||
int pusch_TargetSNRx10;
|
||||
int pucch_TargetSNRx10;
|
||||
bool enable_sdap;
|
||||
} gNB_RrcConfigurationReq;
|
||||
|
||||
typedef struct NRDuDlReq_s {
|
||||
|
||||
+13
-11
@@ -32,16 +32,18 @@ void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
abort();
|
||||
}
|
||||
|
||||
boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id
|
||||
) {
|
||||
boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id,
|
||||
const uint8_t qfi,
|
||||
const boolean_t rqi,
|
||||
const int pdusession_id) {
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -1192,7 +1192,9 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
LOG_I(RRC, "256 QAM: %s\n", NRRRC_CONFIGURATION_REQ (msg_p).force_256qam_off ? "force off" : "may be on");
|
||||
NRRRC_CONFIGURATION_REQ (msg_p).scc = scc;
|
||||
NRRRC_CONFIGURATION_REQ (msg_p).scd = scd;
|
||||
|
||||
NRRRC_CONFIGURATION_REQ (msg_p).enable_sdap = *GNBParamList.paramarray[i][GNB_ENABLE_SDAP_IDX].iptr;
|
||||
LOG_I(GNB_APP, "SDAP layer is %s\n", NRRRC_CONFIGURATION_REQ (msg_p).enable_sdap ? "enabled" : "disabled");
|
||||
|
||||
}//
|
||||
}//End for (k=0; k <num_gnbs ; k++)
|
||||
memcpy(&rrc->configuration, &NRRRC_CONFIGURATION_REQ(msg_p), sizeof(NRRRC_CONFIGURATION_REQ(msg_p)));
|
||||
@@ -2061,6 +2063,7 @@ void configure_gnb_du_mac(int inst) {
|
||||
rrc->configuration.minRXTXTIME,
|
||||
rrc->configuration.scc,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0, // rnti
|
||||
(NR_CellGroupConfig_t *)NULL
|
||||
|
||||
@@ -125,7 +125,8 @@ typedef enum {
|
||||
#define GNB_CONFIG_STRING_MINRXTXTIME "min_rxtxtime"
|
||||
#define GNB_CONFIG_STRING_ULPRBBLACKLIST "ul_prbblacklist"
|
||||
#define GNB_CONFIG_STRING_FORCE256QAMOFF "force_256qam_off"
|
||||
|
||||
#define GNB_CONFIG_STRING_ENABLE_SDAP "enable_sdap"
|
||||
#define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n"
|
||||
|
||||
#define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support"
|
||||
|
||||
@@ -153,13 +154,14 @@ typedef enum {
|
||||
{GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N2, "vert. log. antenna ports", 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP, "XP log. antenna ports", 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_PUSCHANTENNAPORTS, NULL, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_SIB1TDA, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_SIB1TDA, NULL, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_DOCSIRS, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_DOSRS, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_NRCELLID, NULL, 0, u64ptr:NULL, defint64val:1, TYPE_UINT64, 0}, \
|
||||
{GNB_CONFIG_STRING_MINRXTXTIME, NULL, 0, iptr:NULL, defintval:2, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_ULPRBBLACKLIST, NULL, 0, strptr:NULL, defstrval:"", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0} \
|
||||
{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
}
|
||||
|
||||
#define GNB_GNB_ID_IDX 0
|
||||
@@ -188,6 +190,7 @@ typedef enum {
|
||||
#define GNB_MINRXTXTIME_IDX 23
|
||||
#define GNB_ULPRBBLACKLIST_IDX 24
|
||||
#define GNB_FORCE256QAMOFF_IDX 25
|
||||
#define GNB_ENABLE_SDAP_IDX 26
|
||||
|
||||
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
|
||||
#define GNBPARAMS_CHECK { \
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "NR_SubcarrierSpacing.h"
|
||||
#include "openair1/SCHED_NR_UE/harq_nr.h"
|
||||
|
||||
#define NR_SHORT_BSR_TABLE_SIZE 32
|
||||
#define NR_LONG_BSR_TABLE_SIZE 256
|
||||
@@ -264,14 +265,29 @@ typedef struct {
|
||||
uint8_t nbits;
|
||||
} dci_field_t;
|
||||
|
||||
typedef struct {
|
||||
/* The active harq sfn/slot field was created to save the
|
||||
scheduled SFN/Slot transmission for the ACK/NAK. If we
|
||||
do not save it, then we have to calculate it again as the
|
||||
NRUE MAC layer already does in get_downlink_ack(). */
|
||||
int active_dl_harq_sfn;
|
||||
int active_dl_harq_slot;
|
||||
int active_ul_harq_sfn_slot;
|
||||
bool active;
|
||||
} emul_l1_harq_t;
|
||||
|
||||
typedef struct {
|
||||
bool expected_sib;
|
||||
bool index_has_sib[16];
|
||||
bool index_has_sib[NR_MAX_HARQ_PROCESSES];
|
||||
bool expected_rar;
|
||||
bool index_has_rar[16];
|
||||
bool index_has_rar[NR_MAX_HARQ_PROCESSES];
|
||||
bool expected_dci;
|
||||
bool index_has_dci[16];
|
||||
int active_harq_sfn_slot;
|
||||
bool index_has_dci[NR_MAX_HARQ_PROCESSES];
|
||||
emul_l1_harq_t harq[NR_MAX_HARQ_PROCESSES];
|
||||
int active_uci_sfn_slot;
|
||||
int num_srs;
|
||||
int num_harqs;
|
||||
int num_csi_reports;
|
||||
} nr_emulated_l1_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -2595,9 +2595,10 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP,
|
||||
const NR_CellGroupConfig_t *cg,
|
||||
dci_pdu_rel15_t *dci_pdu,
|
||||
nr_dci_format_t format,
|
||||
nr_rnti_type_t rnti_type,
|
||||
uint16_t N_RB,
|
||||
int bwp_id) {
|
||||
nr_rnti_type_t rnti_type,
|
||||
uint16_t N_RB,
|
||||
int bwp_id,
|
||||
uint16_t cset0_bwp_size) {
|
||||
|
||||
uint16_t size = 0;
|
||||
uint16_t numRBG = 0;
|
||||
@@ -2627,15 +2628,17 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP,
|
||||
srs_config = (ubwpd->srs_Config) ? ubwpd->srs_Config->choice.setup : NULL;
|
||||
}
|
||||
else if (cg){
|
||||
bwpd=cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP;
|
||||
bwpc=initialDownlinkBWP;
|
||||
ubwpd=cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP;
|
||||
ubwpc=initialUplinkBWP;
|
||||
pdsch_Config = (bwpd->pdsch_Config) ? bwpd->pdsch_Config->choice.setup : NULL;
|
||||
pdcch_Config = (bwpd->pdcch_Config) ? bwpd->pdcch_Config->choice.setup : NULL;
|
||||
pucch_Config = (ubwpd->pucch_Config) ? ubwpd->pucch_Config->choice.setup : NULL;
|
||||
pusch_Config = (ubwpd->pusch_Config) ? ubwpd->pusch_Config->choice.setup : NULL;
|
||||
srs_config = (ubwpd->srs_Config) ? ubwpd->srs_Config->choice.setup: NULL;
|
||||
bwpc = initialDownlinkBWP;
|
||||
ubwpc = initialUplinkBWP;
|
||||
bwpd = cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated ?
|
||||
cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
|
||||
ubwpd = cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
pdsch_Config = (bwpd && bwpd->pdsch_Config) ? bwpd->pdsch_Config->choice.setup : NULL;
|
||||
pdcch_Config = (bwpd && bwpd->pdcch_Config) ? bwpd->pdcch_Config->choice.setup : NULL;
|
||||
pucch_Config = (ubwpd && ubwpd->pucch_Config) ? ubwpd->pucch_Config->choice.setup : NULL;
|
||||
pusch_Config = (ubwpd && ubwpd->pusch_Config) ? ubwpd->pusch_Config->choice.setup : NULL;
|
||||
srs_config = (ubwpd && ubwpd->srs_Config) ? ubwpd->srs_Config->choice.setup: NULL;
|
||||
}
|
||||
|
||||
int n_ul_bwp=1,n_dl_bwp=1;
|
||||
@@ -2645,7 +2648,9 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP,
|
||||
/// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
|
||||
size += 20;
|
||||
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated
|
||||
size += nr_dci_size(initialDownlinkBWP,initialUplinkBWP,cg,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id) - size; // Padding to match 1_0 size
|
||||
int dci_10_size = nr_dci_size(initialDownlinkBWP,initialUplinkBWP,cg,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id, cset0_bwp_size);
|
||||
AssertFatal(dci_10_size >= size, "NR_UL_DCI_FORMAT_0_0 size is bigger than NR_DL_DCI_FORMAT_1_0! 3GPP TS 38.212 Section 7.3.1.0: DCI size alignment is not fully implemented");
|
||||
size += dci_10_size - size; // Padding to match 1_0 size
|
||||
// UL/SUL indicator assumed to be 0
|
||||
break;
|
||||
|
||||
@@ -2863,6 +2868,14 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP,
|
||||
|
||||
case NR_DL_DCI_FORMAT_1_0:
|
||||
/// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 Time Domain assgnmt 4 -- 28
|
||||
|
||||
// 3GPP TS 38.212 Section 7.3.1.0: DCI size alignment
|
||||
// Size of DCI format 1_0 is given by the size of CORESET 0 if CORESET 0 is configured for the cell and the size
|
||||
// of initial DL bandwidth part if CORESET 0 is not configured for the cell
|
||||
if(cset0_bwp_size>0) {
|
||||
N_RB = cset0_bwp_size;
|
||||
}
|
||||
|
||||
size = 28;
|
||||
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment
|
||||
|
||||
|
||||
@@ -54,7 +54,8 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP,
|
||||
nr_dci_format_t format,
|
||||
nr_rnti_type_t rnti_type,
|
||||
uint16_t N_RB,
|
||||
int bwp_id);
|
||||
int bwp_id,
|
||||
uint16_t cset0_bwp_size);
|
||||
|
||||
void find_aggregation_candidates(uint8_t *aggregation_level,
|
||||
uint8_t *nr_of_candidates,
|
||||
|
||||
@@ -432,7 +432,7 @@ typedef struct {
|
||||
|
||||
// Defined for abstracted mode
|
||||
nr_downlink_indication_t dl_info;
|
||||
NR_UE_HARQ_STATUS_t dl_harq_info[16];
|
||||
NR_UE_HARQ_STATUS_t dl_harq_info[NR_MAX_HARQ_PROCESSES];
|
||||
|
||||
nr_emulated_l1_t nr_ue_emul_l1;
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
|
||||
}
|
||||
for (int i = 0; i < rel15->num_dci_options; i++) {
|
||||
rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id);
|
||||
rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id, mac->type0_PDCCH_CSS_config.num_rbs);
|
||||
}
|
||||
break;
|
||||
case NR_RNTI_RA:
|
||||
@@ -185,7 +185,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
}
|
||||
rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
|
||||
rel15->dci_length_options[0] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id);
|
||||
rel15->dci_length_options[0] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id, mac->type0_PDCCH_CSS_config.num_rbs);
|
||||
break;
|
||||
case NR_RNTI_P:
|
||||
break;
|
||||
@@ -200,7 +200,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
rel15->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb;
|
||||
rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
|
||||
for (int i = 0; i < rel15->num_dci_options; i++) {
|
||||
rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_TC, rel15->BWPSize, bwp_id);
|
||||
rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_TC, rel15->BWPSize, bwp_id, mac->type0_PDCCH_CSS_config.num_rbs);
|
||||
}
|
||||
break;
|
||||
case NR_RNTI_SP_CSI:
|
||||
@@ -223,7 +223,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2;
|
||||
|
||||
for (int i = 0; i < rel15->num_dci_options; i++) {
|
||||
rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0);
|
||||
rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0, mac->type0_PDCCH_CSS_config.num_rbs);
|
||||
}
|
||||
break;
|
||||
case NR_RNTI_SFI:
|
||||
|
||||
@@ -281,7 +281,6 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){
|
||||
LOG_D(MAC, "In %s: returning rnti_type %s \n", __FUNCTION__, rnti_types[rnti_type]);
|
||||
|
||||
return rnti_type;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -876,14 +875,26 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
if(pdsch_TimeDomainAllocationList && rnti!=SI_RNTI)
|
||||
mappingtype = pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType;
|
||||
|
||||
struct NR_DMRS_DownlinkConfig *dl_dmrs_config = NULL;
|
||||
if(mac->DLbwp[0])
|
||||
dl_dmrs_config = (mappingtype == typeA) ?
|
||||
mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup :
|
||||
mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
|
||||
|
||||
dlsch_config_pdu_1_0->nscid = 0;
|
||||
if(dl_dmrs_config && dl_dmrs_config->scramblingID0)
|
||||
dlsch_config_pdu_1_0->dlDmrsScramblingId = *dl_dmrs_config->scramblingID0;
|
||||
else
|
||||
dlsch_config_pdu_1_0->dlDmrsScramblingId = mac->physCellId;
|
||||
|
||||
/* dmrs symbol positions*/
|
||||
dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
|
||||
(get_softmodem_params()->nsa) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position,
|
||||
dlsch_config_pdu_1_0->number_symbols,
|
||||
dlsch_config_pdu_1_0->start_symbol,
|
||||
mappingtype, 1);
|
||||
dlsch_config_pdu_1_0->dmrsConfigType = (mac->DLbwp[0] != NULL) ?
|
||||
(mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
|
||||
dlsch_config_pdu_1_0->dmrsConfigType = (dl_dmrs_config != NULL) ?
|
||||
(dl_dmrs_config->dmrs_Type == NULL ? 0 : 1) : 0;
|
||||
|
||||
/* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */
|
||||
if (dlsch_config_pdu_1_0->number_symbols == 2)
|
||||
@@ -1077,7 +1088,30 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
if(pdsch_TimeDomainAllocationList)
|
||||
mappingtype = pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType;
|
||||
|
||||
dlsch_config_pdu_1_1->dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2;
|
||||
struct NR_DMRS_DownlinkConfig *dl_dmrs_config = (mappingtype == typeA) ?
|
||||
pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup :
|
||||
pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
|
||||
|
||||
switch (dci->dmrs_sequence_initialization.val) {
|
||||
case 0:
|
||||
dlsch_config_pdu_1_1->nscid = 0;
|
||||
if(dl_dmrs_config->scramblingID0)
|
||||
dlsch_config_pdu_1_1->dlDmrsScramblingId = *dl_dmrs_config->scramblingID0;
|
||||
else
|
||||
dlsch_config_pdu_1_1->dlDmrsScramblingId = mac->physCellId;
|
||||
break;
|
||||
case 1:
|
||||
dlsch_config_pdu_1_1->nscid = 1;
|
||||
if(dl_dmrs_config->scramblingID1)
|
||||
dlsch_config_pdu_1_1->dlDmrsScramblingId = *dl_dmrs_config->scramblingID1;
|
||||
else
|
||||
dlsch_config_pdu_1_1->dlDmrsScramblingId = mac->physCellId;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid dmrs sequence initialization value\n");
|
||||
}
|
||||
|
||||
dlsch_config_pdu_1_1->dmrsConfigType = dl_dmrs_config->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2;
|
||||
|
||||
/* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214,
|
||||
using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */
|
||||
@@ -1138,17 +1172,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
|
||||
/* ANTENNA_PORTS */
|
||||
uint8_t n_codewords = 1; // FIXME!!!
|
||||
long *max_length = NULL;
|
||||
long *dmrs_type = NULL;
|
||||
long *max_length = dl_dmrs_config->maxLength;
|
||||
long *dmrs_type = dl_dmrs_config->dmrs_Type;
|
||||
|
||||
dlsch_config_pdu_1_1->n_front_load_symb = 1; // default value
|
||||
if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA) {
|
||||
max_length = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength;
|
||||
dmrs_type = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type;
|
||||
}
|
||||
if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB) {
|
||||
max_length = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength;
|
||||
dmrs_type = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type;
|
||||
}
|
||||
|
||||
if ((dmrs_type == NULL) && (max_length == NULL)){
|
||||
// Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1
|
||||
dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_1[dci->antenna_ports.val][0];
|
||||
@@ -1370,10 +1398,18 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
|
||||
// FIXME k0 != 0 currently not taken into consideration
|
||||
current_harq->dl_frame = frame;
|
||||
current_harq->dl_slot = slot;
|
||||
mac->nr_ue_emul_l1.active_harq_sfn_slot = NFAPI_SFNSLOT2HEX(frame, (slot + data_toul_fb));
|
||||
if (get_softmodem_params()->emulate_l1) {
|
||||
int scs = get_softmodem_params()->numerology;
|
||||
int slots_per_frame = nr_slots_per_frame[scs];
|
||||
slot += data_toul_fb;
|
||||
if (slot >= slots_per_frame) {
|
||||
frame = (frame + 1) % 1024;
|
||||
slot %= slots_per_frame;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d\n",
|
||||
harq_id, frame, slot, frame, (slot + data_toul_fb));
|
||||
harq_id, current_harq->dl_frame, current_harq->dl_slot, frame, slot);
|
||||
}
|
||||
|
||||
|
||||
@@ -1855,7 +1891,8 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size) {
|
||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id] != NULL)) {
|
||||
if (uci_size <= 2) {
|
||||
// PUCCH with format0 can be up to 3 bits (2 ack/nacks + 1 sr is 3 max bits)
|
||||
if (uci_size <= 3) {
|
||||
pucch_resource_set_id = 0;
|
||||
return (pucch_resource_set_id);
|
||||
break;
|
||||
@@ -2056,11 +2093,17 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
|
||||
sched_frame = current_harq->dl_frame;
|
||||
if (sched_slot>=slots_per_frame){
|
||||
sched_slot %= slots_per_frame;
|
||||
sched_frame++;
|
||||
sched_frame = (sched_frame + 1) % 1024;
|
||||
}
|
||||
AssertFatal(sched_slot < slots_per_frame, "sched_slot was calculated incorrect %d\n", sched_slot);
|
||||
LOG_D(PHY,"HARQ pid %d is active for %d.%d (dl_slot %d, feedback_to_ul %d, is_common %d\n",dl_harq_pid, sched_frame,sched_slot,current_harq->dl_slot,current_harq->feedback_to_ul,current_harq->is_common);
|
||||
/* check if current tx slot should transmit downlink acknowlegment */
|
||||
if (sched_frame == frame && sched_slot == slot) {
|
||||
if (get_softmodem_params()->emulate_l1) {
|
||||
mac->nr_ue_emul_l1.harq[dl_harq_pid].active = true;
|
||||
mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_sfn = frame;
|
||||
mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_slot = slot;
|
||||
}
|
||||
|
||||
if (current_harq->dai > NR_DL_MAX_DAI) {
|
||||
LOG_E(MAC,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
|
||||
|
||||
@@ -736,6 +736,11 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
? pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
|
||||
}
|
||||
|
||||
pusch_config_pdu->scid = 0;
|
||||
pusch_config_pdu->ul_dmrs_scrambling_id = mac->physCellId;
|
||||
if(*dci_format == NR_UL_DCI_FORMAT_0_1)
|
||||
pusch_config_pdu->scid = dci->dmrs_sequence_initialization.val;
|
||||
|
||||
/* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/
|
||||
|
||||
if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) {
|
||||
@@ -761,6 +766,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", pusch_config_pdu->num_dmrs_cdm_grps_no_data,
|
||||
pusch_config_pdu->dfts_ofdm.low_papr_group_number);
|
||||
}
|
||||
else {
|
||||
if (pusch_config_pdu->scid == 0 &&
|
||||
NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0)
|
||||
pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0;
|
||||
if (pusch_config_pdu->scid == 1 &&
|
||||
NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1)
|
||||
pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1;
|
||||
}
|
||||
|
||||
/* TRANSFORM PRECODING --------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -1081,6 +1094,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
else
|
||||
{
|
||||
dl_config->number_pdus = 0;
|
||||
}
|
||||
}
|
||||
} else if (ul_info) {
|
||||
|
||||
@@ -2253,26 +2270,27 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
|
||||
int O_CSI = 0;
|
||||
int N_UCI = 0;
|
||||
|
||||
PUCCH_sched_t *pucch = calloc(1,sizeof(*pucch));
|
||||
pucch->resource_indicator = -1;
|
||||
pucch->initial_pucch_id = -1;
|
||||
PUCCH_sched_t pucch = {
|
||||
.resource_indicator = -1,
|
||||
.initial_pucch_id = -1
|
||||
};
|
||||
uint16_t rnti = mac->crnti; //FIXME not sure this is valid for all pucch instances
|
||||
|
||||
// SR
|
||||
if(trigger_periodic_scheduling_request(mac, pucch, frameP, slotP)) {
|
||||
if (trigger_periodic_scheduling_request(mac, &pucch, frameP, slotP)) {
|
||||
O_SR = 1;
|
||||
/* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
|
||||
pucch->sr_payload = nr_ue_get_SR(module_idP,
|
||||
pucch.sr_payload = nr_ue_get_SR(module_idP,
|
||||
frameP,
|
||||
slotP);
|
||||
}
|
||||
|
||||
// CSI
|
||||
if (mac->ra.ra_state == RA_SUCCEEDED || get_softmodem_params()->phy_test == 1)
|
||||
O_CSI = nr_get_csi_measurements(mac, frameP, slotP, pucch);
|
||||
O_CSI = nr_get_csi_measurements(mac, frameP, slotP, &pucch);
|
||||
|
||||
// ACKNACK
|
||||
O_ACK = get_downlink_ack(mac, frameP, slotP, pucch);
|
||||
O_ACK = get_downlink_ack(mac, frameP, slotP, &pucch);
|
||||
|
||||
NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
|
||||
NR_PUCCH_Config_t *pucch_Config = NULL;
|
||||
@@ -2302,35 +2320,39 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
|
||||
pucch_Config->format2 &&
|
||||
(pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI == NULL)) {
|
||||
O_CSI = 0;
|
||||
pucch->csi_part1_payload = 0;
|
||||
pucch->csi_part2_payload = 0;
|
||||
pucch.csi_part1_payload = 0;
|
||||
pucch.csi_part2_payload = 0;
|
||||
}
|
||||
|
||||
N_UCI = O_SR + O_ACK + O_CSI;
|
||||
mac->nr_ue_emul_l1.num_srs = O_SR;
|
||||
mac->nr_ue_emul_l1.num_harqs = O_ACK;
|
||||
mac->nr_ue_emul_l1.num_csi_reports = O_CSI;
|
||||
|
||||
// do no transmit pucch if only SR scheduled and it is negative
|
||||
if ((O_ACK + O_CSI) == 0 && pucch->sr_payload == 0)
|
||||
if ((O_ACK + O_CSI) == 0 && pucch.sr_payload == 0)
|
||||
return;
|
||||
|
||||
if (N_UCI > 0) {
|
||||
LOG_D(NR_MAC,"%d.%d configure pucch, O_SR %d, O_ACK %d, O_CSI %d\n",frameP,slotP,O_SR,O_ACK,O_CSI);
|
||||
pucch->resource_set_id = find_pucch_resource_set(mac, O_ACK + O_CSI);
|
||||
select_pucch_resource(mac, pucch);
|
||||
pucch.resource_set_id = find_pucch_resource_set(mac, O_ACK + O_CSI);
|
||||
select_pucch_resource(mac, &pucch);
|
||||
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
|
||||
pthread_mutex_lock(&ul_config->mutex_ul_config);
|
||||
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu;
|
||||
|
||||
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
|
||||
mac->nr_ue_emul_l1.active_uci_sfn_slot = NFAPI_SFNSLOT2HEX(frameP, slotP);
|
||||
pthread_mutex_unlock(&ul_config->mutex_ul_config);
|
||||
|
||||
nr_ue_configure_pucch(mac,
|
||||
slotP,
|
||||
rnti,
|
||||
pucch,
|
||||
&pucch,
|
||||
pucch_pdu,
|
||||
O_SR, O_ACK, O_CSI);
|
||||
LOG_D(NR_MAC,"Configuring pucch, is_common = %d\n",pucch->is_common);
|
||||
LOG_D(NR_MAC, "Configuring pucch, is_common = %d\n", pucch.is_common);
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id, NULL);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
||||
|
||||
@@ -458,9 +458,10 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
int minRXTXTIMEpdsch,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BCCH_BCH_Message_t *mib,
|
||||
int add_ue,
|
||||
NR_BCCH_DL_SCH_Message_t *sib1,
|
||||
int add_ue,
|
||||
uint32_t rnti,
|
||||
NR_CellGroupConfig_t *CellGroup) {
|
||||
NR_CellGroupConfig_t *CellGroup) {
|
||||
|
||||
if (scc != NULL ) {
|
||||
AssertFatal((scc->ssb_PositionsInBurst->present > 0) && (scc->ssb_PositionsInBurst->present < 4), "SSB Bitmap type %d is not valid\n",scc->ssb_PositionsInBurst->present);
|
||||
@@ -568,28 +569,34 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
}
|
||||
}
|
||||
|
||||
if (mib) RC.nrmac[Mod_idP]->common_channels[0].mib = mib;
|
||||
|
||||
if (mib) RC.nrmac[Mod_idP]->common_channels[0].mib = mib;
|
||||
if (sib1) RC.nrmac[Mod_idP]->common_channels[0].sib1 = sib1;
|
||||
|
||||
if (CellGroup) {
|
||||
|
||||
const NR_ServingCellConfig_t *servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
|
||||
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
|
||||
if(bwpList) {
|
||||
AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n");
|
||||
for (int i = 0; i < bwpList->list.count; ++i) {
|
||||
const NR_BWP_Downlink_t *bwp = bwpList->list.array[i];
|
||||
calculate_preferred_dl_tda(Mod_idP, bwp);
|
||||
}
|
||||
} else {
|
||||
if (get_softmodem_params()->sa) {
|
||||
calculate_preferred_dl_tda(Mod_idP, NULL);
|
||||
}
|
||||
|
||||
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
|
||||
if(ubwpList) {
|
||||
AssertFatal(ubwpList->list.count > 0, "uplinkBWP_ToAddModList no BWPs!\n");
|
||||
for (int i = 0; i < ubwpList->list.count; ++i) {
|
||||
const NR_BWP_Uplink_t *ubwp = ubwpList->list.array[i];
|
||||
calculate_preferred_ul_tda(Mod_idP, ubwp);
|
||||
const NR_ServingCellConfig_t *servingCellConfig = NULL;
|
||||
if(CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated) {
|
||||
servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
|
||||
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
|
||||
if(bwpList) {
|
||||
AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n");
|
||||
for (int i = 0; i < bwpList->list.count; ++i) {
|
||||
const NR_BWP_Downlink_t *bwp = bwpList->list.array[i];
|
||||
calculate_preferred_dl_tda(Mod_idP, bwp);
|
||||
}
|
||||
}
|
||||
|
||||
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
|
||||
if(ubwpList) {
|
||||
AssertFatal(ubwpList->list.count > 0, "uplinkBWP_ToAddModList no BWPs!\n");
|
||||
for (int i = 0; i < ubwpList->list.count; ++i) {
|
||||
const NR_BWP_Uplink_t *ubwp = ubwpList->list.array[i];
|
||||
calculate_preferred_ul_tda(Mod_idP, ubwp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,7 +656,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
UE_info->CellGroup[UE_id] = CellGroup;
|
||||
LOG_I(NR_MAC,"Modified UE_id %d/%x with CellGroup\n",UE_id,rnti);
|
||||
process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]);
|
||||
const NR_ServingCellConfig_t *servingCellConfig = CellGroup ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
sched_ctrl->update_pdsch_ps = true;
|
||||
sched_ctrl->update_pusch_ps = true;
|
||||
@@ -674,16 +680,14 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
bwpd = (void*)CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP;
|
||||
genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Either initial BWP or active BWP should always be present\n");
|
||||
sched_ctrl->search_space = get_searchspace(scc, bwpd, target_ss);
|
||||
sched_ctrl->search_space = get_searchspace(sib1 ? sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL, scc, bwpd, target_ss);
|
||||
sched_ctrl->coreset = get_coreset(Mod_idP, scc, bwpd, sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[Mod_idP],
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
scc,
|
||||
genericParameters,
|
||||
NULL);
|
||||
RC.nrmac[Mod_idP]->type0_PDCCH_CSS_config);
|
||||
sched_ctrl->maxL = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +300,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
|
||||
(RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index;
|
||||
|
||||
if((prach_occasion_id < cc->total_prach_occasions) && (td_index == 0)){
|
||||
AssertFatal(UL_tti_req->n_pdus < sizeof(UL_tti_req->pdus_list) / sizeof(UL_tti_req->pdus_list[0]),
|
||||
"Invalid UL_tti_req->n_pdus %d\n", UL_tti_req->n_pdus);
|
||||
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
|
||||
@@ -635,7 +637,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
ra->coreset,
|
||||
scc,
|
||||
genericParameters,
|
||||
NULL);
|
||||
&nr_mac->type0_PDCCH_CSS_config[ra->beam_id]);
|
||||
|
||||
// retrieving ra pdcch monitoring period and offset
|
||||
find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset);
|
||||
@@ -803,6 +805,9 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
future_ul_tti_req->Slot,
|
||||
sched_frame,
|
||||
sched_slot);
|
||||
AssertFatal(future_ul_tti_req->n_pdus <
|
||||
sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
|
||||
"Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
|
||||
@@ -871,7 +876,9 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
dci_pdu_rel15_t uldci_payload;
|
||||
memset(&uldci_payload, 0, sizeof(uldci_payload));
|
||||
|
||||
config_uldci(ubwp,
|
||||
const NR_SIB1_t *sib1 = cc->sib1 ? cc->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
config_uldci(sib1,
|
||||
ubwp,
|
||||
ubwpd,
|
||||
scc,
|
||||
pusch_pdu,
|
||||
@@ -889,7 +896,8 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
NR_UL_DCI_FORMAT_0_0,
|
||||
NR_RNTI_TC,
|
||||
pusch_pdu->bwp_size,
|
||||
ra->bwp_id);
|
||||
ra->bwp_id,
|
||||
nr_mac->cset0_bwp_size);
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
|
||||
@@ -1460,7 +1468,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
NR_DL_DCI_FORMAT_1_0,
|
||||
NR_RNTI_RA,
|
||||
BWPSize,
|
||||
bwpid);
|
||||
bwpid,
|
||||
nr_mac->cset0_bwp_size);
|
||||
|
||||
// DL TX request
|
||||
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
|
||||
@@ -1602,17 +1611,11 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
return;
|
||||
}
|
||||
|
||||
int n_rb=0;
|
||||
for (int i=0;i<6;i++)
|
||||
for (int j=0;j<8;j++) {
|
||||
n_rb+=((coreset->frequencyDomainResources.buf[i]>>j)&1);
|
||||
}
|
||||
n_rb*=6;
|
||||
const uint16_t N_cce = n_rb * coreset->duration / NR_NB_REG_PER_CCE;
|
||||
const int delta_PRI=0;
|
||||
int r_pucch = ((CCEIndex<<1)/N_cce)+(delta_PRI<<1);
|
||||
int r_pucch = nr_get_pucch_resource(coreset, sched_ctrl->active_ubwp, NULL, CCEIndex);
|
||||
|
||||
LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, nb_of_candidates %d, delta_PRI %d)\n", r_pucch, CCEIndex, nr_of_candidates, delta_PRI);
|
||||
|
||||
LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, N_cce %d, nb_of_candidates %d,delta_PRI %d)\n",r_pucch,CCEIndex,N_cce,nr_of_candidates,delta_PRI);
|
||||
int alloc = nr_acknack_scheduling(module_idP, UE_id, frameP, slotP, r_pucch, 1);
|
||||
AssertFatal(alloc>=0,"Couldn't find a pucch allocation for ack nack (msg4)\n");
|
||||
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc];
|
||||
@@ -1853,7 +1856,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
NR_DL_DCI_FORMAT_1_0,
|
||||
NR_RNTI_TC,
|
||||
pdsch_pdu_rel15->BWPSize,
|
||||
bwpid);
|
||||
bwpid,
|
||||
nr_mac->cset0_bwp_size);
|
||||
|
||||
// Add padding header and zero rest out if there is space left
|
||||
if (ra->mac_pdu_length < harq->tb_size) {
|
||||
|
||||
@@ -545,7 +545,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
dci_format,
|
||||
rnti_type,
|
||||
pdsch_pdu_rel15->BWPSize,
|
||||
0);
|
||||
0,
|
||||
gNB_mac->cset0_bwp_size);
|
||||
|
||||
LOG_D(MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
|
||||
LOG_D(MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart);
|
||||
@@ -620,6 +621,8 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
1, &is_typeA,
|
||||
&startSymbolIndex, &nrOfSymbols);
|
||||
|
||||
AssertFatal((startSymbolIndex+nrOfSymbols)<14,"SIB1 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n",time_domain_allocation);
|
||||
|
||||
int mappingtype = is_typeA? typeA: typeB;
|
||||
uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex, mappingtype, 1);
|
||||
|
||||
|
||||
@@ -86,16 +86,22 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
|
||||
else {
|
||||
target_ss = NR_SearchSpace__searchSpaceType_PR_common;
|
||||
}
|
||||
NR_SearchSpace_t *search_space = get_searchspace(scc, bwp ? bwp->bwp_Dedicated : NULL, target_ss);
|
||||
const NR_SIB1_t *sib1 = nrmac->common_channels[0].sib1 ? nrmac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_SearchSpace_t *search_space = get_searchspace(sib1,
|
||||
scc,
|
||||
bwp ? bwp->bwp_Dedicated : NULL,
|
||||
target_ss);
|
||||
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(module_id, scc, bwp ? bwp->bwp_Dedicated : NULL, search_space, target_ss);
|
||||
// get coreset symbol "map"
|
||||
const uint16_t symb_coreset = (1 << coreset->duration) - 1;
|
||||
|
||||
/* check that TDA index 0 fits into DL and does not overlap CORESET */
|
||||
const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = bwp ?
|
||||
bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = get_pdsch_TimeDomainAllocationList(bwp,
|
||||
scc,
|
||||
sib1);
|
||||
AssertFatal(tdaList->list.count >= 1, "need to have at least one TDA for DL slots\n");
|
||||
|
||||
/* check that TDA index 0 fits into DL and does not overlap CORESET */
|
||||
const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_DL = tdaList->list.array[0];
|
||||
AssertFatal(!tdaP_DL->k0 || *tdaP_DL->k0 == 0,
|
||||
"TimeDomainAllocation at index 1: non-null k0 (%ld) is not supported by the scheduler\n",
|
||||
@@ -525,19 +531,33 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
int UE_id,
|
||||
int current_harq_pid) {
|
||||
|
||||
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_DownlinkDedicated_t *bwpd= cg ? cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP:NULL;
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
cg &&
|
||||
cg->spCellConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated ?
|
||||
cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
|
||||
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
|
||||
&sched_ctrl->active_bwp->bwp_Common->genericParameters :
|
||||
&RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
NR_BWP_UplinkDedicated_t *ubwpd =
|
||||
cg &&
|
||||
cg->spCellConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
|
||||
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
||||
sib1);
|
||||
|
||||
const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
@@ -565,7 +585,15 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
/* check whether we need to switch the TDA allocation since the last
|
||||
* (re-)transmission */
|
||||
if (ps->time_domain_allocation != tda || sched_ctrl->update_pdsch_ps) {
|
||||
nr_set_pdsch_semi_static(scc, cg, sched_ctrl->active_bwp, bwpd, tda, ps->nrOfLayers, sched_ctrl, ps);
|
||||
nr_set_pdsch_semi_static(sib1,
|
||||
scc,
|
||||
cg,
|
||||
sched_ctrl->active_bwp,
|
||||
bwpd,
|
||||
tda,
|
||||
ps->nrOfLayers,
|
||||
sched_ctrl,
|
||||
ps);
|
||||
sched_ctrl->update_pdsch_ps = false;
|
||||
}
|
||||
} else {
|
||||
@@ -573,7 +601,15 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
* that we have enough resources */
|
||||
|
||||
NR_pdsch_semi_static_t temp_ps = *ps;
|
||||
nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, bwpd, tda, ps->nrOfLayers, sched_ctrl, &temp_ps);
|
||||
nr_set_pdsch_semi_static(sib1,
|
||||
scc,
|
||||
UE_info->CellGroup[UE_id],
|
||||
sched_ctrl->active_bwp,
|
||||
bwpd,
|
||||
tda,
|
||||
ps->nrOfLayers,
|
||||
sched_ctrl,
|
||||
&temp_ps);
|
||||
while (rbStart < bwpSize &&
|
||||
!(rballoc_mask[rbStart]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
|
||||
rbStart++;
|
||||
@@ -634,7 +670,8 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
|
||||
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
||||
* allocation after CCE alloc fail would be more complex) */
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1, 0);
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
||||
if (alloc<0) {
|
||||
LOG_D(MAC,
|
||||
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
@@ -765,15 +802,30 @@ void pf_dl(module_id_t module_id,
|
||||
*max = UE_sched.next[*max];
|
||||
*p = -1;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_DownlinkDedicated_t *bwpd= cg ? cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP:NULL;
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
cg &&
|
||||
cg->spCellConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated ?
|
||||
cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
|
||||
|
||||
NR_BWP_UplinkDedicated_t *ubwpd =
|
||||
cg &&
|
||||
cg->spCellConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
|
||||
&sched_ctrl->active_bwp->bwp_Common->genericParameters:
|
||||
&scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
|
||||
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
||||
sib1);
|
||||
|
||||
const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
if (sched_ctrl->available_dl_harq.head < 0) {
|
||||
@@ -809,7 +861,8 @@ void pf_dl(module_id_t module_id,
|
||||
|
||||
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
||||
* allocation after CCE alloc fail would be more complex) */
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1, 0);
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
||||
if (alloc<0) {
|
||||
LOG_D(NR_MAC,
|
||||
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
@@ -846,10 +899,16 @@ void pf_dl(module_id_t module_id,
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
|
||||
if (ps->nrOfLayers != layers[UE_id] ||
|
||||
ps->time_domain_allocation != tda ||
|
||||
sched_ctrl->update_pdsch_ps) {
|
||||
nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, bwpd, tda, layers[UE_id], sched_ctrl, ps);
|
||||
if (ps->nrOfLayers != layers[UE_id] || ps->time_domain_allocation != tda || sched_ctrl->update_pdsch_ps) {
|
||||
nr_set_pdsch_semi_static(sib1,
|
||||
scc,
|
||||
UE_info->CellGroup[UE_id],
|
||||
sched_ctrl->active_bwp,
|
||||
bwpd,
|
||||
tda,
|
||||
layers[UE_id],
|
||||
sched_ctrl,
|
||||
ps);
|
||||
sched_ctrl->update_pdsch_ps = false;
|
||||
}
|
||||
|
||||
@@ -921,14 +980,21 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp ?
|
||||
sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const uint16_t BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp ?
|
||||
sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
|
||||
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
||||
sib1);
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
UE_info->CellGroup[UE_id] &&
|
||||
UE_info->CellGroup[UE_id]->spCellConfig &&
|
||||
UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated ?
|
||||
UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
|
||||
|
||||
const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
|
||||
const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
const uint16_t BWPStart = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_start : NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols);
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
@@ -1008,7 +1074,12 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
UE_info->mac_stats[UE_id].dlsch_current_bytes = 0;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_DownlinkDedicated_t *bwpd= cg ? cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP:NULL;
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
cg &&
|
||||
cg->spCellConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated ?
|
||||
cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
|
||||
|
||||
/* update TA and set ta_apply every 10 frames.
|
||||
* Possible improvement: take the periodicity from input file.
|
||||
@@ -1087,15 +1158,17 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
sched_ctrl->tpc1);
|
||||
|
||||
NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(bwp,
|
||||
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
||||
sib1);
|
||||
|
||||
/* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not
|
||||
* exist, create it */
|
||||
|
||||
// BWP
|
||||
NR_BWP_t *genericParameters = bwp ? &bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
NR_SearchSpace_t *ss = (bwp||bwpd) ? sched_ctrl->search_space : gNB_mac->sched_ctrlCommon->search_space;
|
||||
|
||||
const int bwpid = bwp ? bwp->bwp_Id : 0;
|
||||
const int coresetid = (bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : gNB_mac->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
|
||||
/* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it */
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][coresetid];
|
||||
if (!pdcch_pdu) {
|
||||
LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n");
|
||||
@@ -1126,8 +1199,14 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
const int pduindex = gNB_mac->pdu_index[CC_id]++;
|
||||
pdsch_pdu->pduIndex = pduindex;
|
||||
|
||||
pdsch_pdu->BWPSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pdsch_pdu->BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
if (coresetid == 0) {
|
||||
pdsch_pdu->BWPSize = gNB_mac->cset0_bwp_size;
|
||||
pdsch_pdu->BWPStart = gNB_mac->cset0_bwp_start;
|
||||
} else {
|
||||
pdsch_pdu->BWPSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pdsch_pdu->BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
}
|
||||
|
||||
pdsch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing;
|
||||
|
||||
pdsch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0;
|
||||
@@ -1257,14 +1336,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
dci_payload.tpc,
|
||||
pucch->timing_indicator);
|
||||
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
int dci_format;
|
||||
if (sched_ctrl->search_space) {
|
||||
dci_format = f ? NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0;
|
||||
}
|
||||
else {
|
||||
dci_format = NR_DL_DCI_FORMAT_1_0;
|
||||
}
|
||||
int dci_format = ss && ss->searchSpaceType && ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ?
|
||||
NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0;
|
||||
|
||||
const int rnti_type = NR_RNTI_C;
|
||||
|
||||
fill_dci_pdu_rel15(scc,
|
||||
@@ -1274,7 +1348,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
dci_format,
|
||||
rnti_type,
|
||||
pdsch_pdu->BWPSize,
|
||||
bwp? bwp->bwp_Id : 0);
|
||||
bwp? bwp->bwp_Id : 0,
|
||||
gNB_mac->cset0_bwp_size);
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
|
||||
|
||||
@@ -280,7 +280,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
ps->nrOfLayers = target_dl_Nl;
|
||||
|
||||
if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl)
|
||||
nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, NULL, tda, target_dl_Nl, sched_ctrl, ps);
|
||||
nr_set_pdsch_semi_static(NULL, scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, NULL, tda, target_dl_Nl, sched_ctrl, ps);
|
||||
|
||||
/* find largest unallocated chunk */
|
||||
const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
@@ -357,7 +357,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
__func__,
|
||||
UE_id);
|
||||
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1, 0);
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, NULL, CCEIndex);
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
||||
if (alloc < 0) {
|
||||
LOG_D(MAC,
|
||||
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
@@ -442,7 +443,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
"time domain assignment %d >= %d\n",
|
||||
tda,
|
||||
tdaList->list.count);
|
||||
int K2 = get_K2(scc,sched_ctrl->active_ubwp, tda, mu);
|
||||
int K2 = get_K2(scc,NULL,sched_ctrl->active_ubwp, tda, mu);
|
||||
const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
|
||||
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
|
||||
/* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE
|
||||
@@ -451,7 +452,9 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
if (!is_xlsch_in_slot(ulsch_slot_bitmap, sched_slot))
|
||||
return false;
|
||||
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
const long f = (sched_ctrl->active_bwp && sched_ctrl->search_space &&
|
||||
sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ?
|
||||
sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0;
|
||||
const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = 1;
|
||||
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
||||
@@ -461,7 +464,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
nr_set_pusch_semi_static(NULL, scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
|
||||
uint16_t rbStart = 0;
|
||||
uint16_t rbSize;
|
||||
|
||||
@@ -226,6 +226,49 @@ void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) {
|
||||
}
|
||||
}
|
||||
|
||||
NR_BWP_t *get_dl_bwp_genericParameters(NR_BWP_Downlink_t *active_bwp,
|
||||
NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
|
||||
const NR_SIB1_t *sib1) {
|
||||
NR_BWP_t *genericParameters = NULL;
|
||||
if (active_bwp) {
|
||||
genericParameters = &active_bwp->bwp_Common->genericParameters;
|
||||
} else if (ServingCellConfigCommon) {
|
||||
genericParameters = &ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
} else {
|
||||
genericParameters = &sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters;
|
||||
}
|
||||
return genericParameters;
|
||||
}
|
||||
|
||||
NR_BWP_t *get_ul_bwp_genericParameters(NR_BWP_Uplink_t *active_ubwp,
|
||||
NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
|
||||
const NR_SIB1_t *sib1) {
|
||||
NR_BWP_t *genericParameters = NULL;
|
||||
if (active_ubwp) {
|
||||
genericParameters = &active_ubwp->bwp_Common->genericParameters;
|
||||
} else if (ServingCellConfigCommon) {
|
||||
genericParameters = &ServingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
} else {
|
||||
genericParameters = &sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.genericParameters;
|
||||
}
|
||||
return genericParameters;
|
||||
}
|
||||
|
||||
NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(const NR_BWP_Downlink_t *active_bwp,
|
||||
const NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
|
||||
const NR_SIB1_t *sib1) {
|
||||
NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = NULL;
|
||||
if (active_bwp) {
|
||||
tdaList = active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
} else if (ServingCellConfigCommon) {
|
||||
tdaList = ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
} else {
|
||||
tdaList = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
}
|
||||
return tdaList;
|
||||
}
|
||||
|
||||
|
||||
NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
void *bwp,
|
||||
@@ -262,17 +305,29 @@ NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
|
||||
}
|
||||
}
|
||||
|
||||
NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
|
||||
NR_SearchSpace__searchSpaceType_PR target_ss) {
|
||||
NR_SearchSpace_t *get_searchspace(const NR_SIB1_t *sib1,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
|
||||
NR_SearchSpace__searchSpaceType_PR target_ss) {
|
||||
|
||||
int n = 0;
|
||||
if(bwp_Dedicated) {
|
||||
n = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;
|
||||
} else if(scc) {
|
||||
n = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count;
|
||||
} else {
|
||||
n = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count;
|
||||
}
|
||||
|
||||
const int n = bwp_Dedicated ?
|
||||
bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count:
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count;
|
||||
for (int i=0;i<n;i++) {
|
||||
NR_SearchSpace_t *ss = bwp_Dedicated ?
|
||||
bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]:
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i];
|
||||
NR_SearchSpace_t *ss = NULL;
|
||||
if(bwp_Dedicated) {
|
||||
ss = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
|
||||
} else if(scc) {
|
||||
ss = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i];
|
||||
} else {
|
||||
ss = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->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) {
|
||||
@@ -504,7 +559,8 @@ bool nr_find_nb_rb(uint16_t Qm,
|
||||
return *tbs >= bytes && *nb_rb <= nb_rb_max;
|
||||
}
|
||||
|
||||
void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
const NR_BWP_Downlink_t *bwp,
|
||||
const NR_BWP_DownlinkDedicated_t *bwpd0,
|
||||
@@ -523,7 +579,8 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
bwpd = (NR_BWP_DownlinkDedicated_t*)bwpd0;
|
||||
}
|
||||
|
||||
if (bwpd->pdsch_Config &&
|
||||
if (bwpd &&
|
||||
bwpd->pdsch_Config &&
|
||||
bwpd->pdsch_Config->choice.setup &&
|
||||
bwpd->pdsch_Config->choice.setup->mcs_Table) {
|
||||
if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0)
|
||||
@@ -546,9 +603,7 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
if (ps->time_domain_allocation != tda) {
|
||||
reset_dmrs = true;
|
||||
ps->time_domain_allocation = tda;
|
||||
const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = bwp ?
|
||||
bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = get_pdsch_TimeDomainAllocationList(bwp, scc, sib1);
|
||||
AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
|
||||
ps->mapping_type = tdaList->list.array[tda]->mappingType;
|
||||
if (pdsch_Config) {
|
||||
@@ -563,7 +618,11 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols);
|
||||
}
|
||||
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
const long f = ((bwp || bwpd) &&
|
||||
sched_ctrl->search_space &&
|
||||
sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ?
|
||||
sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0;
|
||||
|
||||
int dci_format;
|
||||
if (sched_ctrl->search_space) {
|
||||
dci_format = f ? NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0;
|
||||
@@ -592,33 +651,39 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
ps->N_PRB_DMRS = ps->numDmrsCdmGrpsNoData * (ps->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
|
||||
|
||||
if (reset_dmrs) {
|
||||
ps->dl_dmrs_symb_pos = fill_dmrs_mask(bwpd ? bwpd->pdsch_Config->choice.setup : NULL, scc->dmrs_TypeA_Position, ps->nrOfSymbols, ps->startSymbolIndex, ps->mapping_type, ps->frontloaded_symb);
|
||||
ps->dl_dmrs_symb_pos = fill_dmrs_mask(bwpd ? bwpd->pdsch_Config->choice.setup : NULL, scc ? scc->dmrs_TypeA_Position : 0, ps->nrOfSymbols, ps->startSymbolIndex, ps->mapping_type, ps->frontloaded_symb);
|
||||
ps->N_DMRS_SLOT = get_num_dmrs(ps->dl_dmrs_symb_pos);
|
||||
}
|
||||
LOG_D(NR_MAC,"bwpd0 %p, bwpd %p : Filling dmrs info, ps->N_PRB_DMRS %d, ps->dl_dmrs_symb_pos %x, ps->N_DMRS_SLOT %d\n",bwpd0,bwpd,ps->N_PRB_DMRS,ps->dl_dmrs_symb_pos,ps->N_DMRS_SLOT);
|
||||
}
|
||||
|
||||
void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
void nr_set_pusch_semi_static(const NR_SIB1_t *sib1,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const NR_BWP_Uplink_t *ubwp,
|
||||
const NR_BWP_UplinkDedicated_t *ubwpd,
|
||||
long dci_format,
|
||||
int tda,
|
||||
uint8_t num_dmrs_cdm_grps_no_data,
|
||||
NR_pusch_semi_static_t *ps)
|
||||
{
|
||||
NR_pusch_semi_static_t *ps) {
|
||||
ps->dci_format = dci_format;
|
||||
ps->time_domain_allocation = tda;
|
||||
|
||||
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
|
||||
ubwp?
|
||||
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList ;
|
||||
NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = NULL;
|
||||
if(ubwp) {
|
||||
tdaList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
} else if(scc) {
|
||||
tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
} else {
|
||||
tdaList = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
}
|
||||
|
||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength,
|
||||
&ps->startSymbolIndex,
|
||||
&ps->nrOfSymbols);
|
||||
|
||||
ps->pusch_Config = ubwp?ubwp->bwp_Dedicated->pusch_Config->choice.setup:(ubwpd ? ubwpd->pusch_Config->choice.setup : NULL);
|
||||
ps->pusch_Config = ubwp && ubwp->bwp_Dedicated && ubwp->bwp_Dedicated->pusch_Config ?
|
||||
ubwp->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd ? ubwpd->pusch_Config->choice.setup : NULL);
|
||||
if (ps->pusch_Config == NULL || !ps->pusch_Config->transformPrecoder)
|
||||
ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder;
|
||||
else
|
||||
@@ -892,7 +957,8 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
|
||||
|
||||
}
|
||||
|
||||
void config_uldci(const NR_BWP_Uplink_t *ubwp,
|
||||
void config_uldci(const NR_SIB1_t *sib1,
|
||||
const NR_BWP_Uplink_t *ubwp,
|
||||
const NR_BWP_UplinkDedicated_t *ubwpd,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
@@ -903,9 +969,11 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
|
||||
int n_ubwp,
|
||||
int bwp_id) {
|
||||
|
||||
const int bw = NRRIV2BW(ubwp ?
|
||||
ubwp->bwp_Common->genericParameters.locationAndBandwidth :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters((NR_BWP_Uplink_t *)ubwp,
|
||||
(NR_ServingCellConfigCommon_t *)scc,
|
||||
(NR_SIB1_t *)sib1);
|
||||
|
||||
const int bw = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
dci_pdu_rel15->frequency_domain_assignment.val =
|
||||
PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw);
|
||||
@@ -1012,9 +1080,24 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
pdcch_pdu->precoderGranularity = coreset->precoderGranularity;
|
||||
}
|
||||
|
||||
int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset,
|
||||
NR_BWP_Uplink_t *bwp,
|
||||
NR_BWP_UplinkDedicated_t *bwpd,
|
||||
int CCEIndex) {
|
||||
int r_pucch = -1;
|
||||
if(bwp == NULL && bwpd == NULL) {
|
||||
int n_rb,rb_offset;
|
||||
get_coreset_rballoc(coreset->frequencyDomainResources.buf,&n_rb,&rb_offset);
|
||||
const uint16_t N_cce = n_rb * coreset->duration / NR_NB_REG_PER_CCE;
|
||||
const int delta_PRI=0;
|
||||
r_pucch = ((CCEIndex<<1)/N_cce)+(delta_PRI<<1);
|
||||
}
|
||||
return r_pucch;
|
||||
}
|
||||
|
||||
// This function configures pucch pdu fapi structure
|
||||
void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
void nr_configure_pucch(const NR_SIB1_t *sib1,
|
||||
nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_CellGroupConfig_t *CellGroup,
|
||||
NR_BWP_Uplink_t *bwp,
|
||||
@@ -1042,7 +1125,13 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
|
||||
uint16_t O_uci = O_csi + O_ack;
|
||||
|
||||
NR_PUSCH_Config_t *pusch_Config = bwp ? bwp->bwp_Dedicated->pusch_Config->choice.setup : bwpd->pusch_Config->choice.setup;
|
||||
NR_PUSCH_Config_t *pusch_Config = NULL;
|
||||
if(bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pusch_Config) {
|
||||
pusch_Config = bwp->bwp_Dedicated->pusch_Config->choice.setup;
|
||||
} else if(bwpd && bwpd->pusch_Config) {
|
||||
pusch_Config = bwpd->pusch_Config->choice.setup;
|
||||
}
|
||||
|
||||
long *pusch_id = pusch_Config ? pusch_Config->dataScramblingIdentityPUSCH : NULL;
|
||||
|
||||
if (pusch_Config && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL)
|
||||
@@ -1051,9 +1140,15 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0;
|
||||
else id0 = scc->physCellId;
|
||||
|
||||
NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon = bwp ?
|
||||
bwp->bwp_Common->pucch_ConfigCommon->choice.setup :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup;
|
||||
NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon = NULL;
|
||||
if(bwp) {
|
||||
pucch_ConfigCommon = bwp->bwp_Common->pucch_ConfigCommon->choice.setup;
|
||||
} else if(scc) {
|
||||
pucch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup;
|
||||
} else {
|
||||
pucch_ConfigCommon = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup;
|
||||
}
|
||||
|
||||
// hop flags and hopping id are valid for any BWP
|
||||
switch (pucch_ConfigCommon->pucch_GroupHopping){
|
||||
case 0 :
|
||||
@@ -1079,9 +1174,9 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
pucch_pdu->hopping_id = *pucch_ConfigCommon->hoppingId;
|
||||
else
|
||||
pucch_pdu->hopping_id = *scc->physCellId;
|
||||
NR_BWP_t *genericParameters = bwp ?
|
||||
&bwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(bwp,scc, sib1);
|
||||
|
||||
pucch_pdu->bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pucch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
pucch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing;
|
||||
@@ -1090,9 +1185,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
LOG_D(NR_MAC,"pucch_acknak: Filling dedicated configuration for PUCCH\n");
|
||||
// we have either a dedicated BWP or Dedicated PUCCH configuration on InitialBWP
|
||||
AssertFatal(bwp!=NULL || bwpd!=NULL,"We need one dedicated configuration for a BWP (neither additional or initial BWP has a dedicated configuration)\n");
|
||||
pucch_Config = bwp ?
|
||||
bwp->bwp_Dedicated->pucch_Config->choice.setup:
|
||||
bwpd->pucch_Config->choice.setup;
|
||||
pucch_Config = bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pucch_Config ?
|
||||
bwp->bwp_Dedicated->pucch_Config->choice.setup : bwpd->pucch_Config->choice.setup;
|
||||
|
||||
AssertFatal(pucch_Config->resourceSetToAddModList!=NULL,
|
||||
"PUCCH resourceSetToAddModList is null\n");
|
||||
@@ -1387,12 +1481,13 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
|
||||
int dci_format,
|
||||
int rnti_type,
|
||||
int N_RB,
|
||||
int bwp_id) {
|
||||
int bwp_id,
|
||||
uint16_t cset0_bwp_size) {
|
||||
uint8_t fsize = 0, pos = 0;
|
||||
|
||||
uint64_t *dci_pdu = (uint64_t *)pdcch_dci_pdu->Payload;
|
||||
*dci_pdu=0;
|
||||
int dci_size = nr_dci_size(scc->downlinkConfigCommon->initialDownlinkBWP,scc->uplinkConfigCommon->initialUplinkBWP, CellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id);
|
||||
int dci_size = nr_dci_size(scc->downlinkConfigCommon->initialDownlinkBWP,scc->uplinkConfigCommon->initialUplinkBWP, CellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id, cset0_bwp_size);
|
||||
pdcch_dci_pdu->PayloadSizeBits = dci_size;
|
||||
AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported");
|
||||
if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1)
|
||||
@@ -1736,7 +1831,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
|
||||
pos+=4;
|
||||
*dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid & 0xf) << (dci_size - pos);
|
||||
// Padding bits
|
||||
for (int a = pos; a < 32; a++)
|
||||
for (int a = pos; a < dci_size; a++)
|
||||
*dci_pdu |= ((uint64_t)dci_pdu_rel15->padding & 1) << (dci_size - pos++);
|
||||
// UL/SUL indicator – 1 bit
|
||||
/* commented for now (RK): need to get this from BWP descriptor
|
||||
@@ -2182,8 +2277,9 @@ int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig)
|
||||
//------------------------------------------------------------------------------
|
||||
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup)
|
||||
{
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_idP]->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[mod_idP];
|
||||
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
LOG_I(NR_MAC, "[gNB %d] Adding UE with rnti 0x%04x (num_UEs %d)\n",
|
||||
mod_idP,
|
||||
rntiP,
|
||||
@@ -2208,7 +2304,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
|
||||
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
memset(sched_ctrl, 0, sizeof(*sched_ctrl));
|
||||
sched_ctrl->set_mcs = TRUE;
|
||||
sched_ctrl->set_mcs = true;
|
||||
sched_ctrl->ta_frame = 0;
|
||||
sched_ctrl->ta_update = 31;
|
||||
sched_ctrl->ta_apply = false;
|
||||
@@ -2224,7 +2320,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
|
||||
/* set illegal time domain allocation to force recomputation of all fields */
|
||||
sched_ctrl->pdsch_semi_static.time_domain_allocation = -1;
|
||||
sched_ctrl->pusch_semi_static.time_domain_allocation = -1;
|
||||
const NR_ServingCellConfig_t *servingCellConfig = CellGroup ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
|
||||
const NR_ServingCellConfig_t *servingCellConfig = CellGroup && CellGroup->spCellConfig ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
|
||||
|
||||
/* Set default BWPs */
|
||||
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL;
|
||||
@@ -2238,7 +2334,9 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
|
||||
&sched_ctrl->active_bwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
const int target_ss = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific : NR_SearchSpace__searchSpaceType_PR_common;
|
||||
sched_ctrl->search_space = get_searchspace(scc,
|
||||
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
sched_ctrl->search_space = get_searchspace(sib1,
|
||||
scc,
|
||||
sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL,
|
||||
target_ss);
|
||||
sched_ctrl->coreset = get_coreset(mod_idP, scc,
|
||||
@@ -2433,7 +2531,7 @@ void get_pdsch_to_harq_feedback(int Mod_idP,
|
||||
bwpd = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated;
|
||||
ubwpd = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated;
|
||||
}
|
||||
else if (CellGroup) { // this is an initialBWP
|
||||
else if (CellGroup && CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated) { // this is an initialBWP
|
||||
AssertFatal((bwpd=CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)!=NULL,
|
||||
"CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP is null\n");
|
||||
AssertFatal((ubwpd=CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)!=NULL,
|
||||
|
||||
@@ -85,7 +85,9 @@ void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id, int
|
||||
void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR_SRS_Resource_t *srs_resource) {
|
||||
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][slot];
|
||||
|
||||
AssertFatal(future_ul_tti_req->n_pdus <
|
||||
sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
|
||||
"Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE;
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_srs_pdu_t);
|
||||
nfapi_nr_srs_pdu_t *srs_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].srs_pdu;
|
||||
|
||||
@@ -44,7 +44,8 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
||||
const NR_sched_pucch_t *pucch,
|
||||
int UE_id)
|
||||
{
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[mod_id];
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req =
|
||||
&RC.nrmac[mod_id]->UL_tti_req_ahead[0][pucch->ul_slot];
|
||||
@@ -55,6 +56,9 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
||||
future_ul_tti_req->Slot,
|
||||
pucch->frame,
|
||||
pucch->ul_slot);
|
||||
AssertFatal(future_ul_tti_req->n_pdus <
|
||||
sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
|
||||
"Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pucch_pdu;
|
||||
@@ -76,13 +80,16 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
|
||||
NR_CellGroupConfig_t *cg=UE_info->CellGroup[UE_id];
|
||||
|
||||
NR_BWP_UplinkDedicated_t *ubwpd;
|
||||
ubwpd = cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
LOG_D(NR_MAC,"%d.%d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %d.%d\n",
|
||||
frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot);
|
||||
|
||||
nr_configure_pucch(pucch_pdu,
|
||||
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
nr_configure_pucch(sib1,
|
||||
pucch_pdu,
|
||||
scc,
|
||||
UE_info->CellGroup[UE_id],
|
||||
UE_info->UE_sched_ctrl[UE_id].active_ubwp,
|
||||
@@ -742,9 +749,11 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
curr_pucch->csi_bits +=
|
||||
nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id);
|
||||
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ?
|
||||
&sched_ctrl->active_ubwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
scc,
|
||||
sib1);
|
||||
|
||||
int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
|
||||
// going through the list of PUCCH resources to find the one indexed by resource_id
|
||||
|
||||
@@ -39,16 +39,11 @@
|
||||
|
||||
int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
int dci_format;
|
||||
if (sched_ctrl->search_space) {
|
||||
dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
|
||||
}
|
||||
else {
|
||||
dci_format = NR_UL_DCI_FORMAT_0_0;
|
||||
}
|
||||
int dci_format = sched_ctrl->search_space && sched_ctrl->search_space->searchSpaceType &&
|
||||
sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ?
|
||||
NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
|
||||
|
||||
return(dci_format);
|
||||
return(dci_format);
|
||||
}
|
||||
|
||||
void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp)
|
||||
@@ -62,9 +57,22 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
|
||||
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
|
||||
lte_frame_type_t frame_type = nrmac->common_channels->frame_type;
|
||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd =
|
||||
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
|
||||
NR_ServingCellConfigCommonSIB_t *scc_sib1 = get_softmodem_params()->sa ?
|
||||
RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1->servingCellConfigCommon : NULL;
|
||||
|
||||
AssertFatal(scc!=NULL || scc_sib1!=NULL,"We need one serving cell config common\n");
|
||||
|
||||
const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing :
|
||||
scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
||||
|
||||
NR_TDD_UL_DL_Pattern_t *tdd = NULL;
|
||||
if (scc && scc->tdd_UL_DL_ConfigurationCommon) {
|
||||
tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
|
||||
} else if (scc_sib1 && scc_sib1->tdd_UL_DL_ConfigurationCommon) {
|
||||
tdd = &scc_sib1->tdd_UL_DL_ConfigurationCommon->pattern1;
|
||||
}
|
||||
|
||||
/* Uplink symbols are at the end of the slot */
|
||||
int symb_ulMixed = 0;
|
||||
int nr_mix_slots = 0;
|
||||
@@ -118,7 +126,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
|
||||
/* check that TDA index 1 fits into UL slot and does not overlap with PUCCH */
|
||||
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_UL = tdaList->list.array[0];
|
||||
const int k2 = get_K2(scc, (NR_BWP_Uplink_t*)ubwp,0, mu);
|
||||
const int k2 = get_K2(scc, scc_sib1, (NR_BWP_Uplink_t*)ubwp,0, mu);
|
||||
int start, len;
|
||||
SLIV2SL(tdaP_UL->startSymbolAndLength, &start, &len);
|
||||
const uint16_t symb_tda = ((1 << len) - 1) << start;
|
||||
@@ -131,10 +139,10 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
|
||||
int tdaMi = -1;
|
||||
if (nr_mix_slots>0) {
|
||||
const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
|
||||
AssertFatal(k2 == get_K2(scc, (NR_BWP_Uplink_t*)ubwp, 1, mu),
|
||||
AssertFatal(k2 == get_K2(scc, scc_sib1, (NR_BWP_Uplink_t*)ubwp, 1, mu),
|
||||
"scheduler cannot handle different k2 for UL slot (%d) and UL Mixed slot (%ld)\n",
|
||||
k2,
|
||||
get_K2(scc, (NR_BWP_Uplink_t*)ubwp, 1, mu));
|
||||
get_K2(scc, scc_sib1, (NR_BWP_Uplink_t*)ubwp, 1, mu));
|
||||
SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
|
||||
const uint16_t symb_tda_mi = ((1 << len) - 1) << start;
|
||||
// check whether PUCCH and TDA overlap: then, we cannot use it. Also, check
|
||||
@@ -271,9 +279,18 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
case UL_SCH_LCID_L_TRUNCATED_BSR:
|
||||
//38.321 section 6.1.3.1
|
||||
//variable length
|
||||
/* Several checks have been added to this function to
|
||||
ensure that the casting of the pduP is possible. There seems
|
||||
to be a partial PDU at the end of this buffer, so here
|
||||
we gracefully ignore that by returning 0. See:
|
||||
https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues/534 */
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return 0;
|
||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||
return 0;
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
}
|
||||
@@ -350,9 +367,13 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT:
|
||||
//38.321 section 6.1.3.9
|
||||
// varialbe length
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return 0;
|
||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||
return 0;
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
}
|
||||
@@ -362,9 +383,13 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT:
|
||||
//38.321 section 6.1.3.9
|
||||
// varialbe length
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return 0;
|
||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||
return 0;
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
}
|
||||
@@ -378,8 +403,12 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
|
||||
case UL_SCH_LCID_SRB1:
|
||||
case UL_SCH_LCID_SRB2:
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return 0;
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
//mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||
return 0;
|
||||
mac_subheader_len = 3;
|
||||
mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
|
||||
| ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
|
||||
@@ -463,8 +492,12 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
|
||||
case UL_SCH_LCID_DTCH:
|
||||
// check if LCID is valid at current time.
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return 0;
|
||||
if (((NR_MAC_SUBHEADER_SHORT *)pduP)->F) {
|
||||
// mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||
return 0;
|
||||
mac_subheader_len = 3;
|
||||
mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L1 & 0x7f) << 8)
|
||||
| ((uint16_t)((NR_MAC_SUBHEADER_LONG *)pduP)->L2 & 0xff);
|
||||
@@ -897,11 +930,21 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
}
|
||||
}
|
||||
|
||||
long get_K2(NR_ServingCellConfigCommon_t *scc,NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
|
||||
DevAssert(scc);
|
||||
const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp ?
|
||||
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
|
||||
long get_K2(NR_ServingCellConfigCommon_t *scc,
|
||||
NR_ServingCellConfigCommonSIB_t *scc_sib1,
|
||||
NR_BWP_Uplink_t *ubwp,
|
||||
int time_domain_assignment,
|
||||
int mu) {
|
||||
|
||||
NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = NULL;
|
||||
if(ubwp) {
|
||||
tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
|
||||
} else if(scc) {
|
||||
tda_list = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
|
||||
} else if(scc_sib1) {
|
||||
tda_list = scc_sib1->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
|
||||
}
|
||||
|
||||
if (tda_list->k2)
|
||||
return *tda_list->k2;
|
||||
else if (mu < 2)
|
||||
@@ -964,13 +1007,22 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
int harq_pid)
|
||||
{
|
||||
const int CC_id = 0;
|
||||
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
(NR_ServingCellConfigCommon_t *)scc,
|
||||
sib1);
|
||||
|
||||
int rbStart = 0; // wrt BWP start
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
@@ -989,7 +1041,14 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
|
||||
|| sched_ctrl->update_pusch_ps) {
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
nr_set_pusch_semi_static(sib1,
|
||||
scc,
|
||||
sched_ctrl->active_ubwp,
|
||||
ubwpd,
|
||||
dci_format,
|
||||
tda,
|
||||
num_dmrs_cdm_grps_no_data,
|
||||
ps);
|
||||
sched_ctrl->update_pusch_ps = false;
|
||||
}
|
||||
|
||||
@@ -1005,7 +1064,14 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
} else {
|
||||
NR_pusch_semi_static_t temp_ps;
|
||||
int dci_format = get_dci_format(sched_ctrl);
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp,ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, &temp_ps);
|
||||
nr_set_pusch_semi_static(sib1,
|
||||
scc,
|
||||
sched_ctrl->active_ubwp,
|
||||
ubwpd,
|
||||
dci_format,
|
||||
tda,
|
||||
num_dmrs_cdm_grps_no_data,
|
||||
&temp_ps);
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
* that we have enough resources */
|
||||
while (rbStart < bwpSize &&
|
||||
@@ -1127,6 +1193,7 @@ void pf_ul(module_id_t module_id,
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
const int min_rb = 5;
|
||||
float coeff_ue[MAX_MOBILES_PER_GNB];
|
||||
// UEs that could be scheduled
|
||||
@@ -1140,10 +1207,16 @@ void pf_ul(module_id_t module_id,
|
||||
|
||||
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %d\n",UE_id);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
scc,
|
||||
sib1);
|
||||
|
||||
int rbStart = 0; // wrt BWP start
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
@@ -1226,7 +1299,14 @@ void pf_ul(module_id_t module_id,
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
|
||||
|| sched_ctrl->update_pusch_ps) {
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
nr_set_pusch_semi_static(sib1,
|
||||
scc,
|
||||
sched_ctrl->active_ubwp,
|
||||
ubwpd,
|
||||
dci_format,
|
||||
tda,
|
||||
num_dmrs_cdm_grps_no_data,
|
||||
ps);
|
||||
sched_ctrl->update_pusch_ps = false;
|
||||
}
|
||||
|
||||
@@ -1333,8 +1413,14 @@ void pf_ul(module_id_t module_id,
|
||||
AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
|
||||
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated
|
||||
&& cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
scc,
|
||||
sib1);
|
||||
|
||||
int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
@@ -1351,7 +1437,14 @@ void pf_ul(module_id_t module_id,
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
|
||||
|| sched_ctrl->update_pusch_ps) {
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
nr_set_pusch_semi_static(sib1,
|
||||
scc,
|
||||
sched_ctrl->active_ubwp,
|
||||
ubwpd,
|
||||
dci_format,
|
||||
tda,
|
||||
num_dmrs_cdm_grps_no_data,
|
||||
ps);
|
||||
sched_ctrl->update_pusch_ps = false;
|
||||
}
|
||||
update_ul_ue_R_Qm(sched_pusch, ps);
|
||||
@@ -1412,7 +1505,14 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_ServingCellConfigCommonSIB_t *scc_sib1 = sib1 ? sib1->servingCellConfigCommon : NULL;
|
||||
|
||||
AssertFatal(scc!=NULL || scc_sib1!=NULL,"We need one serving cell config common\n");
|
||||
|
||||
const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing :
|
||||
scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
||||
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
|
||||
if (UE_info->num_UEs == 0)
|
||||
@@ -1429,7 +1529,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
if (tda < 0)
|
||||
return false;
|
||||
int K2 = get_K2(scc, sched_ctrl->active_ubwp, tda, mu);
|
||||
int K2 = get_K2(scc, scc_sib1, sched_ctrl->active_ubwp, tda, mu);
|
||||
const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
|
||||
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
|
||||
|
||||
@@ -1461,8 +1561,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
AssertFatal(K2 == get_K2(scc,sched_ctrl->active_ubwp, tda, mu),
|
||||
"Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(scc,sched_ctrl->active_ubwp, tda, mu), UE_id);
|
||||
AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu),
|
||||
"Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE_id);
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
}
|
||||
@@ -1472,17 +1572,24 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
* Calculate largest contiguous RBs */
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const uint16_t bwpStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
scc,
|
||||
sib1);
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
const uint16_t bwpStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
|
||||
NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = NULL;
|
||||
if (sched_ctrl->active_ubwp) {
|
||||
tdaList = sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
} else if (scc) {
|
||||
tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
} else {
|
||||
NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1;
|
||||
tdaList = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
}
|
||||
|
||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
@@ -1577,13 +1684,18 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
const NR_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->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue;
|
||||
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
|
||||
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
UE_info->mac_stats[UE_id].ulsch_current_bytes = 0;
|
||||
|
||||
/* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
|
||||
@@ -1690,6 +1802,9 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
future_ul_tti_req->Slot,
|
||||
sched_pusch->frame,
|
||||
sched_pusch->slot);
|
||||
AssertFatal(future_ul_tti_req->n_pdus <
|
||||
sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
|
||||
"Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
|
||||
@@ -1704,7 +1819,10 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
pusch_pdu->handle = 0; //not yet used
|
||||
|
||||
/* FAPI: BWP */
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters:&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
scc,
|
||||
sib1);
|
||||
|
||||
pusch_pdu->bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pusch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pusch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing;
|
||||
@@ -1846,10 +1964,16 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
dci_pdu_rel15_t uldci_payload;
|
||||
memset(&uldci_payload, 0, sizeof(uldci_payload));
|
||||
int n_ubwp=1;
|
||||
if (cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList)
|
||||
n_ubwp = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
|
||||
if (cg &&
|
||||
cg->spCellConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList) {
|
||||
n_ubwp = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
|
||||
}
|
||||
|
||||
config_uldci(sched_ctrl->active_ubwp,
|
||||
config_uldci(sib1,
|
||||
sched_ctrl->active_ubwp,
|
||||
ubwpd,
|
||||
scc,
|
||||
pusch_pdu,
|
||||
@@ -1866,7 +1990,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
ps->dci_format,
|
||||
rnti_types[0],
|
||||
pusch_pdu->bwp_size,
|
||||
bwpid);
|
||||
bwpid,
|
||||
nr_mac->cset0_bwp_size);
|
||||
|
||||
memset(sched_pusch, 0, sizeof(*sched_pusch));
|
||||
}
|
||||
|
||||
@@ -38,12 +38,13 @@ void set_cset_offset(uint16_t);
|
||||
|
||||
void mac_top_init_gNB(void);
|
||||
|
||||
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
void config_common(int Mod_idP,
|
||||
int ssb_SubcarrierOffset,
|
||||
rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
|
||||
int pusch_AntennaPorts,
|
||||
NR_ServingCellConfigCommon_t *scc
|
||||
);
|
||||
NR_ServingCellConfigCommon_t *scc);
|
||||
|
||||
int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
int ssb_SubcarrierOffset,
|
||||
@@ -53,6 +54,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
int minRXTXTIMEpdsch,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BCCH_BCH_Message_t *mib,
|
||||
NR_BCCH_DL_SCH_Message_t *sib1,
|
||||
int add_ue,
|
||||
uint32_t rnti,
|
||||
NR_CellGroupConfig_t *CellGroup);
|
||||
@@ -176,7 +178,8 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234);
|
||||
|
||||
|
||||
void config_uldci(const NR_BWP_Uplink_t *ubwp,
|
||||
void config_uldci(const NR_SIB1_t *sib1,
|
||||
const NR_BWP_Uplink_t *ubwp,
|
||||
const NR_BWP_UplinkDedicated_t *ubwpd,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
@@ -235,7 +238,13 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space,
|
||||
nfapi_nr_config_request_scf_t cfg);
|
||||
*/
|
||||
|
||||
void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset,
|
||||
NR_BWP_Uplink_t *bwp,
|
||||
NR_BWP_UplinkDedicated_t *bwpd,
|
||||
int CCEIndex);
|
||||
|
||||
void nr_configure_pucch(const NR_SIB1_t *sib1,
|
||||
nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_CellGroupConfig_t *CellGroup,
|
||||
NR_BWP_Uplink_t *bwp,
|
||||
@@ -284,7 +293,8 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
|
||||
int dci_formats,
|
||||
int rnti_types,
|
||||
int N_RB,
|
||||
int bwp_id);
|
||||
int bwp_id,
|
||||
uint16_t cset0_bwp_size);
|
||||
|
||||
void prepare_dci(const NR_CellGroupConfig_t *CellGroup,
|
||||
dci_pdu_rel15_t *dci_pdu_rel15,
|
||||
@@ -299,6 +309,18 @@ void set_r_pucch_parms(int rsetindex,
|
||||
int *nr_of_symbols,
|
||||
int *start_symbol_index);
|
||||
|
||||
NR_BWP_t *get_dl_bwp_genericParameters(NR_BWP_Downlink_t *active_bwp,
|
||||
NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
|
||||
const NR_SIB1_t *sib1);
|
||||
|
||||
NR_BWP_t *get_ul_bwp_genericParameters(NR_BWP_Uplink_t *active_ubwp,
|
||||
NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
|
||||
const NR_SIB1_t *sib1);
|
||||
|
||||
NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(const NR_BWP_Downlink_t *active_bwp,
|
||||
const NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
|
||||
const NR_SIB1_t *sib1);
|
||||
|
||||
/* find coreset within the search space */
|
||||
NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
@@ -307,13 +329,19 @@ NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
|
||||
NR_SearchSpace__searchSpaceType_PR ss_type);
|
||||
|
||||
/* find a search space within a BWP */
|
||||
NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
|
||||
NR_SearchSpace_t *get_searchspace(const NR_SIB1_t *sib1,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
|
||||
NR_SearchSpace__searchSpaceType_PR target_ss);
|
||||
|
||||
long get_K2(NR_ServingCellConfigCommon_t *scc, NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
|
||||
long get_K2(NR_ServingCellConfigCommon_t *scc,
|
||||
NR_ServingCellConfigCommonSIB_t *scc_sib1,
|
||||
NR_BWP_Uplink_t *ubwp,
|
||||
int time_domain_assignment,
|
||||
int mu);
|
||||
|
||||
void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
const NR_BWP_Downlink_t *bwp,
|
||||
const NR_BWP_DownlinkDedicated_t *bwpd0,
|
||||
@@ -322,9 +350,10 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
NR_pdsch_semi_static_t *ps);
|
||||
|
||||
void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
void nr_set_pusch_semi_static(const NR_SIB1_t *sib1,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const NR_BWP_Uplink_t *ubwp,
|
||||
const NR_BWP_UplinkDedicated_t *ubwpd,
|
||||
const NR_BWP_UplinkDedicated_t *ubwpd,
|
||||
long dci_format,
|
||||
int tda,
|
||||
uint8_t num_dmrs_cdm_grps_no_data,
|
||||
@@ -490,4 +519,7 @@ bool nr_find_nb_rb(uint16_t Qm,
|
||||
void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
|
||||
|
||||
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp);
|
||||
|
||||
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
||||
|
||||
@@ -205,6 +205,7 @@ typedef struct {
|
||||
lte_frame_type_t frame_type;
|
||||
uint64_t dl_CarrierFreq;
|
||||
NR_BCCH_BCH_Message_t *mib;
|
||||
NR_BCCH_DL_SCH_Message_t *sib1;
|
||||
NR_ServingCellConfigCommon_t *ServingCellConfigCommon;
|
||||
NR_ARFCN_ValueEUTRA_t ul_CarrierFreq;
|
||||
long ul_Bandwidth;
|
||||
|
||||
@@ -51,7 +51,12 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
||||
|
||||
if (entity->type != NR_PDCP_SRB && !(buffer[0] & 0x80)) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
/* TODO: This is something of a hack. The most significant bit
|
||||
in buffer[0] should be 1 if the packet is a data packet. We are
|
||||
processing malformed data packets if the most significant bit
|
||||
is 0. Rather than exit(1), this hack allows us to continue for now.
|
||||
We need to investigate why this hack is neccessary. */
|
||||
buffer[0] |= 128;
|
||||
}
|
||||
|
||||
if (entity->sn_size == 12) {
|
||||
@@ -368,8 +373,8 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||
ret->set_security = nr_pdcp_entity_set_security;
|
||||
ret->set_time = nr_pdcp_entity_set_time;
|
||||
|
||||
ret->delete = nr_pdcp_entity_delete;
|
||||
|
||||
ret->delete_entity = nr_pdcp_entity_delete;
|
||||
|
||||
ret->deliver_sdu = deliver_sdu;
|
||||
ret->deliver_sdu_data = deliver_sdu_data;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ typedef struct nr_pdcp_entity_t {
|
||||
void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
|
||||
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
|
||||
int sdu_id);
|
||||
void (*delete)(struct nr_pdcp_entity_t *entity);
|
||||
void (*delete_entity)(struct nr_pdcp_entity_t *entity);
|
||||
|
||||
/* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
|
||||
* to keep the current algorithm
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "pdcp.h"
|
||||
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h"
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
|
||||
|
||||
#define TODO do { \
|
||||
printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
|
||||
@@ -438,9 +438,13 @@ static void *enb_tun_read_thread(void *_)
|
||||
|
||||
ctxt.rnti = rnti;
|
||||
|
||||
pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
|
||||
uint8_t qfi = 7;
|
||||
boolean_t rqi = 0;
|
||||
int pdusession_id = 10;
|
||||
|
||||
sdap_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
|
||||
RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf,
|
||||
PDCP_TRANSMISSION_MODE_DATA, NULL, NULL);
|
||||
PDCP_TRANSMISSION_MODE_DATA, NULL, NULL, qfi, rqi, pdusession_id);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -481,9 +485,13 @@ static void *ue_tun_read_thread(void *_)
|
||||
|
||||
ctxt.rnti = rnti;
|
||||
|
||||
pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
|
||||
boolean_t dc = SDAP_HDR_UL_DATA_PDU;
|
||||
uint8_t qfi = 7;
|
||||
int pdusession_id = 10;
|
||||
|
||||
sdap_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
|
||||
RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf,
|
||||
PDCP_TRANSMISSION_MODE_DATA, NULL, NULL);
|
||||
PDCP_TRANSMISSION_MODE_DATA, NULL, NULL, qfi, dc, pdusession_id);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -607,28 +615,20 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
|
||||
static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
char *buf, int size)
|
||||
{
|
||||
extern int nas_sock_fd[];
|
||||
int len;
|
||||
nr_pdcp_ue_t *ue = _ue;
|
||||
MessageDef *message_p;
|
||||
uint8_t *gtpu_buffer_p;
|
||||
int rb_id;
|
||||
int i;
|
||||
|
||||
if (IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN) {
|
||||
LOG_D(PDCP, "IP packet received, to be sent to TUN interface");
|
||||
|
||||
if(entity->has_sdapDLheader){
|
||||
size -= SDAP_HDR_LENGTH;
|
||||
len = write(nas_sock_fd[0], &buf[SDAP_HDR_LENGTH], size);
|
||||
} else {
|
||||
len = write(nas_sock_fd[0], buf, size);
|
||||
}
|
||||
|
||||
if (len != size) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal error %d: %s\n", __FILE__, __LINE__, __FUNCTION__, errno, strerror(errno));
|
||||
}
|
||||
|
||||
LOG_D(PDCP, "IP packet received with size %d, to be sent to SDAP interface, UE rnti: %d\n", size, ue->rnti);
|
||||
sdap_data_ind(entity->rb_id,
|
||||
entity->is_gnb,
|
||||
entity->has_sdap,
|
||||
entity->has_sdapULheader,
|
||||
entity->pdusession_id,
|
||||
ue->rnti,
|
||||
buf,
|
||||
size);
|
||||
}
|
||||
else{
|
||||
for (i = 0; i < 5; i++) {
|
||||
@@ -644,31 +644,16 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
|
||||
rb_found:
|
||||
{
|
||||
int offset=0;
|
||||
if (entity->has_sdap == 1 && entity->has_sdapULheader == 1)
|
||||
offset = 1; // this is the offset of the SDAP header in bytes
|
||||
|
||||
message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ,
|
||||
sizeof(gtpv1u_gnb_tunnel_data_req_t) + size
|
||||
+ GTPU_HEADER_OVERHEAD_MAX - offset);
|
||||
AssertFatal(message_p != NULL, "OUT OF MEMORY");
|
||||
|
||||
gtpv1u_gnb_tunnel_data_req_t *req=>PV1U_GNB_TUNNEL_DATA_REQ(message_p);
|
||||
gtpu_buffer_p = (uint8_t*)(req+1);
|
||||
memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX, buf+offset, size-offset);
|
||||
req->buffer = gtpu_buffer_p;
|
||||
req->length = size-offset;
|
||||
req->offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
req->rnti = ue->rnti;
|
||||
req->pdusession_id = entity->pdusession_id;
|
||||
if (offset==1) {
|
||||
LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
|
||||
sdap_gnb_ul_header_handler(buf[0]); // Handler for the UL gNB SDAP Header
|
||||
}
|
||||
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size-offset);
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
|
||||
}
|
||||
LOG_D(PDCP, "%s() (drb %d) sending message to SDAP size %d\n", __func__, rb_id, size);
|
||||
sdap_data_ind(rb_id,
|
||||
ue->drb[rb_id-1]->is_gnb,
|
||||
ue->drb[rb_id-1]->has_sdap,
|
||||
ue->drb[rb_id-1]->has_sdapULheader,
|
||||
ue->drb[rb_id-1]->pdusession_id,
|
||||
ue->rnti,
|
||||
buf,
|
||||
size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -967,6 +952,9 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
|
||||
int has_sdap = 0;
|
||||
int has_sdapULheader=0;
|
||||
int has_sdapDLheader=0;
|
||||
boolean_t is_sdap_DefaultDRB = false;
|
||||
NR_QFI_t *mappedQFIs2Add = NULL;
|
||||
uint8_t mappedQFIs2AddCount=0;
|
||||
if (s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity)
|
||||
pdusession_id = s->cnAssociation->choice.eps_BearerIdentity;
|
||||
else {
|
||||
@@ -975,9 +963,13 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
|
||||
exit(-1);
|
||||
}
|
||||
pdusession_id = s->cnAssociation->choice.sdap_Config->pdu_Session;
|
||||
has_sdap = 1;
|
||||
has_sdapULheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present ? 1 : 0;
|
||||
has_sdapDLheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present ? 1 : 0;
|
||||
has_sdap = has_sdapULheader | has_sdapDLheader;
|
||||
is_sdap_DefaultDRB = s->cnAssociation->choice.sdap_Config->defaultDRB == true ? 1 : 0;
|
||||
mappedQFIs2Add = (NR_QFI_t*)s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.array[0];
|
||||
mappedQFIs2AddCount = s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.count;
|
||||
LOG_D(SDAP, "Captured mappedQoS_FlowsToAdd from RRC: %ld \n", *mappedQFIs2Add);
|
||||
}
|
||||
/* TODO(?): accept different UL and DL SN sizes? */
|
||||
if (sn_size_ul != sn_size_dl) {
|
||||
@@ -1009,6 +1001,15 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
|
||||
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
|
||||
|
||||
LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
||||
|
||||
new_nr_sdap_entity(has_sdap,
|
||||
rnti,
|
||||
pdusession_id,
|
||||
is_sdap_DefaultDRB,
|
||||
drb_id,
|
||||
mappedQFIs2Add,
|
||||
mappedQFIs2AddCount);
|
||||
LOG_D(SDAP, "Added SDAP entity to ue rnti %x with pdusession_id %d\n", rnti, pdusession_id);
|
||||
}
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
}
|
||||
@@ -1140,7 +1141,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
|
||||
NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
|
||||
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
|
||||
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
|
||||
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5;
|
||||
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 10;
|
||||
drb_ToAddMod->drb_Identity = 1;
|
||||
drb_ToAddMod->reestablishPDCP = NULL;
|
||||
drb_ToAddMod->recoverPDCP = NULL;
|
||||
@@ -1450,3 +1451,10 @@ void nr_pdcp_tick(int frame, int subframe)
|
||||
nr_pdcp_wakeup_timer_thread(nr_pdcp_current_time);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For the SDAP API
|
||||
*/
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager(){
|
||||
return nr_pdcp_ue_manager;
|
||||
}
|
||||
|
||||
@@ -127,11 +127,11 @@ void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *_m, int rnti)
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
if (ue->srb[j] != NULL)
|
||||
ue->srb[j]->delete(ue->srb[j]);
|
||||
ue->srb[j]->delete_entity(ue->srb[j]);
|
||||
|
||||
for (j = 0; j < 5; j++)
|
||||
if (ue->drb[j] != NULL)
|
||||
ue->drb[j]->delete(ue->drb[j]);
|
||||
ue->drb[j]->delete_entity(ue->drb[j]);
|
||||
|
||||
free(ue);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,15 +41,44 @@
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||
|
||||
#define NR_NUM_MCS 29
|
||||
#define NUM_SINR 100
|
||||
#define NUM_BLER_COL 13
|
||||
#define NUM_NFAPI_SLOT 20
|
||||
#define NR_NUM_LAYER 1
|
||||
|
||||
typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
|
||||
|
||||
typedef struct nr_phy_channel_params_t
|
||||
{
|
||||
uint16_t sfn_slot;
|
||||
float sinr;
|
||||
uint16_t message_id;
|
||||
uint16_t nb_of_sinrs;
|
||||
float sinr[NR_NUM_LAYER];
|
||||
// Incomplete, need all channel parameters
|
||||
} nr_phy_channel_params_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t slot;
|
||||
uint16_t rnti[256];
|
||||
uint8_t mcs[256];
|
||||
uint8_t rvIndex[256];
|
||||
float sinr;
|
||||
uint16_t num_pdus;
|
||||
bool drop_flag[256];
|
||||
bool latest;
|
||||
|
||||
} slot_rnti_mcs_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t length;
|
||||
float bler_table[NUM_SINR][NUM_BLER_COL];
|
||||
} nr_bler_struct;
|
||||
|
||||
extern nr_bler_struct nr_bler_data[NR_NUM_MCS];
|
||||
|
||||
typedef enum {
|
||||
ONLY_PUSCH,
|
||||
NOT_PUSCH,
|
||||
@@ -246,6 +275,8 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_request,
|
||||
nfapi_nr_ul_tti_request_t *ul_tti_request);
|
||||
|
||||
bool sfn_slot_matcher(void *wanted, void *candidate);
|
||||
|
||||
/**\brief done free of memory allocation by module_id and release to pointer pool.
|
||||
\param module_id module id*/
|
||||
int nr_ue_if_module_kill(uint32_t module_id);
|
||||
|
||||
@@ -1259,6 +1259,17 @@ void ue_init_standalone_socket(int tx_port, int rx_port)
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t get_message_id(const uint8_t *buffer, ssize_t len)
|
||||
{
|
||||
if (len < 4)
|
||||
return 0;
|
||||
|
||||
// Unpack 2 bytes message_id from buffer.
|
||||
uint16_t v;
|
||||
memcpy(&v, buffer + 2, sizeof(v));
|
||||
return ntohs(v);
|
||||
}
|
||||
|
||||
void *ue_standalone_pnf_task(void *context)
|
||||
{
|
||||
struct sockaddr_in server_address;
|
||||
@@ -1301,7 +1312,7 @@ void *ue_standalone_pnf_task(void *context)
|
||||
abort();
|
||||
}
|
||||
}
|
||||
else if (len == sizeof(phy_channel_params_t))
|
||||
else if (get_message_id((const uint8_t *)buffer, len) == 0x0FFF) // 0x0FFF : channel info identifier.
|
||||
{
|
||||
phy_channel_params_t ch_info;
|
||||
memcpy(&ch_info, buffer, sizeof(phy_channel_params_t));
|
||||
@@ -1314,8 +1325,15 @@ void *ue_standalone_pnf_task(void *context)
|
||||
uint16_t sf = ch_info.sfn_sf & 15;
|
||||
assert(sf < 10);
|
||||
|
||||
sf_rnti_mcs[sf].sinr = ch_info.sinr;
|
||||
LOG_D(MAC, "Received_SINR = %f\n",ch_info.sinr);
|
||||
if (ch_info.nb_of_sinrs > 1)
|
||||
LOG_W(MAC, "Expecting at most one SINR.\n");
|
||||
|
||||
// TODO: Update sinr field of slot_rnti_mcs to be array.
|
||||
for (int i = 0; i < ch_info.nb_of_sinrs; ++i)
|
||||
{
|
||||
sf_rnti_mcs[sf].sinr = ch_info.sinr[i];
|
||||
LOG_D(MAC, "Received_SINR[%d] = %f\n", i, ch_info.sinr[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define NUM_MCS 28
|
||||
#define NUM_SINR 100
|
||||
#define NUM_BLER_COL 13
|
||||
#define LTE_NUM_LAYER 1
|
||||
|
||||
// this mutex is used to set multiple UE's UL value in L2 FAPI simulator.
|
||||
extern FILL_UL_INFO_MUTEX_t fill_ul_mutex;
|
||||
@@ -126,7 +127,9 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
|
||||
typedef struct phy_channel_params_t
|
||||
{
|
||||
uint16_t sfn_sf;
|
||||
float sinr;
|
||||
uint16_t message_id;
|
||||
uint16_t nb_of_sinrs;
|
||||
float sinr[LTE_NUM_LAYER];
|
||||
// Incomplete, need all channel parameters
|
||||
} phy_channel_params_t;
|
||||
|
||||
|
||||
@@ -1452,15 +1452,15 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr
|
||||
ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig_drb);
|
||||
}
|
||||
|
||||
|
||||
void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
|
||||
rrc_gNB_carrier_data_t *carrier,
|
||||
NR_UE_NR_Capability_t *uecap,
|
||||
const gNB_RrcConfigurationReq* configuration)
|
||||
{
|
||||
const gNB_RrcConfigurationReq* configuration) {
|
||||
|
||||
NR_SpCellConfig_t *SpCellConfig = cellGroupConfig->spCellConfig;
|
||||
if (SpCellConfig == NULL) return;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = carrier->servingcellconfigcommon;
|
||||
NR_ServingCellConfigCommon_t *scc = configuration->scc;
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP;
|
||||
set_dl_mcs_table(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing,
|
||||
@@ -1471,7 +1471,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
|
||||
for (int i=0; i<DL_BWP_list->list.count; i++){
|
||||
NR_BWP_Downlink_t *bwp = DL_BWP_list->list.array[i];
|
||||
int scs = bwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, bwp->bwp_Dedicated, carrier->servingcellconfigcommon);
|
||||
set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, bwp->bwp_Dedicated, scc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1951,9 +1951,9 @@ int16_t do_RRCReconfiguration(
|
||||
|
||||
if(cellGroupConfig!=NULL){
|
||||
update_cellGroupConfig(cellGroupConfig,
|
||||
carrier,
|
||||
ue_context_pP->ue_context.UE_Capability_nr,
|
||||
configuration);
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
|
||||
NULL,
|
||||
(void *)cellGroupConfig,
|
||||
|
||||
@@ -112,7 +112,6 @@ void fill_initial_cellGroupConfig(int uid,
|
||||
const gNB_RrcConfigurationReq *configuration);
|
||||
|
||||
void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
|
||||
rrc_gNB_carrier_data_t *carrier,
|
||||
NR_UE_NR_Capability_t *uecap,
|
||||
const gNB_RrcConfigurationReq *configuration);
|
||||
|
||||
|
||||
@@ -31,6 +31,145 @@
|
||||
#include "nr_rrc_config.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||
|
||||
|
||||
void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, int uid, int nb_slots_per_period) {
|
||||
|
||||
nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset));
|
||||
int ideal_period = nb_slots_per_period*MAX_MOBILES_PER_GNB;
|
||||
|
||||
if (ideal_period<5) {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots4;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots4 = nb_slots_per_period*uid;
|
||||
}
|
||||
else if (ideal_period<6) {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots5;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots5 = nb_slots_per_period*uid;
|
||||
}
|
||||
else if (ideal_period<9) {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots8;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots8 = nb_slots_per_period*uid;
|
||||
}
|
||||
else if (ideal_period<11) {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots10;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots10 = nb_slots_per_period*uid;
|
||||
}
|
||||
else if (ideal_period<17) {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots16;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots16 = nb_slots_per_period*uid;
|
||||
}
|
||||
else if (ideal_period<21) {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots20;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots20 = nb_slots_per_period*uid;
|
||||
}
|
||||
else if (ideal_period<41) {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots40;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots40 = nb_slots_per_period*uid;
|
||||
}
|
||||
else if (ideal_period<81) {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots80;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots80 = nb_slots_per_period*uid;
|
||||
}
|
||||
else if (ideal_period<161) {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots160 = nb_slots_per_period*uid;
|
||||
}
|
||||
else {
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots320 = (nb_slots_per_period*uid)%320 + (nb_slots_per_period*uid)/320;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
int uid,
|
||||
int num_dl_antenna_ports,
|
||||
int curr_bwp,
|
||||
int do_csirs) {
|
||||
|
||||
if (do_csirs) {
|
||||
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList));
|
||||
NR_NZP_CSI_RS_ResourceSet_t *nzpcsirs0 = calloc(1,sizeof(*nzpcsirs0));
|
||||
nzpcsirs0->nzp_CSI_ResourceSetId = 0;
|
||||
NR_NZP_CSI_RS_ResourceId_t *nzpid0 = calloc(1,sizeof(*nzpid0));
|
||||
*nzpid0 = 0;
|
||||
ASN_SEQUENCE_ADD(&nzpcsirs0->nzp_CSI_RS_Resources,nzpid0);
|
||||
nzpcsirs0->repetition = NULL;
|
||||
nzpcsirs0->aperiodicTriggeringOffset = NULL;
|
||||
nzpcsirs0->trs_Info = NULL;
|
||||
ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpcsirs0);
|
||||
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = servingcellconfigcommon->tdd_UL_DL_ConfigurationCommon ?
|
||||
&servingcellconfigcommon->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
|
||||
const int n_slots_frame = slotsperframe[*servingcellconfigcommon->ssbSubcarrierSpacing];
|
||||
|
||||
int nb_slots_per_period = n_slots_frame;
|
||||
if (tdd)
|
||||
nb_slots_per_period = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
|
||||
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList));
|
||||
NR_NZP_CSI_RS_Resource_t *nzpcsi0 = calloc(1,sizeof(*nzpcsi0));
|
||||
nzpcsi0->nzp_CSI_RS_ResourceId = 0;
|
||||
NR_CSI_RS_ResourceMapping_t resourceMapping;
|
||||
switch (num_dl_antenna_ports) {
|
||||
case 1:
|
||||
resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.size = 2;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 4;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.buf[0] = 0;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.buf[1] = 16;
|
||||
resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1;
|
||||
resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM;
|
||||
break;
|
||||
case 2:
|
||||
resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other;
|
||||
resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(2, sizeof(uint8_t));
|
||||
resourceMapping.frequencyDomainAllocation.choice.other.size = 1;
|
||||
resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2;
|
||||
resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 4;
|
||||
resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p2;
|
||||
resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
|
||||
break;
|
||||
case 4:
|
||||
resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row4.buf = calloc(2, sizeof(uint8_t));
|
||||
resourceMapping.frequencyDomainAllocation.choice.row4.size = 1;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row4.bits_unused = 5;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row4.buf[0] = 32;
|
||||
resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p4;
|
||||
resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Number of ports not yet supported\n");
|
||||
}
|
||||
resourceMapping.firstOFDMSymbolInTimeDomain = 13; // last symbol of slot
|
||||
resourceMapping.firstOFDMSymbolInTimeDomain2 = NULL;
|
||||
resourceMapping.density.present = NR_CSI_RS_ResourceMapping__density_PR_one;
|
||||
resourceMapping.density.choice.one = (NULL_t)0;
|
||||
resourceMapping.freqBand.startingRB = 0;
|
||||
resourceMapping.freqBand.nrofRBs = ((curr_bwp>>2)+(curr_bwp%4>0))<<2;
|
||||
nzpcsi0->resourceMapping = resourceMapping;
|
||||
nzpcsi0->powerControlOffset = 0;
|
||||
nzpcsi0->powerControlOffsetSS=calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS));
|
||||
*nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
|
||||
nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
|
||||
set_csirs_periodicity(nzpcsi0, uid, nb_slots_per_period);
|
||||
nzpcsi0->qcl_InfoPeriodicCSI_RS = NULL;
|
||||
ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
|
||||
}
|
||||
else {
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = NULL;
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList = NULL;
|
||||
}
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL;
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList = NULL;
|
||||
}
|
||||
|
||||
void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
int numerology,
|
||||
|
||||
@@ -113,6 +113,12 @@ typedef struct physicalcellgroup_s{
|
||||
|
||||
void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc);
|
||||
void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay);
|
||||
void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
int uid,
|
||||
int num_dl_antenna_ports,
|
||||
int curr_bwp,
|
||||
int do_csirs);
|
||||
void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
|
||||
NR_ServingCellConfigCommon_t *scc);
|
||||
|
||||
@@ -82,12 +82,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
const gNB_RrcConfigurationReq *configuration,
|
||||
int uid);
|
||||
|
||||
void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
int dl_antenna_ports,
|
||||
int curr_bwp,
|
||||
int do_csirs);
|
||||
|
||||
void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_ServingCellConfig_t *servingcellconfigdedicated,
|
||||
NR_RRCReconfiguration_IEs_t *reconfig,
|
||||
|
||||
@@ -173,6 +173,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
|
||||
rrc->configuration.minRXTXTIME,
|
||||
rrc->carrier.servingcellconfigcommon,
|
||||
&rrc->carrier.mib,
|
||||
rrc->carrier.siblock1,
|
||||
0,
|
||||
0, // WIP hardcoded rnti
|
||||
NULL);
|
||||
@@ -281,6 +282,7 @@ void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
rrc->configuration.minRXTXTIME,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
cgc);
|
||||
@@ -468,6 +470,7 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
|
||||
rrc_instance_p->configuration.minRXTXTIME,
|
||||
rrc_instance_p->carrier.servingcellconfigcommon,
|
||||
&rrc_instance_p->carrier.mib,
|
||||
rrc_instance_p->carrier.siblock1,
|
||||
0,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
NULL);
|
||||
@@ -818,7 +821,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
uint8_t buffer[RRC_BUF_SIZE];
|
||||
uint16_t size;
|
||||
int qos_flow_index = 0;
|
||||
NR_QFI_t qfi = 0;
|
||||
int pdu_sessions_done = 0;
|
||||
int i;
|
||||
NR_CellGroupConfig_t *cellGroupConfig;
|
||||
@@ -869,15 +871,21 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
|
||||
sdap_config->pdu_Session = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
|
||||
sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
|
||||
sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||
if (rrc->configuration.enable_sdap) {
|
||||
sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
|
||||
sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
|
||||
} else {
|
||||
sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||
sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||
}
|
||||
sdap_config->defaultDRB = TRUE;
|
||||
sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
|
||||
memset(sdap_config->mappedQoS_FlowsToAdd, 0, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
|
||||
|
||||
for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[i].param.nb_qos; qos_flow_index++) {
|
||||
qfi = ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].qfi;
|
||||
ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, &qfi);
|
||||
NR_QFI_t *qfi = calloc(1, sizeof(NR_QFI_t));
|
||||
*qfi = ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].qfi;
|
||||
ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, qfi);
|
||||
}
|
||||
sdap_config->mappedQoS_FlowsToRelease = NULL;
|
||||
DRB_config->cnAssociation->choice.sdap_Config = sdap_config;
|
||||
@@ -1368,6 +1376,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
||||
rrc->configuration.minRXTXTIME,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
ue_context_pP->ue_context.masterCellGroup);
|
||||
|
||||
@@ -354,6 +354,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
rrc->configuration.minRXTXTIME,
|
||||
rrc->carrier.servingcellconfigcommon,
|
||||
&rrc->carrier.mib,
|
||||
NULL,
|
||||
1, // add_ue flag
|
||||
ue_context_p->ue_id_rnti,
|
||||
ue_context_p->ue_context.secondaryCellGroup);
|
||||
@@ -366,6 +367,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
rrc->configuration.minRXTXTIME,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
1, // add_ue flag
|
||||
ue_context_p->ue_id_rnti,
|
||||
ue_context_p->ue_context.secondaryCellGroup);
|
||||
|
||||
@@ -1066,24 +1066,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
csi_MeasConfig->csi_IM_ResourceToReleaseList = NULL;
|
||||
csi_MeasConfig->csi_IM_ResourceSetToReleaseList = NULL;
|
||||
|
||||
if (do_csirs) {
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList));
|
||||
NR_NZP_CSI_RS_ResourceSet_t *nzpcsirs0 = calloc(1,sizeof(*nzpcsirs0));
|
||||
nzpcsirs0->nzp_CSI_ResourceSetId = 0;
|
||||
NR_NZP_CSI_RS_ResourceId_t *nzpid0 = calloc(1,sizeof(*nzpid0));
|
||||
*nzpid0 = 0;
|
||||
ASN_SEQUENCE_ADD(&nzpcsirs0->nzp_CSI_RS_Resources,nzpid0);
|
||||
nzpcsirs0->repetition = NULL;
|
||||
nzpcsirs0->aperiodicTriggeringOffset = NULL;
|
||||
nzpcsirs0->trs_Info = NULL;
|
||||
ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpcsirs0);
|
||||
}
|
||||
else
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList = NULL;
|
||||
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL;
|
||||
|
||||
config_csirs(servingcellconfigcommon, csi_MeasConfig,dl_antenna_ports,curr_bwp,do_csirs);
|
||||
config_csirs(servingcellconfigcommon, csi_MeasConfig, uid, dl_antenna_ports, curr_bwp, do_csirs);
|
||||
|
||||
csi_MeasConfig->csi_SSB_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_SSB_ResourceSetToAddModList));
|
||||
csi_MeasConfig->csi_SSB_ResourceSetToReleaseList = NULL;
|
||||
@@ -1102,9 +1085,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list,ssbresset0);
|
||||
|
||||
csi_MeasConfig->csi_ResourceConfigToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_ResourceConfigToAddModList));
|
||||
csi_MeasConfig->csi_ResourceConfigToReleaseList = NULL;
|
||||
|
||||
if (do_csirs) {
|
||||
csi_MeasConfig->csi_ResourceConfigToReleaseList = NULL;
|
||||
NR_CSI_ResourceConfig_t *csires0 = calloc(1,sizeof(*csires0));
|
||||
csires0->csi_ResourceConfigId=0;
|
||||
csires0->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB;
|
||||
@@ -1315,62 +1298,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
}
|
||||
|
||||
|
||||
void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
int dl_antenna_ports,
|
||||
int curr_bwp,
|
||||
int do_csirs) {
|
||||
|
||||
if (do_csirs) {
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList));
|
||||
NR_NZP_CSI_RS_Resource_t *nzpcsi0 = calloc(1,sizeof(*nzpcsi0));
|
||||
nzpcsi0->nzp_CSI_RS_ResourceId = 0;
|
||||
NR_CSI_RS_ResourceMapping_t resourceMapping;
|
||||
switch (dl_antenna_ports) {
|
||||
case 1:
|
||||
resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.size = 2;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 4;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.buf[0] = 0;
|
||||
resourceMapping.frequencyDomainAllocation.choice.row2.buf[1] = 16;
|
||||
resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1;
|
||||
resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM;
|
||||
break;
|
||||
case 2:
|
||||
resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other;
|
||||
resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(2, sizeof(uint8_t));
|
||||
resourceMapping.frequencyDomainAllocation.choice.other.size = 1;
|
||||
resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2;
|
||||
resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 4;
|
||||
resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p2;
|
||||
resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Number of ports not yet supported\n");
|
||||
}
|
||||
resourceMapping.firstOFDMSymbolInTimeDomain = 6;
|
||||
resourceMapping.firstOFDMSymbolInTimeDomain2 = NULL;
|
||||
resourceMapping.density.present = NR_CSI_RS_ResourceMapping__density_PR_one;
|
||||
resourceMapping.density.choice.one = (NULL_t)0;
|
||||
resourceMapping.freqBand.startingRB = 0;
|
||||
resourceMapping.freqBand.nrofRBs = ((curr_bwp>>2)+(curr_bwp%4>0))<<2;
|
||||
nzpcsi0->resourceMapping = resourceMapping;
|
||||
nzpcsi0->powerControlOffset = 0;
|
||||
nzpcsi0->powerControlOffsetSS=calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS));
|
||||
*nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
|
||||
nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
|
||||
nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset));
|
||||
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320;
|
||||
nzpcsi0->periodicityAndOffset->choice.slots320 = 0;
|
||||
nzpcsi0->qcl_InfoPeriodicCSI_RS = NULL;
|
||||
ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
|
||||
}
|
||||
else
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = NULL;
|
||||
}
|
||||
|
||||
|
||||
void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_ServingCellConfig_t *servingcellconfigdedicated,
|
||||
NR_RRCReconfiguration_IEs_t *reconfig,
|
||||
|
||||
@@ -2795,7 +2795,6 @@ void start_oai_nrue_threads()
|
||||
init_queue(&nr_tx_req_queue);
|
||||
init_queue(&nr_ul_dci_req_queue);
|
||||
init_queue(&nr_ul_tti_req_queue);
|
||||
init_queue(&nr_wait_ul_tti_req_queue);
|
||||
|
||||
if (sem_init(&sfn_slot_semaphore, 0, 0) != 0)
|
||||
{
|
||||
|
||||
@@ -51,7 +51,6 @@ extern queue_t nr_dl_tti_req_queue;
|
||||
extern queue_t nr_tx_req_queue;
|
||||
extern queue_t nr_ul_dci_req_queue;
|
||||
extern queue_t nr_ul_tti_req_queue;
|
||||
extern queue_t nr_wait_ul_tti_req_queue;
|
||||
//
|
||||
// main_rrc.c
|
||||
//
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "nr_sdap.h"
|
||||
|
||||
boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id,
|
||||
const uint8_t qfi,
|
||||
const boolean_t rqi,
|
||||
const int pdusession_id) {
|
||||
nr_sdap_entity_t *sdap_entity;
|
||||
sdap_entity = nr_sdap_get_entity(ctxt_p->rnti, pdusession_id);
|
||||
|
||||
if(sdap_entity == NULL) {
|
||||
LOG_E(SDAP, "%s:%d:%s: Entity not found with ue rnti: %x and pdusession id: %d\n", __FILE__, __LINE__, __FUNCTION__, ctxt_p->rnti, pdusession_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean_t ret = sdap_entity->tx_entity(sdap_entity,
|
||||
ctxt_p,
|
||||
srb_flag,
|
||||
rb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size,
|
||||
sdu_buffer,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id,
|
||||
qfi,
|
||||
rqi);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sdap_data_ind(rb_id_t pdcp_entity,
|
||||
int is_gnb,
|
||||
int has_sdap,
|
||||
int has_sdapULheader,
|
||||
int pdusession_id,
|
||||
int rnti,
|
||||
char *buf,
|
||||
int size) {
|
||||
nr_sdap_entity_t *sdap_entity;
|
||||
sdap_entity = nr_sdap_get_entity(rnti, pdusession_id);
|
||||
|
||||
if(sdap_entity == NULL) {
|
||||
LOG_E(SDAP, "%s:%d:%s: Entity not found\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
sdap_entity->rx_entity(sdap_entity,
|
||||
pdcp_entity,
|
||||
is_gnb,
|
||||
has_sdap,
|
||||
has_sdapULheader,
|
||||
pdusession_id,
|
||||
rnti,
|
||||
buf,
|
||||
size);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _NR_SDAP_GNB_H_
|
||||
#define _NR_SDAP_GNB_H_
|
||||
|
||||
#include "openair2/COMMON/platform_types.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "nr_sdap_entity.h"
|
||||
|
||||
/*
|
||||
* TS 37.324 4.4 Functions
|
||||
* Transfer of user plane data
|
||||
* Downlink - gNB
|
||||
* Uplink - nrUE
|
||||
*/
|
||||
boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id,
|
||||
const uint8_t qfi,
|
||||
const boolean_t rqi,
|
||||
const int pdusession_id
|
||||
);
|
||||
|
||||
/*
|
||||
* TS 37.324 4.4 Functions
|
||||
* Transfer of user plane data
|
||||
* Uplink - gNB
|
||||
* Downlink - nrUE
|
||||
*/
|
||||
void sdap_data_ind(rb_id_t pdcp_entity,
|
||||
int is_gnb,
|
||||
int has_sdap,
|
||||
int has_sdapULheader,
|
||||
int pdusession_id,
|
||||
int rnti,
|
||||
char *buf,
|
||||
int size
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "nr_sdap_entity.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef struct {
|
||||
nr_sdap_entity_t *sdap_entity_llist;
|
||||
} nr_sdap_entity_info;
|
||||
|
||||
static nr_sdap_entity_info sdap_info;
|
||||
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager(void);
|
||||
|
||||
void nr_pdcp_submit_sdap_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu){
|
||||
nr_pdcp_ue_t *ue;
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
|
||||
nr_pdcp_ue_manager = nr_pdcp_sdap_get_ue_manager();
|
||||
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
|
||||
ue->drb[sdap_ctrl_pdu_drb-1]->recv_sdu(ue->drb[sdap_ctrl_pdu_drb-1], (char*)&ctrl_pdu, SDAP_HDR_LENGTH, RLC_MUI_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
|
||||
static boolean_t nr_sdap_tx_entity(nr_sdap_entity_t *entity,
|
||||
protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id,
|
||||
const uint8_t qfi,
|
||||
const boolean_t rqi
|
||||
) {
|
||||
/* The offset of the SDAP header, it might be 0 if the has_sdap is not true in the pdcp entity. */
|
||||
int offset=0;
|
||||
boolean_t ret=false;
|
||||
/*Hardcode DRB ID given from upper layer (ue/enb_tun_read_thread rb_id), it will change if we have SDAP*/
|
||||
rb_id_t sdap_drb_id = rb_id;
|
||||
int pdcp_ent_has_sdap = 0;
|
||||
|
||||
if(sdu_buffer == NULL) {
|
||||
LOG_E(SDAP, "%s:%d:%s: NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uint8_t sdap_buf[SDAP_MAX_PDU];
|
||||
rb_id_t pdcp_entity = entity->qfi2drb_map(entity, qfi, rb_id);
|
||||
|
||||
if(pdcp_entity){
|
||||
sdap_drb_id = pdcp_entity;
|
||||
pdcp_ent_has_sdap = entity->qfi2drb_table[qfi].hasSdap;
|
||||
}
|
||||
|
||||
if(!pdcp_ent_has_sdap){
|
||||
ret = pdcp_data_req(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size,
|
||||
sdu_buffer,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id);
|
||||
|
||||
if(!ret)
|
||||
LOG_E(SDAP, "%s:%d:%s: PDCP refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(sdu_buffer_size == 0 || sdu_buffer_size > 8999) {
|
||||
LOG_E(SDAP, "%s:%d:%s: NULL or 0 or exceeded sdu_buffer_size (over max PDCP SDU)\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(ctxt_p->enb_flag) { // gNB
|
||||
offset = SDAP_HDR_LENGTH;
|
||||
/*
|
||||
* TS 37.324 4.4 Functions
|
||||
* marking QoS flow ID in DL packets.
|
||||
*
|
||||
* Construct the DL SDAP data PDU.
|
||||
*/
|
||||
nr_sdap_dl_hdr_t sdap_hdr;
|
||||
sdap_hdr.QFI = qfi;
|
||||
sdap_hdr.RQI = rqi;
|
||||
sdap_hdr.RDI = 0; // SDAP Hardcoded Value
|
||||
/* Add the SDAP DL Header to the buffer */
|
||||
memcpy(&sdap_buf[0], &sdap_hdr, SDAP_HDR_LENGTH);
|
||||
memcpy(&sdap_buf[SDAP_HDR_LENGTH], sdu_buffer, sdu_buffer_size);
|
||||
LOG_D(SDAP, "TX Entity QFI: %u \n", sdap_hdr.QFI);
|
||||
LOG_D(SDAP, "TX Entity RQI: %u \n", sdap_hdr.RQI);
|
||||
LOG_D(SDAP, "TX Entity RDI: %u \n", sdap_hdr.RDI);
|
||||
} else { // nrUE
|
||||
offset = SDAP_HDR_LENGTH;
|
||||
/*
|
||||
* TS 37.324 4.4 Functions
|
||||
* marking QoS flow ID in UL packets.
|
||||
*
|
||||
* 5.2.1 Uplink
|
||||
* construct the UL SDAP data PDU as specified in the subclause 6.2.2.3.
|
||||
*/
|
||||
nr_sdap_ul_hdr_t sdap_hdr;
|
||||
sdap_hdr.QFI = qfi;
|
||||
sdap_hdr.R = 0;
|
||||
sdap_hdr.DC = rqi;
|
||||
/* Add the SDAP UL Header to the buffer */
|
||||
memcpy(&sdap_buf[0], &sdap_hdr, SDAP_HDR_LENGTH);
|
||||
memcpy(&sdap_buf[SDAP_HDR_LENGTH], sdu_buffer, sdu_buffer_size);
|
||||
LOG_D(SDAP, "TX Entity QFI: %u \n", sdap_hdr.QFI);
|
||||
LOG_D(SDAP, "TX Entity R: %u \n", sdap_hdr.R);
|
||||
LOG_D(SDAP, "TX Entity DC: %u \n", sdap_hdr.DC);
|
||||
}
|
||||
|
||||
/*
|
||||
* TS 37.324 5.2 Data transfer
|
||||
* 5.2.1 Uplink UE side
|
||||
* submit the constructed UL SDAP data PDU to the lower layers
|
||||
*
|
||||
* Downlink gNB side
|
||||
*/
|
||||
ret = pdcp_data_req(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size+offset,
|
||||
sdap_buf,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id);
|
||||
|
||||
if(!ret)
|
||||
LOG_E(SDAP, "%s:%d:%s: PDCP refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
|
||||
rb_id_t pdcp_entity,
|
||||
int is_gnb,
|
||||
int has_sdap,
|
||||
int has_sdapHeader,
|
||||
int pdusession_id,
|
||||
int rnti,
|
||||
char *buf,
|
||||
int size) {
|
||||
/* The offset of the SDAP header, it might be 0 if the has_sdap is not true in the pdcp entity. */
|
||||
int offset=0;
|
||||
|
||||
if(is_gnb) { // gNB
|
||||
if(has_sdap && has_sdapHeader ) { // Handling the SDAP Header
|
||||
offset = SDAP_HDR_LENGTH;
|
||||
nr_sdap_ul_hdr_t *sdap_hdr = (nr_sdap_ul_hdr_t *)buf;
|
||||
LOG_D(SDAP, "RX Entity Received QFI : %u\n", sdap_hdr->QFI);
|
||||
LOG_D(SDAP, "RX Entity Received Reserved bit : %u\n", sdap_hdr->R);
|
||||
LOG_D(SDAP, "RX Entity Received DC bit : %u\n", sdap_hdr->DC);
|
||||
|
||||
switch (sdap_hdr->DC) {
|
||||
case SDAP_HDR_UL_DATA_PDU:
|
||||
LOG_D(SDAP, "RX Entity Received SDAP Data PDU\n");
|
||||
break;
|
||||
|
||||
case SDAP_HDR_UL_CTRL_PDU:
|
||||
LOG_D(SDAP, "RX Entity Received SDAP Control PDU\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Pushing SDAP SDU to GTP-U Layer
|
||||
MessageDef *message_p;
|
||||
uint8_t *gtpu_buffer_p;
|
||||
gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U, size + GTPU_HEADER_OVERHEAD_MAX - offset);
|
||||
AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
|
||||
memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf+offset, size-offset);
|
||||
message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0 , GTPV1U_GNB_TUNNEL_DATA_REQ);
|
||||
AssertFatal(message_p != NULL, "OUT OF MEMORY");
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).length = size-offset;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti = rnti;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id = pdusession_id;
|
||||
LOG_D(SDAP, "%s() sending message to gtp size %d\n", __func__, size-offset);
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
|
||||
} else { //nrUE
|
||||
/*
|
||||
* TS 37.324 5.2 Data transfer
|
||||
* 5.2.2 Downlink
|
||||
* if the DRB from which this SDAP data PDU is received is configured by RRC with the presence of SDAP header.
|
||||
*/
|
||||
if(has_sdap && has_sdapHeader) { // Handling the SDAP Header
|
||||
offset = SDAP_HDR_LENGTH;
|
||||
/*
|
||||
* TS 37.324 5.2 Data transfer
|
||||
* 5.2.2 Downlink
|
||||
* retrieve the SDAP SDU from the DL SDAP data PDU as specified in the subclause 6.2.2.2.
|
||||
*/
|
||||
nr_sdap_dl_hdr_t *sdap_hdr = (nr_sdap_dl_hdr_t *)buf;
|
||||
LOG_D(SDAP, "RX Entity Received QFI : %u\n", sdap_hdr->QFI);
|
||||
LOG_D(SDAP, "RX Entity Received RQI : %u\n", sdap_hdr->RQI);
|
||||
LOG_D(SDAP, "RX Entity Received RDI : %u\n", sdap_hdr->RDI);
|
||||
|
||||
/*
|
||||
* TS 37.324 5.2 Data transfer
|
||||
* 5.2.2 Downlink
|
||||
* Perform reflective QoS flow to DRB mapping as specified in the subclause 5.3.2.
|
||||
*/
|
||||
if(sdap_hdr->RDI == SDAP_REFLECTIVE_MAPPING) {
|
||||
/*
|
||||
* TS 37.324 5.3 QoS flow to DRB Mapping
|
||||
* 5.3.2 Reflective mapping
|
||||
* If there is no stored QoS flow to DRB mapping rule for the QoS flow and a default DRB is configured.
|
||||
*/
|
||||
if(!entity->qfi2drb_table[sdap_hdr->QFI].drb_id && entity->default_drb){
|
||||
nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(sdap_hdr->QFI);
|
||||
rb_id_t sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, sdap_hdr->QFI);
|
||||
entity->sdap_submit_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
|
||||
}
|
||||
|
||||
/*
|
||||
* TS 37.324 5.3 QoS flow to DRB mapping
|
||||
* 5.3.2 Reflective mapping
|
||||
* if the stored QoS flow to DRB mapping rule for the QoS flow
|
||||
* is different from the QoS flow to DRB mapping of the DL SDAP data PDU
|
||||
* and
|
||||
* the DRB according to the stored QoS flow to DRB mapping rule is configured by RRC
|
||||
* with the presence of UL SDAP header
|
||||
*/
|
||||
if( (pdcp_entity != entity->qfi2drb_table[sdap_hdr->QFI].drb_id) &&
|
||||
has_sdapHeader ){
|
||||
nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(sdap_hdr->QFI);
|
||||
rb_id_t sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, sdap_hdr->QFI);
|
||||
entity->sdap_submit_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
|
||||
}
|
||||
|
||||
/*
|
||||
* TS 37.324 5.3 QoS flow to DRB Mapping
|
||||
* 5.3.2 Reflective mapping
|
||||
* store the QoS flow to DRB mapping of the DL SDAP data PDU as the QoS flow to DRB mapping rule for the UL.
|
||||
*/
|
||||
entity->qfi2drb_table[sdap_hdr->QFI].drb_id = pdcp_entity;
|
||||
}
|
||||
|
||||
/*
|
||||
* TS 37.324 5.2 Data transfer
|
||||
* 5.2.2 Downlink
|
||||
* perform RQI handling as specified in the subclause 5.4
|
||||
*/
|
||||
if(sdap_hdr->RQI == SDAP_RQI_HANDLING) {
|
||||
LOG_W(SDAP, "UE - TODD 5.4\n");
|
||||
}
|
||||
} /* else - retrieve the SDAP SDU from the DL SDAP data PDU as specified in the subclause 6.2.2.1 */
|
||||
|
||||
/*
|
||||
* TS 37.324 5.2 Data transfer
|
||||
* 5.2.2 Downlink
|
||||
* deliver the retrieved SDAP SDU to the upper layer.
|
||||
*/
|
||||
extern int nas_sock_fd[];
|
||||
int len = write(nas_sock_fd[0], &buf[offset], size-offset);
|
||||
LOG_D(SDAP, "RX Entity len : %d\n", len);
|
||||
LOG_D(SDAP, "RX Entity size : %d\n", size);
|
||||
LOG_D(SDAP, "RX Entity offset : %d\n", offset);
|
||||
|
||||
if (len != size-offset)
|
||||
LOG_E(SDAP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap){
|
||||
if(qfi < SDAP_MAX_QFI &&
|
||||
qfi > SDAP_MAP_RULE_EMPTY &&
|
||||
drb > 0 &&
|
||||
drb <= AVLBL_DRB)
|
||||
{
|
||||
entity->qfi2drb_table[qfi].drb_id = drb;
|
||||
entity->qfi2drb_table[qfi].hasSdap = hasSdap;
|
||||
LOG_D(SDAP, "Updated QFI to DRB Map: QFI %u -> DRB %ld \n", qfi, entity->qfi2drb_table[qfi].drb_id);
|
||||
LOG_D(SDAP, "DRB %ld %s\n", entity->qfi2drb_table[qfi].drb_id, hasSdap ? "has SDAP" : "does not have SDAP");
|
||||
}
|
||||
}
|
||||
|
||||
void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi){
|
||||
entity->qfi2drb_table[qfi].drb_id = SDAP_NO_MAPPING_RULE;
|
||||
LOG_D(SDAP, "Deleted QFI to DRB Map for QFI %u \n", qfi);
|
||||
}
|
||||
|
||||
rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t upper_layer_rb_id){
|
||||
rb_id_t pdcp_entity;
|
||||
|
||||
pdcp_entity = entity->qfi2drb_table[qfi].drb_id;
|
||||
|
||||
if(pdcp_entity){
|
||||
return pdcp_entity;
|
||||
} else if(entity->default_drb) {
|
||||
LOG_D(SDAP, "Mapped QFI %u to Default DRB\n", qfi);
|
||||
return entity->default_drb;
|
||||
} else {
|
||||
return SDAP_MAP_RULE_EMPTY;
|
||||
}
|
||||
|
||||
return pdcp_entity;
|
||||
}
|
||||
|
||||
nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi){
|
||||
nr_sdap_ul_hdr_t sdap_end_marker_hdr;
|
||||
sdap_end_marker_hdr.QFI = qfi;
|
||||
sdap_end_marker_hdr.R = 0;
|
||||
sdap_end_marker_hdr.DC = SDAP_HDR_UL_CTRL_PDU;
|
||||
LOG_D(SDAP, "Constructed Control PDU with QFI:%u R:%u DC:%u \n", sdap_end_marker_hdr.QFI,
|
||||
sdap_end_marker_hdr.R,
|
||||
sdap_end_marker_hdr.DC);
|
||||
return sdap_end_marker_hdr;
|
||||
}
|
||||
|
||||
rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi){
|
||||
rb_id_t drb_of_endmarker = 0;
|
||||
if(map_type == SDAP_CTRL_PDU_MAP_DEF_DRB){
|
||||
drb_of_endmarker = entity->default_drb;
|
||||
LOG_D(SDAP, "Mapped Control PDU to default drb\n");
|
||||
}
|
||||
if(map_type == SDAP_CTRL_PDU_MAP_RULE_DRB){
|
||||
drb_of_endmarker = entity->qfi2drb_map(entity, dl_qfi, pdcp_entity);
|
||||
LOG_D(SDAP, "Mapped Control PDU according to the mapping rule, qfi %u \n", dl_qfi);
|
||||
}
|
||||
return drb_of_endmarker;
|
||||
}
|
||||
|
||||
void nr_sdap_submit_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu){
|
||||
if(sdap_ctrl_pdu_drb){
|
||||
nr_pdcp_submit_sdap_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, ctrl_pdu);
|
||||
LOG_D(SDAP, "Sent Control PDU to PDCP Layer.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity,
|
||||
rb_id_t pdcp_entity,
|
||||
uint16_t rnti,
|
||||
NR_QFI_t *mapped_qfi_2_add,
|
||||
uint8_t mappedQFIs2AddCount,
|
||||
uint8_t drb_identity)
|
||||
{
|
||||
uint8_t qfi = 0;
|
||||
|
||||
for(int i = 0; i < mappedQFIs2AddCount; i++){
|
||||
qfi = mapped_qfi_2_add[i];
|
||||
if(existing_sdap_entity->default_drb && existing_sdap_entity->qfi2drb_table[qfi].drb_id == SDAP_NO_MAPPING_RULE){
|
||||
nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi);
|
||||
rb_id_t sdap_ctrl_pdu_drb = existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, qfi);
|
||||
existing_sdap_entity->sdap_submit_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
|
||||
}
|
||||
if(existing_sdap_entity->qfi2drb_table[qfi].drb_id != drb_identity && existing_sdap_entity->qfi2drb_table[qfi].hasSdap){
|
||||
nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi);
|
||||
rb_id_t sdap_ctrl_pdu_drb = existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, qfi);
|
||||
existing_sdap_entity->sdap_submit_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nr_sdap_entity_t *new_nr_sdap_entity(int has_sdap,
|
||||
uint16_t rnti,
|
||||
int pdusession_id,
|
||||
boolean_t is_defaultDRB,
|
||||
uint8_t drb_identity,
|
||||
NR_QFI_t *mapped_qfi_2_add,
|
||||
uint8_t mappedQFIs2AddCount)
|
||||
{
|
||||
if(nr_sdap_get_entity(rnti, pdusession_id)) {
|
||||
LOG_E(SDAP, "SDAP Entity for UE already exists.\n");
|
||||
nr_sdap_entity_t *existing_sdap_entity = nr_sdap_get_entity(rnti, pdusession_id);
|
||||
rb_id_t pdcp_entity = existing_sdap_entity->default_drb;
|
||||
nr_sdap_ue_qfi2drb_config(existing_sdap_entity, pdcp_entity, rnti, mapped_qfi_2_add, mappedQFIs2AddCount, drb_identity);
|
||||
return existing_sdap_entity;
|
||||
}
|
||||
|
||||
nr_sdap_entity_t *sdap_entity;
|
||||
sdap_entity = calloc(1, sizeof(nr_sdap_entity_t));
|
||||
|
||||
if(sdap_entity == NULL) {
|
||||
LOG_E(SDAP, "SDAP Entity creation failed, out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sdap_entity->rnti = rnti;
|
||||
sdap_entity->pdusession_id = pdusession_id;
|
||||
|
||||
sdap_entity->tx_entity = nr_sdap_tx_entity;
|
||||
sdap_entity->rx_entity = nr_sdap_rx_entity;
|
||||
|
||||
sdap_entity->sdap_construct_ctrl_pdu = nr_sdap_construct_ctrl_pdu;
|
||||
sdap_entity->sdap_map_ctrl_pdu = nr_sdap_map_ctrl_pdu;
|
||||
sdap_entity->sdap_submit_ctrl_pdu = nr_sdap_submit_ctrl_pdu;
|
||||
|
||||
sdap_entity->qfi2drb_map_update = nr_sdap_qfi2drb_map_update;
|
||||
sdap_entity->qfi2drb_map_delete = nr_sdap_qfi2drb_map_del;
|
||||
sdap_entity->qfi2drb_map = nr_sdap_qfi2drb_map;
|
||||
|
||||
if(is_defaultDRB) {
|
||||
sdap_entity->default_drb = drb_identity;
|
||||
LOG_I(SDAP, "Default DRB for the created SDAP entity: %ld \n", sdap_entity->default_drb);
|
||||
|
||||
if(mappedQFIs2AddCount) {
|
||||
for (int i = 0; i < mappedQFIs2AddCount; i++)
|
||||
{
|
||||
LOG_D(SDAP, "Mapped QFI to Add : %ld \n", mapped_qfi_2_add[i]);
|
||||
sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sdap_entity->next_entity = sdap_info.sdap_entity_llist;
|
||||
sdap_info.sdap_entity_llist = sdap_entity;
|
||||
return sdap_entity;
|
||||
}
|
||||
|
||||
nr_sdap_entity_t *nr_sdap_get_entity(uint16_t rnti, int pdusession_id) {
|
||||
nr_sdap_entity_t *sdap_entity;
|
||||
sdap_entity = sdap_info.sdap_entity_llist;
|
||||
|
||||
if(sdap_entity == NULL)
|
||||
return NULL;
|
||||
|
||||
while(sdap_entity->rnti != rnti && sdap_entity->next_entity != NULL) {
|
||||
sdap_entity = sdap_entity->next_entity;
|
||||
}
|
||||
|
||||
if (sdap_entity->rnti == rnti && sdap_entity->pdusession_id == pdusession_id)
|
||||
return sdap_entity;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void delete_nr_sdap_entity(uint16_t rnti) {
|
||||
nr_sdap_entity_t *entityPtr, *entityPrev = NULL;
|
||||
entityPtr = sdap_info.sdap_entity_llist;
|
||||
|
||||
if(entityPtr->rnti == rnti) {
|
||||
sdap_info.sdap_entity_llist = sdap_info.sdap_entity_llist->next_entity;
|
||||
free(entityPtr);
|
||||
} else {
|
||||
while(entityPtr->rnti != rnti && entityPtr->next_entity != NULL) {
|
||||
entityPrev = entityPtr;
|
||||
entityPtr = entityPtr->next_entity;
|
||||
}
|
||||
|
||||
if(entityPtr->rnti != rnti) {
|
||||
entityPrev->next_entity = entityPtr->next_entity;
|
||||
free(entityPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _NR_SDAP_ENTITY_H_
|
||||
#define _NR_SDAP_ENTITY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "openair2/COMMON/platform_types.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
|
||||
#include "NR_RadioBearerConfig.h"
|
||||
|
||||
#define SDAP_BITMASK_DC (0x80)
|
||||
#define SDAP_BITMASK_R (0x40)
|
||||
#define SDAP_BITMASK_QFI (0x3F)
|
||||
#define SDAP_BITMASK_RQI (0x40)
|
||||
#define SDAP_HDR_UL_DATA_PDU (1)
|
||||
#define SDAP_HDR_UL_CTRL_PDU (0)
|
||||
#define SDAP_HDR_LENGTH (1)
|
||||
#define SDAP_MAX_QFI (64)
|
||||
#define SDAP_MAP_RULE_EMPTY (0)
|
||||
#define AVLBL_DRB (5)
|
||||
#define SDAP_NO_MAPPING_RULE (0)
|
||||
#define SDAP_REFLECTIVE_MAPPING (1)
|
||||
#define SDAP_RQI_HANDLING (1)
|
||||
#define SDAP_CTRL_PDU_MAP_DEF_DRB (0)
|
||||
#define SDAP_CTRL_PDU_MAP_RULE_DRB (1)
|
||||
#define SDAP_MAX_PDU (9000)
|
||||
|
||||
/*
|
||||
* The values of QoS Flow ID (QFI) and Reflective QoS Indication,
|
||||
* are located in the PDU Session Container, which is conveyed by
|
||||
* the GTP-U Extension Header. Inside the DL PDU SESSION INFORMATION frame.
|
||||
* TS 38.415 Fig. 5.5.2.1-1
|
||||
*/
|
||||
typedef struct nr_sdap_dl_hdr_s {
|
||||
uint8_t QFI:6;
|
||||
uint8_t RQI:1;
|
||||
uint8_t RDI:1;
|
||||
} __attribute__((packed)) nr_sdap_dl_hdr_t;
|
||||
|
||||
typedef struct nr_sdap_ul_hdr_s {
|
||||
uint8_t QFI:6;
|
||||
uint8_t R:1;
|
||||
uint8_t DC:1;
|
||||
} __attribute__((packed)) nr_sdap_ul_hdr_t;
|
||||
|
||||
typedef struct qfi2drb_s {
|
||||
rb_id_t drb_id;
|
||||
boolean_t hasSdap;
|
||||
} qfi2drb_t;
|
||||
|
||||
void nr_pdcp_submit_sdap_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
|
||||
|
||||
typedef struct nr_sdap_entity_s {
|
||||
uint16_t rnti;
|
||||
rb_id_t default_drb;
|
||||
int pdusession_id;
|
||||
qfi2drb_t qfi2drb_table[SDAP_MAX_QFI];
|
||||
|
||||
void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap);
|
||||
void (*qfi2drb_map_delete)(struct nr_sdap_entity_s *entity, uint8_t qfi);
|
||||
rb_id_t (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t upper_layer_rb_id);
|
||||
|
||||
nr_sdap_ul_hdr_t (*sdap_construct_ctrl_pdu)(uint8_t qfi);
|
||||
rb_id_t (*sdap_map_ctrl_pdu)(struct nr_sdap_entity_s *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi);
|
||||
void (*sdap_submit_ctrl_pdu)(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
|
||||
|
||||
|
||||
boolean_t (*tx_entity)(struct nr_sdap_entity_s *entity,
|
||||
protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id,
|
||||
const uint8_t qfi,
|
||||
const boolean_t rqi
|
||||
);
|
||||
|
||||
void (*rx_entity)(struct nr_sdap_entity_s *entity,
|
||||
rb_id_t pdcp_entity,
|
||||
int is_gnb,
|
||||
int has_sdap,
|
||||
int has_sdapULheader,
|
||||
int pdusession_id,
|
||||
int rnti,
|
||||
char *buf,
|
||||
int size);
|
||||
|
||||
/* List of entities */
|
||||
struct nr_sdap_entity_s *next_entity;
|
||||
} nr_sdap_entity_t;
|
||||
|
||||
/* QFI to DRB Mapping Related Function */
|
||||
void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap);
|
||||
|
||||
/* QFI to DRB Mapping Related Function */
|
||||
void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi);
|
||||
|
||||
/*
|
||||
* TS 37.324
|
||||
* 4.4 Functions
|
||||
* Mapping between a QoS flow and a DRB for both DL and UL.
|
||||
*
|
||||
* 5.2.1 Uplink
|
||||
* If there is no stored QoS flow to DRB mapping rule for the QoS flow as specified in the subclause 5.3, map the SDAP SDU to the default DRB
|
||||
* else, map the SDAP SDU to the DRB according to the stored QoS flow to DRB mapping rule.
|
||||
*/
|
||||
rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t upper_layer_rb_id);
|
||||
|
||||
/*
|
||||
* TS 37.324 5.3 QoS flow to DRB Mapping
|
||||
* construct an end-marker control PDU, as specified in the subclause 6.2.3, for the QoS flow;
|
||||
*/
|
||||
nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi);
|
||||
|
||||
/*
|
||||
* TS 37.324 5.3 QoS flow to DRB Mapping
|
||||
* map the end-marker control PDU to the
|
||||
* 1.) default DRB or
|
||||
* 2.) DRB according to the stored QoS flow to DRB mapping rule
|
||||
*/
|
||||
rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi);
|
||||
|
||||
/*
|
||||
* TS 37.324 5.3 QoS flow to DRB Mapping
|
||||
* Submit the end-marker control PDU to the lower layer.
|
||||
*/
|
||||
void nr_sdap_submit_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
|
||||
|
||||
/*
|
||||
* TS 37.324 5.3 QoS flow to DRB Mapping
|
||||
* 5.3.1 Configuration Procedures
|
||||
*/
|
||||
void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity,
|
||||
rb_id_t pdcp_entity,
|
||||
uint16_t rnti,
|
||||
NR_QFI_t *mapped_qfi_2_add,
|
||||
uint8_t mappedQFIs2AddCount,
|
||||
uint8_t drb_identity);
|
||||
|
||||
/*
|
||||
* TS 37.324 4.4 5.1.1 SDAP entity establishment
|
||||
* Establish an SDAP entity.
|
||||
*/
|
||||
nr_sdap_entity_t *new_nr_sdap_entity(int has_sdap,
|
||||
uint16_t rnti,
|
||||
int pdusession_id,
|
||||
boolean_t is_defaultDRB,
|
||||
uint8_t default_DRB,
|
||||
NR_QFI_t *mapped_qfi_2_add,
|
||||
uint8_t mappedQFIs2AddCount);
|
||||
|
||||
/* Entity Handling Related Functions */
|
||||
nr_sdap_entity_t *nr_sdap_get_entity(uint16_t rnti, int pdusession_id);
|
||||
|
||||
/* Entity Handling Related Functions */
|
||||
void delete_nr_sdap_entity(uint16_t rnti);
|
||||
|
||||
#endif
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "nr_sdap_gnb.h"
|
||||
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
|
||||
|
||||
boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id
|
||||
) {
|
||||
if(sdu_buffer == NULL) {
|
||||
LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(sdu_buffer_size == 0) {
|
||||
LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL or 0 sdu_buffer_size \n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uint8_t *sdap_buf = (uint8_t *)malloc(sdu_buffer_size+SDAP_HDR_LENGTH);
|
||||
nr_sdap_dl_hdr_t sdap_hdr;
|
||||
sdap_hdr.RDI = 0; // SDAP_Hardcoded -
|
||||
sdap_hdr.RQI = 0; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION
|
||||
sdap_hdr.QFI = 1; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION
|
||||
memcpy(&sdap_buf[0], &sdap_hdr, 1);
|
||||
memcpy(&sdap_buf[1], sdu_buffer, sdu_buffer_size);
|
||||
rb_id_t sdap_drb_id = rb_id; // SDAP_Hardcoded - Should get this info from QFI to DRB mapping table
|
||||
boolean_t ret = pdcp_data_req(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size+1,
|
||||
sdap_buf,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id);
|
||||
|
||||
if(!ret) {
|
||||
LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - PDCP DL refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
free(sdap_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(sdap_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr) {
|
||||
nr_sdap_ul_hdr_t *sdap_hdr_ul = (nr_sdap_ul_hdr_t *)&sdap_gnb_ul_hdr;
|
||||
|
||||
switch (sdap_hdr_ul->DC) {
|
||||
case SDAP_HDR_UL_DATA_PDU:
|
||||
LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - UL Received SDAP Data PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
break;
|
||||
|
||||
case SDAP_HDR_UL_CTRL_PDU:
|
||||
LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - Received SDAP Control PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _NR_SDAP_GNB_
|
||||
#define _NR_SDAP_GNB_
|
||||
|
||||
#include "openair2/COMMON/platform_types.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#define SDAP_BITMASK_DC (0x80)
|
||||
#define SDAP_BITMASK_R (0x40)
|
||||
#define SDAP_BITMASK_QFI (0x3F)
|
||||
#define SDAP_HDR_UL_DATA_PDU (1)
|
||||
#define SDAP_HDR_UL_CTRL_PDU (0)
|
||||
#define SDAP_HDR_LENGTH (1)
|
||||
|
||||
typedef struct nr_sdap_dl_hdr_s {
|
||||
uint8_t QFI:6;
|
||||
uint8_t RQI:1;
|
||||
uint8_t RDI:1;
|
||||
} __attribute__((packed)) nr_sdap_dl_hdr_t;
|
||||
|
||||
typedef struct nr_sdap_ul_hdr_s {
|
||||
uint8_t QFI:6;
|
||||
uint8_t R:1;
|
||||
uint8_t DC:1;
|
||||
} __attribute__((packed)) nr_sdap_ul_hdr_t;
|
||||
|
||||
boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id
|
||||
);
|
||||
|
||||
void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr);
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file sdap_gNB.c
|
||||
* \brief sdap tasks for gNB
|
||||
* \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr>
|
||||
* \date 2018
|
||||
* \version 1.0
|
||||
*/
|
||||
#define SDAP_GNB
|
||||
#define SDAP_GNB_C
|
||||
|
||||
Reference in New Issue
Block a user