Merge remote-tracking branch 'oai-eurecom/develop' into NR_MAC_SSB_RO_UE_IDCC
This commit is contained in:
@@ -65,18 +65,6 @@
|
||||
#define MAX_NR_RRC_UE_CONTEXTS 64
|
||||
|
||||
#ifndef UE_EXPANSION
|
||||
// TODO:L2 FAPI simulator.
|
||||
// UESIM_EXPANSION is used to be same value of MAX_MOBILES_PER_ENB
|
||||
// in eNB and UE.
|
||||
// now , if we use --mu option in UE, compiling error will occur.
|
||||
// This problem will be fixed in the future.
|
||||
#ifdef UESIM_EXPANSION
|
||||
#define MAX_MOBILES_PER_ENB 256
|
||||
#define MAX_MOBILES_PER_ENB_NB_IoT 256
|
||||
#define MAX_MOBILES_PER_GNB 256
|
||||
#define MAX_eNB 2
|
||||
#define MAX_gNB 2
|
||||
#else
|
||||
#ifdef LARGE_SCALE
|
||||
#define MAX_MOBILES_PER_ENB 128
|
||||
#define MAX_MOBILES_PER_ENB_NB_IoT 128
|
||||
@@ -90,7 +78,6 @@
|
||||
#define MAX_eNB 2
|
||||
#define MAX_gNB 2
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define MAX_MOBILES_PER_ENB 256
|
||||
#define MAX_MOBILES_PER_ENB_NB_IoT 256
|
||||
|
||||
@@ -1469,7 +1469,7 @@ nr_bandentry_t nr_bandtable[] = {
|
||||
{5, 824000, 849000, 869000, 894000, 20, 173800, 100},
|
||||
{7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100},
|
||||
{8, 880000, 915000, 925000, 960000, 20, 185000, 100},
|
||||
{12, 698000, 716000, 728000, 746000, 20, 145800, 100},
|
||||
{12, 698000, 716000, 729000, 746000, 20, 145800, 100},
|
||||
{20, 832000, 862000, 791000, 821000, 20, 158200, 100},
|
||||
{25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100},
|
||||
{28, 703000, 758000, 758000, 813000, 20, 151600, 100},
|
||||
@@ -1491,22 +1491,22 @@ nr_bandentry_t nr_bandtable[] = {
|
||||
{77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30},
|
||||
{78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15},
|
||||
{78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30},
|
||||
{79, 4400000, 5000000, 4400000, 5000000, 1, 693334, 15},
|
||||
{79, 4400000, 5000000, 4400000, 5000000, 2, 693334, 30},
|
||||
{79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15},
|
||||
{79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30},
|
||||
{80, 1710000, 1785000, 000, 000, 20, 342000, 100},
|
||||
{81, 860000, 915000, 000, 000, 20, 176000, 100},
|
||||
{81, 880000, 915000, 000, 000, 20, 176000, 100},
|
||||
{82, 832000, 862000, 000, 000, 20, 166400, 100},
|
||||
{83, 703000, 748000, 000, 000, 20, 140600, 100},
|
||||
{84, 1920000, 1980000, 000, 000, 20, 384000, 100},
|
||||
{86, 1710000, 1785000, 000, 000, 20, 342000, 100},
|
||||
{257,26500000,29500000,26500000,29500000, 1,2054166, 60},
|
||||
{257,26500000,29500000,26500000,29500000, 2,2054167, 120},
|
||||
{258,24250000,27500000,24250000,27500000, 1,2016667, 60},
|
||||
{258,24250000,27500000,24250000,27500000, 2,2016667, 120},
|
||||
{260,37000000,40000000,37000000,40000000, 1,2229166, 60},
|
||||
{260,37000000,40000000,37000000,40000000, 2,2229167, 120},
|
||||
{261,27500000,28350000,27500000,28350000, 1,2070833, 60},
|
||||
{261,27500000,28350000,27500000,28350000, 2,2070833, 120}
|
||||
{257,26500020,29500000,26500020,29500000, 1,2054166, 60},
|
||||
{257,26500080,29500000,26500080,29500000, 2,2054167, 120},
|
||||
{258,24250080,27500000,24250080,27500000, 1,2016667, 60},
|
||||
{258,24250080,27500000,24250080,27500000, 2,2016667, 120},
|
||||
{260,37000020,40000000,37000020,40000000, 1,2229166, 60},
|
||||
{260,37000080,40000000,37000080,40000000, 2,2229167, 120},
|
||||
{261,27500040,28350000,27500040,28350000, 1,2070833, 60},
|
||||
{261,27500040,28350000,27500040,28350000, 2,2070833, 120}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +63,11 @@
|
||||
#include "NR_PhysicalCellGroupConfig.h"
|
||||
#include "NR_CellGroupConfig.h"
|
||||
#include "NR_ServingCellConfig.h"
|
||||
|
||||
#include "NR_MeasConfig.h"
|
||||
#include "fapi_nr_ue_interface.h"
|
||||
#include "NR_IF_Module.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h"
|
||||
|
||||
#define NB_NR_UE_MAC_INST 1
|
||||
/*!\brief Maximum number of logical channl group IDs */
|
||||
@@ -158,6 +162,7 @@ typedef struct {
|
||||
NR_CellGroupConfig_t *scg;
|
||||
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated;
|
||||
int servCellIndex;
|
||||
NR_CSI_ReportConfig_t *csirc;
|
||||
//// MAC config
|
||||
NR_DRX_Config_t *drx_Config;
|
||||
NR_SchedulingRequestConfig_t *schedulingRequestConfig;
|
||||
|
||||
@@ -1214,7 +1214,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
// first_symbol_index = 0;
|
||||
// }
|
||||
// 38.213 chapter 13: over two consecutive slots
|
||||
// search_space_duration = 2;
|
||||
//search_space_duration = 2;
|
||||
}
|
||||
|
||||
/// MUX PATTERN 2
|
||||
|
||||
@@ -315,6 +315,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
|
||||
}
|
||||
|
||||
|
||||
|
||||
int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
int ssb_SubcarrierOffset,
|
||||
int pdsch_AntennaPorts,
|
||||
@@ -367,6 +368,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
if (add_ue == 1 && get_softmodem_params()->phy_test) {
|
||||
const int UE_id = add_new_nr_ue(Mod_idP,rnti);
|
||||
UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
|
||||
compute_csi_bitlen (secondaryCellGroup, UE_info, UE_id);
|
||||
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
|
||||
AssertFatal(bwpList->list.count == 1,
|
||||
|
||||
@@ -344,9 +344,8 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP) {
|
||||
|
||||
uint16_t O_uci;
|
||||
uint16_t O_ack;
|
||||
uint8_t SR_flag = 0; // no SR in PUCCH implemented for now
|
||||
uint16_t O_csi, O_ack, O_uci;
|
||||
uint8_t O_sr = 0; // no SR in PUCCH implemented for now
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
|
||||
@@ -359,31 +358,36 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
NR_sched_pucch *curr_pucch;
|
||||
|
||||
for (int k=0; k<nr_ulmix_slots; k++) {
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k];
|
||||
if ((curr_pucch->dai_c > 0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
|
||||
UL_tti_req->SFN = curr_pucch->frame;
|
||||
UL_tti_req->Slot = curr_pucch->ul_slot;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu;
|
||||
memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t));
|
||||
UL_tti_req->n_pdus+=1;
|
||||
for (int l=0; l<2; l++) {
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l];
|
||||
O_ack = curr_pucch->dai_c;
|
||||
O_uci = O_ack; // for now we are just sending acknacks in pucch
|
||||
O_csi = curr_pucch->csi_bits;
|
||||
O_uci = O_ack + O_csi + O_sr;
|
||||
if ((O_uci>0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
|
||||
UL_tti_req->SFN = curr_pucch->frame;
|
||||
UL_tti_req->Slot = curr_pucch->ul_slot;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu;
|
||||
memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t));
|
||||
UL_tti_req->n_pdus+=1;
|
||||
|
||||
LOG_D(MAC, "Scheduling pucch reception for frame %d slot %d\n", frameP, slotP);
|
||||
LOG_I(MAC,"Scheduling pucch reception for frame %d slot %d with (%d, %d, %d) (SR ACK, CSI) bits\n",
|
||||
frameP,slotP,O_sr,O_ack,curr_pucch->csi_bits);
|
||||
|
||||
nr_configure_pucch(pucch_pdu,
|
||||
scc,
|
||||
ubwp,
|
||||
curr_pucch->resource_indicator,
|
||||
O_uci,
|
||||
O_ack,
|
||||
SR_flag);
|
||||
nr_configure_pucch(pucch_pdu,
|
||||
scc,
|
||||
ubwp,
|
||||
UE_info->rnti[UE_id],
|
||||
curr_pucch->resource_indicator,
|
||||
O_csi,
|
||||
O_ack,
|
||||
O_sr);
|
||||
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -395,6 +399,7 @@ bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot){
|
||||
|
||||
protocol_ctxt_t ctxt;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
|
||||
|
||||
@@ -411,19 +416,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity);
|
||||
const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
|
||||
|
||||
if (slot == 0 && UE_info->active[UE_id]) {
|
||||
for (int k=0; k<nr_ulmix_slots; k++) {
|
||||
/* Seems to be covered 384? */
|
||||
/*memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));*/
|
||||
/* Seems to be covered in line 335? */
|
||||
/*memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pusch));*/
|
||||
}
|
||||
}
|
||||
|
||||
start_meas(&RC.nrmac[module_idP]->eNB_scheduler);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
|
||||
|
||||
@@ -466,8 +458,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
// This schedule SR
|
||||
// TODO
|
||||
|
||||
// This schedule CSI
|
||||
// TODO
|
||||
// This schedule CSI measurement reporting
|
||||
if (UE_info->active[UE_id])
|
||||
nr_csi_meas_reporting(module_idP, UE_id, frame, slot, num_slots_per_tdd, nr_ulmix_slots, slots_per_frame[*scc->ssbSubcarrierSpacing]);
|
||||
|
||||
// This schedule RA procedure if not in phy_test mode
|
||||
// Otherwise already consider 5G already connected
|
||||
|
||||
@@ -343,68 +343,98 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
|
||||
return offset;
|
||||
}
|
||||
|
||||
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10) {
|
||||
void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234,
|
||||
NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) {
|
||||
|
||||
// TODO
|
||||
int max_harq_rounds = 4; // TODO define macro
|
||||
int num_ucis = UL_info->uci_ind.num_ucis;
|
||||
nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
|
||||
|
||||
for (int i = 0; i < num_ucis; i++) {
|
||||
switch (uci_list[i].pdu_type) {
|
||||
case NFAPI_NR_UCI_PDCCH_PDU_TYPE: break;
|
||||
if (uci_01 != NULL) {
|
||||
// handle harq
|
||||
int harq_idx_s = 0;
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
|
||||
//if (get_softmodem_params()->phy_test == 0) {
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
|
||||
// handle harq
|
||||
int harq_idx_s = 0;
|
||||
// tpc (power control)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
|
||||
// iterate over received harq bits
|
||||
for (int harq_bit = 0; harq_bit < uci_pdu->harq->num_harq; harq_bit++) {
|
||||
// search for the right harq process
|
||||
for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES; harq_idx++) {
|
||||
// if the gNB received ack with a good confidence
|
||||
if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
|
||||
if ((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) &&
|
||||
(uci_pdu->harq->harq_confidence_level == 0)) {
|
||||
// toggle NDI and reset round
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
}
|
||||
else
|
||||
sched_ctrl->harq_processes[harq_idx].round++;
|
||||
sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
|
||||
harq_idx_s = harq_idx + 1;
|
||||
// if the max harq rounds was reached
|
||||
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
stats->dlsch_errors++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if feedback slot processing is aborted
|
||||
else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) &&
|
||||
(sched_ctrl->harq_processes[harq_idx].is_waiting)) {
|
||||
sched_ctrl->harq_processes[harq_idx].round++;
|
||||
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
}
|
||||
sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
|
||||
}
|
||||
}
|
||||
// iterate over received harq bits
|
||||
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
|
||||
// search for the right harq process
|
||||
for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES; harq_idx++) {
|
||||
// if the gNB received ack with a good confidence
|
||||
if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
|
||||
if ((uci_01->harq->harq_list[harq_bit].harq_value == 1) &&
|
||||
(uci_01->harq->harq_confidence_level == 0)) {
|
||||
// toggle NDI and reset round
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
}
|
||||
//}
|
||||
break;
|
||||
else
|
||||
sched_ctrl->harq_processes[harq_idx].round++;
|
||||
sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
|
||||
harq_idx_s = harq_idx + 1;
|
||||
// if the max harq rounds was reached
|
||||
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
stats->dlsch_errors++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if feedback slot processing is aborted
|
||||
else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) &&
|
||||
(sched_ctrl->harq_processes[harq_idx].is_waiting)) {
|
||||
sched_ctrl->harq_processes[harq_idx].round++;
|
||||
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
}
|
||||
sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
|
||||
}
|
||||
}
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: break;
|
||||
}
|
||||
}
|
||||
|
||||
UL_info->uci_ind.num_ucis = 0;
|
||||
|
||||
if (uci_234 != NULL) {
|
||||
int harq_idx_s = 0;
|
||||
int acknack;
|
||||
|
||||
// iterate over received harq bits
|
||||
for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
|
||||
acknack = ((uci_234->harq.harq_payload[harq_bit>>3])>>harq_bit)&0x01;
|
||||
for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) {
|
||||
// if the gNB received ack with a good confidence or if the max harq rounds was reached
|
||||
if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
|
||||
// TODO add some confidence level for when there is no CRC
|
||||
if ((uci_234->harq.harq_crc != 1) && acknack) {
|
||||
// toggle NDI and reset round
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
}
|
||||
else
|
||||
sched_ctrl->harq_processes[harq_idx].round++;
|
||||
sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
|
||||
harq_idx_s = harq_idx + 1;
|
||||
// if the max harq rounds was reached
|
||||
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
stats->dlsch_errors++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if feedback slot processing is aborted
|
||||
else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) &&
|
||||
(sched_ctrl->harq_processes[harq_idx].is_waiting)) {
|
||||
sched_ctrl->harq_processes[harq_idx].round++;
|
||||
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
}
|
||||
sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) {
|
||||
@@ -505,8 +535,14 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
|
||||
/* Find PUCCH occasion */
|
||||
nr_update_pucch_scheduling(
|
||||
module_id, UE_id, frame, slot, num_slots_per_tdd, &sched_ctrl->pucch_sched_idx);
|
||||
nr_acknack_scheduling(module_id,
|
||||
UE_id,
|
||||
frame,
|
||||
slot,
|
||||
num_slots_per_tdd,
|
||||
&sched_ctrl->pucch_sched_idx,
|
||||
&sched_ctrl->pucch_occ_idx);
|
||||
|
||||
AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n");
|
||||
|
||||
uint8_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
@@ -634,7 +670,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
|
||||
const int current_harq_pid = sched_ctrl->current_harq_pid;
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx];
|
||||
NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx][sched_ctrl->pucch_occ_idx];
|
||||
harq->feedback_slot = pucch->ul_slot;
|
||||
harq->is_waiting = 1;
|
||||
UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
|
||||
|
||||
@@ -369,7 +369,6 @@ int configure_fapi_dl_pdu_phytest(int Mod_idP,
|
||||
dci_pdu_rel15[0].ndi = UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi;
|
||||
// DAI
|
||||
dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3;
|
||||
|
||||
// TPC for PUCCH
|
||||
dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213
|
||||
// PUCCH resource indicator
|
||||
|
||||
@@ -735,10 +735,11 @@ void nr_configure_pdcch(gNB_MAC_INST *nr_mac,
|
||||
void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_Uplink_t *bwp,
|
||||
uint16_t rnti,
|
||||
uint8_t pucch_resource,
|
||||
uint16_t O_uci,
|
||||
uint16_t O_csi,
|
||||
uint16_t O_ack,
|
||||
uint8_t SR_flag) {
|
||||
uint8_t O_sr) {
|
||||
|
||||
NR_PUCCH_Config_t *pucch_Config;
|
||||
NR_PUCCH_Resource_t *pucchres;
|
||||
@@ -753,6 +754,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
|
||||
pucch_pdu->bit_len_harq = O_ack;
|
||||
|
||||
uint16_t O_uci = O_csi + O_ack;
|
||||
|
||||
if (bwp) { // This is not the InitialBWP
|
||||
|
||||
NR_PUSCH_Config_t *pusch_Config = bwp->bwp_Dedicated->pusch_Config->choice.setup;
|
||||
@@ -815,7 +818,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
else
|
||||
AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci);
|
||||
}
|
||||
else {
|
||||
if (pucchresset->pucch_ResourceSetId == 1 && O_uci>2) {
|
||||
N3 = pucchresset->maxPayloadMinus1!= NULL ? *pucchresset->maxPayloadMinus1 : 1706;
|
||||
if (N2<O_uci && N3>O_uci) {
|
||||
if (pucch_resource < n_list)
|
||||
@@ -841,6 +844,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
if (pucchres->pucch_ResourceId == *resource_id) {
|
||||
res_found = 1;
|
||||
pucch_pdu->prb_start = pucchres->startingPRB;
|
||||
pucch_pdu->rnti = rnti;
|
||||
// FIXME why there is only one frequency hopping flag
|
||||
// what about inter slot frequency hopping?
|
||||
pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ? 1 : 0;
|
||||
@@ -851,7 +855,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format0->initialCyclicShift;
|
||||
pucch_pdu->nr_of_symbols = pucchres->format.choice.format0->nrofSymbols;
|
||||
pucch_pdu->start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex;
|
||||
pucch_pdu->sr_flag = SR_flag;
|
||||
pucch_pdu->sr_flag = O_sr;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format1 :
|
||||
pucch_pdu->format_type = 1;
|
||||
@@ -859,21 +863,23 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
pucch_pdu->nr_of_symbols = pucchres->format.choice.format1->nrofSymbols;
|
||||
pucch_pdu->start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex;
|
||||
pucch_pdu->time_domain_occ_idx = pucchres->format.choice.format1->timeDomainOCC;
|
||||
pucch_pdu->sr_flag = SR_flag;
|
||||
pucch_pdu->sr_flag = O_sr;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format2 :
|
||||
pucch_pdu->format_type = 2;
|
||||
pucch_pdu->nr_of_symbols = pucchres->format.choice.format2->nrofSymbols;
|
||||
pucch_pdu->start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex;
|
||||
pucch_pdu->prb_size = pucchres->format.choice.format2->nrofPRBs;
|
||||
pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
|
||||
pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : *scc->physCellId;
|
||||
pucch_pdu->prb_size = compute_pucch_prb_size(2,pucchres->format.choice.format2->nrofPRBs,
|
||||
O_uci+O_sr,O_csi,pucch_Config->format2->choice.setup->maxCodeRate,
|
||||
2,pucchres->format.choice.format2->nrofSymbols,8);
|
||||
pucch_pdu->bit_len_csi_part1 = O_csi;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format3 :
|
||||
pucch_pdu->format_type = 3;
|
||||
pucch_pdu->nr_of_symbols = pucchres->format.choice.format3->nrofSymbols;
|
||||
pucch_pdu->start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex;
|
||||
pucch_pdu->prb_size = pucchres->format.choice.format3->nrofPRBs;
|
||||
pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
|
||||
if (pucch_Config->format3 == NULL) {
|
||||
pucch_pdu->pi_2bpsk = 0;
|
||||
@@ -884,6 +890,19 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0;
|
||||
pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0;
|
||||
}
|
||||
int f3_dmrs_symbols;
|
||||
if (pucchres->format.choice.format3->nrofSymbols==4)
|
||||
f3_dmrs_symbols = 1<<pucch_pdu->freq_hop_flag;
|
||||
else {
|
||||
if(pucchres->format.choice.format3->nrofSymbols<10)
|
||||
f3_dmrs_symbols = 2;
|
||||
else
|
||||
f3_dmrs_symbols = 2<<pucch_pdu->add_dmrs_flag;
|
||||
}
|
||||
pucch_pdu->prb_size = compute_pucch_prb_size(3,pucchres->format.choice.format3->nrofPRBs,
|
||||
O_uci+O_sr,O_csi,pucch_Config->format3->choice.setup->maxCodeRate,
|
||||
2-pucch_pdu->pi_2bpsk,pucchres->format.choice.format3->nrofSymbols-f3_dmrs_symbols,12);
|
||||
pucch_pdu->bit_len_csi_part1 = O_csi;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format4 :
|
||||
pucch_pdu->format_type = 4;
|
||||
@@ -901,6 +920,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0;
|
||||
pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0;
|
||||
}
|
||||
pucch_pdu->bit_len_csi_part1 = O_csi;
|
||||
break;
|
||||
default :
|
||||
AssertFatal(1==0,"Undefined PUCCH format \n");
|
||||
@@ -916,6 +936,84 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
}
|
||||
|
||||
|
||||
uint16_t compute_pucch_prb_size(uint8_t format,
|
||||
uint8_t nr_prbs,
|
||||
uint16_t O_tot,
|
||||
uint16_t O_csi,
|
||||
NR_PUCCH_MaxCodeRate_t *maxCodeRate,
|
||||
uint8_t Qm,
|
||||
uint8_t n_symb,
|
||||
uint8_t n_re_ctrl) {
|
||||
|
||||
uint16_t O_crc;
|
||||
|
||||
if (O_tot<12)
|
||||
O_crc = 0;
|
||||
else{
|
||||
if (O_tot<20)
|
||||
O_crc = 6;
|
||||
else {
|
||||
if (O_tot<360)
|
||||
O_crc = 11;
|
||||
else
|
||||
AssertFatal(1==0,"Case for segmented PUCCH not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
int rtimes100;
|
||||
switch(*maxCodeRate){
|
||||
case NR_PUCCH_MaxCodeRate_zeroDot08 :
|
||||
rtimes100 = 8;
|
||||
break;
|
||||
case NR_PUCCH_MaxCodeRate_zeroDot15 :
|
||||
rtimes100 = 15;
|
||||
break;
|
||||
case NR_PUCCH_MaxCodeRate_zeroDot25 :
|
||||
rtimes100 = 25;
|
||||
break;
|
||||
case NR_PUCCH_MaxCodeRate_zeroDot35 :
|
||||
rtimes100 = 35;
|
||||
break;
|
||||
case NR_PUCCH_MaxCodeRate_zeroDot45 :
|
||||
rtimes100 = 45;
|
||||
break;
|
||||
case NR_PUCCH_MaxCodeRate_zeroDot60 :
|
||||
rtimes100 = 60;
|
||||
break;
|
||||
case NR_PUCCH_MaxCodeRate_zeroDot80 :
|
||||
rtimes100 = 80;
|
||||
break;
|
||||
default :
|
||||
AssertFatal(1==0,"Invalid MaxCodeRate");
|
||||
}
|
||||
|
||||
float r = (float)rtimes100/100;
|
||||
|
||||
if (O_csi == O_tot) {
|
||||
if ((O_tot+O_csi)>(nr_prbs*n_re_ctrl*n_symb*Qm*r))
|
||||
AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with %d PRBs",
|
||||
r,O_tot,O_crc,nr_prbs);
|
||||
else
|
||||
return nr_prbs;
|
||||
}
|
||||
|
||||
if (format==2){
|
||||
// TODO fix this for multiple CSI reports
|
||||
for (int i=1; i<=nr_prbs; i++){
|
||||
if((O_tot+O_crc)<=(i*n_symb*Qm*n_re_ctrl*r) &&
|
||||
(O_tot+O_crc)>((i-1)*n_symb*Qm*n_re_ctrl*r))
|
||||
return i;
|
||||
}
|
||||
AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with at most %d PRBs",
|
||||
r,O_tot,O_crc,nr_prbs);
|
||||
}
|
||||
else{
|
||||
AssertFatal(1==0,"Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
dci_pdu_rel15_t *dci_pdu_rel15,
|
||||
nr_dci_format_t format,
|
||||
@@ -1686,15 +1784,21 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id],
|
||||
0,
|
||||
sizeof(NR_UE_sched_ctrl_t));
|
||||
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_timer = 100;
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_update = 31;
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_rssi = 0;
|
||||
UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch));
|
||||
UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch **)malloc(num_slots_ul*sizeof(NR_sched_pucch *));
|
||||
for (int s=0; s<num_slots_ul;s++)
|
||||
UE_info->UE_sched_ctrl[UE_id].sched_pucch[s] = (NR_sched_pucch *)malloc(2*sizeof(NR_sched_pucch));
|
||||
UE_info->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch));
|
||||
|
||||
for (int k=0; k<num_slots_ul; k++) {
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
for (int l=0; l<2; l++)
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pusch));
|
||||
@@ -1817,50 +1921,302 @@ void get_pdsch_to_harq_feedback(int Mod_idP,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t nr_get_csi_bitlen(int Mod_idP,
|
||||
int UE_id,
|
||||
uint8_t csi_report_id) {
|
||||
|
||||
uint16_t csi_bitlen =0;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
CRI_SSBRI_RSRP_bitlen_t * CSI_report_bitlen = NULL;
|
||||
|
||||
CSI_report_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0]);
|
||||
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 )) *UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report);
|
||||
|
||||
return csi_bitlen;
|
||||
}
|
||||
|
||||
|
||||
void csi_period_offset(NR_CSI_ReportConfig_t *csirep,
|
||||
int *period, int *offset) {
|
||||
|
||||
NR_CSI_ReportPeriodicityAndOffset_PR p_and_o = csirep->reportConfigType.choice.periodic->reportSlotConfig.present;
|
||||
|
||||
switch(p_and_o){
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots4:
|
||||
*period = 4;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots4;
|
||||
break;
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots5:
|
||||
*period = 5;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots5;
|
||||
break;
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots8:
|
||||
*period = 8;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots8;
|
||||
break;
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots10:
|
||||
*period = 10;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots10;
|
||||
break;
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots16:
|
||||
*period = 16;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots16;
|
||||
break;
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots20:
|
||||
*period = 20;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots20;
|
||||
break;
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots40:
|
||||
*period = 40;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots40;
|
||||
break;
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots80:
|
||||
*period = 80;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots80;
|
||||
break;
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots160:
|
||||
*period = 160;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots160;
|
||||
break;
|
||||
case NR_CSI_ReportPeriodicityAndOffset_PR_slots320:
|
||||
*period = 320;
|
||||
*offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"No periodicity and offset resource found in CSI report");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//!TODO : same function can be written to handle csi_resources
|
||||
void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t *UE_info, int UE_id) {
|
||||
uint8_t csi_report_id = 0;
|
||||
uint8_t csi_resourceidx =0;
|
||||
uint8_t csi_ssb_idx =0;
|
||||
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
|
||||
NR_CSI_ResourceConfigId_t csi_ResourceConfigId;
|
||||
for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||
csi_ResourceConfigId=csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->resourcesForChannelMeasurement;
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->reportQuantity.present;
|
||||
|
||||
for ( csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
|
||||
if ( csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_ResourceConfigId != csi_ResourceConfigId)
|
||||
continue;
|
||||
else {
|
||||
//Finding the CSI_RS or SSB Resources
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_Resource_type= csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.present;
|
||||
if (NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB ==UE_info->csi_report_template[UE_id][csi_report_id].CSI_Resource_type){
|
||||
struct NR_CSI_ResourceConfig__csi_RS_ResourceSetList__nzp_CSI_RS_SSB * nzp_CSI_RS_SSB = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB;
|
||||
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].nb_of_nzp_csi_report = nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.count:0;
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report = nzp_CSI_RS_SSB->csi_SSB_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.count:0;
|
||||
}
|
||||
|
||||
if (0 != UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report){
|
||||
uint8_t nb_ssb_resources =0;
|
||||
for ( csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) {
|
||||
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId ==
|
||||
*(csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->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
|
||||
if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled ==
|
||||
csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.present ) {
|
||||
if (NULL != csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri = *(csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->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
|
||||
*/
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri= 1;
|
||||
}else
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri= 2;
|
||||
|
||||
nb_ssb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count;
|
||||
if (nb_ssb_resources){
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen =ceil(log2 (nb_ssb_resources));
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
|
||||
}
|
||||
else{
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen =0;
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen = 0;
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =0;
|
||||
}
|
||||
|
||||
LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d",
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen,
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen,
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen);
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0 != UE_info->csi_report_template[UE_id][csi_report_id].nb_of_nzp_csi_report){
|
||||
AssertFatal(1==0,"Currently configuring only SSB beamreporting.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nr_csi_meas_reporting(int Mod_idP,
|
||||
int UE_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int slots_per_tdd,
|
||||
int ul_slots,
|
||||
int n_slots_frame) {
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_sched_pucch *curr_pucch;
|
||||
NR_PUCCH_ResourceSet_t *pucchresset;
|
||||
NR_CSI_ReportConfig_t *csirep;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
|
||||
NR_CSI_MeasConfig_t *csi_measconfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
|
||||
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];
|
||||
NR_PUCCH_Config_t *pucch_Config = ubwp->bwp_Dedicated->pucch_Config->choice.setup;
|
||||
|
||||
AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count>0,"NO CSI report configuration available");
|
||||
|
||||
for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||
|
||||
csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||
|
||||
AssertFatal(csirep->reportConfigType.choice.periodic!=NULL,"Only periodic CSI reporting is implemented currently");
|
||||
int period, offset, sched_slot;
|
||||
csi_period_offset(csirep,&period,&offset);
|
||||
sched_slot = (period+offset)%n_slots_frame;
|
||||
// prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214
|
||||
// preparation is done in first slot of tdd period
|
||||
if ( (frame%(period/n_slots_frame)==(offset/n_slots_frame)) && (slot==((sched_slot/slots_per_tdd)*slots_per_tdd))) {
|
||||
|
||||
// we are scheduling pucch for csi in the first pucch occasion (this comes before ack/nack)
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[sched_slot-slots_per_tdd+ul_slots][0];
|
||||
|
||||
NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0];
|
||||
|
||||
int found = -1;
|
||||
pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1
|
||||
int n_list = pucchresset->resourceList.list.count;
|
||||
for (int i=0; i<n_list; i++) {
|
||||
if (*pucchresset->resourceList.list.array[i] == pucchcsires->pucch_Resource)
|
||||
found = i;
|
||||
}
|
||||
AssertFatal(found>-1,"CSI resource not found among PUCCH resources");
|
||||
|
||||
curr_pucch->resource_indicator = found;
|
||||
|
||||
n_list = pucch_Config->resourceToAddModList->list.count;
|
||||
|
||||
// going through the list of PUCCH resources to find the one indexed by resource_id
|
||||
for (int i=0; i<n_list; i++) {
|
||||
NR_PUCCH_Resource_t *pucchres = pucch_Config->resourceToAddModList->list.array[i];
|
||||
if (pucchres->pucch_ResourceId == *pucchresset->resourceList.list.array[found]) {
|
||||
switch(pucchres->format.present){
|
||||
case NR_PUCCH_Resource__format_PR_format2:
|
||||
if (pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI == NULL)
|
||||
curr_pucch->simultaneous_harqcsi = false;
|
||||
else
|
||||
curr_pucch->simultaneous_harqcsi = true;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format3:
|
||||
if (pucch_Config->format3->choice.setup->simultaneousHARQ_ACK_CSI == NULL)
|
||||
curr_pucch->simultaneous_harqcsi = false;
|
||||
else
|
||||
curr_pucch->simultaneous_harqcsi = true;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format4:
|
||||
if (pucch_Config->format4->choice.setup->simultaneousHARQ_ACK_CSI == NULL)
|
||||
curr_pucch->simultaneous_harqcsi = false;
|
||||
else
|
||||
curr_pucch->simultaneous_harqcsi = true;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid PUCCH format type");
|
||||
}
|
||||
}
|
||||
}
|
||||
curr_pucch->csi_bits += nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id); // TODO function to compute CSI meas report bit size
|
||||
curr_pucch->frame = frame;
|
||||
curr_pucch->ul_slot = sched_slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function to update pucch scheduling parameters in UE list when a USS DL is scheduled
|
||||
void nr_update_pucch_scheduling(int Mod_idP,
|
||||
int UE_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int slots_per_tdd,
|
||||
int *pucch_id) {
|
||||
void nr_acknack_scheduling(int Mod_idP,
|
||||
int UE_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int slots_per_tdd,
|
||||
int *pucch_id,
|
||||
int *pucch_occ) {
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_sched_pucch *curr_pucch;
|
||||
int first_ul_slot_tdd,k,i;
|
||||
int max_acknacks,pucch_res,first_ul_slot_tdd,k,i,l;
|
||||
uint8_t pdsch_to_harq_feedback[8];
|
||||
int found = 0;
|
||||
int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
|
||||
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0)
|
||||
nr_ulmix_slots++;
|
||||
|
||||
bool csi_pres=false;
|
||||
for (k=0; k<nr_ulmix_slots; k++) {
|
||||
if(UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][0].csi_bits>0)
|
||||
csi_pres=true;
|
||||
}
|
||||
|
||||
// As a preference always schedule ack nacks in PUCCH0 (max 2 per slots)
|
||||
// Unless there is CSI meas reporting scheduled in the period to avoid conflicts in the same slot
|
||||
if (csi_pres)
|
||||
max_acknacks=10;
|
||||
else
|
||||
max_acknacks=2;
|
||||
|
||||
// this is hardcoded for now as ue specific
|
||||
NR_SearchSpace__searchSpaceType_PR ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
get_pdsch_to_harq_feedback(Mod_idP,UE_id,ss_type,pdsch_to_harq_feedback);
|
||||
|
||||
// for each possible ul or mixed slot
|
||||
for (k=0; k<nr_ulmix_slots; k++) {
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k];
|
||||
// if there is free room in current pucch structure
|
||||
if (curr_pucch->dai_c<MAX_ACK_BITS) {
|
||||
curr_pucch->frame = frameP;
|
||||
curr_pucch->dai_c++;
|
||||
curr_pucch->resource_indicator = 0; // in phytest with only 1 UE we are using just the 1st resource
|
||||
// first pucch occasion in first UL or MIXED slot
|
||||
first_ul_slot_tdd = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
|
||||
i = 0;
|
||||
while (i<8 && found == 0) { // look if timing indicator is among allowed values
|
||||
if (pdsch_to_harq_feedback[i]==(first_ul_slot_tdd+k)-(slotP % slots_per_tdd))
|
||||
found = 1;
|
||||
if (found == 0) i++;
|
||||
}
|
||||
if (found == 1) {
|
||||
// computing slot in which pucch is scheduled
|
||||
curr_pucch->ul_slot = first_ul_slot_tdd + k + (slotP - (slotP % slots_per_tdd));
|
||||
curr_pucch->timing_indicator = i; // index in the list of timing indicators
|
||||
*pucch_id = k;
|
||||
return;
|
||||
for (l=0; l<1; l++) { // scheduling 2 PUCCH in a single slot does not work with the phone, currently
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l];
|
||||
//if it is possible to schedule acknack in current pucch (no exclusive csi pucch)
|
||||
if ((curr_pucch->csi_bits == 0) || (curr_pucch->simultaneous_harqcsi==true)) {
|
||||
// if there is free room in current pucch structure
|
||||
if (curr_pucch->dai_c<max_acknacks) {
|
||||
pucch_res = get_pucch_resource(UE_info,UE_id,k,l);
|
||||
if (pucch_res>-1){
|
||||
curr_pucch->resource_indicator = pucch_res;
|
||||
curr_pucch->frame = frameP;
|
||||
// first pucch occasion in first UL or MIXED slot
|
||||
first_ul_slot_tdd = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
|
||||
i = 0;
|
||||
while (i<8 && found == 0) { // look if timing indicator is among allowed values
|
||||
if (pdsch_to_harq_feedback[i]==(first_ul_slot_tdd+k)-(slotP % slots_per_tdd))
|
||||
found = 1;
|
||||
if (found == 0) i++;
|
||||
}
|
||||
if (found == 1) {
|
||||
// computing slot in which pucch is scheduled
|
||||
curr_pucch->dai_c++;
|
||||
curr_pucch->ul_slot = first_ul_slot_tdd + k + (slotP - (slotP % slots_per_tdd));
|
||||
curr_pucch->timing_indicator = i; // index in the list of timing indicators
|
||||
*pucch_id = k;
|
||||
*pucch_occ = l;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1868,6 +2224,22 @@ void nr_update_pucch_scheduling(int Mod_idP,
|
||||
}
|
||||
|
||||
|
||||
int get_pucch_resource(NR_UE_info_t *UE_info,int UE_id,int k,int l) {
|
||||
|
||||
// to be updated later, for now simple implementation
|
||||
// use the second allocation just in case there is csi in the first
|
||||
// in that case use second resource (for a different symbol) see 9.2 in 38.213
|
||||
if (l==1) {
|
||||
if (UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][0].csi_bits==0)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void find_aggregation_candidates(uint8_t *aggregation_level,
|
||||
uint8_t *nr_of_candidates,
|
||||
NR_SearchSpace_t *ss) {
|
||||
|
||||
@@ -340,6 +340,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti);
|
||||
const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti);
|
||||
UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup;
|
||||
compute_csi_bitlen (ra->secondaryCellGroup, UE_info, UE_id);
|
||||
UE_info->UE_beam_index[UE_id] = ra->beam_id;
|
||||
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
|
||||
AssertFatal(bwpList->list.count == 1,
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "NR_TAG-Id.h"
|
||||
|
||||
#define MAX_ACK_BITS 2 //only format 0 is available for now
|
||||
|
||||
void set_cset_offset(uint16_t);
|
||||
|
||||
void mac_top_init_gNB(void);
|
||||
@@ -163,6 +161,11 @@ int configure_fapi_dl_pdu_phytest(int Mod_id,
|
||||
uint16_t *rbSize,
|
||||
uint16_t *rbStart);
|
||||
|
||||
void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234,
|
||||
NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats);
|
||||
|
||||
void config_uldci(NR_BWP_Uplink_t *ubwp,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
@@ -198,12 +201,23 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP);
|
||||
|
||||
void nr_update_pucch_scheduling(int Mod_idP,
|
||||
int UE_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int slots_per_tdd,
|
||||
int *pucch_id);
|
||||
void nr_csi_meas_reporting(int Mod_idP,
|
||||
int UE_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int slots_per_tdd,
|
||||
int ul_slots,
|
||||
int n_slots_frame);
|
||||
|
||||
void nr_acknack_scheduling(int Mod_idP,
|
||||
int UE_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int slots_per_tdd,
|
||||
int *pucch_id,
|
||||
int *pucch_occ);
|
||||
|
||||
int get_pucch_resource(NR_UE_info_t *UE_info,int UE_id,int k,int l);
|
||||
|
||||
void get_pdsch_to_harq_feedback(int Mod_idP,
|
||||
int UE_id,
|
||||
@@ -232,10 +246,11 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space,
|
||||
void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_Uplink_t *bwp,
|
||||
uint16_t rnti,
|
||||
uint8_t pucch_resource,
|
||||
uint16_t O_uci,
|
||||
uint16_t O_csi,
|
||||
uint16_t O_ack,
|
||||
uint8_t SR_flag);
|
||||
uint8_t O_sr);
|
||||
|
||||
void find_search_space(int ss_type,
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
@@ -320,6 +335,17 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
int m,
|
||||
int nr_of_candidates);
|
||||
|
||||
uint16_t compute_pucch_prb_size(uint8_t format,
|
||||
uint8_t nr_prbs,
|
||||
uint16_t O_tot,
|
||||
uint16_t O_csi,
|
||||
NR_PUCCH_MaxCodeRate_t *maxCodeRate,
|
||||
uint8_t Qm,
|
||||
uint8_t n_symb,
|
||||
uint8_t n_re_ctrl);
|
||||
|
||||
void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t *UE_info, int UE_id);
|
||||
|
||||
int get_dlscs(nfapi_nr_config_request_t *cfg);
|
||||
|
||||
int get_ulscs(nfapi_nr_config_request_t *cfg);
|
||||
|
||||
@@ -274,10 +274,12 @@ typedef struct UE_info {
|
||||
typedef struct NR_sched_pucch {
|
||||
int frame;
|
||||
int ul_slot;
|
||||
bool sr_flag;
|
||||
int csi_bits;
|
||||
bool simultaneous_harqcsi;
|
||||
uint8_t dai_c;
|
||||
uint8_t timing_indicator;
|
||||
uint8_t resource_indicator;
|
||||
bool active;
|
||||
} NR_sched_pucch;
|
||||
|
||||
typedef struct NR_sched_pusch {
|
||||
@@ -315,6 +317,25 @@ typedef struct NR_UE_ul_harq {
|
||||
NR_UL_harq_states_t state;
|
||||
} NR_UE_ul_harq_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t nb_ssbri_cri;
|
||||
uint8_t cri_ssbri_bitlen;
|
||||
uint8_t rsrp_bitlen;
|
||||
uint8_t diff_rsrp_bitlen;
|
||||
}CRI_SSBRI_RSRP_bitlen_t;
|
||||
|
||||
|
||||
#define MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG 16
|
||||
typedef struct nr_csi_report {
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||
NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR CSI_Resource_type;
|
||||
uint8_t nb_of_nzp_csi_report;
|
||||
uint8_t nb_of_csi_ssb_report;
|
||||
CRI_SSBRI_RSRP_bitlen_t CSI_report_bitlen[MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG];
|
||||
} nr_csi_report_t;
|
||||
|
||||
|
||||
/*! \brief scheduling control information set through an API */
|
||||
typedef struct {
|
||||
/// total amount of data awaiting for this UE
|
||||
@@ -324,9 +345,10 @@ typedef struct {
|
||||
|
||||
/// the currently active BWP in DL
|
||||
NR_BWP_Downlink_t *active_bwp;
|
||||
NR_sched_pucch *sched_pucch;
|
||||
NR_sched_pucch **sched_pucch;
|
||||
/// selected PUCCH index, if scheduled
|
||||
int pucch_sched_idx;
|
||||
int pucch_occ_idx;
|
||||
NR_sched_pusch *sched_pusch;
|
||||
|
||||
/// CCE index and aggregation, should be coherent with cce_list
|
||||
@@ -385,9 +407,11 @@ typedef struct {
|
||||
} NR_UE_list_t;
|
||||
|
||||
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
|
||||
#define MAX_CSI_REPORTCONFIG 48
|
||||
typedef struct {
|
||||
DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
|
||||
/// scheduling control info
|
||||
nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG];
|
||||
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
|
||||
NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB];
|
||||
NR_UE_list_t list;
|
||||
|
||||
@@ -996,17 +996,7 @@ pdcp_data_ind(
|
||||
* TODO: be sure of this
|
||||
*/
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF ) {
|
||||
#ifdef UESIM_EXPANSION
|
||||
|
||||
if (UE_NAS_USE_TUN) {
|
||||
pdcpHead->inst = ctxt_pP->module_id;
|
||||
} else {
|
||||
pdcpHead->inst = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
pdcpHead->inst = ctxt_pP->module_id;
|
||||
#endif
|
||||
} else { // nfapi_mode
|
||||
if (UE_NAS_USE_TUN) {
|
||||
pdcpHead->inst = ctxt_pP->module_id;
|
||||
@@ -2287,7 +2277,7 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
|
||||
nas_getparams();
|
||||
|
||||
if(UE_NAS_USE_TUN) {
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1;
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun("ue",num_if);
|
||||
if (IS_SOFTMODEM_NOS1)
|
||||
nas_config(1, 1, 2, "ue");
|
||||
|
||||
@@ -53,9 +53,6 @@ typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *cons
|
||||
typedef boolean_t (*pdcp_data_ind_func_t)( const protocol_ctxt_t *, const srb_flag_t,
|
||||
const MBMS_flag_t, const rb_id_t, const sdu_size_t,
|
||||
mem_block_t *,const uint32_t *const, const uint32_t *const);
|
||||
/* maximum number of tun interfaces that will be created to emulates UEs */
|
||||
/* UEs beyond that will be multiplexed on the same tun */
|
||||
#define MAX_NUMBER_NETIF 16
|
||||
|
||||
#define ENB_NAS_USE_TUN_W_MBMS_BIT (1<< 10)
|
||||
#define PDCP_USE_NETLINK_BIT (1<< 11)
|
||||
|
||||
@@ -86,12 +86,6 @@ extern struct msghdr nas_msg_rx;
|
||||
|
||||
|
||||
|
||||
#ifdef UESIM_EXPANSION
|
||||
extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX];
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
# include "gtpv1u_eNB_task.h"
|
||||
# include "gtpv1u_eNB_defs.h"
|
||||
|
||||
@@ -503,11 +497,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
|
||||
}
|
||||
} else { // ctxt.enb_flag => UE
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF) {
|
||||
#ifdef UESIM_EXPANSION
|
||||
ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst];
|
||||
#else
|
||||
ctxt.module_id = pdcp_read_header_g.inst;
|
||||
#endif
|
||||
} else {
|
||||
ctxt.module_id = 0;
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ uint64_t pdcp_module_init(uint64_t _pdcp_optmask)
|
||||
nas_getparams();
|
||||
|
||||
if(UE_NAS_USE_TUN) {
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1;
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun("ue",num_if);
|
||||
//Add --nr-ip-over-lte option check for next line
|
||||
if (IS_SOFTMODEM_NOS1)
|
||||
|
||||
@@ -287,18 +287,6 @@ ue_ip_common_ip2wireless(
|
||||
printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, dst_addr[0],dst_addr[1],dst_addr[2],dst_addr[3]);
|
||||
}
|
||||
|
||||
// modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator start
|
||||
#ifdef UESIM_EXPANSION
|
||||
|
||||
if ((src_addr[3] - 2)> instP) {
|
||||
pdcph.inst = src_addr[3] - 2;
|
||||
printk("[UE_IP_DRV] change INST from %d to %d\n",instP, pdcph.inst);
|
||||
instP = src_addr[3] - 2;
|
||||
priv_p=netdev_priv(ue_ip_dev[instP]);
|
||||
}
|
||||
|
||||
#endif
|
||||
// modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator end
|
||||
//get Ipv4 address and pass to PCDP header
|
||||
printk("[UE_IP_DRV] source Id: 0x%08x\n",pdcph.sourceL2Id );
|
||||
printk("[UE_IP_DRV] destinationL2Id Id: 0x%08x\n",pdcph.destinationL2Id );
|
||||
|
||||
@@ -79,6 +79,44 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
|
||||
}
|
||||
|
||||
|
||||
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10) {
|
||||
|
||||
int num_ucis = UL_info->uci_ind.num_ucis;
|
||||
nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
|
||||
|
||||
for (int i = 0; i < num_ucis; i++) {
|
||||
switch (uci_list[i].pdu_type) {
|
||||
case NFAPI_NR_UCI_PUSCH_PDU_TYPE: break;
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
|
||||
|
||||
// tpc (power control)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
|
||||
|
||||
if( (uci_pdu->pduBitmap>>1) & 0x01)
|
||||
nr_rx_acknack(NULL,uci_pdu,NULL,UL_info,sched_ctrl,stats);
|
||||
|
||||
break;
|
||||
}
|
||||
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
|
||||
|
||||
// tpc (power control)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
|
||||
|
||||
if( (uci_pdu->pduBitmap>>1) & 0x01)
|
||||
nr_rx_acknack(NULL,NULL,uci_pdu,UL_info,sched_ctrl,stats);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UL_info->uci_ind.num_ucis = 0;
|
||||
}
|
||||
|
||||
|
||||
void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) {
|
||||
|
||||
if(nfapi_mode == 1) {
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
|
||||
#include "executables/softmodem-common.h"
|
||||
#include <openair2/RRC/NR/rrc_gNB_UE_context.h>
|
||||
#include "x2ap_eNB.h"
|
||||
|
||||
//#define XER_PRINT
|
||||
|
||||
@@ -317,8 +318,10 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
MessageDef *msg;
|
||||
|
||||
/* send a tick to x2ap */
|
||||
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS);
|
||||
itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg);
|
||||
if (is_x2ap_enabled()){
|
||||
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS);
|
||||
itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg);
|
||||
}
|
||||
}
|
||||
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user