Merge remote-tracking branch 'origin/develop' into if5_ECPRI_rework
Conflicts: openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
This commit is contained in:
@@ -181,6 +181,7 @@ typedef struct gtpv1u_gnb_create_tunnel_req_s {
|
||||
int num_tunnels;
|
||||
//teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
||||
teid_t outgoing_teid[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
int outgoing_qfi[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
ebi_t incoming_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
//ebi_t outgoing_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
|
||||
|
||||
@@ -515,15 +515,16 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
int sz=sizeof(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address);
|
||||
memcpy(addr.buffer,&f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz);
|
||||
addr.length = sz*8;
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid=
|
||||
newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
||||
f1ap_ue_context_setup_req->rnti,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||
0xFFFF, // We will set the right value from DU answer
|
||||
addr,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
||||
cu_f1u_data_req);
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
||||
f1ap_ue_context_setup_req->rnti,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||
0xFFFF, // We will set the right value from DU answer
|
||||
-1, // no qfi
|
||||
addr,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
||||
cu_f1u_data_req,
|
||||
NULL);
|
||||
/* 12.3.1 ULTunnels_ToBeSetup_Item */
|
||||
asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list,
|
||||
F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
|
||||
@@ -1491,15 +1492,16 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context
|
||||
memcpy(addr.buffer,&f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz);
|
||||
addr.length = sz*8;
|
||||
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid=
|
||||
newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
||||
f1ap_ue_context_modification_req->rnti,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
||||
0xFFFF, // We will set the right value from DU answer
|
||||
addr,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
||||
cu_f1u_data_req);
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
|
||||
f1ap_ue_context_modification_req->rnti,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id,
|
||||
0xFFFF, // We will set the right value from DU answer
|
||||
-1, // no qfi
|
||||
addr,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
||||
cu_f1u_data_req,
|
||||
NULL);
|
||||
/* 12.3.1 ULTunnels_ToBeSetup_Item */
|
||||
asn1cSequenceAdd(drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list,
|
||||
F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
|
||||
|
||||
@@ -187,14 +187,16 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
transport_layer_addr_t addr;
|
||||
memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address));
|
||||
addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8;
|
||||
drb_p->up_dl_tnl[0].teid=newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
||||
f1ap_ue_context_setup_req->rnti,
|
||||
drb_p->drb_id,
|
||||
drb_p->drb_id,
|
||||
drb_p->up_ul_tnl[0].teid,
|
||||
addr,
|
||||
drb_p->up_ul_tnl[0].port,
|
||||
lteDURecvCb);
|
||||
drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
||||
f1ap_ue_context_setup_req->rnti,
|
||||
drb_p->drb_id,
|
||||
drb_p->drb_id,
|
||||
drb_p->up_ul_tnl[0].teid,
|
||||
-1, // no qfi
|
||||
addr,
|
||||
drb_p->up_ul_tnl[0].port,
|
||||
lteDURecvCb,
|
||||
NULL);
|
||||
drb_p->up_dl_tnl_length++;
|
||||
}
|
||||
}
|
||||
@@ -1171,14 +1173,16 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
||||
transport_layer_addr_t addr;
|
||||
memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address));
|
||||
addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8;
|
||||
drb_p->up_dl_tnl[0].teid=newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
||||
f1ap_ue_context_modification_req->rnti,
|
||||
drb_p->drb_id,
|
||||
drb_p->drb_id,
|
||||
drb_p->up_ul_tnl[0].teid,
|
||||
addr,
|
||||
drb_p->up_ul_tnl[0].port,
|
||||
lteDURecvCb);
|
||||
drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT,
|
||||
f1ap_ue_context_modification_req->rnti,
|
||||
drb_p->drb_id,
|
||||
drb_p->drb_id,
|
||||
drb_p->up_ul_tnl[0].teid,
|
||||
-1, // no qfi
|
||||
addr,
|
||||
drb_p->up_ul_tnl[0].port,
|
||||
lteDURecvCb,
|
||||
NULL);
|
||||
drb_p->up_dl_tnl_length++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,8 @@
|
||||
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER "ul_bler_target_upper"
|
||||
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER "ul_bler_target_lower"
|
||||
#define CONFIG_STRING_MACRLC_UL_MAX_MCS "ul_max_mcs"
|
||||
#define CONFIG_STRING_MACRLC_HARQ_ROUND_MAX "harq_round_max"
|
||||
#define CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX "dl_harq_round_max"
|
||||
#define CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX "ul_harq_round_max"
|
||||
#define CONFIG_STRING_MACRLC_MIN_GRANT_PRB "min_grant_prb"
|
||||
#define CONFIG_STRING_MACRLC_MIN_GRANT_MCS "min_grant_mcs"
|
||||
|
||||
@@ -97,7 +98,7 @@
|
||||
{CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY, NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_UL_PRBBLACK_SNR_THRESHOLD, "SNR threshold to decide whether a PRB will be blacklisted or not", 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_UL_PRBBLACK_SNR_THRESHOLD, "SNR threshold to decide whether a PRB will be blacklisted or not", 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUSCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
|
||||
@@ -106,9 +107,10 @@
|
||||
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease UL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
|
||||
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase UL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \
|
||||
{CONFIG_STRING_MACRLC_UL_MAX_MCS, "Maximum UL MCS that should be used", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_HARQ_ROUND_MAX, "Maximum number of HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX, "Maximum number of DL HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX, "Maximum number of UL HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_MIN_GRANT_PRB, "Minimal Periodic ULSCH Grant PRBs", 0, u8ptr:NULL, defintval:5, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0} \
|
||||
{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \
|
||||
}
|
||||
#define MACRLC_CC_IDX 0
|
||||
#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1
|
||||
@@ -139,9 +141,46 @@
|
||||
#define MACRLC_UL_BLER_TARGET_UPPER_IDX 26
|
||||
#define MACRLC_UL_BLER_TARGET_LOWER_IDX 27
|
||||
#define MACRLC_UL_MAX_MCS_IDX 28
|
||||
#define MACRLC_HARQ_ROUND_MAX_IDX 29
|
||||
#define MACRLC_MIN_GRANT_PRB_IDX 30
|
||||
#define MACRLC_MIN_GRANT_MCS_IDX 31
|
||||
#define MACRLC_DL_HARQ_ROUND_MAX_IDX 29
|
||||
#define MACRLC_UL_HARQ_ROUND_MAX_IDX 30
|
||||
#define MACRLC_MIN_GRANT_PRB_IDX 31
|
||||
#define MACRLC_MIN_GRANT_MCS_IDX 32
|
||||
|
||||
#define MACRLCPARAMS_CHECK { \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s2 = { config_check_intrange, {1, 8} } }, /* DL max HARQ rounds */ \
|
||||
{ .s2 = { config_check_intrange, {1, 8} } }, /* UL max HARQ rounds */ \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
@@ -816,6 +816,10 @@ void RCconfig_nr_macrlc() {
|
||||
}
|
||||
paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
|
||||
paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
|
||||
/* map parameter checking array instances to parameter definition array instances */
|
||||
checkedparam_t config_check_MacRLCParams [] = MACRLCPARAMS_CHECK;
|
||||
for (int i = 0; i < sizeof(MacRLC_Params) / sizeof(paramdef_t); ++i)
|
||||
MacRLC_Params[i].chkPptr = &(config_check_MacRLCParams[i]);
|
||||
config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);
|
||||
|
||||
if ( MacRLC_ParamList.numelt > 0) {
|
||||
@@ -887,11 +891,12 @@ void RCconfig_nr_macrlc() {
|
||||
dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr);
|
||||
dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr);
|
||||
dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr);
|
||||
dl_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_HARQ_ROUND_MAX_IDX].u8ptr);
|
||||
NR_bler_options_t *ul_bler_options = &RC.nrmac[j]->ul_bler;
|
||||
ul_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_UPPER_IDX].dblptr);
|
||||
ul_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_LOWER_IDX].dblptr);
|
||||
ul_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_MAX_MCS_IDX].u8ptr);
|
||||
RC.nrmac[j]->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_HARQ_ROUND_MAX_IDX].u8ptr);
|
||||
ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr);
|
||||
RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr);
|
||||
RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr);
|
||||
RC.nrmac[j]->num_ulprbbl = num_prbbl;
|
||||
|
||||
@@ -158,9 +158,9 @@ typedef enum {
|
||||
{GNB_CONFIG_STRING_NRCELLID, NULL, 0, u64ptr:NULL, defint64val:1, TYPE_UINT64, 0}, \
|
||||
{GNB_CONFIG_STRING_MINRXTXTIME, NULL, 0, iptr:NULL, defintval:2, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_ULPRBBLACKLIST, NULL, 0, strptr:NULL, defstrval:"", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0} \
|
||||
{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
}
|
||||
|
||||
#define GNB_GNB_ID_IDX 0
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "NR_SubcarrierSpacing.h"
|
||||
#include "NR_CSI-ReportConfig.h"
|
||||
#include "openair1/SCHED_NR_UE/harq_nr.h"
|
||||
|
||||
#define NR_SHORT_BSR_TABLE_SIZE 32
|
||||
@@ -63,6 +64,7 @@
|
||||
#define CCCH_PAYLOAD_SIZE_MAX 512
|
||||
#define RAR_PAYLOAD_SIZE_MAX 128
|
||||
#define MAX_BWP_SIZE 275
|
||||
#define MAX_CSI_REPORTCONFIG 48
|
||||
|
||||
typedef enum frequency_range_e {
|
||||
FR1 = 0,
|
||||
@@ -512,5 +514,37 @@ typedef struct Type0_PDCCH_CSS_config_s {
|
||||
bool active;
|
||||
} NR_Type0_PDCCH_CSS_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t nb_ssbri_cri;
|
||||
uint8_t cri_ssbri_bitlen;
|
||||
uint8_t rsrp_bitlen;
|
||||
uint8_t diff_rsrp_bitlen;
|
||||
} L1_RSRP_bitlen_t;
|
||||
|
||||
typedef struct{
|
||||
uint8_t ri_restriction;
|
||||
uint8_t cri_bitlen;
|
||||
uint8_t ri_bitlen;
|
||||
uint8_t li_bitlen[8];
|
||||
uint8_t pmi_x1_bitlen[8];
|
||||
uint8_t pmi_x2_bitlen[8];
|
||||
uint8_t cqi_bitlen[8];
|
||||
} CSI_Meas_bitlen_t;
|
||||
|
||||
typedef struct nr_csi_report {
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||
long periodicity;
|
||||
uint16_t offset;
|
||||
long ** SSB_Index_list;
|
||||
long ** CSI_Index_list;
|
||||
// uint8_t nb_of_nzp_csi_report;
|
||||
uint8_t nb_of_csi_ssb_report;
|
||||
L1_RSRP_bitlen_t CSI_report_bitlen;
|
||||
CSI_Meas_bitlen_t csi_meas_bitlen;
|
||||
int codebook_mode;
|
||||
int N1;
|
||||
int N2;
|
||||
} nr_csi_report_t;
|
||||
|
||||
#endif /*__LAYER2_MAC_H__ */
|
||||
|
||||
|
||||
@@ -4221,3 +4221,521 @@ bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config,
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
//! Calculating number of bits set
|
||||
uint8_t number_of_bits_set(uint8_t buf) {
|
||||
uint8_t nb_of_bits_set = 0;
|
||||
uint8_t mask = 0xff;
|
||||
uint8_t index = 0;
|
||||
|
||||
for (index=7; (buf & mask) && (index>=0) ; index--){
|
||||
if (buf & (1<<index))
|
||||
nb_of_bits_set++;
|
||||
|
||||
mask>>=1;
|
||||
}
|
||||
return nb_of_bits_set;
|
||||
}
|
||||
|
||||
void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t nb_resources,
|
||||
nr_csi_report_t *csi_report) {
|
||||
|
||||
if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) {
|
||||
if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
|
||||
csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1;
|
||||
else
|
||||
/*! From Spec 38.331
|
||||
* nrofReportedRS
|
||||
* The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE
|
||||
* capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report.
|
||||
* When the field is absent the UE applies the value 1
|
||||
*/
|
||||
csi_report->CSI_report_bitlen.nb_ssbri_cri= 1;
|
||||
} else
|
||||
csi_report->CSI_report_bitlen.nb_ssbri_cri= 2;
|
||||
|
||||
if (nb_resources) {
|
||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources));
|
||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
} else {
|
||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0;
|
||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
|
||||
csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
nr_csi_report_t *csi_report) {
|
||||
|
||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||
uint8_t nb_allowed_ri, ri_bitlen;
|
||||
uint8_t ri_restriction = 0;
|
||||
|
||||
if (codebookConfig == NULL) {
|
||||
csi_report->csi_meas_bitlen.ri_bitlen=0;
|
||||
return ri_restriction;
|
||||
}
|
||||
|
||||
// codebook type1 single panel
|
||||
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){
|
||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
|
||||
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){
|
||||
|
||||
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
||||
|
||||
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
||||
ri_bitlen = ceil(log2(nb_allowed_ri));
|
||||
|
||||
ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
|
||||
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
||||
}
|
||||
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){
|
||||
if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present ==
|
||||
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
|
||||
// 4 ports
|
||||
|
||||
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
||||
|
||||
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
||||
ri_bitlen = ceil(log2(nb_allowed_ri));
|
||||
|
||||
ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
|
||||
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
||||
}
|
||||
else {
|
||||
// more than 4 ports
|
||||
|
||||
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
||||
|
||||
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
||||
ri_bitlen = ceil(log2(nb_allowed_ri));
|
||||
|
||||
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
||||
}
|
||||
}
|
||||
return ri_restriction;
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report) {
|
||||
|
||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||
for(int i=0; i<8; i++) {
|
||||
if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0)
|
||||
csi_report->csi_meas_bitlen.li_bitlen[i]=0;
|
||||
else {
|
||||
// codebook type1 single panel
|
||||
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present)
|
||||
csi_report->csi_meas_bitlen.li_bitlen[i]=ceil(log2(i+1))<2?ceil(log2(i+1)):2;
|
||||
else
|
||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2,
|
||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo) {
|
||||
|
||||
// Table 5.2.2.2.1-2 in 38.214 for supported configurations
|
||||
switch(morethantwo->n1_n2.present){
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 2;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 2;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 3;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 6;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 8;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_three_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 3;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_twelve_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 12;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_four_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 4;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 8;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_sixteen_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 16;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Not supported configuration for n1_n2 in codebook configuration");
|
||||
}
|
||||
}
|
||||
|
||||
void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2,
|
||||
int *x1, int *x2, int rank, int codebook_mode) {
|
||||
|
||||
// Table 6.3.1.1.2-1 in 38.212
|
||||
switch(rank){
|
||||
case 1:
|
||||
if(n2>1) {
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 2;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2));
|
||||
*x2 = 4;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 2;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2));
|
||||
*x2 = 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(n1*n2 == 2) {
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2));
|
||||
*x2 = 3;
|
||||
}
|
||||
*x1 += 1;
|
||||
}
|
||||
else {
|
||||
if(n2>1) {
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 3;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2));
|
||||
*x2 = 3;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2));
|
||||
*x2 = 3;
|
||||
}
|
||||
}
|
||||
*x1 += 2;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
if(n1*n2 == 2) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
if(n1*n2 >= 8) {
|
||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)) + 2;
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)) + 2;
|
||||
*x2 = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
if(n1 == 4 && n2 == 1) {
|
||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
if(n1 > 2 && n2 == 2) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2/2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid rank in x1 x2 bit length computation\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report) {
|
||||
|
||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||
for(int i=0; i<8; i++) {
|
||||
csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=0;
|
||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=0;
|
||||
if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0)
|
||||
return;
|
||||
else {
|
||||
if(codebookConfig->codebookType.present == NR_CodebookConfig__codebookType_PR_type1) {
|
||||
if(codebookConfig->codebookType.choice.type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) {
|
||||
if(codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present ==
|
||||
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) {
|
||||
csi_report->N1 = 1;
|
||||
csi_report->N2 = 1;
|
||||
if (i==0)
|
||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=2;
|
||||
if (i==1)
|
||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=1;
|
||||
}
|
||||
else { // more than two
|
||||
int n1,n2,o1,o2,x1,x2;
|
||||
get_n1n2_o1o2_singlepanel(&n1,&n2,&o1,&o2,codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo);
|
||||
get_x1x2_bitlen_singlepanel(n1,n2,o1,o2,&x1,&x2,i+1,codebookConfig->codebookType.choice.type1->codebookMode);
|
||||
csi_report->N1 = n1;
|
||||
csi_report->N2 = n2;
|
||||
csi_report->codebook_mode = codebookConfig->codebookType.choice.type1->codebookMode;
|
||||
csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=x1;
|
||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=x2;
|
||||
}
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Type1 Multi-panel Codebook Config not yet implemented\n");
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Type2 Codebook Config not yet implemented\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report) {
|
||||
|
||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||
struct NR_CSI_ReportConfig__reportFreqConfiguration *freq_config = csi_reportconfig->reportFreqConfiguration;
|
||||
|
||||
if (*freq_config->cqi_FormatIndicator == NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI) {
|
||||
for(int i=0; i<8; i++) {
|
||||
if ((ri_restriction>>i)&0x01) {
|
||||
csi_report->csi_meas_bitlen.cqi_bitlen[i] = 4;
|
||||
if(codebookConfig != NULL) {
|
||||
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present){
|
||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
|
||||
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo) {
|
||||
if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present >
|
||||
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
|
||||
// more than 4 antenna ports
|
||||
if (i > 4)
|
||||
csi_report->csi_meas_bitlen.cqi_bitlen[i] += 4; // CQI for second TB
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
csi_report->csi_meas_bitlen.cqi_bitlen[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Sub-band CQI reporting not yet supported");
|
||||
}
|
||||
|
||||
//!TODO : same function can be written to handle csi_resources
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template) {
|
||||
uint8_t csi_report_id = 0;
|
||||
uint8_t nb_resources = 0;
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId;
|
||||
struct NR_CSI_ResourceConfig *csi_resourceconfig;
|
||||
|
||||
// for each CSI measurement report configuration (list of CSI-ReportConfig)
|
||||
LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count);
|
||||
for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||
// MAC structure for CSI measurement reports (per UE and per report)
|
||||
nr_csi_report_t *csi_report = &csi_report_template[csi_report_id];
|
||||
// csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration
|
||||
// (either CSI-RS or SSB)
|
||||
csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
||||
// looking for CSI-ResourceConfig
|
||||
int found_resource = 0;
|
||||
int csi_resourceidx = 0;
|
||||
while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) {
|
||||
csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||
if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId)
|
||||
found_resource = 1;
|
||||
csi_resourceidx++;
|
||||
}
|
||||
AssertFatal(found_resource==1,"Not able to found any CSI-ResourceConfig with csi-ResourceConfigId %ld\n",
|
||||
csi_ResourceConfigId);
|
||||
|
||||
long resourceType = csi_resourceconfig->resourceType;
|
||||
|
||||
reportQuantity_type = csi_reportconfig->reportQuantity.present;
|
||||
csi_report->reportQuantity_type = reportQuantity_type;
|
||||
|
||||
// setting the CSI or SSB index list
|
||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) {
|
||||
for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId ==
|
||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
|
||||
//We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
|
||||
nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count;
|
||||
csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array;
|
||||
csi_report->CSI_Index_list = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) {
|
||||
AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL,
|
||||
"Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n");
|
||||
for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
||||
//For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212
|
||||
nb_resources = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.count;
|
||||
csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.array;
|
||||
csi_report->SSB_Index_list = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else AssertFatal(1==0,"Only periodic resource configuration currently supported\n");
|
||||
}
|
||||
LOG_D(NR_MAC,"nb_resources %d\n",nb_resources);
|
||||
// computation of bit length depending on the report type
|
||||
switch(reportQuantity_type){
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP):
|
||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP):
|
||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Not yet supported CSI report quantity type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id) {
|
||||
|
||||
uint16_t csi_bitlen = 0;
|
||||
uint16_t max_bitlen = 0;
|
||||
L1_RSRP_bitlen_t *CSI_report_bitlen = NULL;
|
||||
CSI_Meas_bitlen_t *csi_meas_bitlen = NULL;
|
||||
|
||||
if (csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP ||
|
||||
csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) {
|
||||
CSI_report_bitlen = &(csi_report_template[csi_report_id].CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
csi_bitlen += ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
|
||||
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
|
||||
(CSI_report_bitlen->nb_ssbri_cri -1 )));
|
||||
} else {
|
||||
csi_meas_bitlen = &(csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
uint16_t temp_bitlen;
|
||||
for (int i=0; i<8; i++) {
|
||||
temp_bitlen = (csi_meas_bitlen->cri_bitlen+
|
||||
csi_meas_bitlen->ri_bitlen+
|
||||
csi_meas_bitlen->li_bitlen[i]+
|
||||
csi_meas_bitlen->cqi_bitlen[i]+
|
||||
csi_meas_bitlen->pmi_x1_bitlen[i]+
|
||||
csi_meas_bitlen->pmi_x2_bitlen[i]);
|
||||
if(temp_bitlen>max_bitlen)
|
||||
max_bitlen = temp_bitlen;
|
||||
}
|
||||
csi_bitlen += max_bitlen;
|
||||
}
|
||||
|
||||
return csi_bitlen;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ uint8_t get_pusch_mcs_table(long *mcs_Table,
|
||||
uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
|
||||
uint8_t nb_preambles,
|
||||
uint8_t unpaired,
|
||||
frequency_range_t);
|
||||
frequency_range_t);
|
||||
|
||||
int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPrecoder);
|
||||
|
||||
@@ -234,4 +234,36 @@ void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP,
|
||||
const frame_t frameP,
|
||||
const sub_frame_t subframeP,
|
||||
const rnti_t rntiP);
|
||||
|
||||
uint8_t number_of_bits_set(uint8_t buf);
|
||||
|
||||
void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t nb_resources,
|
||||
nr_csi_report_t *csi_report);
|
||||
|
||||
uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
nr_csi_report_t *csi_report);
|
||||
|
||||
void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report);
|
||||
|
||||
void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2,
|
||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo);
|
||||
|
||||
void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2,
|
||||
int *x1, int *x2, int rank, int codebook_mode);
|
||||
|
||||
void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report);
|
||||
|
||||
void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report);
|
||||
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template);
|
||||
|
||||
uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -399,6 +399,11 @@ typedef struct {
|
||||
/// measured SSB RSRP in dBm
|
||||
short ssb_rsrp_dBm;
|
||||
|
||||
nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG];
|
||||
|
||||
/// measurements from CSI-RS
|
||||
fapi_nr_csirs_measurements_t csirs_measurements;
|
||||
|
||||
/// Last NDI of UL HARQ processes
|
||||
uint8_t UL_ndi[NR_MAX_HARQ_PROCESSES];
|
||||
/// first ULTX of UL HARQ processes
|
||||
|
||||
@@ -194,6 +194,7 @@ int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer);
|
||||
|
||||
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind);
|
||||
int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
|
||||
int8_t nr_ue_process_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements);
|
||||
|
||||
uint32_t get_ssb_frame(uint32_t test);
|
||||
|
||||
@@ -213,6 +214,18 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
|
||||
uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
|
||||
uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||
|
||||
uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
int csi_report_id,
|
||||
|
||||
@@ -1462,6 +1462,16 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
|
||||
}
|
||||
|
||||
int8_t nr_ue_process_csirs_measurements(module_id_t module_id,
|
||||
frame_t frame,
|
||||
int slot,
|
||||
fapi_nr_csirs_measurements_t *csirs_measurements) {
|
||||
LOG_D(NR_MAC,"(%d.%d) Received CSI-RS measurements\n", frame, slot);
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
memcpy(&mac->csirs_measurements, csirs_measurements, sizeof(*csirs_measurements));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_harq_status(NR_UE_MAC_INST_t *mac,
|
||||
uint8_t pucch_id,
|
||||
uint8_t harq_id,
|
||||
@@ -2564,13 +2574,17 @@ uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||
n_csi_bits = get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||
n_csi_bits = get_csirs_RI_PMI_CQI_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||
n_csi_bits = get_csirs_RSRP_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
||||
LOG_E(NR_MAC,"Measurement report based on CSI-RS not available\n");
|
||||
LOG_E(NR_MAC,"Measurement report %d based on CSI-RS is not available\n", csi_reportconfig->reportQuantity.present);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
|
||||
@@ -2658,6 +2672,122 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||
return bits;
|
||||
}
|
||||
|
||||
uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||
|
||||
int n_bits = 0;
|
||||
uint32_t temp_payload = 0;
|
||||
|
||||
for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
|
||||
|
||||
struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||
if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) {
|
||||
|
||||
for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
||||
|
||||
nr_csi_report_t *csi_report = &mac->csi_report_template[csi_reportconfig->reportConfigId];
|
||||
compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template);
|
||||
n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_reportconfig->reportConfigId);
|
||||
|
||||
int cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||
int ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
|
||||
int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->csirs_measurements.rank_indicator];
|
||||
int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->csirs_measurements.rank_indicator];
|
||||
int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->csirs_measurements.rank_indicator];
|
||||
int padding_bitlen = n_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen);
|
||||
|
||||
// TODO: Improvements will be needed to cri_bitlen>0 and pmi_x1_bitlen>0
|
||||
temp_payload = (mac->csirs_measurements.rank_indicator<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen+padding_bitlen+pmi_x1_bitlen)) |
|
||||
(mac->csirs_measurements.i1<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen)) |
|
||||
(mac->csirs_measurements.i2<<(cri_bitlen+cqi_bitlen)) |
|
||||
(mac->csirs_measurements.cqi<<cri_bitlen) |
|
||||
0;
|
||||
|
||||
reverse_n_bits((uint8_t *)&temp_payload, n_bits);
|
||||
|
||||
LOG_D(NR_MAC, "cri_bitlen = %d\n", cri_bitlen);
|
||||
LOG_D(NR_MAC, "ri_bitlen = %d\n", ri_bitlen);
|
||||
LOG_D(NR_MAC, "pmi_x1_bitlen = %d\n", pmi_x1_bitlen);
|
||||
LOG_D(NR_MAC, "pmi_x2_bitlen = %d\n", pmi_x2_bitlen);
|
||||
LOG_D(NR_MAC, "cqi_bitlen = %d\n", cqi_bitlen);
|
||||
LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload);
|
||||
|
||||
LOG_D(NR_MAC, "n_bits = %d\n", n_bits);
|
||||
LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pucch->csi_part1_payload = temp_payload;
|
||||
return n_bits;
|
||||
}
|
||||
|
||||
uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||
|
||||
int n_bits = 0;
|
||||
uint32_t temp_payload = 0;
|
||||
|
||||
for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
|
||||
|
||||
struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||
if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) {
|
||||
|
||||
for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
||||
|
||||
nr_csi_report_t *csi_report = &mac->csi_report_template[csi_reportconfig->reportConfigId];
|
||||
compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template);
|
||||
n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_reportconfig->reportConfigId);
|
||||
|
||||
int cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
|
||||
int rsrp_bitlen = csi_report->CSI_report_bitlen.rsrp_bitlen;
|
||||
int diff_rsrp_bitlen = csi_report->CSI_report_bitlen.diff_rsrp_bitlen;
|
||||
|
||||
if (cri_ssbri_bitlen > 0) {
|
||||
LOG_E(NR_MAC, "Implementation for cri_ssbri_bitlen>0 is not supported yet!\n");;
|
||||
}
|
||||
|
||||
// TODO: Improvements will be needed to cri_ssbri_bitlen>0
|
||||
// TS 38.133 - Table 10.1.6.1-1
|
||||
int rsrp_dBm = mac->csirs_measurements.rsrp_dBm;
|
||||
if (rsrp_dBm < -140) {
|
||||
temp_payload = 16;
|
||||
} else if (rsrp_dBm > -44) {
|
||||
temp_payload = 113;
|
||||
} else {
|
||||
temp_payload = mac->csirs_measurements.rsrp_dBm + 157;
|
||||
}
|
||||
|
||||
reverse_n_bits((uint8_t *)&temp_payload, n_bits);
|
||||
|
||||
LOG_D(NR_MAC, "cri_ssbri_bitlen = %d\n", cri_ssbri_bitlen);
|
||||
LOG_D(NR_MAC, "rsrp_bitlen = %d\n", rsrp_bitlen);
|
||||
LOG_D(NR_MAC, "diff_rsrp_bitlen = %d\n", diff_rsrp_bitlen);
|
||||
|
||||
LOG_D(NR_MAC, "n_bits = %d\n", n_bits);
|
||||
LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pucch->csi_part1_payload = temp_payload;
|
||||
return n_bits;
|
||||
}
|
||||
|
||||
// returns index from RSRP
|
||||
// according to Table 10.1.6.1-1 in 38.133
|
||||
@@ -3586,7 +3716,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
#endif
|
||||
*/
|
||||
|
||||
LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id);
|
||||
LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id);
|
||||
|
||||
break;
|
||||
case DL_SCH_LCID_CON_RES_ID:
|
||||
|
||||
@@ -1090,13 +1090,16 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
pusch_pdu->vrb_to_prb_mapping = 0;
|
||||
|
||||
pusch_pdu->frequency_hopping = fh;
|
||||
//pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
|
||||
//pusch_pdu->tx_direct_current_location;
|
||||
//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299,
|
||||
//which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300,
|
||||
//which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
|
||||
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
|
||||
//Resource Allocation in time domain
|
||||
pusch_pdu->start_symbol_index = start_symbol_index;
|
||||
pusch_pdu->nr_of_symbols = nr_of_symbols;
|
||||
//Optional Data only included if indicated in pduBitmap
|
||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round];
|
||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round%4];
|
||||
pusch_pdu->pusch_data.harq_process_id = 0;
|
||||
pusch_pdu->pusch_data.new_data_indicator = 1;
|
||||
pusch_pdu->pusch_data.num_cb = 0;
|
||||
@@ -1804,7 +1807,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
||||
pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
|
||||
pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx;
|
||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round];
|
||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round%4];
|
||||
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->nrOfLayers = 1;
|
||||
pdsch_pdu_rel15->transmissionScheme = 0;
|
||||
|
||||
@@ -285,7 +285,7 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
int nrOfSymbols,
|
||||
uint16_t dlDmrsSymbPos,
|
||||
uint8_t candidate_idx,
|
||||
int num_total_bytes) {
|
||||
uint16_t num_total_bytes) {
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
|
||||
@@ -437,7 +437,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
||||
pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs;
|
||||
pdsch_pdu_rel15->mcsTable[0] = 0;
|
||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0];
|
||||
pdsch_pdu_rel15->rvIndex[0] = 0;
|
||||
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->nrOfLayers = 1;
|
||||
pdsch_pdu_rel15->transmissionScheme = 0;
|
||||
@@ -570,7 +570,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
|
||||
// Get SIB1
|
||||
uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
|
||||
uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload);
|
||||
uint16_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload);
|
||||
LOG_D(NR_MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
|
||||
LOG_D(NR_MAC,"SIB1: \n");
|
||||
for (int k=0;k<sib1_sdu_length;k++)
|
||||
@@ -598,7 +598,8 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
startSymbolIndex,
|
||||
nrOfSymbols,
|
||||
dlDmrsSymbPos,
|
||||
candidate_idx, sib1_sdu_length);
|
||||
candidate_idx,
|
||||
sib1_sdu_length);
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
int pdu_index = gNB_mac->pdu_index[0]++;
|
||||
|
||||
@@ -642,7 +642,10 @@ void pf_dl(module_id_t module_id,
|
||||
const NR_bler_options_t *bo = &mac->dl_bler;
|
||||
const int max_mcs_table = ps->mcsTableIdx == 1 ? 27 : 28;
|
||||
const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table);
|
||||
sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame);
|
||||
if (bo->harq_round_max == 1)
|
||||
sched_pdsch->mcs = max_mcs;
|
||||
else
|
||||
sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame);
|
||||
UE->layers = set_dl_nrOfLayers(sched_ctrl);
|
||||
const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
@@ -926,8 +929,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
|
||||
return;
|
||||
|
||||
//if (slot==7 || slot == 17) return;
|
||||
|
||||
/* PREPROCESSOR */
|
||||
gNB_mac->pre_processor_dl(module_id, frame, slot);
|
||||
const int CC_id = 0;
|
||||
@@ -1016,7 +1017,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
TBS,
|
||||
current_harq_pid,
|
||||
harq->round,
|
||||
nr_rv_round_map[harq->round],
|
||||
nr_rv_round_map[harq->round%4],
|
||||
harq->ndi,
|
||||
pucch->timing_indicator,
|
||||
pucch->frame,
|
||||
@@ -1084,8 +1085,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs;
|
||||
pdsch_pdu->mcsTable[0] = ps->mcsTableIdx;
|
||||
AssertFatal(harq!=NULL,"harq is null\n");
|
||||
AssertFatal(harq->round<4,"%d",harq->round);
|
||||
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round];
|
||||
AssertFatal(harq->round<gNB_mac->dl_bler.harq_round_max,"%d",harq->round);
|
||||
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round%4];
|
||||
pdsch_pdu->TBSize[0] = TBS;
|
||||
pdsch_pdu->dataScramblingId = *scc->physCellId;
|
||||
pdsch_pdu->nrOfLayers = nrOfLayers;
|
||||
@@ -1119,9 +1120,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
csi_report->codebook_mode);
|
||||
}
|
||||
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
||||
long *maxMIMO_Layers = cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers;
|
||||
AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n");
|
||||
int nl_tbslbrm = *maxMIMO_Layers < 4 ? *maxMIMO_Layers : 4;
|
||||
long maxMIMO_Layers = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated ? *cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers : 1;
|
||||
int nl_tbslbrm = maxMIMO_Layers < 4 ? maxMIMO_Layers : 4;
|
||||
// Maximum number of PRBs across all configured DL BWPs
|
||||
int bw_tbslbrm = get_bw_tbslbrm(genericParameters, cg);
|
||||
pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(ps->mcsTableIdx,
|
||||
@@ -1317,7 +1317,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
lcid < 4 ? "DCCH" : "DTCH",
|
||||
lcid,
|
||||
ndata,
|
||||
bufEnd-buf-+sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
|
||||
if (len == 0)
|
||||
break;
|
||||
|
||||
@@ -1436,7 +1436,6 @@ void set_r_pucch_parms(int rsetindex,
|
||||
*start_symbol_index = default_pucch_firstsymb[rsetindex];
|
||||
}
|
||||
|
||||
|
||||
void prepare_dci(const NR_CellGroupConfig_t *CellGroup,
|
||||
dci_pdu_rel15_t *dci_pdu_rel15,
|
||||
nr_dci_format_t format,
|
||||
@@ -2386,7 +2385,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
|
||||
CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) {
|
||||
compute_csi_bitlen(CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
|
||||
compute_csi_bitlen(CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE->csi_report_template);
|
||||
}
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
@@ -2957,6 +2956,10 @@ void nr_mac_update_timers(module_id_t module_id,
|
||||
LOG_I(NR_MAC, "(%d.%d) Switching to initialUplinkBWP\n", frame, slot);
|
||||
}
|
||||
UE->Msg3_dcch_dtch = false;
|
||||
|
||||
// Schedule BWP switching to the first active BWP (previous active BWP before RA with Msg3 carrying DCCH or DTCH message)
|
||||
sched_ctrl->next_dl_bwp_id = current_bwp_id;
|
||||
sched_ctrl->next_ul_bwp_id = current_ubwp_id;
|
||||
} else if (spCellConfigDedicated &&
|
||||
spCellConfigDedicated->downlinkBWP_ToAddModList &&
|
||||
spCellConfigDedicated->uplinkConfig &&
|
||||
@@ -2969,6 +2972,19 @@ void nr_mac_update_timers(module_id_t module_id,
|
||||
if (*spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id != current_ubwp_id) {
|
||||
LOG_I(NR_MAC, "(%d.%d) Switching to UL-BWP %li\n", frame, slot, sched_ctrl->active_ubwp->bwp_Id);
|
||||
}
|
||||
|
||||
// Update next_dl_bwp_id to not trigger BWP switching, UE should be already on active_bwp
|
||||
sched_ctrl->next_dl_bwp_id = sched_ctrl->active_bwp->bwp_Id;
|
||||
// Update next_ul_bwp_id to not trigger BWP switching, UE should be already on active_ubwp
|
||||
sched_ctrl->next_ul_bwp_id = sched_ctrl->active_ubwp->bwp_Id;
|
||||
} else {
|
||||
sched_ctrl->active_bwp = NULL;
|
||||
sched_ctrl->active_ubwp = NULL;
|
||||
|
||||
// Update next_dl_bwp_id to not trigger BWP switching, UE should be already on Initial BWP
|
||||
sched_ctrl->next_dl_bwp_id = 0;
|
||||
// Update next_ul_bwp_id to not trigger BWP switching, UE should be already on Initial BWP
|
||||
sched_ctrl->next_ul_bwp_id = 0;
|
||||
}
|
||||
|
||||
// Update coreset/searchspace
|
||||
@@ -3002,7 +3018,7 @@ void nr_mac_update_timers(module_id_t module_id,
|
||||
cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) {
|
||||
compute_csi_bitlen (cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
|
||||
compute_csi_bitlen (cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE->csi_report_template);
|
||||
}
|
||||
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
@@ -3062,14 +3078,27 @@ void schedule_nr_bwp_switch(module_id_t module_id,
|
||||
|
||||
UE_iterator(UE_info->list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
if (sched_ctrl->rrc_processing_timer == 0 &&
|
||||
UE->Msg4_ACKed &&
|
||||
((sched_ctrl->next_dl_bwp_id >= 0 && sched_ctrl->active_bwp && sched_ctrl->active_bwp->bwp_Id != sched_ctrl->next_dl_bwp_id) ||
|
||||
(sched_ctrl->next_ul_bwp_id >= 0 && sched_ctrl->active_ubwp && sched_ctrl->active_ubwp->bwp_Id != sched_ctrl->next_ul_bwp_id))) {
|
||||
if (sched_ctrl->rrc_processing_timer == 0 && UE->Msg4_ACKed && sched_ctrl->next_dl_bwp_id >= 0) {
|
||||
|
||||
LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n",
|
||||
frame, slot, UE->rnti, sched_ctrl->active_bwp->bwp_Id, sched_ctrl->next_dl_bwp_id, sched_ctrl->active_ubwp->bwp_Id, sched_ctrl->next_ul_bwp_id);
|
||||
nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id);
|
||||
int schedule_bwp_switching = false;
|
||||
if (sched_ctrl->active_bwp == NULL) {
|
||||
// Switching from Initial BWP to Dedicated BWP
|
||||
if (sched_ctrl->next_dl_bwp_id > 0 && sched_ctrl->next_ul_bwp_id > 0) {
|
||||
schedule_bwp_switching = true;
|
||||
LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from Initial DL BWP to %ld and from Initial UL BWP to %ld\n",
|
||||
frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id);
|
||||
}
|
||||
} else if (sched_ctrl->active_bwp->bwp_Id != sched_ctrl->next_dl_bwp_id && sched_ctrl->active_ubwp->bwp_Id != sched_ctrl->next_ul_bwp_id) {
|
||||
// Switching between Dedicated BWPs
|
||||
schedule_bwp_switching = true;
|
||||
LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n",
|
||||
frame, slot, UE->rnti, sched_ctrl->active_bwp->bwp_Id, sched_ctrl->next_dl_bwp_id, sched_ctrl->active_ubwp->bwp_Id, sched_ctrl->next_ul_bwp_id);
|
||||
}
|
||||
|
||||
if (schedule_bwp_switching) {
|
||||
AssertFatal(sched_ctrl->next_dl_bwp_id > 0 && sched_ctrl->next_ul_bwp_id > 0, "BWP switching from a Dedicated BWP to the Initial BWP not handled yet!");
|
||||
nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,530 +169,6 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Calculating number of bits set
|
||||
uint8_t number_of_bits_set (uint8_t buf){
|
||||
uint8_t nb_of_bits_set = 0;
|
||||
uint8_t mask = 0xff;
|
||||
uint8_t index = 0;
|
||||
|
||||
for (index=7; (buf & mask) && (index>=0) ; index--){
|
||||
if (buf & (1<<index))
|
||||
nb_of_bits_set++;
|
||||
|
||||
mask>>=1;
|
||||
}
|
||||
return nb_of_bits_set;
|
||||
}
|
||||
|
||||
|
||||
void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t nb_resources,
|
||||
nr_csi_report_t *csi_report) {
|
||||
|
||||
if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) {
|
||||
if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
|
||||
csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1;
|
||||
else
|
||||
/*! From Spec 38.331
|
||||
* nrofReportedRS
|
||||
* The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE
|
||||
* capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report.
|
||||
* When the field is absent the UE applies the value 1
|
||||
*/
|
||||
csi_report->CSI_report_bitlen.nb_ssbri_cri= 1;
|
||||
} else
|
||||
csi_report->CSI_report_bitlen.nb_ssbri_cri= 2;
|
||||
|
||||
if (nb_resources) {
|
||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources));
|
||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
} else {
|
||||
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0;
|
||||
csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
|
||||
csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
nr_csi_report_t *csi_report){
|
||||
|
||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||
uint8_t nb_allowed_ri, ri_bitlen;
|
||||
uint8_t ri_restriction = 0;
|
||||
|
||||
if (codebookConfig == NULL) {
|
||||
csi_report->csi_meas_bitlen.ri_bitlen=0;
|
||||
return ri_restriction;
|
||||
}
|
||||
|
||||
// codebook type1 single panel
|
||||
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){
|
||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
|
||||
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){
|
||||
|
||||
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
||||
|
||||
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
||||
ri_bitlen = ceil(log2(nb_allowed_ri));
|
||||
|
||||
ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
|
||||
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
||||
}
|
||||
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){
|
||||
if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present ==
|
||||
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
|
||||
// 4 ports
|
||||
|
||||
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
||||
|
||||
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
||||
ri_bitlen = ceil(log2(nb_allowed_ri));
|
||||
|
||||
ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
|
||||
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
||||
}
|
||||
else {
|
||||
// more than 4 ports
|
||||
|
||||
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
|
||||
|
||||
nb_allowed_ri = number_of_bits_set(ri_restriction);
|
||||
ri_bitlen = ceil(log2(nb_allowed_ri));
|
||||
|
||||
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
|
||||
}
|
||||
}
|
||||
return ri_restriction;
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report){
|
||||
|
||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||
for(int i=0; i<8; i++) {
|
||||
if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0)
|
||||
csi_report->csi_meas_bitlen.li_bitlen[i]=0;
|
||||
else {
|
||||
// codebook type1 single panel
|
||||
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present)
|
||||
csi_report->csi_meas_bitlen.li_bitlen[i]=ceil(log2(i+1))<2?ceil(log2(i+1)):2;
|
||||
else
|
||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2,
|
||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo) {
|
||||
|
||||
// Table 5.2.2.2.1-2 in 38.214 for supported configurations
|
||||
switch(morethantwo->n1_n2.present){
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 2;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 2;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 3;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 6;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 8;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_three_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 3;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_twelve_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 12;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_four_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 4;
|
||||
*n2 = 4;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_two_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 8;
|
||||
*n2 = 2;
|
||||
*o1 = 4;
|
||||
*o2 = 4;
|
||||
break;
|
||||
case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_sixteen_one_TypeI_SinglePanel_Restriction):
|
||||
*n1 = 16;
|
||||
*n2 = 1;
|
||||
*o1 = 4;
|
||||
*o2 = 1;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Not supported configuration for n1_n2 in codebook configuration");
|
||||
}
|
||||
}
|
||||
|
||||
void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2,
|
||||
int *x1, int *x2, int rank, int codebook_mode) {
|
||||
|
||||
// Table 6.3.1.1.2-1 in 38.212
|
||||
switch(rank){
|
||||
case 1:
|
||||
if(n2>1) {
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 2;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2));
|
||||
*x2 = 4;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 2;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2));
|
||||
*x2 = 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(n1*n2 == 2) {
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2));
|
||||
*x2 = 3;
|
||||
}
|
||||
*x1 += 1;
|
||||
}
|
||||
else {
|
||||
if(n2>1) {
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 3;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2));
|
||||
*x2 = 3;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (codebook_mode == 1) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1/2));
|
||||
*x2 = 3;
|
||||
}
|
||||
}
|
||||
*x1 += 2;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
if(n1*n2 == 2) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
if(n1*n2 >= 8) {
|
||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)) + 2;
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)) + 2;
|
||||
*x2 = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
if(n1 == 4 && n2 == 1) {
|
||||
*x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
if(n1 > 2 && n2 == 2) {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2/2));
|
||||
*x2 = 1;
|
||||
}
|
||||
else {
|
||||
*x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2));
|
||||
*x2 = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid rank in x1 x2 bit length computation\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report){
|
||||
|
||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||
for(int i=0; i<8; i++) {
|
||||
csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=0;
|
||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=0;
|
||||
if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0)
|
||||
return;
|
||||
else {
|
||||
if(codebookConfig->codebookType.present == NR_CodebookConfig__codebookType_PR_type1) {
|
||||
if(codebookConfig->codebookType.choice.type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) {
|
||||
if(codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present ==
|
||||
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) {
|
||||
csi_report->N1 = 1;
|
||||
csi_report->N2 = 1;
|
||||
if (i==0)
|
||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=2;
|
||||
if (i==1)
|
||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=1;
|
||||
}
|
||||
else { // more than two
|
||||
int n1,n2,o1,o2,x1,x2;
|
||||
get_n1n2_o1o2_singlepanel(&n1,&n2,&o1,&o2,codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo);
|
||||
get_x1x2_bitlen_singlepanel(n1,n2,o1,o2,&x1,&x2,i+1,codebookConfig->codebookType.choice.type1->codebookMode);
|
||||
csi_report->N1 = n1;
|
||||
csi_report->N2 = n2;
|
||||
csi_report->codebook_mode = codebookConfig->codebookType.choice.type1->codebookMode;
|
||||
csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=x1;
|
||||
csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=x2;
|
||||
}
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Type1 Multi-panel Codebook Config not yet implemented\n");
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Type2 Codebook Config not yet implemented\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
uint8_t ri_restriction,
|
||||
nr_csi_report_t *csi_report){
|
||||
|
||||
struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
|
||||
struct NR_CSI_ReportConfig__reportFreqConfiguration *freq_config = csi_reportconfig->reportFreqConfiguration;
|
||||
|
||||
if (*freq_config->cqi_FormatIndicator == NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI) {
|
||||
for(int i=0; i<8; i++) {
|
||||
if ((ri_restriction>>i)&0x01) {
|
||||
csi_report->csi_meas_bitlen.cqi_bitlen[i] = 4;
|
||||
if(codebookConfig != NULL) {
|
||||
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present){
|
||||
struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
|
||||
if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo) {
|
||||
if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present >
|
||||
NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
|
||||
// more than 4 antenna ports
|
||||
if (i > 4)
|
||||
csi_report->csi_meas_bitlen.cqi_bitlen[i] += 4; // CQI for second TB
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
csi_report->csi_meas_bitlen.cqi_bitlen[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Sub-band CQI reporting not yet supported");
|
||||
}
|
||||
|
||||
//!TODO : same function can be written to handle csi_resources
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE){
|
||||
uint8_t csi_report_id = 0;
|
||||
uint8_t nb_resources = 0;
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId;
|
||||
struct NR_CSI_ResourceConfig *csi_resourceconfig;
|
||||
|
||||
// for each CSI measurement report configuration (list of CSI-ReportConfig)
|
||||
LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count);
|
||||
for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||
// MAC structure for CSI measurement reports (per UE and per report)
|
||||
nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
|
||||
// csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration
|
||||
// (either CSI-RS or SSB)
|
||||
csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
||||
// looking for CSI-ResourceConfig
|
||||
int found_resource = 0;
|
||||
int csi_resourceidx = 0;
|
||||
while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) {
|
||||
csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||
if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId)
|
||||
found_resource = 1;
|
||||
csi_resourceidx++;
|
||||
}
|
||||
AssertFatal(found_resource==1,"Not able to found any CSI-ResourceConfig with csi-ResourceConfigId %ld\n",
|
||||
csi_ResourceConfigId);
|
||||
|
||||
long resourceType = csi_resourceconfig->resourceType;
|
||||
|
||||
reportQuantity_type = csi_reportconfig->reportQuantity.present;
|
||||
csi_report->reportQuantity_type = reportQuantity_type;
|
||||
|
||||
// setting the CSI or SSB index list
|
||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) {
|
||||
for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId ==
|
||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
|
||||
//We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
|
||||
nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count;
|
||||
csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array;
|
||||
csi_report->CSI_Index_list = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) {
|
||||
AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL,
|
||||
"Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n");
|
||||
for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) {
|
||||
if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
|
||||
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
|
||||
//For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212
|
||||
nb_resources = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.count;
|
||||
csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.array;
|
||||
csi_report->SSB_Index_list = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else AssertFatal(1==0,"Only periodic resource configuration currently supported\n");
|
||||
}
|
||||
LOG_D(NR_MAC,"nb_resources %d\n",nb_resources);
|
||||
// computation of bit length depending on the report type
|
||||
switch(reportQuantity_type){
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP):
|
||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP):
|
||||
compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI):
|
||||
csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
|
||||
csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report);
|
||||
compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Not yet supported CSI report quantity type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t nr_get_csi_bitlen(NR_UE_info_t *UE,
|
||||
uint8_t csi_report_id) {
|
||||
|
||||
uint16_t csi_bitlen = 0;
|
||||
uint16_t max_bitlen = 0;
|
||||
L1_RSRP_bitlen_t * CSI_report_bitlen = NULL;
|
||||
CSI_Meas_bitlen_t * csi_meas_bitlen = NULL;
|
||||
|
||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type||
|
||||
NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type){
|
||||
CSI_report_bitlen = &(UE->csi_report_template[csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
|
||||
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
|
||||
(CSI_report_bitlen->nb_ssbri_cri -1 )));
|
||||
} else{
|
||||
csi_meas_bitlen = &(UE->csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
uint16_t temp_bitlen;
|
||||
for (int i=0; i<8; i++) {
|
||||
temp_bitlen = (csi_meas_bitlen->cri_bitlen+
|
||||
csi_meas_bitlen->ri_bitlen+
|
||||
csi_meas_bitlen->li_bitlen[i]+
|
||||
csi_meas_bitlen->cqi_bitlen[i]+
|
||||
csi_meas_bitlen->pmi_x1_bitlen[i]+
|
||||
csi_meas_bitlen->pmi_x2_bitlen[i]);
|
||||
if(temp_bitlen>max_bitlen)
|
||||
max_bitlen = temp_bitlen;
|
||||
}
|
||||
csi_bitlen += max_bitlen;
|
||||
}
|
||||
|
||||
return csi_bitlen;
|
||||
}
|
||||
|
||||
|
||||
void nr_csi_meas_reporting(int Mod_idP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
@@ -700,7 +176,6 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
|
||||
|
||||
UE_iterator(RC.nrmac[Mod_idP]->UE_info.list, UE ) {
|
||||
const NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
@@ -760,7 +235,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
curr_pucch->frame = frame;
|
||||
curr_pucch->ul_slot = sched_slot;
|
||||
curr_pucch->resource_indicator = res_index;
|
||||
curr_pucch->csi_bits += nr_get_csi_bitlen(UE,csi_report_id);
|
||||
curr_pucch->csi_bits += nr_get_csi_bitlen(UE->csi_report_template, csi_report_id);
|
||||
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
@@ -824,7 +299,6 @@ static void handle_dl_harq(NR_UE_info_t * UE,
|
||||
add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid);
|
||||
harq->round = 0;
|
||||
harq->ndi ^= 1;
|
||||
|
||||
} else if (harq->round >= harq_round_max - 1) {
|
||||
abort_nr_dl_harq(UE, harq_pid);
|
||||
LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, UE->mac_stats.dl.errors);
|
||||
@@ -1177,7 +651,6 @@ void evaluate_rsrp_report(NR_UE_info_t *UE,
|
||||
stats->num_rsrp_meas++;
|
||||
}
|
||||
|
||||
|
||||
void evaluate_cri_report(uint8_t *payload,
|
||||
uint8_t cri_bitlen,
|
||||
int cumul_bits,
|
||||
@@ -1456,7 +929,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
|
||||
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
|
||||
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
|
||||
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max);
|
||||
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max);
|
||||
if (!harq) {
|
||||
LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__);
|
||||
break;
|
||||
@@ -1465,7 +938,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
|
||||
handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->harq_round_max);
|
||||
handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->dl_bler.harq_round_max);
|
||||
if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++;
|
||||
}
|
||||
}
|
||||
@@ -1518,13 +991,13 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
// iterate over received harq bits
|
||||
for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
|
||||
const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01;
|
||||
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max);
|
||||
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max);
|
||||
if (!harq)
|
||||
break;
|
||||
DevAssert(harq->is_waiting);
|
||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->harq_round_max);
|
||||
handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->dl_bler.harq_round_max);
|
||||
}
|
||||
}
|
||||
if ((uci_234->pduBitmap >> 2) & 0x01) {
|
||||
@@ -1593,7 +1066,6 @@ bool test_acknack_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// this function returns an index to NR_sched_pucch structure
|
||||
// currently this structure contains PUCCH0 at index 0 and PUCCH2 at index 1
|
||||
// if the function returns -1 it was not possible to schedule acknack
|
||||
@@ -1662,7 +1134,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
&& csi_pucch->csi_bits > 0
|
||||
&& csi_pucch->frame == f
|
||||
&& csi_pucch->ul_slot == s))
|
||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
|
||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
|
||||
|
||||
memset(pucch, 0, sizeof(*pucch));
|
||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||
@@ -1735,7 +1207,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
csi_pucch->csi_bits > 0 &&
|
||||
csi_pucch->frame == f &&
|
||||
csi_pucch->ul_slot == s))
|
||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
|
||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
|
||||
memset(pucch, 0, sizeof(*pucch));
|
||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||
if(((s + 1)%nr_slots_period) == 0)
|
||||
@@ -1837,7 +1309,6 @@ int nr_acknack_scheduling(int mod_id,
|
||||
// FIXME currently we support at most 11 bits in pucch2 so skip also in that case
|
||||
if(!csi_pucch->simultaneous_harqcsi
|
||||
|| ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) {
|
||||
|
||||
LOG_D(NR_MAC,"Cannot multiplex csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot);
|
||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, csi_pucch, UE);
|
||||
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
||||
|
||||
@@ -336,38 +336,41 @@ int nr_process_mac_pdu( instance_t module_idP,
|
||||
|
||||
case UL_SCH_LCID_DTCH ... (UL_SCH_LCID_DTCH + 28):
|
||||
// check if LCID is valid at current time.
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return 0;
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n",
|
||||
UE->rnti,
|
||||
frameP,
|
||||
slot,
|
||||
rx_lcid<4?"DCCH":"DTCH",
|
||||
rx_lcid,
|
||||
module_idP,
|
||||
mac_len);
|
||||
UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len;
|
||||
LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n",
|
||||
UE->rnti,
|
||||
frameP,
|
||||
slot,
|
||||
rx_lcid<4?"DCCH":"DTCH",
|
||||
rx_lcid,
|
||||
module_idP,
|
||||
mac_len);
|
||||
UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len;
|
||||
|
||||
mac_rlc_data_ind(module_idP,
|
||||
UE->rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
rx_lcid,
|
||||
(char *)(pduP + mac_subheader_len),
|
||||
mac_len,
|
||||
1,
|
||||
NULL);
|
||||
mac_rlc_data_ind(module_idP,
|
||||
UE->rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
rx_lcid,
|
||||
(char *)(pduP + mac_subheader_len),
|
||||
mac_len,
|
||||
1,
|
||||
NULL);
|
||||
|
||||
/* Updated estimated buffer when receiving data */
|
||||
if (sched_ctrl->estimated_ul_buffer >= mac_len)
|
||||
sched_ctrl->estimated_ul_buffer -= mac_len;
|
||||
else
|
||||
sched_ctrl->estimated_ul_buffer = 0;
|
||||
break;
|
||||
/* Updated estimated buffer when receiving data */
|
||||
if (sched_ctrl->estimated_ul_buffer >= mac_len) {
|
||||
sched_ctrl->estimated_ul_buffer -= mac_len;
|
||||
} else {
|
||||
sched_ctrl->estimated_ul_buffer = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(NR_MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid);
|
||||
@@ -402,7 +405,7 @@ int nr_process_mac_pdu( instance_t module_idP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void abort_nr_ul_harq( NR_UE_info_t* UE, int8_t harq_pid)
|
||||
void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid)
|
||||
{
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid];
|
||||
@@ -452,7 +455,7 @@ void handle_nr_ul_harq(const int CC_idP,
|
||||
remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
|
||||
sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false;
|
||||
|
||||
if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->harq_round_max - 1) {
|
||||
if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) {
|
||||
abort_nr_ul_harq(UE, harq_pid);
|
||||
} else {
|
||||
sched_ctrl->ul_harq_processes[harq_pid].round++;
|
||||
@@ -473,7 +476,7 @@ void handle_nr_ul_harq(const int CC_idP,
|
||||
harq_pid,
|
||||
crc_pdu->rnti);
|
||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
|
||||
} else if (harq->round >= RC.nrmac[mod_id]->harq_round_max - 1) {
|
||||
} else if (harq->round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) {
|
||||
abort_nr_ul_harq(UE, harq_pid);
|
||||
LOG_D(NR_MAC,
|
||||
"RNTI %04x: Ulharq id %d crc failed in all rounds\n",
|
||||
@@ -546,7 +549,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
else{
|
||||
LOG_D(NR_MAC,"[UE %04x] Detected DTX : increasing UE TX power\n",UE->rnti);
|
||||
UE_scheduling_control->tpc0 = 1;
|
||||
|
||||
}
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
@@ -749,14 +751,13 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
return;
|
||||
}
|
||||
|
||||
if (ra->msg3_round >= MAX_HARQ_ROUNDS - 1) {
|
||||
LOG_D(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state);
|
||||
if (ra->msg3_round >= gNB_mac->ul_bler.harq_round_max - 1) {
|
||||
LOG_W(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i);
|
||||
|
||||
ra->msg3_round++;
|
||||
@@ -846,10 +847,8 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc,
|
||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
const int now = frame * n + slot;
|
||||
|
||||
|
||||
const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl;
|
||||
|
||||
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd =
|
||||
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
int num_slots_per_period;
|
||||
@@ -1071,7 +1070,7 @@ static int comparator(const void *p, const void *q) {
|
||||
void pf_ul(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
NR_UE_info_t *UE_list[],
|
||||
NR_UE_info_t *UE_list[],
|
||||
int max_num_ue,
|
||||
int n_rb_sched,
|
||||
uint16_t *rballoc_mask) {
|
||||
@@ -1132,10 +1131,11 @@ void pf_ul(module_id_t module_id,
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
remainUEs--;
|
||||
|
||||
// we have filled all with mandatory retransmissions
|
||||
// no need to schedule new transmissions
|
||||
if (remainUEs == 0)
|
||||
// we have filled all with mandatory retransmissions
|
||||
// no need to schedule new transmissions
|
||||
return;
|
||||
return;
|
||||
|
||||
continue;
|
||||
}
|
||||
const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
|
||||
@@ -1143,12 +1143,16 @@ void pf_ul(module_id_t module_id,
|
||||
const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_pusch->frame, sched_pusch->slot, nrmac->ulsch_max_frame_inactivity);
|
||||
|
||||
LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n",UE->rnti,do_sched ? "yes" : "no");
|
||||
if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0))
|
||||
if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0)) {
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
const NR_bler_options_t *bo = &nrmac->ul_bler;
|
||||
const int max_mcs = bo->max_mcs; /* no per-user maximum MCS yet */
|
||||
sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame);
|
||||
if (bo->harq_round_max == 1)
|
||||
sched_pusch->mcs = max_mcs;
|
||||
else
|
||||
sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame);
|
||||
|
||||
/* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled
|
||||
* based on data to transmit) */
|
||||
@@ -1158,12 +1162,12 @@ void pf_ul(module_id_t module_id,
|
||||
const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti);
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
@@ -1172,18 +1176,19 @@ void pf_ul(module_id_t module_id,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti);
|
||||
continue;
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
remainUEs--;
|
||||
|
||||
|
||||
// we have filled all with mandatory retransmissions
|
||||
// no need to schedule new transmissions
|
||||
if (remainUEs == 0)
|
||||
// we have filled all with mandatory retransmissions
|
||||
// no need to schedule new transmissions
|
||||
return;
|
||||
return;
|
||||
|
||||
/* Save PUSCH field */
|
||||
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
||||
@@ -1278,7 +1283,7 @@ void pf_ul(module_id_t module_id,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0)
|
||||
break;
|
||||
break;
|
||||
}
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
@@ -1379,8 +1384,8 @@ void pf_ul(module_id_t module_id,
|
||||
|
||||
n_rb_sched -= sched_pusch->rbSize;
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
||||
|
||||
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap;
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
remainUEs--;
|
||||
iterator++;
|
||||
@@ -1400,8 +1405,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing :
|
||||
scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
||||
|
||||
// no UEs
|
||||
if (nr_mac->UE_info.list[0] == NULL)
|
||||
// no UEs
|
||||
return false;
|
||||
|
||||
const int CC_id = 0;
|
||||
@@ -1448,8 +1453,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
UE_iterator(nr_mac->UE_info.list, UE2) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl;
|
||||
AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu),
|
||||
"Different K2, %d(UE%d) != %ld(UE%04x)\n",
|
||||
K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE2->rnti);
|
||||
"Different K2, %d(UE%d) != %ld(UE%04x)\n", K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE2->rnti);
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
}
|
||||
@@ -1626,7 +1630,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
|
||||
|
||||
/* Statistics */
|
||||
AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round);
|
||||
AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round);
|
||||
UE->mac_stats.ul.rounds[cur_harq->round]++;
|
||||
if (cur_harq->round == 0) {
|
||||
UE->mac_stats.ulsch_total_bytes_scheduled += sched_pusch->tb_size;
|
||||
@@ -1672,7 +1676,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
sched_pusch->tb_size,
|
||||
harq_id,
|
||||
cur_harq->round,
|
||||
nr_rv_round_map[cur_harq->round],
|
||||
nr_rv_round_map[cur_harq->round%4],
|
||||
cur_harq->ndi,
|
||||
sched_ctrl->estimated_ul_buffer,
|
||||
sched_ctrl->sched_ul_bytes,
|
||||
@@ -1768,8 +1772,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
pusch_pdu->nr_of_symbols = ps->nrOfSymbols;
|
||||
|
||||
/* PUSCH PDU */
|
||||
AssertFatal(cur_harq->round < 4, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round);
|
||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
|
||||
AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round%4);
|
||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round%4];
|
||||
pusch_pdu->pusch_data.harq_process_id = harq_id;
|
||||
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
|
||||
pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size;
|
||||
|
||||
@@ -93,7 +93,7 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
int nrOfSymbols,
|
||||
uint16_t dlDmrsSymbPos,
|
||||
uint8_t candidate_idx,
|
||||
int num_total_bytes);
|
||||
uint16_t num_total_bytes);
|
||||
|
||||
/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
|
||||
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id);
|
||||
@@ -201,7 +201,7 @@ void config_uldci(const NR_SIB1_t *sib1,
|
||||
int n_ubwp,
|
||||
int bwp_id);
|
||||
|
||||
void nr_schedule_pucch(gNB_MAC_INST* nrmac,
|
||||
void nr_schedule_pucch(gNB_MAC_INST *nrmac,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP);
|
||||
|
||||
@@ -216,12 +216,12 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP);
|
||||
|
||||
int nr_acknack_scheduling( int Mod_idP,
|
||||
NR_UE_info_t * UE,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int r_pucch,
|
||||
int do_common);
|
||||
int nr_acknack_scheduling(int Mod_idP,
|
||||
NR_UE_info_t *UE,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int r_pucch,
|
||||
int do_common);
|
||||
|
||||
void get_pdsch_to_harq_feedback(NR_UE_info_t *,
|
||||
int bwp_id,
|
||||
@@ -410,8 +410,6 @@ void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti);
|
||||
|
||||
int nr_get_default_pucch_res(int pucch_ResourceCommon);
|
||||
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE);
|
||||
|
||||
int get_dlscs(nfapi_nr_config_request_t *cfg);
|
||||
|
||||
int get_ulscs(nfapi_nr_config_request_t *cfg);
|
||||
|
||||
@@ -105,17 +105,21 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
||||
end - output,
|
||||
"UE %04x: CQI %d, RI %d, PMI (%d,%d)\n",
|
||||
UE->rnti,
|
||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb,
|
||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.ri+1,
|
||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1,
|
||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb,
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.ri+1,
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1,
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
|
||||
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"UE %04x: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
|
||||
UE->rnti,
|
||||
stats->dl.rounds[0], stats->dl.rounds[1],
|
||||
stats->dl.rounds[2], stats->dl.rounds[3],
|
||||
"UE %04x: dlsch_rounds ", UE->rnti);
|
||||
output += snprintf(output, end - output, "%"PRIu64, stats->dl.rounds[0]);
|
||||
for (int i = 1; i < gNB->dl_bler.harq_round_max; i++)
|
||||
output += snprintf(output, end - output, "/%"PRIu64, stats->dl.rounds[i]);
|
||||
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
|
||||
stats->dl.errors,
|
||||
stats->pucch0_DTX,
|
||||
sched_ctrl->dl_bler_stats.bler,
|
||||
@@ -127,23 +131,27 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"UE %04x: dlsch_total_bytes %"PRIu64"\n",
|
||||
UE->rnti,
|
||||
stats->dl.total_bytes);
|
||||
UE->rnti, stats->dl.total_bytes);
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"UE %04x: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n",
|
||||
UE->rnti,
|
||||
stats->ul.rounds[0], stats->ul.rounds[1],
|
||||
stats->ul.rounds[2], stats->ul.rounds[3],
|
||||
"UE %04x: ulsch_rounds ", UE->rnti);
|
||||
output += snprintf(output, end - output, "%"PRIu64, stats->ul.rounds[0]);
|
||||
for (int i = 1; i < gNB->ul_bler.harq_round_max; i++)
|
||||
output += snprintf(output, end - output, "/%"PRIu64, stats->ul.rounds[i]);
|
||||
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n",
|
||||
stats->ulsch_DTX,
|
||||
stats->ul.errors,
|
||||
sched_ctrl->ul_bler_stats.bler,
|
||||
sched_ctrl->ul_bler_stats.mcs);
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
|
||||
UE->rnti,
|
||||
stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes);
|
||||
"UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
|
||||
UE->rnti,
|
||||
stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes);
|
||||
|
||||
for (int lc_id = 0; lc_id < 63; lc_id++) {
|
||||
if (stats->dl.lc_bytes[lc_id] > 0)
|
||||
output += snprintf(output,
|
||||
|
||||
@@ -75,7 +75,6 @@
|
||||
#define MAX_NUM_BWP 5
|
||||
#define MAX_NUM_CORESET 12
|
||||
#define MAX_NUM_CCE 90
|
||||
#define MAX_HARQ_ROUNDS 4
|
||||
/*!\brief Maximum number of random access process */
|
||||
#define NR_NB_RA_PROC_MAX 4
|
||||
#define MAX_NUM_OF_SSB 64
|
||||
@@ -509,38 +508,6 @@ struct CSI_Report {
|
||||
|
||||
#define MAX_SR_BITLEN 8
|
||||
|
||||
typedef struct {
|
||||
uint8_t nb_ssbri_cri;
|
||||
uint8_t cri_ssbri_bitlen;
|
||||
uint8_t rsrp_bitlen;
|
||||
uint8_t diff_rsrp_bitlen;
|
||||
}L1_RSRP_bitlen_t;
|
||||
|
||||
typedef struct{
|
||||
uint8_t ri_restriction;
|
||||
uint8_t cri_bitlen;
|
||||
uint8_t ri_bitlen;
|
||||
uint8_t li_bitlen[8];
|
||||
uint8_t pmi_x1_bitlen[8];
|
||||
uint8_t pmi_x2_bitlen[8];
|
||||
uint8_t cqi_bitlen[8];
|
||||
} CSI_Meas_bitlen_t;
|
||||
|
||||
typedef struct nr_csi_report {
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||
long periodicity;
|
||||
uint16_t offset;
|
||||
long ** SSB_Index_list;
|
||||
long ** CSI_Index_list;
|
||||
// uint8_t nb_of_nzp_csi_report;
|
||||
uint8_t nb_of_csi_ssb_report;
|
||||
L1_RSRP_bitlen_t CSI_report_bitlen;
|
||||
CSI_Meas_bitlen_t csi_meas_bitlen;
|
||||
int codebook_mode;
|
||||
int N1;
|
||||
int N2;
|
||||
} nr_csi_report_t;
|
||||
|
||||
/*! As per the spec 38.212 and table: 6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report
|
||||
the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE
|
||||
From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set
|
||||
@@ -700,10 +667,10 @@ typedef struct NR_bler_options {
|
||||
double upper;
|
||||
double lower;
|
||||
uint8_t max_mcs;
|
||||
uint8_t harq_round_max;
|
||||
} NR_bler_options_t;
|
||||
|
||||
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
|
||||
#define MAX_CSI_REPORTCONFIG 48
|
||||
typedef struct {
|
||||
rnti_t rnti;
|
||||
/// scheduling control info
|
||||
@@ -854,7 +821,6 @@ typedef struct gNB_MAC_INST_s {
|
||||
bool first_MIB;
|
||||
NR_bler_options_t dl_bler;
|
||||
NR_bler_options_t ul_bler;
|
||||
uint8_t harq_round_max;
|
||||
uint8_t min_grant_prb;
|
||||
uint8_t min_grant_mcs;
|
||||
} gNB_MAC_INST;
|
||||
|
||||
@@ -1103,6 +1103,10 @@ int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *u
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t handle_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements) {
|
||||
return nr_ue_process_csirs_measurements(module_id, frame, slot, csirs_measurements);
|
||||
}
|
||||
|
||||
void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack) {
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
@@ -1228,7 +1232,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_length,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_start_subcarrier,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB;
|
||||
free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu);
|
||||
free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu);
|
||||
break;
|
||||
case FAPI_NR_RX_PDU_TYPE_SIB:
|
||||
ret_mask |= (handle_bcch_dlsch(dl_info->module_id,
|
||||
@@ -1243,6 +1247,12 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
case FAPI_NR_RX_PDU_TYPE_RAR:
|
||||
ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
|
||||
break;
|
||||
case FAPI_NR_CSIRS_IND:
|
||||
ret_mask |= (handle_csirs_measurements(dl_info->module_id,
|
||||
dl_info->frame,
|
||||
dl_info->slot,
|
||||
&(dl_info->rx_ind->rx_indication_body+i)->csirs_measurements)) << FAPI_NR_CSIRS_IND;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -49,102 +49,6 @@
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
int generate_pdcch_ConfigSIB1(NR_PDCCH_ConfigSIB1_t *pdcch_ConfigSIB1,
|
||||
long ssbSubcarrierSpacing,
|
||||
long subCarrierSpacingCommon,
|
||||
channel_bandwidth_t min_channel_bw) {
|
||||
|
||||
nr_ssb_and_cset_mux_pattern_type_t mux_pattern = 0;
|
||||
|
||||
switch (ssbSubcarrierSpacing) {
|
||||
|
||||
case NR_SubcarrierSpacing_kHz15:
|
||||
if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_1_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_1_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_2_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_2_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid subCarrierSpacingCommon\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_SubcarrierSpacing_kHz30:
|
||||
if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) {
|
||||
|
||||
if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_3_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_3_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (min_channel_bw == bw_40MHz) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_5_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_5_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid min_bandwidth\n");
|
||||
}
|
||||
|
||||
} else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) {
|
||||
|
||||
if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_4_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_4_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (min_channel_bw == bw_40MHz) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_6_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_6_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid min_bandwidth\n");
|
||||
}
|
||||
|
||||
} else {
|
||||
AssertFatal(true,"Invalid subCarrierSpacingCommon\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_SubcarrierSpacing_kHz120:
|
||||
if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_7_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_7_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_8_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_8_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid subCarrierSpacingCommon\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_SubcarrierSpacing_kHz240:
|
||||
if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_9_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_9_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_10_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_10_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid subCarrierSpacingCommon\n");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(true,"Invalid ssbSubcarrierSpacing\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
frequency_range_t frequency_range = FR1;
|
||||
if(ssbSubcarrierSpacing>=60) {
|
||||
frequency_range = FR2;
|
||||
}
|
||||
|
||||
pdcch_ConfigSIB1->searchSpaceZero = 0;
|
||||
if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR1){
|
||||
pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_11_NUM_INDEXES;
|
||||
}
|
||||
if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR2){
|
||||
pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_12_NUM_INDEXES;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nr_rrc_mac_remove_ue(module_id_t mod_idP,
|
||||
@@ -227,14 +131,6 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
|
||||
rrc_gNB_carrier_data_t *carrier = &RC.nrrrc[Mod_idP]->carrier;
|
||||
NR_BCCH_BCH_Message_t *mib = &carrier->mib;
|
||||
|
||||
// Currently we are getting the pdcch_ConfigSIB1 from the configuration file.
|
||||
// Uncomment this function for a dynamic pdcch_ConfigSIB1.
|
||||
//channel_bandwidth_t min_channel_bw = bw_10MHz; // Must be obtained based on TS 38.101-1 Table 5.3.5-1
|
||||
//generate_pdcch_ConfigSIB1(carrier->pdcch_ConfigSIB1,
|
||||
// *carrier->servingcellconfigcommon->ssbSubcarrierSpacing,
|
||||
// carrier->mib.message.choice.mib->subCarrierSpacingCommon,
|
||||
// min_channel_bw);
|
||||
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = carrier->pdcch_ConfigSIB1->controlResourceSetZero;
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = carrier->pdcch_ConfigSIB1->searchSpaceZero;
|
||||
|
||||
|
||||
@@ -306,9 +306,8 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) {
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
gNB_RrcConfigurationReq *configuration
|
||||
) {
|
||||
uint16_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration) {
|
||||
|
||||
asn_enc_rval_t enc_rval;
|
||||
|
||||
NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t));
|
||||
@@ -661,12 +660,9 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
(void *)sib1_message,
|
||||
carrier->SIB1,
|
||||
NR_MAX_SIB_LENGTH/8);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
if (enc_rval.encoded==-1) {
|
||||
return(-1);
|
||||
}
|
||||
AssertFatal(enc_rval.encoded <= NR_MAX_SIB_LENGTH, "ASN1 encoded length %zd bits. 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.\n", enc_rval.encoded);
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
@@ -73,9 +73,7 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,
|
||||
@param carrier pointer to Carrier information
|
||||
@param configuration Pointer Configuration Request structure
|
||||
@return size of encoded bit stream in bytes*/
|
||||
uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
gNB_RrcConfigurationReq *configuration
|
||||
);
|
||||
uint16_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration);
|
||||
|
||||
uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
gNB_RrcConfigurationReq *configuration);
|
||||
|
||||
@@ -548,7 +548,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
|
||||
pusch_timedomainresourceallocation->k2 = CALLOC(1,sizeof(long));
|
||||
*pusch_timedomainresourceallocation->k2 = k2;
|
||||
pusch_timedomainresourceallocation->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
|
||||
pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(0,13);
|
||||
pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(0,13);
|
||||
ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation);
|
||||
|
||||
if(frame_type==TDD) {
|
||||
@@ -780,7 +780,8 @@ void scheduling_request_config(NR_ServingCellConfigCommon_t *scc,
|
||||
ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
|
||||
}
|
||||
|
||||
void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
|
||||
void set_dl_mcs_table(int scs,
|
||||
NR_UE_NR_Capability_t *cap,
|
||||
NR_SpCellConfig_t *SpCellConfig,
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
|
||||
NR_ServingCellConfigCommon_t *scc) {
|
||||
@@ -820,7 +821,7 @@ void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
|
||||
if(bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
|
||||
bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table));
|
||||
*bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256;
|
||||
// set table 2 in correct entry in SpCellConfig->spCellConfigDedicated->csi_MeasConfig->csi_ReportConfigToAddModList->list
|
||||
// set table 2 in correct entry in SpCellConfig->spCellConfigDedicated->csi_MeasConfig->csi_ReportConfigToAddModList->list
|
||||
AssertFatal(SpCellConfig!=NULL,"SpCellConfig shouldn't be null\n");
|
||||
AssertFatal(SpCellConfig->spCellConfigDedicated!=NULL,"SpCellConfigDedicated shouldn't be null\n");
|
||||
if (SpCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
||||
|
||||
@@ -138,7 +138,8 @@ void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config,
|
||||
const NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
const int uid,
|
||||
const int do_srs);
|
||||
void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
|
||||
void set_dl_mcs_table(int scs,
|
||||
NR_UE_NR_Capability_t *cap,
|
||||
NR_SpCellConfig_t *SpCellConfig,
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
|
||||
NR_ServingCellConfigCommon_t *scc);
|
||||
|
||||
@@ -435,7 +435,7 @@ typedef struct {
|
||||
uint8_t sizeof_MIB;
|
||||
|
||||
uint8_t *SIB1;
|
||||
uint8_t sizeof_SIB1;
|
||||
uint16_t sizeof_SIB1;
|
||||
|
||||
uint8_t *SIB23;
|
||||
uint8_t sizeof_SIB23;
|
||||
|
||||
+23
-20
@@ -1768,15 +1768,16 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
}
|
||||
}
|
||||
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
/* Save e RAB information for later */
|
||||
memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
|
||||
|
||||
for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
|
||||
if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) {
|
||||
create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
|
||||
create_tunnel_req.incoming_rb_id[j] = i+1;
|
||||
create_tunnel_req.outgoing_teid[j] = ue_context_pP->ue_context.pduSession[i].param.gtp_teid;
|
||||
// to be developped, use the first QFI only
|
||||
create_tunnel_req.outgoing_qfi[j] = ue_context_pP->ue_context.pduSession[i].param.qos[0].qfi;
|
||||
memcpy(create_tunnel_req.dst_addr[j].buffer,
|
||||
ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer,
|
||||
sizeof(uint8_t)*20);
|
||||
@@ -2806,8 +2807,6 @@ rrc_gNB_decode_dcch(
|
||||
SRBs[0].lcid = 2;
|
||||
|
||||
/*Instruction towards the DU for DRB configuration and tunnel creation*/
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
||||
memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
|
||||
req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t));
|
||||
req->drbs_to_be_setup_length = 1;
|
||||
f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup;
|
||||
@@ -3434,14 +3433,16 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha
|
||||
addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8;
|
||||
extern instance_t DUuniqInstance;
|
||||
if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id;
|
||||
incoming_teid=newGtpuCreateTunnel(DUuniqInstance,
|
||||
req->rnti,
|
||||
drb_p.drb_id,
|
||||
drb_p.drb_id,
|
||||
drb_p.up_ul_tnl[0].teid,
|
||||
addr,
|
||||
drb_p.up_ul_tnl[0].port,
|
||||
DURecvCb);
|
||||
incoming_teid = newGtpuCreateTunnel(DUuniqInstance,
|
||||
req->rnti,
|
||||
drb_p.drb_id,
|
||||
drb_p.drb_id,
|
||||
drb_p.up_ul_tnl[0].teid,
|
||||
-1, // no qfi
|
||||
addr,
|
||||
drb_p.up_ul_tnl[0].port,
|
||||
DURecvCb,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3573,14 +3574,16 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co
|
||||
memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address));
|
||||
addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8;
|
||||
extern instance_t DUuniqInstance;
|
||||
incoming_teid=newGtpuCreateTunnel(DUuniqInstance,
|
||||
req->rnti,
|
||||
drb_p.drb_id,
|
||||
drb_p.drb_id,
|
||||
drb_p.up_ul_tnl[0].teid,
|
||||
addr,
|
||||
drb_p.up_ul_tnl[0].port,
|
||||
DURecvCb);
|
||||
incoming_teid = newGtpuCreateTunnel(DUuniqInstance,
|
||||
req->rnti,
|
||||
drb_p.drb_id,
|
||||
drb_p.drb_id,
|
||||
drb_p.up_ul_tnl[0].teid,
|
||||
-1, // no qfi
|
||||
addr,
|
||||
drb_p.up_ul_tnl[0].port,
|
||||
DURecvCb,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -474,7 +474,6 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
protocol_ctxt_t ctxt={0};
|
||||
uint8_t pdu_sessions_done = 0;
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp;
|
||||
uint8_t inde_list[NR_NB_RB_MAX - 3]= {0};
|
||||
int ret = 0;
|
||||
@@ -503,7 +502,7 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
|
||||
uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
|
||||
if (nb_pdusessions_tosetup != 0) {
|
||||
memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
|
||||
if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
|
||||
continue;
|
||||
@@ -512,6 +511,8 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].pdusession_id;
|
||||
create_tunnel_req.incoming_rb_id[pdu_sessions_done] = i+1;
|
||||
create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid;
|
||||
// To be developped: hardcoded first flow
|
||||
create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].qos[0].qfi;
|
||||
create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length;
|
||||
memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer,
|
||||
NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.buffer,
|
||||
@@ -1003,6 +1004,7 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
||||
create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id;
|
||||
create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1;
|
||||
create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid;
|
||||
create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].qos[0].qfi;
|
||||
memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer,
|
||||
NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer,
|
||||
sizeof(uint8_t)*20);
|
||||
|
||||
Reference in New Issue
Block a user