Merge remote-tracking branch 'origin/develop' into tdd25period_for_MR
This commit is contained in:
@@ -354,7 +354,7 @@ typedef struct m2ap_register_mce_req_s {
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs];
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int16_t N_RB_DL[MAX_NUM_CCs];
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
@@ -427,7 +427,7 @@ typedef struct m2ap_register_enb_req_s {
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs];
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int16_t N_RB_DL[MAX_NUM_CCs];
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
|
||||
@@ -123,7 +123,7 @@ typedef struct m3ap_register_mce_req_s {
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs];
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int16_t N_RB_DL[MAX_NUM_CCs];
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
|
||||
@@ -70,7 +70,7 @@ typedef struct CellInfo_s {
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// eNB: ENB_APP -> PHY messages
|
||||
typedef struct PhyConfigurationReq_s {
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
frame_type_t frame_type[MAX_NUM_CCs];
|
||||
lte_prefix_type_t prefix_type[MAX_NUM_CCs];
|
||||
uint32_t downlink_frequency[MAX_NUM_CCs];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs];
|
||||
|
||||
@@ -188,7 +188,7 @@ typedef struct RrcConfigurationReq_s {
|
||||
uint32_t rrc_inactivity_timer_thres; // for testing, maybe change later
|
||||
paging_drx_t default_drx;
|
||||
int16_t nb_cc;
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint8_t tdd_config[MAX_NUM_CCs];
|
||||
uint8_t tdd_config_s[MAX_NUM_CCs];
|
||||
lte_prefix_type_t prefix_type[MAX_NUM_CCs];
|
||||
@@ -339,7 +339,7 @@ typedef struct NbIoTRrcConfigurationReq_s {
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
uint8_t mnc_digit_length;
|
||||
lte_frame_type_t frame_type;
|
||||
frame_type_t frame_type;
|
||||
uint8_t tdd_config;
|
||||
uint8_t tdd_config_s;
|
||||
lte_prefix_type_t prefix_type;
|
||||
|
||||
@@ -138,7 +138,7 @@ typedef struct x2ap_register_enb_req_s {
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs];
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int16_t N_RB_DL[MAX_NUM_CCs];
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
|
||||
uint32_t subframeAssignment[MAX_NUM_CCs];
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef struct eutra_band_s {
|
||||
uint32_t ul_max;
|
||||
uint32_t dl_min;
|
||||
uint32_t dl_max;
|
||||
lte_frame_type_t frame_type;
|
||||
frame_type_t frame_type;
|
||||
} eutra_band_t;
|
||||
|
||||
|
||||
|
||||
@@ -1352,7 +1352,7 @@ void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t
|
||||
}
|
||||
}
|
||||
|
||||
void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type) {
|
||||
void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, frame_type_t frame_type) {
|
||||
if (phy_is_present(mod_id, cc_id)) {
|
||||
RC.eNB[mod_id][cc_id]->frame_parms.frame_type = frame_type;
|
||||
} else {
|
||||
|
||||
@@ -433,7 +433,7 @@ void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t
|
||||
void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB);
|
||||
|
||||
/*set frame type*/
|
||||
void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type);
|
||||
void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, frame_type_t frame_type);
|
||||
|
||||
/*RRC status flexRAN*/
|
||||
uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
@@ -346,7 +346,7 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
|
||||
// prepare DL Allocation lists
|
||||
nr_rrc_config_dl_tda(scc);
|
||||
|
||||
lte_frame_type_t frame_type = get_frame_type((int)*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
frame_type_t frame_type = get_frame_type((int)*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
if (frame_type == FDD) {
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_TDD_UL_DL_ConfigCommon, scc->tdd_UL_DL_ConfigurationCommon);
|
||||
scc->tdd_UL_DL_ConfigurationCommon = NULL;
|
||||
|
||||
@@ -58,11 +58,6 @@ extern int l2_init_eNB(void);
|
||||
extern void mac_top_init_eNB(void);
|
||||
extern void mac_init_cell_params(int Mod_idP,int CC_idP);
|
||||
|
||||
|
||||
int32_t **rxdata;
|
||||
int32_t **txdata;
|
||||
|
||||
|
||||
typedef struct eutra_bandentry_s {
|
||||
int16_t band;
|
||||
uint32_t ul_min;
|
||||
|
||||
@@ -107,11 +107,10 @@ typedef struct {
|
||||
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_SHORT;
|
||||
|
||||
typedef struct {
|
||||
uint8_t LCID: 6; // octet 1 [5:0]
|
||||
uint8_t F: 1; // octet 1 [6]
|
||||
uint8_t R: 1; // octet 1 [7]
|
||||
uint8_t L1: 8; // octet 2 [7:0]
|
||||
uint8_t L2: 8; // octet 3 [7:0]
|
||||
uint8_t LCID: 6;
|
||||
uint8_t F: 1;
|
||||
uint8_t R: 1;
|
||||
uint16_t L: 16;
|
||||
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_LONG;
|
||||
|
||||
typedef struct {
|
||||
@@ -119,6 +118,23 @@ typedef struct {
|
||||
uint8_t R: 2; // octet 1 [7:6]
|
||||
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
|
||||
|
||||
static inline int get_mac_len(uint8_t* pdu, int pdu_len, uint16_t *mac_ce_len, uint16_t *mac_subheader_len) {
|
||||
if ( pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return false;
|
||||
NR_MAC_SUBHEADER_SHORT *s = (NR_MAC_SUBHEADER_SHORT*) pdu;
|
||||
NR_MAC_SUBHEADER_LONG *l = (NR_MAC_SUBHEADER_LONG*) pdu;
|
||||
if (s->F && pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||
return false;
|
||||
if (s->F) {
|
||||
*mac_subheader_len = sizeof(*l);
|
||||
*mac_ce_len = ntohs(l->L);
|
||||
} else {
|
||||
*mac_subheader_len = sizeof(*s);
|
||||
*mac_ce_len = s->L;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// BSR MAC CEs
|
||||
// TS 38.321 ch. 6.1.3.1
|
||||
// Short BSR for a specific logical channel group ID
|
||||
|
||||
@@ -3092,7 +3092,7 @@ int is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slo
|
||||
else return(slot_in_period <= slots1+tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);
|
||||
}
|
||||
|
||||
int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slot, lte_frame_type_t frame_type) {
|
||||
int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slot, frame_type_t frame_type) {
|
||||
|
||||
int period,period1,period2=0;
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i
|
||||
|
||||
int is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slot_t slotP);
|
||||
|
||||
int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, lte_frame_type_t frame_type);
|
||||
int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, frame_type_t frame_type);
|
||||
|
||||
uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP,
|
||||
const NR_BWP_UplinkCommon_t *initialULBWP,
|
||||
|
||||
@@ -323,7 +323,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
|
||||
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
mac->frequency_range = band<100?FR1:FR2;
|
||||
|
||||
lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
|
||||
// cell config
|
||||
|
||||
|
||||
@@ -369,7 +369,7 @@ typedef struct {
|
||||
NR_ControlResourceSet_t *coreset[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP];
|
||||
NR_SearchSpace_t *SSpace[MAX_NUM_BWP][FAPI_NR_MAX_SS];
|
||||
|
||||
lte_frame_type_t frame_type;
|
||||
frame_type_t frame_type;
|
||||
|
||||
/*BWP*/
|
||||
// dedicated active DL BWP
|
||||
|
||||
@@ -48,6 +48,7 @@ void nr_ue_init_mac(module_id_t module_idP);
|
||||
\param module_id module id
|
||||
\param cc_id component carrier id
|
||||
\param gNB_index gNB index
|
||||
\param phy_data PHY structure to be filled in by the callee in the FAPI call (L1 caller -> indication to L2 -> FAPI call to L1 callee)
|
||||
\param extra_bits extra bits for frame calculation
|
||||
\param l_ssb_equal_64 check if ssb number of candicate is equal 64, 1=equal; 0=non equal. Reference 38.212 7.1.1
|
||||
\param pduP pointer to pdu
|
||||
@@ -56,7 +57,8 @@ void nr_ue_init_mac(module_id_t module_idP);
|
||||
int8_t nr_ue_decode_mib(
|
||||
module_id_t module_id,
|
||||
int cc_id,
|
||||
uint8_t gNB_index,
|
||||
uint8_t gNB_index,
|
||||
void *phy_data,
|
||||
uint8_t extra_bits,
|
||||
uint32_t ssb_length,
|
||||
uint32_t ssb_index,
|
||||
@@ -132,7 +134,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
@param int cc_id CC ID
|
||||
@param frame_t frame frame number
|
||||
@param int slot reference number
|
||||
@param UE_nr_rxtx_proc_t *proc pointer to process context */
|
||||
@param void *phy_pata pointer to a PHY specific structure to be filled in the scheduler response (can be null) */
|
||||
void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
|
||||
fapi_nr_dl_config_request_t *dl_config,
|
||||
fapi_nr_ul_config_request_t *ul_config,
|
||||
@@ -141,7 +143,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
|
||||
int cc_id,
|
||||
frame_t frame,
|
||||
int slot,
|
||||
int thread_id);
|
||||
int thread_id,
|
||||
void *phy_data);
|
||||
|
||||
/*! \fn int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
|
||||
\brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU.
|
||||
@@ -373,7 +376,8 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
|
||||
uint8_t ssb_subcarrier_offset,
|
||||
uint32_t ssb_index,
|
||||
uint16_t ssb_start_subcarrier,
|
||||
frequency_range_t frequency_range);
|
||||
frequency_range_t frequency_range,
|
||||
void *phy_data);
|
||||
|
||||
/* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI.
|
||||
@param Mod_id Index of UE instance
|
||||
|
||||
@@ -287,6 +287,7 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){
|
||||
int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
int cc_id,
|
||||
uint8_t gNB_index,
|
||||
void *phy_data,
|
||||
uint8_t extra_bits, // 8bits 38.212 c7.1.1
|
||||
uint32_t ssb_length,
|
||||
uint32_t ssb_index,
|
||||
@@ -362,7 +363,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
ssb_subcarrier_offset,
|
||||
ssb_index,
|
||||
ssb_start_subcarrier,
|
||||
mac->frequency_range);
|
||||
mac->frequency_range,
|
||||
phy_data);
|
||||
}
|
||||
else {
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
@@ -2135,6 +2137,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
|
||||
pucch->is_common = current_harq->is_common;
|
||||
current_harq->active = false;
|
||||
current_harq->ack_received = false;
|
||||
LOG_D(PHY,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3368,10 +3371,6 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment,
|
||||
int pdu_id){
|
||||
|
||||
uint8_t rx_lcid;
|
||||
uint16_t mac_ce_len;
|
||||
uint16_t mac_subheader_len;
|
||||
uint16_t mac_sdu_len;
|
||||
module_id_t module_idP = dl_info->module_id;
|
||||
frame_t frameP = dl_info->frame;
|
||||
int slot = dl_info->slot;
|
||||
@@ -3390,139 +3389,100 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
LOG_D(MAC, "In %s [%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, pdu_len, dl_info->rx_ind->number_pdus);
|
||||
|
||||
while (!done && pdu_len > 0){
|
||||
mac_ce_len = 0x0000;
|
||||
mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
|
||||
mac_sdu_len = 0x0000;
|
||||
rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
||||
uint16_t mac_len = 0x0000;
|
||||
uint16_t mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
|
||||
uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
||||
|
||||
LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len);
|
||||
bool ret;
|
||||
switch(rx_lcid){
|
||||
// MAC CE
|
||||
case DL_SCH_LCID_CCCH:
|
||||
// MSG4 RRC Setup 38.331
|
||||
// variable length
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
|
||||
| ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
|
||||
mac_subheader_len = 3;
|
||||
} else {
|
||||
mac_sdu_len = ((NR_MAC_SUBHEADER_SHORT *) pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
|
||||
AssertFatal(pdu_len > mac_sdu_len, "The mac_sdu_len (%d) has an invalid size. PDU len = %d! \n",
|
||||
mac_sdu_len, pdu_len);
|
||||
ret=get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len);
|
||||
AssertFatal(ret, "The mac_len (%d) has an invalid size. PDU len = %d! \n",
|
||||
mac_len, pdu_len);
|
||||
|
||||
// Check if it is a valid CCCH message, we get all 00's messages very often
|
||||
int i = 0;
|
||||
for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
|
||||
for(i=0; i<(mac_subheader_len+mac_len); i++) {
|
||||
if(pduP[i] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == (mac_subheader_len+mac_sdu_len)) {
|
||||
if (i == (mac_subheader_len+mac_len)) {
|
||||
LOG_D(NR_MAC, "%s() Invalid CCCH message!, pdu_len: %d\n", __func__, pdu_len);
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( mac_sdu_len > 0 ) {
|
||||
LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_sdu_len);
|
||||
if ( mac_len > 0 ) {
|
||||
LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_len);
|
||||
for (int i = 0; i < mac_subheader_len; i++) {
|
||||
LOG_D(NR_MAC, "MAC header %d: 0x%x\n", i, pduP[i]);
|
||||
}
|
||||
for (int i = 0; i < mac_sdu_len; i++) {
|
||||
for (int i = 0; i < mac_len; i++) {
|
||||
LOG_D(NR_MAC, "%d: 0x%x\n", i, pduP[mac_subheader_len + i]);
|
||||
}
|
||||
nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_sdu_len);
|
||||
nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_len);
|
||||
}
|
||||
break;
|
||||
case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH:
|
||||
case DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL:
|
||||
case DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT:
|
||||
case DL_SCH_LCID_SP_SRS_ACTIVATION:
|
||||
|
||||
// 38.321 Ch6.1.3.14
|
||||
// varialbe length
|
||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
}
|
||||
break;
|
||||
case DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL:
|
||||
// 38.321 Ch6.1.3.13
|
||||
// varialbe length
|
||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
}
|
||||
break;
|
||||
case DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT:
|
||||
// 38.321 Ch6.1.3.12
|
||||
// varialbe length
|
||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
}
|
||||
break;
|
||||
case DL_SCH_LCID_SP_SRS_ACTIVATION:
|
||||
// 38.321 Ch6.1.3.17
|
||||
// varialbe length
|
||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
}
|
||||
get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len);
|
||||
break;
|
||||
|
||||
case DL_SCH_LCID_RECOMMENDED_BITRATE:
|
||||
// 38.321 Ch6.1.3.20
|
||||
mac_ce_len = 2;
|
||||
mac_len = 2;
|
||||
break;
|
||||
case DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT:
|
||||
// 38.321 Ch6.1.3.19
|
||||
mac_ce_len = 2;
|
||||
mac_len = 2;
|
||||
break;
|
||||
case DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT:
|
||||
// 38.321 Ch6.1.3.18
|
||||
mac_ce_len = 3;
|
||||
mac_len = 3;
|
||||
break;
|
||||
case DL_SCH_LCID_SP_CSI_REP_PUCCH_ACT:
|
||||
// 38.321 Ch6.1.3.16
|
||||
mac_ce_len = 2;
|
||||
mac_len = 2;
|
||||
break;
|
||||
case DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH:
|
||||
// 38.321 Ch6.1.3.15
|
||||
mac_ce_len = 2;
|
||||
mac_len = 2;
|
||||
break;
|
||||
case DL_SCH_LCID_DUPLICATION_ACT:
|
||||
// 38.321 Ch6.1.3.11
|
||||
mac_ce_len = 1;
|
||||
mac_len = 1;
|
||||
break;
|
||||
case DL_SCH_LCID_SCell_ACT_4_OCT:
|
||||
// 38.321 Ch6.1.3.10
|
||||
mac_ce_len = 4;
|
||||
mac_len = 4;
|
||||
break;
|
||||
case DL_SCH_LCID_SCell_ACT_1_OCT:
|
||||
// 38.321 Ch6.1.3.10
|
||||
mac_ce_len = 1;
|
||||
mac_len = 1;
|
||||
break;
|
||||
case DL_SCH_LCID_L_DRX:
|
||||
// 38.321 Ch6.1.3.6
|
||||
// fixed length but not yet specify.
|
||||
mac_ce_len = 0;
|
||||
mac_len = 0;
|
||||
break;
|
||||
case DL_SCH_LCID_DRX:
|
||||
// 38.321 Ch6.1.3.5
|
||||
// fixed length but not yet specify.
|
||||
mac_ce_len = 0;
|
||||
mac_len = 0;
|
||||
break;
|
||||
case DL_SCH_LCID_TA_COMMAND:
|
||||
// 38.321 Ch6.1.3.4
|
||||
mac_ce_len = 1;
|
||||
mac_len = 1;
|
||||
|
||||
/*uint8_t ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
|
||||
uint8_t tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;*/
|
||||
@@ -3544,14 +3504,14 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
// Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
|
||||
// MAC Header: 1 byte (R/R/LCID)
|
||||
// MAC SDU: 6 bytes (UE Contention Resolution Identity)
|
||||
mac_ce_len = 6;
|
||||
mac_len = 6;
|
||||
|
||||
if(ra->ra_state == WAIT_CONTENTION_RESOLUTION) {
|
||||
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n",
|
||||
module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]);
|
||||
|
||||
bool ra_success = true;
|
||||
for(int i = 0; i<mac_ce_len; i++) {
|
||||
for(int i = 0; i<mac_len; i++) {
|
||||
if(ra->cont_res_id[i] != pduP[i+1]) {
|
||||
ra_success = false;
|
||||
break;
|
||||
@@ -3579,25 +3539,9 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
// check if LCID is valid at current time.
|
||||
default:
|
||||
{
|
||||
// check if LCID is valid at current time.
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return;
|
||||
NR_MAC_SUBHEADER_SHORT *shs = (NR_MAC_SUBHEADER_SHORT *)pduP;
|
||||
if (shs->F) {
|
||||
//mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||
return;
|
||||
NR_MAC_SUBHEADER_LONG *shl = (NR_MAC_SUBHEADER_LONG *)pduP;
|
||||
mac_sdu_len = ((uint16_t)(shl->L1 & 0x7f) << 8) | (uint16_t)(shl->L2 & 0xff);
|
||||
} else {
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return;
|
||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len);
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return;
|
||||
LOG_D(NR_MAC, "[UE %d] %4d.%2d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, slot, rx_lcid, gNB_index, mac_len);
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
|
||||
@@ -3618,7 +3562,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
MBMS_FLAG_NO,
|
||||
rx_lcid,
|
||||
(char *) (pduP + mac_subheader_len),
|
||||
mac_sdu_len,
|
||||
mac_len,
|
||||
1,
|
||||
NULL);
|
||||
} else {
|
||||
@@ -3629,8 +3573,8 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
break;
|
||||
}
|
||||
}
|
||||
pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
pduP += ( mac_subheader_len + mac_len );
|
||||
pdu_len -= ( mac_subheader_len + mac_len );
|
||||
if (pdu_len < 0)
|
||||
LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", module_idP, frameP, slot, pdu_len);
|
||||
}
|
||||
|
||||
@@ -93,7 +93,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
|
||||
int cc_id,
|
||||
frame_t frame,
|
||||
int slot,
|
||||
int thread_id){
|
||||
int thread_id,
|
||||
void *phy_data){
|
||||
|
||||
scheduled_response->dl_config = dl_config;
|
||||
scheduled_response->ul_config = ul_config;
|
||||
@@ -103,6 +104,7 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
|
||||
scheduled_response->frame = frame;
|
||||
scheduled_response->slot = slot;
|
||||
scheduled_response->thread_id = thread_id;
|
||||
scheduled_response->phy_data = phy_data;
|
||||
|
||||
}
|
||||
|
||||
@@ -1072,7 +1074,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
|
||||
mac->dl_config_request = dcireq.dl_config_req;
|
||||
|
||||
fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
|
||||
fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
@@ -1088,7 +1090,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
fill_dci_search_candidates(mac->ra.ss, rel15);
|
||||
dl_config->number_pdus = 1;
|
||||
LOG_D(MAC,"mac->cg %p: Calling fill_scheduled_response rnti %x, type0_pdcch, num_pdus %d\n",mac->cg,rel15->rnti,dl_config->number_pdus);
|
||||
fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
|
||||
fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
@@ -1197,7 +1199,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
}
|
||||
pthread_mutex_unlock(&ul_config->mutex_ul_config); // avoid double lock
|
||||
|
||||
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, frame_tx, slot_tx, ul_info->thread_id);
|
||||
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, frame_tx, slot_tx, ul_info->thread_id, NULL);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
@@ -2352,7 +2354,7 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
|
||||
O_SR, O_ACK, O_CSI);
|
||||
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);
|
||||
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)
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
@@ -2699,7 +2701,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
|
||||
}
|
||||
} // if format1
|
||||
|
||||
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
|
||||
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)
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
} // is_nr_prach_slot
|
||||
@@ -2714,7 +2716,8 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
|
||||
uint8_t ssb_subcarrier_offset,
|
||||
uint32_t ssb_index,
|
||||
uint16_t ssb_start_subcarrier,
|
||||
frequency_range_t frequency_range) {
|
||||
frequency_range_t frequency_range,
|
||||
void *phy_data) {
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
@@ -2762,7 +2765,7 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
|
||||
slot_s = mac->type0_PDCCH_CSS_config.n_c;
|
||||
}
|
||||
LOG_D(MAC,"Calling fill_scheduled_response, type0_pdcch, num_pdus %d\n",dl_config->number_pdus);
|
||||
fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, 0); // TODO fix thread_id, for now assumed 0
|
||||
fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, 0, phy_data); // TODO fix thread_id, for now assumed 0
|
||||
|
||||
if (dl_config->number_pdus) {
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
||||
@@ -3140,8 +3143,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
||||
header->R = 0;
|
||||
header->F = 1;
|
||||
header->LCID = lcid;
|
||||
header->L1 = ((unsigned short) sdu_length >> 8) & 0x7f;
|
||||
header->L2 = (unsigned short) sdu_length & 0xff;
|
||||
header->L = htons(sdu_length);
|
||||
|
||||
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
||||
LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size);
|
||||
|
||||
@@ -233,7 +233,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, rrc_pdsch_AntennaPorts
|
||||
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
frequency_range_t frequency_range = band<100?FR1:FR2;
|
||||
|
||||
lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
|
||||
|
||||
// Cell configuration
|
||||
|
||||
@@ -399,7 +399,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
|
||||
void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
|
||||
uint16_t *msg2_frame, uint16_t *msg2_slot,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
lte_frame_type_t frame_type,
|
||||
frame_type_t frame_type,
|
||||
uint16_t monitoring_slot_period,
|
||||
uint16_t monitoring_offset,uint8_t beam_index,
|
||||
uint8_t num_active_ssb,
|
||||
@@ -525,7 +525,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
lte_frame_type_t frame_type = cc->frame_type;
|
||||
frame_type_t frame_type = cc->frame_type;
|
||||
|
||||
uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES;
|
||||
uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
|
||||
@@ -934,7 +934,7 @@ void nr_get_Msg3alloc(module_id_t module_id,
|
||||
|
||||
uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes
|
||||
|
||||
lte_frame_type_t frame_type = RC.nrmac[module_id]->common_channels->frame_type;
|
||||
frame_type_t frame_type = RC.nrmac[module_id]->common_channels->frame_type;
|
||||
|
||||
int mu = ubwp ?
|
||||
ubwp->bwp_Common->genericParameters.subcarrierSpacing :
|
||||
@@ -1631,7 +1631,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
harq->feedback_slot = pucch->ul_slot;
|
||||
harq->feedback_frame = pucch->frame;
|
||||
|
||||
uint8_t *buf = (uint8_t *) harq->tb;
|
||||
uint8_t *buf = (uint8_t *) harq->transportBlock;
|
||||
// Bytes to be transmitted
|
||||
if (harq->round == 0) {
|
||||
if (ra->msg3_dcch_dtch) {
|
||||
@@ -1880,11 +1880,11 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
}
|
||||
|
||||
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti),
|
||||
T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->tb, harq->tb_size));
|
||||
T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, harq->tb_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];
|
||||
memcpy(tx_req->TLVs[0].value.direct, harq->tb, sizeof(uint8_t) * harq->tb_size);
|
||||
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, sizeof(uint8_t) * harq->tb_size);
|
||||
tx_req->PDU_length = harq->tb_size;
|
||||
tx_req->PDU_index = pduindex;
|
||||
tx_req->num_TLV = 1;
|
||||
|
||||
@@ -53,39 +53,39 @@
|
||||
#define WORD 32
|
||||
//#define SIZE_OF_POINTER sizeof (void *)
|
||||
|
||||
void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp)
|
||||
{
|
||||
void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp) {
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||
const int bwp_id = bwp ? bwp->bwp_Id : 0;
|
||||
|
||||
if (nrmac->preferred_dl_tda[bwp_id])
|
||||
return;
|
||||
|
||||
/* there is a mixed slot only when in TDD */
|
||||
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
|
||||
lte_frame_type_t frame_type = nrmac->common_channels->frame_type;
|
||||
frame_type_t frame_type = nrmac->common_channels->frame_type;
|
||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd =
|
||||
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
|
||||
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
int symb_dlMixed = 0;
|
||||
int nr_mix_slots = 0;
|
||||
int nr_slots_period = n;
|
||||
|
||||
if (tdd) {
|
||||
symb_dlMixed = (1 << tdd->nrofDownlinkSymbols) - 1;
|
||||
nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
|
||||
nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
|
||||
}
|
||||
else
|
||||
} else
|
||||
// if TDD configuration is not present and the band is not FDD, it means it is a dynamic TDD configuration
|
||||
AssertFatal(nrmac->common_channels->frame_type == FDD,"Dynamic TDD not handled yet\n");
|
||||
|
||||
int target_ss;
|
||||
|
||||
if (bwp) {
|
||||
target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
target_ss = NR_SearchSpace__searchSpaceType_PR_common;
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -113,9 +113,9 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
|
||||
// here we assume that the coreset is scheduled every slot (which it
|
||||
// currently is) and starting at symbol 0
|
||||
AssertFatal((symb_coreset & symb_tda) == 0, "TDA index 0 for DL overlaps with CORESET\n");
|
||||
|
||||
/* check that TDA index 1 fits into DL part of mixed slot, if it exists */
|
||||
int tdaMi = -1;
|
||||
|
||||
if (frame_type == TDD && tdaList->list.count > 1) {
|
||||
const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
|
||||
AssertFatal(!tdaP_Mi->k0 || *tdaP_Mi->k0 == 0,
|
||||
@@ -124,6 +124,7 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
|
||||
int start, len;
|
||||
SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
|
||||
const uint16_t symb_tda = ((1 << len) - 1) << start;
|
||||
|
||||
// check whether coreset and TDA overlap: then, we cannot use it. Also,
|
||||
// check whether TDA is entirely within mixed slot DL. Note that
|
||||
// here we assume that the coreset is scheduled every slot (which it
|
||||
@@ -143,10 +144,12 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
nrmac->preferred_dl_tda[bwp_id][i] = -1;
|
||||
|
||||
if (frame_type == FDD || i % nr_slots_period < tdd->nrofDownlinkSlots)
|
||||
nrmac->preferred_dl_tda[bwp_id][i] = 0;
|
||||
else if (nr_mix_slots && i % nr_slots_period == tdd->nrofDownlinkSlots)
|
||||
nrmac->preferred_dl_tda[bwp_id][i] = tdaMi;
|
||||
|
||||
LOG_D(MAC, "slot %d preferred_dl_tda %d\n", i, nrmac->preferred_dl_tda[bwp_id][i]);
|
||||
}
|
||||
}
|
||||
@@ -157,8 +160,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
||||
const NR_UE_sched_ctrl_t *ue_sched_ctl,
|
||||
unsigned char *mac_pdu,
|
||||
unsigned char drx_cmd,
|
||||
unsigned char *ue_cont_res_id)
|
||||
{
|
||||
unsigned char *ue_cont_res_id) {
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu;
|
||||
uint8_t last_size = 0;
|
||||
@@ -201,8 +203,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
||||
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
|
||||
ce_ptr += mac_ce_size;
|
||||
mac_pdu_ptr += (unsigned char) mac_ce_size;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Contention resolution fixed subheader and MAC CE
|
||||
@@ -399,18 +399,18 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
||||
|
||||
#define BLER_UPDATE_FRAME 10
|
||||
#define BLER_FILTER 0.9f
|
||||
int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id, int mcs_table)
|
||||
{
|
||||
int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id, int mcs_table) {
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
|
||||
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
|
||||
int max_allowed_mcs = (mcs_table == 1) ? 27 : 28;
|
||||
int max_mcs = nrmac->dl_max_mcs;
|
||||
|
||||
if (nrmac->dl_max_mcs>max_allowed_mcs)
|
||||
max_mcs = max_allowed_mcs;
|
||||
|
||||
NR_DL_bler_stats_t *bler_stats = &nrmac->UE_info.UE_sched_ctrl[UE_id].dl_bler_stats;
|
||||
|
||||
/* first call: everything is zero. Initialize to sensible default */
|
||||
if (bler_stats->last_frame_slot == 0 && bler_stats->mcs == 0) {
|
||||
bler_stats->last_frame_slot = frame * n + slot;
|
||||
@@ -418,13 +418,16 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
||||
bler_stats->bler = (nrmac->dl_bler_target_lower + nrmac->dl_bler_target_upper) / 2;
|
||||
bler_stats->rd2_bler = nrmac->dl_rd2_bler_threshold;
|
||||
}
|
||||
|
||||
const int now = frame * n + slot;
|
||||
int diff = now - bler_stats->last_frame_slot;
|
||||
|
||||
if (diff < 0) // wrap around
|
||||
diff += 1024 * n;
|
||||
|
||||
const uint8_t old_mcs = bler_stats->mcs;
|
||||
const NR_mac_stats_t *stats = &nrmac->UE_info.mac_stats[UE_id];
|
||||
|
||||
// TODO put back this condition when relevant
|
||||
/*const int dret3x = stats->dlsch_rounds[3] - bler_stats->dlsch_rounds[3];
|
||||
if (dret3x > 0) {
|
||||
@@ -447,8 +450,8 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
||||
const float rd2_bler_wnd = dtx > 0 ? (float) dretx2 / dtx : bler_stats->rd2_bler;
|
||||
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
|
||||
bler_stats->rd2_bler = BLER_FILTER / 4 * bler_stats->rd2_bler + (1 - BLER_FILTER / 4) * rd2_bler_wnd;
|
||||
|
||||
int new_mcs = old_mcs;
|
||||
|
||||
// TODO put back this condition when relevant
|
||||
/* first ensure that number of 2nd retx is below threshold. If this is the
|
||||
* case, use 1st retx to adjust faster
|
||||
@@ -459,9 +462,8 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
||||
new_mcs += 1;
|
||||
else if (bler_stats->bler > nrmac->dl_bler_target_upper && old_mcs > 6)
|
||||
new_mcs -= 1;
|
||||
|
||||
// else we are within threshold boundaries
|
||||
|
||||
|
||||
bler_stats->last_frame_slot = now;
|
||||
bler_stats->mcs = new_mcs;
|
||||
memcpy(bler_stats->dlsch_rounds, stats->dlsch_rounds, sizeof(stats->dlsch_rounds));
|
||||
@@ -473,11 +475,9 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
||||
void nr_store_dlsch_buffer(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
|
||||
for (int UE_id = UE_info->list.head; 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];
|
||||
sched_ctrl->num_total_bytes = 0;
|
||||
sched_ctrl->dl_pdus_total = 0;
|
||||
@@ -485,21 +485,20 @@ void nr_store_dlsch_buffer(module_id_t module_id,
|
||||
/* loop over all activated logical channels */
|
||||
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
|
||||
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
|
||||
|
||||
const int lcid = sched_ctrl->dl_lc_ids[i];
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
LOG_D(NR_MAC, "In %s: UE %d/%x: LCID %d\n", __FUNCTION__, UE_id, rnti, lcid);
|
||||
start_meas(&RC.nrmac[module_id]->rlc_status_ind);
|
||||
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
|
||||
rnti,
|
||||
module_id,
|
||||
frame,
|
||||
slot,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
0,
|
||||
0);
|
||||
rnti,
|
||||
module_id,
|
||||
frame,
|
||||
slot,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
0,
|
||||
0);
|
||||
stop_meas(&RC.nrmac[module_id]->rlc_status_ind);
|
||||
|
||||
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
||||
@@ -531,6 +530,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
int UE_id,
|
||||
int current_harq_pid) {
|
||||
|
||||
|
||||
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;
|
||||
@@ -558,30 +558,34 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
|
||||
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;
|
||||
|
||||
int rbSize = 0;
|
||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
||||
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
|
||||
if (tda == retInfo->time_domain_allocation) {
|
||||
/* Check that there are enough resources for retransmission */
|
||||
while (rbSize < retInfo->rbSize) {
|
||||
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
||||
rbSize = 0;
|
||||
|
||||
while (rbStart < bwpSize &&
|
||||
!(rballoc_mask[rbStart]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)))
|
||||
rbStart++;
|
||||
|
||||
if (rbStart >= bwpSize) {
|
||||
LOG_D(NR_MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (rbStart + rbSize < bwpSize &&
|
||||
(rballoc_mask[rbStart + rbSize]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)) &&
|
||||
rbSize < retInfo->rbSize)
|
||||
rbSize++;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
@@ -600,10 +604,21 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
* that we have enough resources */
|
||||
NR_pdsch_semi_static_t temp_ps = *ps;
|
||||
nr_set_pdsch_semi_static(sib1,scc, cg, sched_ctrl->active_bwp, bwpd,tda, ps->nrOfLayers, sched_ctrl, &temp_ps);
|
||||
|
||||
nr_set_pdsch_semi_static(sib1,
|
||||
scc,
|
||||
cg,
|
||||
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++;
|
||||
|
||||
while (rbStart + rbSize < bwpSize &&
|
||||
(rballoc_mask[rbStart + rbSize]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
|
||||
rbSize++;
|
||||
@@ -620,10 +635,12 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
rbSize,
|
||||
&new_tbs,
|
||||
&new_rbSize);
|
||||
|
||||
if (!success || new_tbs != retInfo->tb_size) {
|
||||
LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
|
||||
LOG_D(MAC, "new TBsize %d of new TDA does not match old TBS %d\n", new_tbs, retInfo->tb_size);
|
||||
return false; /* the maximum TBsize we might have is smaller than what we need */
|
||||
}
|
||||
|
||||
/* we can allocate it. Overwrite the time_domain_allocation, the number
|
||||
* of RBs, and the new TB size. The rest is done below */
|
||||
retInfo->tb_size = new_tbs;
|
||||
@@ -636,12 +653,14 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
uint8_t nr_of_candidates;
|
||||
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
|
||||
@@ -661,12 +680,12 @@ 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) */
|
||||
|
||||
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",
|
||||
__func__,
|
||||
"could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
UE_id,
|
||||
UE_info->rnti[UE_id],
|
||||
frame,
|
||||
@@ -676,23 +695,21 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
|
||||
fill_pdcch_vrb_map(RC.nrmac[module_id],
|
||||
/* CC_id = */ 0,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
/* just reuse from previous scheduling opportunity, set new start RB */
|
||||
sched_ctrl->sched_pdsch = *retInfo;
|
||||
sched_ctrl->sched_pdsch.rbStart = rbStart;
|
||||
|
||||
sched_ctrl->sched_pdsch.pucch_allocation = alloc;
|
||||
|
||||
/* retransmissions: directly allocate */
|
||||
*n_rb_sched -= sched_ctrl->sched_pdsch.rbSize;
|
||||
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++)
|
||||
rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] ^= SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -706,7 +723,6 @@ void pf_dl(module_id_t module_id,
|
||||
int max_num_ue,
|
||||
int n_rb_sched,
|
||||
uint16_t *rballoc_mask) {
|
||||
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
NR_UE_info_t *UE_info = &mac->UE_info;
|
||||
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
|
||||
@@ -719,15 +735,16 @@ void pf_dl(module_id_t module_id,
|
||||
/* Loop UE_info->list to check retransmission */
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
if (UE_info->Msg4_ACKed[UE_id] != true) continue;
|
||||
|
||||
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_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
|
||||
sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
|
||||
|
||||
layers[UE_id] = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
|
||||
|
||||
/* Calculate Throughput */
|
||||
const float a = 0.0005f; // corresponds to 200ms window
|
||||
const uint32_t b = UE_info->mac_stats[UE_id].dlsch_current_bytes;
|
||||
@@ -737,13 +754,16 @@ void pf_dl(module_id_t module_id,
|
||||
if (sched_pdsch->dl_harq_pid >= 0) {
|
||||
/* Allocate retransmission */
|
||||
bool r = allocate_dl_retransmission(
|
||||
module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid);
|
||||
module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid);
|
||||
|
||||
if (!r) {
|
||||
LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
max_num_ue--;
|
||||
|
||||
if (max_num_ue < 0) return;
|
||||
} else {
|
||||
/* Check DL buffer and skip this UE if no bytes and no TA necessary */
|
||||
@@ -773,18 +793,21 @@ void pf_dl(module_id_t module_id,
|
||||
}
|
||||
|
||||
const int min_rbSize = 5;
|
||||
|
||||
/* Loop UE_sched to find max coeff and allocate transmission */
|
||||
while (max_num_ue > 0 && n_rb_sched >= min_rbSize && UE_sched.head >= 0) {
|
||||
|
||||
/* Find max coeff from UE_sched*/
|
||||
int *max = &UE_sched.head; /* assume head is max */
|
||||
int *p = &UE_sched.next[*max];
|
||||
|
||||
while (*p >= 0) {
|
||||
/* if the current one has larger coeff, save for later */
|
||||
if (coeff_ue[*p] > coeff_ue[*max])
|
||||
max = p;
|
||||
|
||||
p = &UE_sched.next[*p];
|
||||
}
|
||||
|
||||
/* remove the max one: do not use remove_nr_list() it goes through the
|
||||
* whole list every time. Note that UE_sched.tail might not be set
|
||||
* correctly anymore */
|
||||
@@ -794,6 +817,7 @@ void pf_dl(module_id_t module_id,
|
||||
*p = -1;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
cg &&
|
||||
cg->spCellConfig &&
|
||||
@@ -828,12 +852,14 @@ void pf_dl(module_id_t module_id,
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
uint8_t nr_of_candidates;
|
||||
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
|
||||
@@ -852,12 +878,13 @@ 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) */
|
||||
|
||||
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",
|
||||
__func__,
|
||||
"could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
UE_id,
|
||||
rnti,
|
||||
frame,
|
||||
@@ -870,21 +897,18 @@ void pf_dl(module_id_t module_id,
|
||||
* and PUCCH */
|
||||
max_num_ue--;
|
||||
AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
|
||||
fill_pdcch_vrb_map(mac,
|
||||
/* CC_id = */ 0,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
max_num_ue--;
|
||||
|
||||
if (max_num_ue < 0) return;
|
||||
|
||||
/* MCS has been set above */
|
||||
|
||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
||||
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
@@ -904,12 +928,14 @@ void pf_dl(module_id_t module_id,
|
||||
}
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||
|
||||
// Freq-demain allocation
|
||||
while (rbStart < bwpSize &&
|
||||
!(rballoc_mask[rbStart]&slbitmap))
|
||||
rbStart++;
|
||||
|
||||
uint16_t max_rbSize = 1;
|
||||
|
||||
while (rbStart + max_rbSize < bwpSize &&
|
||||
(rballoc_mask[rbStart + max_rbSize]&slbitmap))
|
||||
max_rbSize++;
|
||||
@@ -938,39 +964,41 @@ void pf_dl(module_id_t module_id,
|
||||
sched_pdsch->rbSize = rbSize;
|
||||
sched_pdsch->rbStart = rbStart;
|
||||
sched_pdsch->tb_size = TBS;
|
||||
|
||||
/* transmissions: directly allocate */
|
||||
n_rb_sched -= sched_pdsch->rbSize;
|
||||
|
||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||
rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap;
|
||||
}
|
||||
}
|
||||
|
||||
void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
{
|
||||
void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
|
||||
if (UE_info->num_UEs == 0)
|
||||
return;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
const int CC_id = 0;
|
||||
|
||||
/* Get bwpSize and TDAfrom the first UE */
|
||||
/* This is temporary and it assumes all UEs have the same BWP and TDA*/
|
||||
int UE_id = UE_info->list.head;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0;
|
||||
|
||||
if (!RC.nrmac[module_id]->preferred_dl_tda[bwp_id])
|
||||
return;
|
||||
|
||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[bwp_id][slot];
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_bwp ?
|
||||
sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
|
||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
|
||||
|
||||
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,
|
||||
@@ -991,19 +1019,20 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
uint16_t rballoc_mask[bwpSize];
|
||||
int n_rb_sched = 0;
|
||||
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
// calculate mask: init with "NOT" vrb_map:
|
||||
// if any RB in vrb_map is blocked (1), the current RBG will be 0
|
||||
rballoc_mask[i] = (~vrb_map[i+BWPStart])&0x3fff; //bitwise not and 14 symbols
|
||||
|
||||
// if all the pdsch symbols are free
|
||||
if((rballoc_mask[i]&slbitmap) ==
|
||||
slbitmap)
|
||||
slbitmap)
|
||||
n_rb_sched++;
|
||||
}
|
||||
|
||||
/* Retrieve amount of data to send for this UE */
|
||||
nr_store_dlsch_buffer(module_id, frame, slot);
|
||||
|
||||
/* proportional fair scheduling algorithm */
|
||||
pf_dl(module_id,
|
||||
frame,
|
||||
@@ -1014,8 +1043,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
rballoc_mask);
|
||||
}
|
||||
|
||||
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
|
||||
{
|
||||
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id) {
|
||||
/* in the PF algorithm, we have to use the TBsize to compute the coefficient.
|
||||
* This would include the number of DMRS symbols, which in turn depends on
|
||||
* the time domain allocation. In case we are in a mixed slot, we do not want
|
||||
@@ -1025,16 +1053,17 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
|
||||
for (int mcs = 0; mcs < 29; ++mcs) {
|
||||
if (mcs > 27 && mcsTableIdx == 1)
|
||||
continue;
|
||||
|
||||
const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx);
|
||||
const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx);
|
||||
pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm,
|
||||
R,
|
||||
1, /* rbSize */
|
||||
10, /* hypothetical number of slots */
|
||||
0, /* N_PRB_DMRS * N_DMRS_SLOT */
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
1 /* nrOfLayers */)
|
||||
R,
|
||||
1, /* rbSize */
|
||||
10, /* hypothetical number of slots */
|
||||
0, /* N_PRB_DMRS * N_DMRS_SLOT */
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
1 /* nrOfLayers */)
|
||||
>> 3;
|
||||
}
|
||||
}
|
||||
@@ -1046,6 +1075,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||
|
||||
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
|
||||
return;
|
||||
|
||||
@@ -1053,17 +1083,17 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
|
||||
/* PREPROCESSOR */
|
||||
gNB_mac->pre_processor_dl(module_id, frame, slot);
|
||||
|
||||
const int CC_id = 0;
|
||||
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
|
||||
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_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];
|
||||
@@ -1078,7 +1108,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
* Possible improvement: take the periodicity from input file.
|
||||
* If such UE is not scheduled now, it will be by the preprocessor later.
|
||||
* If we add the CE, ta_apply will be reset */
|
||||
if (frame == (sched_ctrl->ta_frame + 10) % 1024){
|
||||
if (frame == (sched_ctrl->ta_frame + 10) % 1024) {
|
||||
sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */
|
||||
LOG_D(NR_MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot);
|
||||
}
|
||||
@@ -1087,19 +1117,17 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
continue;
|
||||
|
||||
const rnti_t rnti = UE_info->rnti[UE_id];
|
||||
|
||||
/* pre-computed PDSCH values that only change if time domain
|
||||
* allocation/DMRS parameters change. Updated in the preprocessor through
|
||||
* nr_set_pdsch_semi_static() */
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
|
||||
/* POST processing */
|
||||
const uint8_t nrOfLayers = ps->nrOfLayers;
|
||||
const uint16_t R = sched_pdsch->R;
|
||||
const uint8_t Qm = sched_pdsch->Qm;
|
||||
const uint32_t TBS = sched_pdsch->tb_size;
|
||||
|
||||
int8_t current_harq_pid = sched_pdsch->dl_harq_pid;
|
||||
|
||||
if (current_harq_pid < 0) {
|
||||
/* PP has not selected a specific HARQ Process, get a new one */
|
||||
current_harq_pid = sched_ctrl->available_dl_harq.head;
|
||||
@@ -1117,6 +1145,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
else
|
||||
remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid);
|
||||
}
|
||||
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
DevAssert(!harq->is_waiting);
|
||||
add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid);
|
||||
@@ -1125,8 +1154,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
harq->feedback_slot = pucch->ul_slot;
|
||||
harq->is_waiting = true;
|
||||
UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
|
||||
|
||||
LOG_D(NR_MAC,"%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
|
||||
frame,
|
||||
slot,
|
||||
UE_id,
|
||||
@@ -1149,8 +1178,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
pucch->ul_slot,
|
||||
sched_pdsch->pucch_allocation,
|
||||
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,
|
||||
@@ -1163,6 +1192,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
|
||||
/* 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");
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
@@ -1183,7 +1213,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
|
||||
pdsch_pdu->pduBitmap = 0;
|
||||
pdsch_pdu->rnti = rnti;
|
||||
/* SCF222: PDU index incremented for each PDSCH PDU sent in TX control
|
||||
@@ -1201,9 +1230,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
}
|
||||
|
||||
pdsch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing;
|
||||
|
||||
pdsch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0;
|
||||
|
||||
// Codeword information
|
||||
pdsch_pdu->NrOfCodewords = 1;
|
||||
pdsch_pdu->targetCodeRate[0] = R;
|
||||
@@ -1214,12 +1241,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
AssertFatal(harq->round<4,"%d",harq->round);
|
||||
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round];
|
||||
pdsch_pdu->TBSize[0] = TBS;
|
||||
|
||||
pdsch_pdu->dataScramblingId = *scc->physCellId;
|
||||
pdsch_pdu->nrOfLayers = nrOfLayers;
|
||||
pdsch_pdu->transmissionScheme = 0;
|
||||
pdsch_pdu->refPoint = 0; // Point A
|
||||
|
||||
// DMRS
|
||||
pdsch_pdu->dlDmrsSymbPos = ps->dl_dmrs_symb_pos;
|
||||
pdsch_pdu->dmrsConfigType = ps->dmrsConfigType;
|
||||
@@ -1227,18 +1252,16 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
pdsch_pdu->SCID = 0;
|
||||
pdsch_pdu->numDmrsCdmGrpsNoData = ps->numDmrsCdmGrpsNoData;
|
||||
pdsch_pdu->dmrsPorts = (1<<nrOfLayers)-1; // FIXME with a better implementation
|
||||
|
||||
// Pdsch Allocation in frequency domain
|
||||
pdsch_pdu->resourceAlloc = 1;
|
||||
pdsch_pdu->rbStart = sched_pdsch->rbStart;
|
||||
pdsch_pdu->rbSize = sched_pdsch->rbSize;
|
||||
pdsch_pdu->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
|
||||
|
||||
// Resource Allocation in time domain
|
||||
pdsch_pdu->StartSymbolIndex = ps->startSymbolIndex;
|
||||
pdsch_pdu->NrOfSymbols = ps->nrOfSymbols;
|
||||
|
||||
NR_PDSCH_Config_t *pdsch_Config=NULL;
|
||||
|
||||
if (bwp &&
|
||||
bwp->bwp_Dedicated &&
|
||||
bwp->bwp_Dedicated->pdsch_Config &&
|
||||
@@ -1247,18 +1270,20 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
|
||||
/* Check and validate PTRS values */
|
||||
struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS =
|
||||
pdsch_Config ? pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS : NULL;
|
||||
pdsch_Config ? pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS : NULL;
|
||||
|
||||
if (phaseTrackingRS) {
|
||||
bool valid_ptrs_setup = set_dl_ptrs_values(phaseTrackingRS->choice.setup,
|
||||
pdsch_pdu->rbSize,
|
||||
pdsch_pdu->mcsIndex[0],
|
||||
pdsch_pdu->mcsTable[0],
|
||||
&pdsch_pdu->PTRSFreqDensity,
|
||||
&pdsch_pdu->PTRSTimeDensity,
|
||||
&pdsch_pdu->PTRSPortIndex,
|
||||
&pdsch_pdu->nEpreRatioOfPDSCHToPTRS,
|
||||
&pdsch_pdu->PTRSReOffset,
|
||||
pdsch_pdu->NrOfSymbols);
|
||||
pdsch_pdu->rbSize,
|
||||
pdsch_pdu->mcsIndex[0],
|
||||
pdsch_pdu->mcsTable[0],
|
||||
&pdsch_pdu->PTRSFreqDensity,
|
||||
&pdsch_pdu->PTRSTimeDensity,
|
||||
&pdsch_pdu->PTRSPortIndex,
|
||||
&pdsch_pdu->nEpreRatioOfPDSCHToPTRS,
|
||||
&pdsch_pdu->PTRSReOffset,
|
||||
pdsch_pdu->NrOfSymbols);
|
||||
|
||||
if (valid_ptrs_setup)
|
||||
pdsch_pdu->pduBitmap |= 0x1; // Bit 0: pdschPtrs - Indicates PTRS included (FR2)
|
||||
}
|
||||
@@ -1268,6 +1293,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci];
|
||||
pdcch_pdu->numDlDci++;
|
||||
dci_pdu->RNTI = rnti;
|
||||
|
||||
if (sched_ctrl->coreset &&
|
||||
sched_ctrl->search_space &&
|
||||
sched_ctrl->coreset->pdcch_DMRS_ScramblingID &&
|
||||
@@ -1278,27 +1304,28 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
dci_pdu->ScramblingId = *scc->physCellId;
|
||||
dci_pdu->ScramblingRNTI = 0;
|
||||
}
|
||||
|
||||
dci_pdu->AggregationLevel = sched_ctrl->aggregation_level;
|
||||
dci_pdu->CceIndex = sched_ctrl->cce_index;
|
||||
dci_pdu->beta_PDCCH_1_0 = 0;
|
||||
dci_pdu->powerControlOffsetSS = 1;
|
||||
|
||||
/* DCI payload */
|
||||
dci_pdu_rel15_t dci_payload;
|
||||
memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t));
|
||||
// bwp indicator
|
||||
const int n_dl_bwp = bwp ? UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count : 0;
|
||||
AssertFatal(n_dl_bwp <= 1, "downlinkBWP_ToAddModList has %d BWP!\n", n_dl_bwp);
|
||||
|
||||
// as per table 7.3.1.1.2-1 in 38.212
|
||||
dci_payload.bwp_indicator.val = bwp ? (n_dl_bwp < 4 ? bwp->bwp_Id : bwp->bwp_Id - 1) : 0;
|
||||
|
||||
if (bwp) AssertFatal(bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1,
|
||||
"Only frequency resource allocation type 1 is currently supported\n");
|
||||
"Only frequency resource allocation type 1 is currently supported\n");
|
||||
|
||||
dci_payload.frequency_domain_assignment.val =
|
||||
PRBalloc_to_locationandbandwidth0(
|
||||
pdsch_pdu->rbSize,
|
||||
pdsch_pdu->rbStart,
|
||||
pdsch_pdu->BWPSize);
|
||||
PRBalloc_to_locationandbandwidth0(
|
||||
pdsch_pdu->rbSize,
|
||||
pdsch_pdu->rbStart,
|
||||
pdsch_pdu->BWPSize);
|
||||
dci_payload.format_indicator = 1;
|
||||
dci_payload.time_domain_assignment.val = ps->time_domain_allocation;
|
||||
dci_payload.mcs = sched_pdsch->mcs;
|
||||
@@ -1329,11 +1356,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
dci_payload.tpc,
|
||||
pucch->timing_indicator);
|
||||
|
||||
|
||||
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,
|
||||
UE_info->CellGroup[UE_id],
|
||||
dci_pdu,
|
||||
@@ -1352,7 +1379,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
|
||||
if (harq->round != 0) { /* retransmission */
|
||||
/* we do not have to do anything, since we do not require to get data
|
||||
* from RLC or encode MAC CEs. The TX_req structure is filled below
|
||||
* from RLC or encode MAC CEs. The TX_req structure is filled below
|
||||
* or copy data to FAPI structures */
|
||||
LOG_D(NR_MAC,
|
||||
"%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n",
|
||||
@@ -1363,20 +1390,15 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
current_harq_pid,
|
||||
harq->round,
|
||||
harq->ndi);
|
||||
|
||||
AssertFatal(harq->sched_pdsch.tb_size == TBS,
|
||||
"UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
|
||||
UE_id,
|
||||
current_harq_pid);
|
||||
|
||||
T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->tb, TBS));
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS));
|
||||
} else { /* initial transmission */
|
||||
|
||||
LOG_D(NR_MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot);
|
||||
|
||||
uint8_t *buf = (uint8_t *) harq->tb;
|
||||
|
||||
uint8_t *buf = (uint8_t *) harq->transportBlock;
|
||||
/* first, write all CEs that might be there */
|
||||
int written = nr_write_ce_dlsch_pdu(module_id,
|
||||
sched_ctrl,
|
||||
@@ -1384,31 +1406,30 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
255, // no drx
|
||||
NULL); // contention res id
|
||||
buf += written;
|
||||
int size = TBS - written;
|
||||
DevAssert(size >= 0);
|
||||
uint8_t *bufEnd = buf + TBS - written;
|
||||
DevAssert(TBS > written);
|
||||
int dlsch_total_bytes = 0;
|
||||
/* next, get RLC data */
|
||||
|
||||
start_meas(&gNB_mac->rlc_data_req);
|
||||
|
||||
if (sched_ctrl->num_total_bytes > 0) {
|
||||
/* loop over all activated logical channels */
|
||||
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
|
||||
|
||||
const int lcid = sched_ctrl->dl_lc_ids[i];
|
||||
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
||||
continue; // no data for this LC
|
||||
|
||||
int dlsch_total_bytes = 0;
|
||||
while (size > 3) {
|
||||
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
||||
continue; // no data for this LC tbs_size_t len = 0;
|
||||
|
||||
int lcid_bytes=0;
|
||||
while (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) + 1 ) {
|
||||
// we do not know how much data we will get from RLC, i.e., whether it
|
||||
// will be longer than 256B or not. Therefore, reserve space for long header, then
|
||||
// fetch data, then fill real length
|
||||
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
|
||||
buf += 3;
|
||||
size -= 3;
|
||||
|
||||
/* limit requested number of bytes to what preprocessor specified, or
|
||||
* such that TBS is full */
|
||||
const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer, size);
|
||||
const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer,
|
||||
bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
tbs_size_t len = mac_rlc_data_req(module_id,
|
||||
rnti,
|
||||
module_id,
|
||||
@@ -1417,12 +1438,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
ndata,
|
||||
(char *)buf,
|
||||
(char *)buf+sizeof(NR_MAC_SUBHEADER_LONG),
|
||||
0,
|
||||
0);
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %d)\n",
|
||||
"%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %ld)\n",
|
||||
frame,
|
||||
slot,
|
||||
rnti,
|
||||
@@ -1430,64 +1450,56 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
lcid < 4 ? "DCCH" : "DTCH",
|
||||
lcid,
|
||||
ndata,
|
||||
size);
|
||||
if (len == 0) {
|
||||
/* RLC did not have data anymore, mark buffer as unused */
|
||||
buf -= 3;
|
||||
size += 3;
|
||||
bufEnd-buf-+sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
|
||||
if (len == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
header->R = 0;
|
||||
header->F = 1;
|
||||
header->LCID = lcid;
|
||||
header->L1 = (len >> 8) & 0xff;
|
||||
header->L2 = len & 0xff;
|
||||
size -= len;
|
||||
buf += len;
|
||||
header->L = htons(len);
|
||||
buf += len+sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
dlsch_total_bytes += len;
|
||||
lcid_bytes += len;
|
||||
}
|
||||
|
||||
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += dlsch_total_bytes;
|
||||
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += lcid_bytes;
|
||||
}
|
||||
} else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
|
||||
/* we will need the large header, phy-test typically allocates all
|
||||
* resources and fills to the last byte below */
|
||||
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
|
||||
buf += 3;
|
||||
size -= 3;
|
||||
DevAssert(size > 0);
|
||||
LOG_D(NR_MAC, "Configuring DL_TX in %d.%d: TBS %d with %d B of random data\n", frame, slot, TBS, size);
|
||||
// fill dlsch_buffer with random data
|
||||
for (int i = 0; i < size; i++)
|
||||
buf[i] = lrand48() & 0xff;
|
||||
header->R = 0;
|
||||
header->F = 1;
|
||||
header->LCID = DL_SCH_LCID_PADDING;
|
||||
header->L1 = (size >> 8) & 0xff;
|
||||
header->L2 = size & 0xff;
|
||||
size -= size;
|
||||
buf += size;
|
||||
LOG_D(NR_MAC, "Configuring DL_TX in %d.%d: TBS %d of random data\n", frame, slot, TBS);
|
||||
|
||||
if (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) ) {
|
||||
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
|
||||
// fill dlsch_buffer with random data
|
||||
header->R = 0;
|
||||
header->F = 1;
|
||||
header->LCID = DL_SCH_LCID_PADDING;
|
||||
buf += sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
header->L = htons(bufEnd-buf);
|
||||
dlsch_total_bytes += bufEnd-buf;
|
||||
|
||||
for (; buf < bufEnd; buf++)
|
||||
*buf = lrand48() & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
stop_meas(&gNB_mac->rlc_data_req);
|
||||
|
||||
// Add padding header and zero rest out if there is space left
|
||||
if (size > 0) {
|
||||
if (bufEnd-buf > 0) {
|
||||
NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) buf;
|
||||
padding->R = 0;
|
||||
padding->LCID = DL_SCH_LCID_PADDING;
|
||||
size -= 1;
|
||||
buf += 1;
|
||||
while (size > 0) {
|
||||
*buf = 0;
|
||||
buf += 1;
|
||||
size -= 1;
|
||||
}
|
||||
memset(buf,0,bufEnd-buf);
|
||||
buf=bufEnd;
|
||||
}
|
||||
|
||||
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
||||
UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS;
|
||||
|
||||
/* save retransmission information */
|
||||
harq->sched_pdsch = *sched_pdsch;
|
||||
/* save which time allocation has been used, to be used on
|
||||
@@ -1506,7 +1518,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
}
|
||||
|
||||
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->tb, TBS));
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, TBS));
|
||||
}
|
||||
|
||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||
@@ -1515,11 +1527,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
tx_req->PDU_index = pduindex;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = TBS + 2;
|
||||
memcpy(tx_req->TLVs[0].value.direct, harq->tb, TBS);
|
||||
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, TBS);
|
||||
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
gNB_mac->TX_req[CC_id].SFN = frame;
|
||||
gNB_mac->TX_req[CC_id].Slot = slot;
|
||||
|
||||
/* mark UE as scheduled */
|
||||
sched_pdsch->rbSize = 0;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
||||
&RC.nrmac[mod_id]->UL_tti_req_ahead[0][pucch->ul_slot];
|
||||
AssertFatal(future_ul_tti_req->SFN == pucch->frame
|
||||
&& future_ul_tti_req->Slot == pucch->ul_slot,
|
||||
"Current %d.%d : future UL_tti_req's frame.slot %d.%d does not match PUCCH %d.%d\n",
|
||||
"Current %d.%d : future UL_tti_req's frame.slot %4d.%2d does not match PUCCH %4d.%2d\n",
|
||||
frame,slot,
|
||||
future_ul_tti_req->SFN,
|
||||
future_ul_tti_req->Slot,
|
||||
@@ -85,7 +85,7 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
||||
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",
|
||||
LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n",
|
||||
frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot);
|
||||
|
||||
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
@@ -162,7 +162,7 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
|| frameP != curr_pucch->frame
|
||||
|| slotP != curr_pucch->ul_slot)
|
||||
continue;
|
||||
if (O_csi > 0) LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %d in %d.%d O_ack %d, O_sr %d, O_csi %d\n",
|
||||
if (O_csi > 0) LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %d in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n",
|
||||
i,UE_id,curr_pucch->frame,curr_pucch->ul_slot,O_ack,O_sr,O_csi);
|
||||
nr_fill_nfapi_pucch(Mod_idP, frameP, slotP, curr_pucch, UE_id);
|
||||
memset(curr_pucch, 0, sizeof(*curr_pucch));
|
||||
@@ -835,6 +835,7 @@ static void handle_dl_harq(module_id_t mod_id,
|
||||
stats->dlsch_errors++;
|
||||
LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dlsch_errors);
|
||||
} else {
|
||||
LOG_D(PHY,"NACK for: pid %d, ue %x\n",harq_pid, UE_id);
|
||||
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid);
|
||||
harq->round++;
|
||||
}
|
||||
@@ -1421,7 +1422,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
|
||||
while (harq->feedback_frame != frame
|
||||
|| (harq->feedback_frame == frame && harq->feedback_slot < slot)) {
|
||||
LOG_W(NR_MAC,
|
||||
"expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the past)\n",
|
||||
"expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the past)\n",
|
||||
pid,
|
||||
harq->feedback_frame,
|
||||
harq->feedback_slot,
|
||||
@@ -1437,7 +1438,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
|
||||
/* feedbacks that we wait for in the future: don't do anything */
|
||||
if (harq->feedback_slot > slot) {
|
||||
LOG_W(NR_MAC,
|
||||
"expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the future)\n",
|
||||
"expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the future)\n",
|
||||
pid,
|
||||
harq->feedback_frame,
|
||||
harq->feedback_slot,
|
||||
@@ -1474,7 +1475,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
DevAssert(harq->is_waiting);
|
||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
LOG_D(NR_MAC,"bit %d pid %d ack/nack %d\n",harq_bit,pid,harq_value);
|
||||
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
|
||||
handle_dl_harq(mod_id, UE_id, pid, harq_value == 0 && harq_confidence == 0);
|
||||
if (harq_confidence == 1) UE_info->mac_stats[UE_id].pucch0_DTX++;
|
||||
}
|
||||
@@ -1516,10 +1517,11 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
// tpc (power control)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
|
||||
uci_234->ul_cqi,
|
||||
30);
|
||||
sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
|
||||
// TODO PUCCH2 SNR computation is not correct -> ignore the following
|
||||
//sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
|
||||
// uci_234->ul_cqi,
|
||||
// 30);
|
||||
//sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
|
||||
|
||||
if ((uci_234->pduBitmap >> 1) & 0x01) {
|
||||
// iterate over received harq bits
|
||||
@@ -1657,7 +1659,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
int bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0];
|
||||
LOG_D(NR_MAC, "In %s: %d.%d Trying to allocate pucch, current DAI %d\n", __FUNCTION__, frame, slot, pucch->dai_c);
|
||||
LOG_D(NR_MAC, "In %s: %4d.%2d Trying to allocate pucch, current DAI %d\n", __FUNCTION__, frame, slot, pucch->dai_c);
|
||||
|
||||
pucch->r_pucch=r_pucch;
|
||||
AssertFatal(pucch->csi_bits == 0,
|
||||
@@ -1672,7 +1674,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
* the same slot again */
|
||||
const int f = pucch->frame;
|
||||
const int s = pucch->ul_slot;
|
||||
LOG_D(NR_MAC, "In %s: %d.%d DAI = 2 pucch currently in %d.%d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s);
|
||||
LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 2 pucch currently in %4d.%2d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s);
|
||||
if (!(csi_pucch
|
||||
&& csi_pucch->csi_bits > 0
|
||||
&& csi_pucch->frame == f
|
||||
@@ -1704,7 +1706,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "In %s: pucch_acknak 1. DL %d.%d, UL_ACK %d.%d, DAI_C %d\n", __FUNCTION__, frame, slot, pucch->frame, pucch->ul_slot, pucch->dai_c);
|
||||
LOG_D(NR_MAC, "In %s: pucch_acknak 1. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame, slot, pucch->frame, pucch->ul_slot, pucch->dai_c);
|
||||
|
||||
// this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP
|
||||
NR_BWP_UplinkDedicated_t *ubwpd=NULL;
|
||||
@@ -1724,7 +1726,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
int max_fb_time = 0;
|
||||
get_pdsch_to_harq_feedback(mod_id, UE_id, bwp_Id, ss_type, &max_fb_time, pdsch_to_harq_feedback);
|
||||
|
||||
LOG_D(NR_MAC, "In %s: 1b. DL %d.%d, UL_ACK %d.%d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c);
|
||||
LOG_D(NR_MAC, "In %s: 1b. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c);
|
||||
/* there is a HARQ. Check whether we can use it for this ACKNACK */
|
||||
if (pucch->dai_c > 0) {
|
||||
/* this UE already has a PUCCH occasion */
|
||||
@@ -1744,11 +1746,12 @@ int nr_acknack_scheduling(int mod_id,
|
||||
const int f = pucch->frame;
|
||||
const int s = pucch->ul_slot;
|
||||
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
LOG_D(NR_MAC, "In %s: %d.%d DAI > 0, cannot reach timing for pucch in %d.%d, advancing slot by 1 and trying again\n", __FUNCTION__, frame, slot, f, s);
|
||||
LOG_D(NR_MAC, "In %s: %4d.%2d DAI > 0, cannot reach timing for pucch in %4d.%2d, advancing slot by 1 and trying again\n", __FUNCTION__, frame, slot, f, s);
|
||||
if (!(csi_pucch &&
|
||||
csi_pucch->csi_bits > 0 &&
|
||||
csi_pucch->frame == f &&
|
||||
csi_pucch->ul_slot == s)) nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
|
||||
csi_pucch->ul_slot == s))
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
|
||||
memset(pucch, 0, sizeof(*pucch));
|
||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||
if(((s + 1)%nr_slots_period) == 0)
|
||||
@@ -1769,11 +1772,11 @@ int nr_acknack_scheduling(int mod_id,
|
||||
csi_pucch->dai_c++;
|
||||
}
|
||||
// retain old resource indicator, and we are good
|
||||
LOG_D(NR_MAC, "In %s: %d.%d. DAI > 0, pucch allocated for %d.%d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
|
||||
LOG_D(NR_MAC, "In %s: %4d.%2d. DAI > 0, pucch allocated for %4d.%2d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "In %s: %d.%d DAI = 0, looking for new pucch occasion\n", __FUNCTION__, frame, slot);
|
||||
LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 0, looking for new pucch occasion\n", __FUNCTION__, frame, slot);
|
||||
/* we need to find a new PUCCH occasion */
|
||||
|
||||
/*(Re)Inizialization of timing information*/
|
||||
@@ -1880,7 +1883,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
|
||||
pucch->timing_indicator = ind_found; // index in the list of timing indicators
|
||||
|
||||
LOG_D(NR_MAC, "In %s: 2. DAI 0 DL %d.%d, UL_ACK %d.%d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
|
||||
LOG_D(NR_MAC, "In %s: 2. DAI 0 DL %4d.%2d, UL_ACK %4d.%2d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
|
||||
|
||||
pucch->dai_c++;
|
||||
pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources
|
||||
|
||||
@@ -55,7 +55,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
|
||||
|
||||
/* there is a mixed slot only when in TDD */
|
||||
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
|
||||
lte_frame_type_t frame_type = nrmac->common_channels->frame_type;
|
||||
frame_type_t frame_type = nrmac->common_channels->frame_type;
|
||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
|
||||
NR_ServingCellConfigCommonSIB_t *scc_sib1 = get_softmodem_params()->sa ?
|
||||
@@ -213,11 +213,8 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
int pdu_len)
|
||||
{
|
||||
|
||||
uint8_t rx_lcid;
|
||||
|
||||
uint8_t done = 0;
|
||||
uint16_t mac_ce_len;
|
||||
uint16_t mac_subheader_len;
|
||||
uint16_t mac_sdu_len;
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
@@ -231,10 +228,9 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
#endif
|
||||
|
||||
while (!done && pdu_len > 0){
|
||||
mac_ce_len = 0;
|
||||
mac_subheader_len = sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
mac_sdu_len = 0;
|
||||
rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
||||
uint16_t mac_len=0;
|
||||
uint16_t mac_subheader_len=sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
||||
|
||||
LOG_D(NR_MAC, "In %s: received UL-SCH sub-PDU with LCID 0x%x in %d.%d (remaining PDU length %d)\n", __func__, rx_lcid, frameP, slot, pdu_len);
|
||||
|
||||
@@ -249,7 +245,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
#endif*/
|
||||
case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
|
||||
// 38.321 Ch6.1.3.20
|
||||
mac_ce_len = 2;
|
||||
mac_len = 2;
|
||||
break;
|
||||
case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION:
|
||||
// 38.321 Ch6.1.3.7
|
||||
@@ -259,7 +255,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
case UL_SCH_LCID_S_TRUNCATED_BSR:
|
||||
//38.321 section 6.1.3.1
|
||||
//fixed length
|
||||
mac_ce_len =1;
|
||||
mac_len =1;
|
||||
/* Extract short BSR value */
|
||||
ce_ptr = &pduP[mac_subheader_len];
|
||||
NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr;
|
||||
@@ -284,16 +280,8 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
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;
|
||||
}
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return 0;
|
||||
/* Extract long BSR value */
|
||||
ce_ptr = &pduP[mac_subheader_len];
|
||||
NR_BSR_LONG *bsr_l = (NR_BSR_LONG *) ce_ptr;
|
||||
@@ -339,14 +327,14 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
|
||||
//38.321 section 6.1.3.2
|
||||
//fixed length
|
||||
mac_ce_len = 2;
|
||||
mac_len = 2;
|
||||
/* Extract CRNTI value */
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_SINGLE_ENTRY_PHR:
|
||||
//38.321 section 6.1.3.8
|
||||
//fixed length
|
||||
mac_ce_len = 2;
|
||||
mac_len = 2;
|
||||
/* Extract SINGLE ENTRY PHR elements for PHR calculation */
|
||||
ce_ptr = &pduP[mac_subheader_len];
|
||||
NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
|
||||
@@ -367,32 +355,16 @@ 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;
|
||||
}
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return 0;
|
||||
/* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT:
|
||||
//38.321 section 6.1.3.9
|
||||
// varialbe length
|
||||
if (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;
|
||||
}
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return 0;
|
||||
/* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */
|
||||
break;
|
||||
|
||||
@@ -403,27 +375,16 @@ 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);
|
||||
} else {
|
||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return 0;
|
||||
|
||||
rnti_t crnti = UE_info->rnti[UE_id];
|
||||
int UE_idx = UE_id;
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
||||
if (ra->state >= WAIT_Msg3 && ra->rnti == UE_info->rnti[UE_id]) {
|
||||
uint8_t *next_subpduP = pduP + mac_subheader_len + mac_sdu_len;
|
||||
if ((pduP[mac_subheader_len+mac_sdu_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
|
||||
uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len;
|
||||
if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
|
||||
crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF);
|
||||
UE_idx = find_nr_UE_id(module_idP, crnti);
|
||||
break;
|
||||
@@ -432,7 +393,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
}
|
||||
|
||||
if (UE_info->CellGroup[UE_idx]) {
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: 0x%04x \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, crnti);
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: 0x%04x \n", module_idP, frameP, rx_lcid, module_idP, mac_len, crnti);
|
||||
mac_rlc_data_ind(module_idP,
|
||||
crnti,
|
||||
module_idP,
|
||||
@@ -441,7 +402,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
MBMS_FLAG_NO,
|
||||
rx_lcid,
|
||||
(char *) (pduP + mac_subheader_len),
|
||||
mac_sdu_len,
|
||||
mac_len,
|
||||
1,
|
||||
NULL);
|
||||
} else {
|
||||
@@ -459,23 +420,23 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
|
||||
if ( rx_lcid == UL_SCH_LCID_CCCH1 ) {
|
||||
// RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes
|
||||
mac_sdu_len = 8;
|
||||
mac_len = 8;
|
||||
|
||||
// Check if it is a valid CCCH1 message, we get all 00's messages very often
|
||||
int i = 0;
|
||||
for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
|
||||
for(i=0; i<(mac_subheader_len+mac_len); i++) {
|
||||
if(pduP[i] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == (mac_subheader_len+mac_sdu_len)) {
|
||||
if (i == (mac_subheader_len+mac_len)) {
|
||||
LOG_D(NR_MAC, "%s() Invalid CCCH1 message!, pdu_len: %d\n", __func__, pdu_len);
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// fixed length of 6 bytes
|
||||
mac_sdu_len = 6;
|
||||
mac_len = 6;
|
||||
}
|
||||
|
||||
nr_mac_rrc_data_ind(module_idP,
|
||||
@@ -486,29 +447,18 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
UE_info->rnti[UE_id],
|
||||
CCCH,
|
||||
pduP + mac_subheader_len,
|
||||
mac_sdu_len,
|
||||
mac_len,
|
||||
0);
|
||||
break;
|
||||
|
||||
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);
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
struct timespec time_request;
|
||||
clock_gettime(CLOCK_REALTIME, &time_request);
|
||||
LOG_D(NR_MAC, "[UE %x] %d.%d : Time %lu.%lu ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
|
||||
LOG_D(NR_MAC, "[UE %04x] %d.%d : Time %lu.%lu ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
|
||||
UE_info->rnti[UE_id],
|
||||
frameP,
|
||||
slot,
|
||||
@@ -517,8 +467,8 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
rx_lcid<4?"DCCH":"DTCH",
|
||||
rx_lcid,
|
||||
module_idP,
|
||||
mac_sdu_len);
|
||||
UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
|
||||
mac_len);
|
||||
UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_len;
|
||||
|
||||
mac_rlc_data_ind(module_idP,
|
||||
UE_info->rnti[UE_id],
|
||||
@@ -528,13 +478,13 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
MBMS_FLAG_NO,
|
||||
rx_lcid,
|
||||
(char *)(pduP + mac_subheader_len),
|
||||
mac_sdu_len,
|
||||
mac_len,
|
||||
1,
|
||||
NULL);
|
||||
|
||||
/* Updated estimated buffer when receiving data */
|
||||
if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len)
|
||||
sched_ctrl->estimated_ul_buffer -= mac_sdu_len;
|
||||
if (sched_ctrl->estimated_ul_buffer >= mac_len)
|
||||
sched_ctrl->estimated_ul_buffer -= mac_len;
|
||||
else
|
||||
sched_ctrl->estimated_ul_buffer = 0;
|
||||
break;
|
||||
@@ -549,16 +499,16 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
if (rx_lcid < 45 || rx_lcid == 52 || rx_lcid == 63) {
|
||||
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU sub-header with length %d (LCID = 0x%02x):\n", __func__, mac_subheader_len, rx_lcid);
|
||||
log_dump(NR_MAC, pduP, mac_subheader_len, LOG_DUMP_CHAR, "\n");
|
||||
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU with length %d (LCID = 0x%02x):\n", __func__, mac_sdu_len, rx_lcid);
|
||||
log_dump(NR_MAC, pduP + mac_subheader_len, mac_sdu_len, LOG_DUMP_CHAR, "\n");
|
||||
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
|
||||
log_dump(NR_MAC, pduP + mac_subheader_len, mac_len, LOG_DUMP_CHAR, "\n");
|
||||
} else {
|
||||
LOG_I(NR_MAC, "In %s: dumping UL MAC CE with length %d (LCID = 0x%02x):\n", __func__, mac_ce_len, rx_lcid);
|
||||
log_dump(NR_MAC, pduP + mac_subheader_len + mac_sdu_len, mac_ce_len, LOG_DUMP_CHAR, "\n");
|
||||
LOG_I(NR_MAC, "In %s: dumping UL MAC CE with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
|
||||
log_dump(NR_MAC, pduP + mac_subheader_len + mac_len, mac_len, LOG_DUMP_CHAR, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
pduP += ( mac_subheader_len + mac_len );
|
||||
pdu_len -= ( mac_subheader_len + mac_len );
|
||||
|
||||
if (pdu_len < 0) {
|
||||
LOG_E(NR_MAC, "In %s: residual UL MAC PDU in %d.%d with length < 0!, pdu_len %d \n", __func__, frameP, slot, pdu_len);
|
||||
@@ -2003,3 +1953,4 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
memset(sched_pusch, 0, sizeof(*sched_pusch));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ typedef struct {
|
||||
int p_gNB;
|
||||
int Ncp;
|
||||
int nr_band;
|
||||
lte_frame_type_t frame_type;
|
||||
frame_type_t frame_type;
|
||||
uint64_t dl_CarrierFreq;
|
||||
NR_BCCH_BCH_Message_t *mib;
|
||||
NR_BCCH_DL_SCH_Message_t *sib1;
|
||||
@@ -445,7 +445,7 @@ typedef struct NR_UE_harq {
|
||||
|
||||
/* Transport block to be sent using this HARQ process, its size is in
|
||||
* sched_pdsch */
|
||||
uint32_t tb[16384];
|
||||
uint32_t transportBlock[16384];
|
||||
uint32_t tb_size;
|
||||
|
||||
/// sched_pdsch keeps information on MCS etc used for the initial transmission
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -84,9 +84,6 @@ typedef struct {
|
||||
nr_rlc_sdu_segment_t *wait_end;
|
||||
|
||||
nr_rlc_sdu_segment_t *retransmit_list;
|
||||
nr_rlc_sdu_segment_t *retransmit_end;
|
||||
|
||||
nr_rlc_sdu_segment_t *ack_list;
|
||||
} nr_rlc_entity_am_t;
|
||||
|
||||
void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *entity,
|
||||
|
||||
@@ -58,14 +58,19 @@ oom:
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu)
|
||||
int nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu)
|
||||
{
|
||||
sdu->sdu->ref_count--;
|
||||
if (sdu->sdu->ref_count == 0) {
|
||||
int ret = 0;
|
||||
|
||||
sdu->sdu->free_count++;
|
||||
if (sdu->sdu->free_count == sdu->sdu->ref_count) {
|
||||
free(sdu->sdu->data);
|
||||
free(sdu->sdu);
|
||||
ret = 1;
|
||||
}
|
||||
free(sdu);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list,
|
||||
|
||||
@@ -30,6 +30,10 @@ typedef struct nr_rlc_sdu_t {
|
||||
int retx_count;
|
||||
|
||||
int ref_count; /* incremented each time the SDU is segmented */
|
||||
int free_count; /* incremented each time a segment is freed
|
||||
* when it equals ref_count we can free the SDU
|
||||
* completely
|
||||
*/
|
||||
} nr_rlc_sdu_t;
|
||||
|
||||
typedef struct nr_rlc_sdu_segment_t {
|
||||
@@ -44,7 +48,8 @@ typedef struct nr_rlc_sdu_segment_t {
|
||||
nr_rlc_sdu_segment_t *nr_rlc_new_sdu(
|
||||
char *buffer, int size,
|
||||
int upper_layer_id);
|
||||
void nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu);
|
||||
/* return 1 if the SDU has been freed too, 0 if not (more segments to free) */
|
||||
int nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu);
|
||||
void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list,
|
||||
nr_rlc_sdu_segment_t **end,
|
||||
nr_rlc_sdu_segment_t *sdu);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -170,7 +170,7 @@ typedef struct m2ap_MCE_instance_s {
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs];
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int16_t N_RB_DL[MAX_NUM_CCs];
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
|
||||
@@ -181,7 +181,7 @@ typedef struct m2ap_eNB_instance_s {
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs];
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int16_t N_RB_DL[MAX_NUM_CCs];
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
|
||||
@@ -89,13 +89,13 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
|
||||
int sd = socket(server_address.sin_family, SOCK_DGRAM, 0);
|
||||
if (sd < 0)
|
||||
{
|
||||
LOG_E(MAC, "Socket creation error standalone PNF\n");
|
||||
LOG_E(NR_MAC, "Socket creation error standalone PNF\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (inet_pton(server_address.sin_family, stub_eth_params.remote_addr, &server_address.sin_addr) <= 0)
|
||||
{
|
||||
LOG_E(MAC, "Invalid standalone PNF Address\n");
|
||||
LOG_E(NR_MAC, "Invalid standalone PNF Address\n");
|
||||
close(sd);
|
||||
return;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
|
||||
// Using connect to use send() instead of sendto()
|
||||
if (connect(sd, (struct sockaddr *)&server_address, addr_len) < 0)
|
||||
{
|
||||
LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
||||
LOG_E(NR_MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
||||
close(sd);
|
||||
return;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
|
||||
|
||||
if (bind(sd, (struct sockaddr *)&server_address, addr_len) < 0)
|
||||
{
|
||||
LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
||||
LOG_E(NR_MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
||||
close(sd);
|
||||
return;
|
||||
}
|
||||
@@ -634,6 +634,7 @@ static void copy_ul_tti_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n
|
||||
AssertFatal(num_pdus >= 0, "Invalid ul_tti_request number of PDUS\n");
|
||||
AssertFatal(num_pdus <= sizeof(ul_tti_req->pdus_list) / sizeof(ul_tti_req->pdus_list[0]),
|
||||
"Too many pdus %d in ul_tti_req\n", num_pdus);
|
||||
|
||||
if (!send_crc_ind_and_rx_ind(sfn_slot))
|
||||
{
|
||||
LOG_T(NR_MAC, "CRC_RX ind not sent\n");
|
||||
@@ -1045,7 +1046,7 @@ void *nrue_standalone_pnf_task(void *context)
|
||||
|
||||
if (sem_post(&sfn_slot_semaphore) != 0)
|
||||
{
|
||||
LOG_E(MAC, "sem_post() error\n");
|
||||
LOG_E(NR_MAC, "sem_post() error\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@@ -1064,7 +1065,7 @@ void *nrue_standalone_pnf_task(void *context)
|
||||
|
||||
// L2 Abstraction Layer
|
||||
int handle_bcch_bch(module_id_t module_id, int cc_id,
|
||||
unsigned int gNB_index, uint8_t *pduP,
|
||||
unsigned int gNB_index, void *phy_data, uint8_t *pduP,
|
||||
unsigned int additional_bits,
|
||||
uint32_t ssb_index, uint32_t ssb_length,
|
||||
uint16_t ssb_start_subcarrier, uint16_t cell_id){
|
||||
@@ -1072,6 +1073,7 @@ int handle_bcch_bch(module_id_t module_id, int cc_id,
|
||||
return nr_ue_decode_mib(module_id,
|
||||
cc_id,
|
||||
gNB_index,
|
||||
phy_data,
|
||||
additional_bits,
|
||||
ssb_length, // Lssb = 64 is not support
|
||||
ssb_index,
|
||||
@@ -1124,13 +1126,13 @@ void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nac
|
||||
}
|
||||
else {
|
||||
//shouldn't get here
|
||||
LOG_E(MAC, "Trying to process acknack for an inactive harq process (%d)\n", harq_pid);
|
||||
LOG_E(NR_MAC, "Trying to process acknack for an inactive harq process (%d)\n", harq_pid);
|
||||
}
|
||||
}
|
||||
|
||||
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
|
||||
|
||||
NR_UE_L2_STATE_t ret;
|
||||
NR_UE_L2_STATE_t ret=0;
|
||||
module_id_t module_id = ul_info->module_id;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
|
||||
@@ -1182,6 +1184,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
} else {
|
||||
// UL indication after reception of DCI or DL PDU
|
||||
if (dl_info && dl_info->dci_ind && dl_info->dci_ind->number_of_dcis) {
|
||||
|
||||
LOG_T(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
|
||||
for (int i = 0; i < dl_info->dci_ind->number_of_dcis; i++) {
|
||||
LOG_T(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
|
||||
@@ -1197,8 +1200,8 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
|
||||
/* The check below filters out UL_DCIs (format 7) which are being processed as DL_DCIs. */
|
||||
if (dci_index->dci_format == 7 && mac->ra.ra_state == RA_SUCCEEDED) {
|
||||
LOG_T(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n");
|
||||
break;
|
||||
LOG_D(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n");
|
||||
continue;
|
||||
}
|
||||
dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci_index->dci_format];
|
||||
g_harq_pid = def_dci_pdu_rel15->harq_pid;
|
||||
@@ -1208,7 +1211,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
if (ret >= 0) {
|
||||
AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" );
|
||||
AssertFatal( nr_ue_if_module_inst[module_id]->scheduled_response != NULL, "scheduled_response is NULL!\n" );
|
||||
fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id);
|
||||
fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id, dl_info->phy_data);
|
||||
nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response);
|
||||
}
|
||||
memset(def_dci_pdu_rel15, 0, sizeof(*def_dci_pdu_rel15));
|
||||
@@ -1221,7 +1224,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
|
||||
for (int i=0; i<dl_info->rx_ind->number_pdus; ++i) {
|
||||
|
||||
LOG_T(MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n",
|
||||
LOG_D(NR_MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n",
|
||||
__FUNCTION__,
|
||||
dl_info->rx_ind->rx_indication_body[i].pdu_type,
|
||||
dl_info->rx_ind->number_pdus);
|
||||
@@ -1229,7 +1232,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
|
||||
case FAPI_NR_RX_PDU_TYPE_SSB:
|
||||
mac->ssb_rsrp_dBm = (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm;
|
||||
ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
|
||||
ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.additional_bits,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index,
|
||||
|
||||
@@ -123,6 +123,9 @@ typedef struct {
|
||||
/// dci reception indication structure
|
||||
fapi_nr_dci_indication_t *dci_ind;
|
||||
|
||||
/// PHY specific data structure that can be passed on to L2 via nr_downlink_indication_t and
|
||||
/// back to L1 via the nr_scheduled_response_t
|
||||
void *phy_data;
|
||||
} nr_downlink_indication_t;
|
||||
|
||||
|
||||
@@ -176,6 +179,9 @@ typedef struct {
|
||||
/// data transmission request structure
|
||||
fapi_nr_tx_request_t *tx_request;
|
||||
|
||||
/// PHY data structure initially passed on to L2 via the nr_downlink_indication_t and
|
||||
/// returned to L1 via nr_scheduled_response_t
|
||||
void *phy_data;
|
||||
} nr_scheduled_response_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -286,6 +292,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq);
|
||||
|
||||
// TODO check
|
||||
/**\brief handle BCCH-BCH message from dl_indication
|
||||
\param phy_data PHY structure to be filled in by the callee in the FAPI call (L1 caller -> indication to L2 -> FAPI call to L1 callee)
|
||||
\param pduP pointer to bch pdu
|
||||
\param additional_bits corresponding to 38.212 ch.7
|
||||
\param ssb_index SSB index within 0 - (L_ssb-1) corresponding to 38.331 ch.13 parameter i
|
||||
@@ -294,6 +301,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq);
|
||||
int handle_bcch_bch(module_id_t module_id,
|
||||
int cc_id,
|
||||
unsigned int gNB_index,
|
||||
void *phy_data,
|
||||
uint8_t *pduP,
|
||||
unsigned int additional_bits,
|
||||
uint32_t ssb_index,
|
||||
|
||||
@@ -3175,7 +3175,8 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,
|
||||
const size_t num_plmn_data = sizeof(plmn_data) / sizeof(plmn_data[0]);
|
||||
for (size_t plmn_ind = 0;; ++plmn_ind) {
|
||||
if (plmn_ind == num_plmn_data) {
|
||||
LOG_E( RRC, "Did not find name from internal table for %u %u\n", mcc, mnc);
|
||||
LOG_W( RRC, "Did not find operator name from internal table for MCC %0*d, MNC %0*d\n",
|
||||
mccdigits, mcc, mncdigits, mnc);
|
||||
break;
|
||||
}
|
||||
if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) {
|
||||
|
||||
@@ -1757,7 +1757,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance
|
||||
&& RC.rrc[instance]->configuration.mnc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
|
||||
&& RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) {
|
||||
for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
|
||||
frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
|
||||
/* get nB from configuration */
|
||||
/* get default DRX cycle from configuration */
|
||||
Tc = (uint8_t)RC.rrc[instance]->configuration.radioresourceconfig[CC_id].pcch_defaultPagingCycle;
|
||||
|
||||
@@ -216,7 +216,7 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
|
||||
|
||||
void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc){
|
||||
|
||||
lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
int curr_bwp = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
// coreset duration setting to be improved in the framework of RRC harmonization, potentially using a common function
|
||||
int len_coreset = 1;
|
||||
@@ -248,7 +248,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
|
||||
|
||||
//TODO change to accomodate for SRS
|
||||
|
||||
lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
int temp_min_delay = 6; // k2 = 2 or 3 won'r work as well as higher values
|
||||
if(frame_type==TDD && scc->tdd_UL_DL_ConfigurationCommon) {
|
||||
|
||||
|
||||
@@ -969,9 +969,9 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
||||
uint16_t ue_initial_id;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
protocol_ctxt_t ctxt;
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp;
|
||||
protocol_ctxt_t ctxt={0};
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
|
||||
uint8_t pdu_sessions_done;
|
||||
uint8_t inde_list[NR_NB_RB_MAX - 3]= {0};
|
||||
int ret = 0;
|
||||
|
||||
@@ -223,7 +223,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
|
||||
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition));
|
||||
*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0;
|
||||
*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1;
|
||||
|
||||
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList));
|
||||
@@ -572,7 +572,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
|
||||
}
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition));
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0;
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1;
|
||||
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList));
|
||||
|
||||
|
||||
@@ -700,7 +700,7 @@ typedef struct {
|
||||
unsigned int n_frames_flag; // if set, then let the emulation goes to infinity
|
||||
node_function_t node_function[MAX_NUM_CCs];
|
||||
node_timing_t node_timing[MAX_NUM_CCs];
|
||||
unsigned char frame_type[MAX_NUM_CCs]; //! LTE frame type (TDD=1, FDD=0). \note this should be converted to \ref lte_frame_type_t (header file reorganization needed)
|
||||
unsigned char frame_type[MAX_NUM_CCs]; //! LTE frame type (TDD=1, FDD=0). \note this should be converted to \ref frame_type_t (header file reorganization needed)
|
||||
char *frame_type_name[MAX_NUM_CCs];
|
||||
unsigned char tdd_config[MAX_NUM_CCs];
|
||||
unsigned char tdd_config_S[MAX_NUM_CCs];
|
||||
|
||||
@@ -172,7 +172,7 @@ typedef struct x2ap_eNB_instance_s {
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs];
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int16_t N_RB_DL[MAX_NUM_CCs];
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
|
||||
uint32_t subframeAssignment[MAX_NUM_CCs];
|
||||
|
||||
Reference in New Issue
Block a user