Merge remote-tracking branch 'origin/develop' into benetel_phase_rotation
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
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
#include "flexran.pb-c.h"
|
||||
#include "flexran_agent_mac.h"
|
||||
#include <dlfcn.h>
|
||||
#include <openair2/LAYER2/MAC/mac.h>
|
||||
|
||||
|
||||
#include "T.h"
|
||||
|
||||
|
||||
@@ -947,6 +947,24 @@ int get_format0(uint8_t index,
|
||||
return format;
|
||||
}
|
||||
|
||||
int64_t *get_prach_config_info(uint32_t pointa,
|
||||
uint8_t index,
|
||||
uint8_t unpaired) {
|
||||
int64_t *prach_config_info_p;
|
||||
|
||||
if (pointa > 2016666) { //FR2
|
||||
prach_config_info_p = table_6_3_3_2_4_prachConfig_Index[index];
|
||||
}
|
||||
else { // FR1
|
||||
if (unpaired)
|
||||
prach_config_info_p = table_6_3_3_2_3_prachConfig_Index[index];
|
||||
else
|
||||
prach_config_info_p = table_6_3_3_2_2_prachConfig_Index[index];
|
||||
} // FR2 / FR1
|
||||
|
||||
return prach_config_info_p;
|
||||
}
|
||||
|
||||
void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss,
|
||||
uint16_t *slot_period,
|
||||
uint16_t *offset) {
|
||||
@@ -1451,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},
|
||||
@@ -1473,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}
|
||||
};
|
||||
|
||||
|
||||
@@ -1718,13 +1736,23 @@ uint32_t to_nrarfcn(int nr_bandP,
|
||||
(long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz));
|
||||
|
||||
int deltaFglobal = 60;
|
||||
uint32_t N_REF_Offs = 2016667;
|
||||
uint64_t F_REF_Offs_khz = 24250080;
|
||||
|
||||
if (dl_CarrierFreq < 3e9) deltaFglobal = 15;
|
||||
if (dl_CarrierFreq < 24.25e9) deltaFglobal = 5;
|
||||
if (dl_CarrierFreq < 24.25e9) {
|
||||
deltaFglobal = 15;
|
||||
N_REF_Offs = 600000;
|
||||
F_REF_Offs_khz = 3000000;
|
||||
}
|
||||
if (dl_CarrierFreq < 3e9) {
|
||||
deltaFglobal = 5;
|
||||
N_REF_Offs = 0;
|
||||
F_REF_Offs_khz = 0;
|
||||
}
|
||||
|
||||
// This is equation before Table 5.4.2.1-1 in 38101-1-f30
|
||||
// F_REF=F_REF_Offs + deltaF_Global(N_REF-NREF_REF_Offs)
|
||||
nrarfcn = (((dl_CarrierFreq_by_1k - nr_bandtable[i].dl_min)/deltaFglobal)+nr_bandtable[i].N_OFFs_DL);
|
||||
nrarfcn = (((dl_CarrierFreq_by_1k - F_REF_Offs_khz)/deltaFglobal)+N_REF_Offs);
|
||||
|
||||
delta_arfcn = nrarfcn - nr_bandtable[i].N_OFFs_DL;
|
||||
if(delta_arfcn%(nr_bandtable[i].step_size)!=0)
|
||||
@@ -1741,13 +1769,21 @@ uint64_t from_nrarfcn(int nr_bandP,
|
||||
{
|
||||
int i;
|
||||
int deltaFglobal = 5;
|
||||
uint32_t N_REF_Offs = 0;
|
||||
uint64_t F_REF_Offs_khz = 0;
|
||||
int scs_khz = 15<<scs_index;
|
||||
uint32_t delta_arfcn;
|
||||
|
||||
if (dl_nrarfcn > 599999 && dl_nrarfcn < 2016667)
|
||||
deltaFglobal = 15;
|
||||
if (dl_nrarfcn > 2016666 && dl_nrarfcn < 3279166)
|
||||
if (dl_nrarfcn > 599999 && dl_nrarfcn < 2016667) {
|
||||
deltaFglobal = 15;
|
||||
N_REF_Offs = 600000;
|
||||
F_REF_Offs_khz = 3000000;
|
||||
}
|
||||
if (dl_nrarfcn > 2016666 && dl_nrarfcn < 3279166) {
|
||||
deltaFglobal = 60;
|
||||
N_REF_Offs = 2016667;
|
||||
F_REF_Offs_khz = 24250080;
|
||||
}
|
||||
|
||||
AssertFatal(nr_bandP <= 261, "nr_band %d > 260\n", nr_bandP);
|
||||
for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++);
|
||||
@@ -1761,14 +1797,11 @@ uint64_t from_nrarfcn(int nr_bandP,
|
||||
if(delta_arfcn%(nr_bandtable[i].step_size)!=0)
|
||||
AssertFatal(1==0,"dl_nrarfcn %u is not on the raster for step size %lu",dl_nrarfcn,nr_bandtable[i].step_size);
|
||||
|
||||
LOG_I(PHY,"Computing dl_frequency (pointA %llu => %llu (dlmin %llu, nr_bandtable[%d].N_OFFs_DL %llu))\n",
|
||||
LOG_I(PHY,"Computing dl_frequency (arfcn %llu => %llu)\n",
|
||||
(unsigned long long)dl_nrarfcn,
|
||||
(unsigned long long)(1000*(nr_bandtable[i].dl_min + (dl_nrarfcn - nr_bandtable[i].N_OFFs_DL) * deltaFglobal)),
|
||||
(unsigned long long)nr_bandtable[i].dl_min,
|
||||
i,
|
||||
(unsigned long long)nr_bandtable[i].N_OFFs_DL);
|
||||
(unsigned long long)(1000*(F_REF_Offs_khz + (dl_nrarfcn - N_REF_Offs) * deltaFglobal)));
|
||||
|
||||
return 1000*(nr_bandtable[i].dl_min + (dl_nrarfcn - nr_bandtable[i].N_OFFs_DL) * deltaFglobal);
|
||||
return 1000*(F_REF_Offs_khz + (dl_nrarfcn - N_REF_Offs) * deltaFglobal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,6 +36,36 @@
|
||||
#include "NR_CellGroupConfig.h"
|
||||
#include "nr_mac.h"
|
||||
|
||||
|
||||
// ===============================================
|
||||
// SSB to RO mapping public defines and structures
|
||||
// ===============================================
|
||||
#define MAX_SSB_PER_RO (16) // Maximum number of SSBs that can be mapped to a single RO
|
||||
#define MAX_TDM (7) // Maximum nb of PRACH occasions TDMed in a slot
|
||||
#define MAX_FDM (8) // Maximum nb of PRACH occasions FDMed in a slot
|
||||
|
||||
// PRACH occasion details
|
||||
typedef struct prach_occasion_info {
|
||||
uint8_t start_symbol; // 0 - 13 (14 symbols in a slot)
|
||||
uint8_t fdm; // 0-7 (possible values of msg1-FDM: 1, 2, 4 or 8)
|
||||
uint8_t slot; // 0 - 159 (maximum number of slots in a 10ms frame - @ 240kHz)
|
||||
uint8_t frame; // 0 - 15 (maximum number of frames in a 160ms association pattern)
|
||||
uint8_t mapped_ssb_idx[MAX_SSB_PER_RO]; // List of mapped SSBs
|
||||
uint8_t nb_mapped_ssb;
|
||||
uint16_t format; // RO preamble format
|
||||
} prach_occasion_info_t;
|
||||
|
||||
// PRACH occasion slot details
|
||||
// A PRACH occasion slot is a series of PRACH occasions in time (symbols) and frequency
|
||||
typedef struct prach_occasion_slot {
|
||||
prach_occasion_info_t prach_occasion[MAX_TDM][MAX_FDM]; // Starting symbol of each PRACH occasions in a slot
|
||||
uint8_t nb_of_prach_occasion_in_time;
|
||||
uint8_t nb_of_prach_occasion_in_freq;
|
||||
} prach_occasion_slot_t;
|
||||
|
||||
// ========================================
|
||||
|
||||
|
||||
typedef enum {
|
||||
NR_DL_DCI_FORMAT_1_0 = 0,
|
||||
NR_DL_DCI_FORMAT_1_1,
|
||||
@@ -133,6 +163,10 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPreco
|
||||
|
||||
int get_format0(uint8_t index, uint8_t unpaired);
|
||||
|
||||
int64_t *get_prach_config_info(uint32_t pointa,
|
||||
uint8_t index,
|
||||
uint8_t unpaired);
|
||||
|
||||
uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config);
|
||||
|
||||
int get_num_dmrs(uint16_t dmrs_mask );
|
||||
|
||||
@@ -204,7 +204,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
|
||||
uint16_t band;
|
||||
int32_t offset;
|
||||
|
||||
get_band((cfg->carrier_config.dl_frequency)*1000,
|
||||
get_band((uint64_t)(cfg->carrier_config.dl_frequency)*1000,
|
||||
&band,
|
||||
&offset,
|
||||
&frame_type);
|
||||
@@ -243,8 +243,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask = 0;
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
|
||||
for (i=0; i<4; i++) {
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<<i*8);
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<<i*8);
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<<i*8);
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<<i*8);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -433,6 +433,9 @@ int nr_rrc_mac_config_req_ue(
|
||||
LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
|
||||
}
|
||||
|
||||
// Setup the SSB to Rach Occasions mapping according to the config
|
||||
build_ssb_to_ro_map(mac->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
|
||||
|
||||
/*
|
||||
if(mac_cell_group_configP != NULL){
|
||||
if(mac_cell_group_configP->drx_Config != NULL ){
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -267,6 +267,7 @@ andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4
|
||||
@param nr_tti_tx slot for PRACH transmission
|
||||
@returns indication to generate PRACH to phy */
|
||||
uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
fapi_nr_ul_config_prach_pdu *prach_pdu,
|
||||
module_id_t mod_id,
|
||||
int CC_id,
|
||||
UE_MODE_t UE_mode,
|
||||
@@ -278,15 +279,14 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
@param module_idP Index of UE instance
|
||||
@param CC_id Component Carrier Index
|
||||
@param gNB_index gNB index
|
||||
@param t_id
|
||||
@param rach_ConfigDedicated
|
||||
@returns void */
|
||||
void nr_get_prach_resources(module_id_t mod_id,
|
||||
int CC_id,
|
||||
uint8_t gNB_id,
|
||||
uint8_t t_id,
|
||||
uint8_t first_Msg3,
|
||||
NR_PRACH_RESOURCES_t *prach_resources,
|
||||
fapi_nr_ul_config_prach_pdu *prach_pdu,
|
||||
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
|
||||
|
||||
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
|
||||
@@ -305,5 +305,8 @@ void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
uint8_t *nb_dmrs_re_per_rb,
|
||||
uint16_t *number_dmrs_symbols);
|
||||
|
||||
void build_ssb_to_ro_map(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired);
|
||||
|
||||
|
||||
#endif
|
||||
/** @}*/
|
||||
|
||||
@@ -75,9 +75,9 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
|
||||
void nr_get_prach_resources(module_id_t mod_id,
|
||||
int CC_id,
|
||||
uint8_t gNB_id,
|
||||
uint8_t t_id,
|
||||
uint8_t first_Msg3,
|
||||
NR_PRACH_RESOURCES_t *prach_resources,
|
||||
fapi_nr_ul_config_prach_pdu *prach_pdu,
|
||||
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
||||
@@ -87,8 +87,8 @@ void nr_get_prach_resources(module_id_t mod_id,
|
||||
|
||||
// NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo
|
||||
|
||||
int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA = 0, numberOfRA_Preambles, i, deltaPreamble_Msg3 = 0;
|
||||
uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, prach_ConfigIndex, SFN_nbr, Msg3_size;
|
||||
int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA = 0, numberOfRA_Preambles, deltaPreamble_Msg3 = 0;
|
||||
uint8_t noGroupB = 0, s_id, t_id, f_id, ul_carrier_id, Msg3_size;
|
||||
|
||||
AssertFatal(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
|
||||
nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
|
||||
@@ -100,6 +100,7 @@ void nr_get_prach_resources(module_id_t mod_id,
|
||||
//////////* UE Random Access Resource Selection *//////////
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// todo:
|
||||
// - switch initialisation cases
|
||||
// -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
|
||||
@@ -129,12 +130,81 @@ void nr_get_prach_resources(module_id_t mod_id,
|
||||
|
||||
// rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB;
|
||||
|
||||
// Determine the SSB to RACH mapping ratio
|
||||
// =======================================
|
||||
NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
|
||||
boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB
|
||||
uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB
|
||||
long cb_preambles_per_ssb; // Nb of preambles per SSB
|
||||
int total_preambles_per_ssb;
|
||||
int starting_preamble_nb = 0;
|
||||
uint8_t ssb_nb_in_ro;
|
||||
|
||||
switch (ssb_perRACH_config){
|
||||
case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth:
|
||||
multiple_ssb_per_ro = false;
|
||||
ssb_rach_ratio = 8;
|
||||
cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1);
|
||||
break;
|
||||
case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth:
|
||||
multiple_ssb_per_ro = false;
|
||||
ssb_rach_ratio = 4;
|
||||
cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1);
|
||||
break;
|
||||
case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf:
|
||||
multiple_ssb_per_ro = false;
|
||||
ssb_rach_ratio = 2;
|
||||
cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1);
|
||||
break;
|
||||
case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one:
|
||||
multiple_ssb_per_ro = true;
|
||||
ssb_rach_ratio = 1;
|
||||
cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1);
|
||||
break;
|
||||
case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two:
|
||||
multiple_ssb_per_ro = true;
|
||||
ssb_rach_ratio = 2;
|
||||
cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1);
|
||||
break;
|
||||
case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four:
|
||||
multiple_ssb_per_ro = true;
|
||||
ssb_rach_ratio = 4;
|
||||
cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four;
|
||||
break;
|
||||
case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight:
|
||||
multiple_ssb_per_ro = true;
|
||||
ssb_rach_ratio = 8;
|
||||
cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight;
|
||||
break;
|
||||
case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen:
|
||||
multiple_ssb_per_ro = true;
|
||||
ssb_rach_ratio = 16;
|
||||
cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config);
|
||||
break;
|
||||
}
|
||||
|
||||
Msg3_size = mac->RA_Msg3_size;
|
||||
|
||||
numberOfRA_Preambles = 64;
|
||||
if(nr_rach_ConfigCommon->totalNumberOfRA_Preambles != NULL)
|
||||
numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
|
||||
|
||||
// Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration
|
||||
if ((true == multiple_ssb_per_ro) &&
|
||||
(ssb_rach_ratio > 1)) {
|
||||
total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio;
|
||||
|
||||
ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro;
|
||||
starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro;
|
||||
}
|
||||
else {
|
||||
total_preambles_per_ssb = numberOfRA_Preambles;
|
||||
starting_preamble_nb = 0;
|
||||
}
|
||||
|
||||
if (!nr_rach_ConfigCommon->groupBconfigured) {
|
||||
noGroupB = 1;
|
||||
} else {
|
||||
@@ -220,29 +290,30 @@ void nr_get_prach_resources(module_id_t mod_id,
|
||||
if (first_Msg3 == 1) {
|
||||
if (noGroupB == 1) {
|
||||
// use Group A preamble
|
||||
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
|
||||
prach_resources->ra_PreambleIndex = starting_preamble_nb + ((taus()) % cb_preambles_per_ssb);
|
||||
mac->RA_usedGroupA = 1;
|
||||
} else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) {
|
||||
// Group B is configured and RA preamble Group A is used
|
||||
// - todo add condition on CCCH_sdu_size for initiation by CCCH
|
||||
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
|
||||
prach_resources->ra_PreambleIndex = starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
|
||||
mac->RA_usedGroupA = 1;
|
||||
} else {
|
||||
// Group B preamble is configured and used
|
||||
// the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
|
||||
// the remaining belong to RA Preambles Group B
|
||||
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
|
||||
prach_resources->ra_PreambleIndex = starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
|
||||
mac->RA_usedGroupA = 0;
|
||||
}
|
||||
} else { // Msg3 is being retransmitted
|
||||
if (mac->RA_usedGroupA == 1 && noGroupB == 1) {
|
||||
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
|
||||
prach_resources->ra_PreambleIndex = starting_preamble_nb + ((taus()) % cb_preambles_per_ssb);
|
||||
} else if (mac->RA_usedGroupA == 1 && noGroupB == 0){
|
||||
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
|
||||
prach_resources->ra_PreambleIndex = starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
|
||||
} else {
|
||||
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
|
||||
prach_resources->ra_PreambleIndex = starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex);
|
||||
}
|
||||
|
||||
@@ -268,27 +339,16 @@ void nr_get_prach_resources(module_id_t mod_id,
|
||||
// 1) this does not apply to contention-free RA Preamble for beam failure recovery request
|
||||
// 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
|
||||
|
||||
prach_ConfigIndex = rach_ConfigGeneric->prach_ConfigurationIndex;
|
||||
|
||||
// ra_RNTI computation
|
||||
// - todo: this is for TDD FR1 only
|
||||
// - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier
|
||||
// - f_id: index of the PRACH occasion in the frequency domain
|
||||
// - s_id is starting symbol of the PRACH occasion [0...14]
|
||||
// - t_id is the first slot of the PRACH occasion in a system frame [0...80]
|
||||
|
||||
ul_carrier_id = 0; // NUL
|
||||
f_id = rach_ConfigGeneric->msg1_FrequencyStart;
|
||||
SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4];
|
||||
s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5];
|
||||
f_id = prach_pdu->num_ra;
|
||||
t_id = prach_pdu->prach_slot;
|
||||
s_id = prach_pdu->prach_start_symbol;
|
||||
|
||||
// Pick the first slot of the PRACH occasion in a system frame
|
||||
for (i = 0; i < 10; i++){
|
||||
if (((SFN_nbr & (1 << i)) >> i) == 1){
|
||||
t_id = 2*i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
|
||||
mac->ra_rnti = prach_resources->ra_RNTI;
|
||||
|
||||
@@ -335,6 +395,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
|
||||
// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
|
||||
|
||||
uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
fapi_nr_ul_config_prach_pdu *prach_pdu,
|
||||
module_id_t mod_id,
|
||||
int CC_id,
|
||||
UE_MODE_t UE_mode,
|
||||
@@ -363,7 +424,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n");
|
||||
|
||||
if (UE_mode < PUSCH && prach_resources->init_msg1) {
|
||||
if (prach_resources->init_msg1) {
|
||||
|
||||
LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active);
|
||||
|
||||
@@ -449,7 +510,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
// Fill in preamble and PRACH resources
|
||||
if (mac->generate_nr_prach == 1)
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, prach_resources, rach_ConfigDedicated);
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, prach_resources, prach_pdu, rach_ConfigDedicated);
|
||||
|
||||
offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer
|
||||
(uint8_t *) payload, // UL MAC pdu pointer
|
||||
@@ -576,7 +637,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
// Fill in preamble and PRACH resources
|
||||
if (mac->generate_nr_prach == 1)
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, prach_resources, prach_pdu, rach_ConfigDedicated);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -590,7 +651,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
// Fill in preamble and PRACH resources
|
||||
if (mac->generate_nr_prach == 1)
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, prach_resources, prach_pdu, rach_ConfigDedicated);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -274,15 +274,22 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
|
||||
if (ue_mac->RA_RAPID_found) {
|
||||
|
||||
uint8_t freq_hopping, mcs, Msg3_t_alloc, Msg3_f_alloc;
|
||||
unsigned char tpc_command, csi_req;
|
||||
unsigned char tpc_command;
|
||||
#ifdef DEBUG_RAR
|
||||
unsigned char csi_req;
|
||||
#endif
|
||||
|
||||
// TC-RNTI
|
||||
*t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
|
||||
ue_mac->t_crnti = *t_crnti;
|
||||
// TA command
|
||||
ta_command = rar->TA2 + (rar->TA1 << 5);
|
||||
|
||||
#ifdef DEBUG_RAR
|
||||
// CSI
|
||||
csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01);
|
||||
#endif
|
||||
|
||||
// TPC
|
||||
tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07);
|
||||
switch (tpc_command){
|
||||
|
||||
@@ -128,7 +128,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
|
||||
uint16_t band;
|
||||
int32_t offset;
|
||||
|
||||
get_band((cfg->carrier_config.dl_frequency.value)*1000,
|
||||
get_band(((uint64_t)cfg->carrier_config.dl_frequency.value)*1000,
|
||||
&band,
|
||||
&offset,
|
||||
&frame_type);
|
||||
@@ -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,9 +399,12 @@ 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);
|
||||
|
||||
int nb_periods_per_frame;
|
||||
|
||||
const int UE_id = 0;
|
||||
const int bwp_id = 1;
|
||||
|
||||
@@ -406,24 +413,49 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_COMMON_channels_t *cc = gNB->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
|
||||
NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
|
||||
const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity);
|
||||
const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
|
||||
|
||||
if (slot == 0 && UE_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));*/
|
||||
}
|
||||
switch(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity) {
|
||||
case 0:
|
||||
nb_periods_per_frame = 20; // 10ms/0p5ms
|
||||
break;
|
||||
|
||||
case 1:
|
||||
nb_periods_per_frame = 16; // 10ms/0p625ms
|
||||
break;
|
||||
|
||||
case 2:
|
||||
nb_periods_per_frame = 10; // 10ms/1ms
|
||||
break;
|
||||
|
||||
case 3:
|
||||
nb_periods_per_frame = 8; // 10ms/1p25ms
|
||||
break;
|
||||
|
||||
case 4:
|
||||
nb_periods_per_frame = 5; // 10ms/2ms
|
||||
break;
|
||||
|
||||
case 5:
|
||||
nb_periods_per_frame = 4; // 10ms/2p5ms
|
||||
break;
|
||||
|
||||
case 6:
|
||||
nb_periods_per_frame = 2; // 10ms/5ms
|
||||
break;
|
||||
|
||||
case 7:
|
||||
nb_periods_per_frame = 1; // 10ms/10ms
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"Undefined tdd period %d\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
|
||||
}
|
||||
|
||||
int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame;
|
||||
|
||||
const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
|
||||
|
||||
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);
|
||||
|
||||
@@ -446,18 +478,18 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
//mbsfn_status[CC_id] = 0;
|
||||
|
||||
// clear vrb_maps
|
||||
memset(cc[CC_id].vrb_map, 0, 275);
|
||||
memset(cc[CC_id].vrb_map_UL, 0, 275);
|
||||
memset(cc[CC_id].vrb_map, 0, sizeof(uint16_t) * 275);
|
||||
memset(cc[CC_id].vrb_map_UL, 0, sizeof(uint16_t) * 275);
|
||||
|
||||
clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot);
|
||||
}
|
||||
|
||||
|
||||
if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]);
|
||||
|
||||
|
||||
// This schedules MIB
|
||||
if((slot == 0) && (frame & 7) == 0){
|
||||
schedule_nr_mib(module_idP, frame, slot);
|
||||
}
|
||||
schedule_nr_mib(module_idP, frame, slot, slots_per_frame[*scc->ssbSubcarrierSpacing]);
|
||||
|
||||
// This schedule PRACH if we are not in phy_test mode
|
||||
if (get_softmodem_params()->phy_test == 0)
|
||||
@@ -466,8 +498,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
|
||||
@@ -475,40 +508,30 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
if (get_softmodem_params()->phy_test == 0) {
|
||||
nr_schedule_RA(module_idP, frame, slot);
|
||||
nr_schedule_reception_msg3(module_idP, 0, frame, slot);
|
||||
}
|
||||
|
||||
if (UE_info->active[UE_id]) {
|
||||
// TbD once RACH is available, start ta_timer when UE is connected
|
||||
if (ue_sched_ctl->ta_timer)
|
||||
ue_sched_ctl->ta_timer--;
|
||||
if (ue_sched_ctl->ta_timer == 0) {
|
||||
ue_sched_ctl->ta_apply = true;
|
||||
/* if time is up, then set the timer to not send it for 5 frames
|
||||
// regardless of the TA value */
|
||||
ue_sched_ctl->ta_timer = 100;
|
||||
}
|
||||
}
|
||||
|
||||
// This schedules the DCI for Uplink and subsequently PUSCH
|
||||
|
||||
// The decision about whether to schedule is done for each UE independently
|
||||
// inside
|
||||
if (UE_info->active[UE_id] && slot < 10) {
|
||||
|
||||
int tda = 1; // time domain assignment hardcoded for now
|
||||
schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda, ulsch_in_slot_bitmap);
|
||||
nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot);
|
||||
}
|
||||
|
||||
|
||||
if (UE_info->active[UE_id]
|
||||
&& (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd))
|
||||
&& slot < 10) {
|
||||
|
||||
ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd;
|
||||
//int pucch_sched;
|
||||
//nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched);
|
||||
//nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_info->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
|
||||
nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd);
|
||||
ue_sched_ctl->ta_apply = false;
|
||||
}
|
||||
|
||||
|
||||
if (UE_info->active[UE_id])
|
||||
nr_schedule_pucch(module_idP, UE_id, nr_ulmix_slots, frame, slot);
|
||||
|
||||
|
||||
@@ -448,9 +448,11 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pr_found) {
|
||||
LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
|
||||
module_idP, preamble_index);
|
||||
|
||||
return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
|
||||
}
|
||||
// This should be handled differently when we use the initialBWP for RA
|
||||
@@ -931,8 +933,12 @@ void nr_generate_Msg2(module_id_t module_idP,
|
||||
nr_mac->TX_req[CC_id].Slot = slotP;
|
||||
memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length);
|
||||
|
||||
T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id),
|
||||
T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */,
|
||||
T_BUFFER(&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length));
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
uint8_t *vrb_map = cc[CC_id].vrb_map;
|
||||
uint16_t *vrb_map = cc[CC_id].vrb_map;
|
||||
for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++)
|
||||
vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern uint8_t SSB_Table[38];
|
||||
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, uint8_t slots_per_frame){
|
||||
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc;
|
||||
@@ -67,93 +67,148 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
|
||||
|
||||
int mib_sdu_length;
|
||||
int CC_id;
|
||||
AssertFatal(slotP == 0, "Subframe must be 0\n");
|
||||
AssertFatal((frameP & 7) == 0, "Frame must be a multiple of 8\n");
|
||||
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
|
||||
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
|
||||
dl_tti_request = &gNB->DL_req[CC_id];
|
||||
dl_req = &dl_tti_request->dl_tti_request_body;
|
||||
cc = &gNB->common_channels[CC_id];
|
||||
#if 0
|
||||
//SSB is transmitted based on SSB periodicity
|
||||
if((frameP % cfg->ssb_table.ssb_period.value) == 0) {
|
||||
uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ;
|
||||
uint32_t ssb_index = -1;
|
||||
for (int i=0; i<2; i++) { // max two SSB per slot
|
||||
ssb_index = i + SSB_Table[slotP]; // computing the ssb_index
|
||||
if ((ssb_index<64) && ((L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1
|
||||
#endif
|
||||
const long band = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
const uint32_t ssb_offset0 = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
|
||||
int ratio;
|
||||
switch (*cc->ServingCellConfigCommon->ssbSubcarrierSpacing) {
|
||||
case NR_SubcarrierSpacing_kHz15:
|
||||
AssertFatal(band <= 79,
|
||||
"Band %ld is not possible for SSB with 15 kHz SCS\n",
|
||||
band);
|
||||
if (band < 77) // below 3GHz
|
||||
ratio = 3; // NRARFCN step is 5 kHz
|
||||
else
|
||||
ratio = 1; // NRARFCN step is 15 kHz
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz30:
|
||||
AssertFatal(band <= 79,
|
||||
"Band %ld is not possible for SSB with 15 kHz SCS\n",
|
||||
band);
|
||||
if (band < 77) // below 3GHz
|
||||
ratio = 6; // NRARFCN step is 5 kHz
|
||||
else
|
||||
ratio = 2; // NRARFCN step is 15 kHz
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz120:
|
||||
AssertFatal(band >= 257,
|
||||
"Band %ld is not possible for SSB with 120 kHz SCS\n",
|
||||
band);
|
||||
ratio = 2; // NRARFCN step is 15 kHz
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz240:
|
||||
AssertFatal(band >= 257,
|
||||
"Band %ld is not possible for SSB with 240 kHz SCS\n",
|
||||
band);
|
||||
ratio = 4; // NRARFCN step is 15 kHz
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",
|
||||
*cc->ServingCellConfigCommon->ssbSubcarrierSpacing);
|
||||
}
|
||||
|
||||
mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); // not used in this case
|
||||
// scheduling MIB every 8 frames, PHY repeats it in between
|
||||
if((slotP == 0) && (frameP & 7) == 0) {
|
||||
dl_tti_request = &gNB->DL_req[CC_id];
|
||||
dl_req = &dl_tti_request->dl_tti_request_body;
|
||||
|
||||
LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length);
|
||||
mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]);
|
||||
|
||||
if (mib_sdu_length > 0) {
|
||||
LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length);
|
||||
|
||||
LOG_D(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->nPDUs, mib_sdu_length);
|
||||
if (mib_sdu_length > 0) {
|
||||
LOG_D(MAC,
|
||||
"Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n",
|
||||
frameP,
|
||||
slotP,
|
||||
dl_req->nPDUs,
|
||||
mib_sdu_length);
|
||||
|
||||
if ((frameP & 1023) < 80){
|
||||
LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length);
|
||||
if ((frameP & 1023) < 80){
|
||||
LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length);
|
||||
}
|
||||
|
||||
dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
|
||||
dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
|
||||
|
||||
AssertFatal(cc->ServingCellConfigCommon->physCellId!=NULL,"cc->ServingCellConfigCommon->physCellId is null\n");
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *cc->ServingCellConfigCommon->physCellId;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
|
||||
AssertFatal(cc->ServingCellConfigCommon->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
|
||||
|
||||
const nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
|
||||
dl_req->nPDUs++;
|
||||
}
|
||||
}
|
||||
|
||||
dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
|
||||
dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
|
||||
|
||||
AssertFatal(cc->ServingCellConfigCommon->physCellId!=NULL,"cc->ServingCellConfigCommon->physCellId is null\n");
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *cc->ServingCellConfigCommon->physCellId;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;//ssb_index ;//SSB index for each SSB
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
|
||||
AssertFatal(cc->ServingCellConfigCommon->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
|
||||
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
|
||||
long band = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
uint32_t ssb_offset0 = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
|
||||
int ratio;
|
||||
switch (*cc->ServingCellConfigCommon->ssbSubcarrierSpacing) {
|
||||
case NR_SubcarrierSpacing_kHz15:
|
||||
AssertFatal(band <= 79, "Band %ld is not possible for SSB with 15 kHz SCS\n",band);
|
||||
if (band<77) // below 3GHz
|
||||
ratio=3; // NRARFCN step is 5 kHz
|
||||
else
|
||||
ratio=1; // NRARFCN step is 15 kHz
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz30:
|
||||
AssertFatal(band <= 79, "Band %ld is not possible for SSB with 15 kHz SCS\n",band);
|
||||
if (band<77) // below 3GHz
|
||||
ratio=6; // NRARFCN step is 5 kHz
|
||||
else
|
||||
ratio=2; // NRARFCN step is 15 kHz
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz120:
|
||||
AssertFatal(band >= 257, "Band %ld is not possible for SSB with 120 kHz SCS\n",band);
|
||||
ratio=2; // NRARFCN step is 15 kHz
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz240:
|
||||
AssertFatal(band >= 257, "Band %ld is not possible for SSB with 240 kHz SCS\n",band);
|
||||
ratio=4; // NRARFCN step is 15 kHz
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"SCS %ld not allowed for SSB \n", *cc->ServingCellConfigCommon->ssbSubcarrierSpacing);
|
||||
}
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10;/*cfg->ssb_table.ssb_offset_point_a.value;*/ // absoluteFrequencySSB is the center of SSB
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
|
||||
dl_req->nPDUs++;
|
||||
|
||||
uint8_t *vrb_map = cc[CC_id].vrb_map;
|
||||
const int rbStart = dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA;
|
||||
for (int rb = 0; rb < 20; rb++)
|
||||
vrb_map[rbStart + rb] = 1;
|
||||
// checking if there is any SSB in slot
|
||||
const int abs_slot = (slots_per_frame * frameP) + slotP;
|
||||
const int slot_per_period = (slots_per_frame>>1)<<(*cc->ServingCellConfigCommon->ssb_periodicityServingCell);
|
||||
int eff_120_slot;
|
||||
const BIT_STRING_t *mediumBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.mediumBitmap;
|
||||
uint8_t buf = 0;
|
||||
switch (cc->ServingCellConfigCommon->ssb_PositionsInBurst->present) {
|
||||
case 1:
|
||||
// presence of ssbs possible in the first 2 slots of ssb period
|
||||
if ((abs_slot % slot_per_period) < 2 &&
|
||||
(((mediumBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
|
||||
fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
|
||||
break;
|
||||
case 2:
|
||||
// presence of ssbs possible in the first 4 slots of ssb period
|
||||
if ((abs_slot % slot_per_period) < 4 &&
|
||||
(((mediumBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
|
||||
fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
|
||||
break;
|
||||
case 3:
|
||||
AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing ==
|
||||
NR_SubcarrierSpacing_kHz120,
|
||||
"240kHZ subcarrier spacing currently not supported for SSBs\n");
|
||||
if ((abs_slot % slot_per_period) < 8) {
|
||||
eff_120_slot = slotP;
|
||||
buf = mediumBitmap->buf[0];
|
||||
} else if ((abs_slot % slot_per_period) < 17) {
|
||||
eff_120_slot = slotP - 9;
|
||||
buf = mediumBitmap->buf[1];
|
||||
} else if ((abs_slot % slot_per_period) < 26) {
|
||||
eff_120_slot = slotP - 18;
|
||||
buf = mediumBitmap->buf[2];
|
||||
} else if ((abs_slot % slot_per_period) < 35) {
|
||||
eff_120_slot = slotP - 27;
|
||||
buf = mediumBitmap->buf[3];
|
||||
}
|
||||
if (((buf >> (6 - (eff_120_slot << 1))) & 3) != 0)
|
||||
fill_ssb_vrb_map(cc, ssb_offset0 / (ratio * 12) - 10, CC_id);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0,
|
||||
"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
|
||||
cc->ServingCellConfigCommon->ssb_PositionsInBurst->present);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
|
||||
//----------------------------------------
|
||||
}
|
||||
|
||||
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id) {
|
||||
uint16_t *vrb_map = cc[CC_id].vrb_map;
|
||||
for (int rb = 0; rb < 20; rb++)
|
||||
vrb_map[rbStart + rb] = 1;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
@@ -453,7 +483,6 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
const int CC_id = 0;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
sched_ctrl->rbSize = 0;
|
||||
|
||||
/* Retrieve amount of data to send for this UE */
|
||||
sched_ctrl->num_total_bytes = 0;
|
||||
@@ -470,7 +499,8 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
0,
|
||||
0);
|
||||
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
|
||||
if (sched_ctrl->num_total_bytes == 0 && !get_softmodem_params()->phy_test)
|
||||
if (sched_ctrl->num_total_bytes == 0
|
||||
&& !sched_ctrl->ta_apply) /* If TA should be applied, give at least one RB */
|
||||
return;
|
||||
LOG_D(MAC,
|
||||
"%d.%d, DTCH%d->DLSCH, RLC status %d bytes\n",
|
||||
@@ -505,11 +535,17 @@ 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;
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
const int current_harq_pid = sched_ctrl->current_harq_pid;
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
|
||||
@@ -589,18 +625,26 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd) {
|
||||
/* PREPROCESSOR */
|
||||
nr_simple_dlsch_preprocessor(module_id, frame, slot, num_slots_per_tdd);
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||
|
||||
/* PREPROCESSOR */
|
||||
gNB_mac->pre_processor_dl(module_id, frame, slot, num_slots_per_tdd);
|
||||
|
||||
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
|
||||
|
||||
const int CC_id = 0;
|
||||
|
||||
NR_UE_list_t *UE_list = &UE_info->list;
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
if (sched_ctrl->rbSize <= 0 && !get_softmodem_params()->phy_test)
|
||||
|
||||
/* update TA and set ta_apply every 10 frames.
|
||||
* Possible improvement: take the periodicity from input file.
|
||||
* If such UE is not scheduled now, it will be by the preprocessor later.
|
||||
* If we add the CE, ta_apply will be reset */
|
||||
if (frame >= (sched_ctrl->ta_frame + 10) % 1023)
|
||||
sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */
|
||||
|
||||
if (sched_ctrl->rbSize <= 0)
|
||||
continue;
|
||||
|
||||
const rnti_t rnti = UE_info->rnti[UE_id];
|
||||
@@ -634,34 +678,24 @@ 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]++;
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nr_fill_nfapi_dl_pdu(module_id,
|
||||
UE_id,
|
||||
sched_ctrl->active_bwp->bwp_Id,
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
dl_req,
|
||||
rnti,
|
||||
UE_info->secondaryCellGroup[UE_id],
|
||||
sched_ctrl,
|
||||
pucch,
|
||||
1 /* nrOfLayers */,
|
||||
sched_ctrl->mcs,
|
||||
sched_ctrl->rbSize,
|
||||
sched_ctrl->rbStart,
|
||||
sched_ctrl->numDmrsCdmGrpsNoData,
|
||||
getDmrsConfigType(sched_ctrl->active_bwp),
|
||||
sched_ctrl->mcsTableIdx,
|
||||
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
TBS,
|
||||
sched_ctrl->time_domain_allocation,
|
||||
startSymbolIndex,
|
||||
nrOfSymbols,
|
||||
sched_ctrl->aggregation_level,
|
||||
sched_ctrl->cce_index,
|
||||
current_harq_pid,
|
||||
harq->ndi,
|
||||
harq->round);
|
||||
@@ -698,7 +732,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
* nr_generate_dlsch_pdu() checks for ta_apply and add TA CE if necessary */
|
||||
const int ta_len = (sched_ctrl->ta_apply) ? 2 : 0;
|
||||
|
||||
/* Get RLC data TODO: remove random data retrieval */
|
||||
/* Get RLC data */
|
||||
int header_length_total = 0;
|
||||
int header_length_last = 0;
|
||||
int sdu_length_total = 0;
|
||||
@@ -740,10 +774,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
sdu_length_total += sdu_lengths[num_sdus];
|
||||
header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
|
||||
header_length_total += header_length_last;
|
||||
|
||||
num_sdus++;
|
||||
|
||||
//ue_sched_ctl->uplane_inactivity_timer = 0;
|
||||
}
|
||||
else if (get_softmodem_params()->phy_test) {
|
||||
LOG_D(MAC, "Configuring DL_TX in %d.%d: random data\n", frame, slot);
|
||||
@@ -760,10 +791,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
||||
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total;
|
||||
|
||||
// Check if there is data from RLC or CE
|
||||
const int post_padding = TBS >= 2 + header_length_total + sdu_length_total + ta_len;
|
||||
// padding param currently not in use
|
||||
//padding = TBS - header_length_total - sdu_length_total - ta_len - 1;
|
||||
|
||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
|
||||
@@ -804,6 +832,20 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
retInfo->mcs = sched_ctrl->mcs;
|
||||
retInfo->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData;
|
||||
|
||||
// ta command is sent, values are reset
|
||||
if (sched_ctrl->ta_apply) {
|
||||
sched_ctrl->ta_apply = false;
|
||||
sched_ctrl->ta_frame = frame;
|
||||
LOG_D(MAC,
|
||||
"%d.%2d UE %d TA scheduled, resetting TA frame\n",
|
||||
frame,
|
||||
slot,
|
||||
UE_id);
|
||||
}
|
||||
|
||||
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(buf, TBS));
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
if (frame%100 == 0) {
|
||||
LOG_I(MAC,
|
||||
@@ -816,5 +858,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* mark UE as scheduled */
|
||||
sched_ctrl->rbSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,240 +252,104 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
}
|
||||
}
|
||||
|
||||
int configure_fapi_dl_pdu_phytest(int Mod_idP,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
uint8_t *mcsIndex,
|
||||
uint16_t *rbSize,
|
||||
uint16_t *rbStart) {
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
|
||||
NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
/* schedules whole bandwidth for first user, all the time */
|
||||
void nr_preprocessor_phytest(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd)
|
||||
{
|
||||
if (slot != 1)
|
||||
return; /* only schedule in slot 1 for now */
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
const int UE_id = 0;
|
||||
const int CC_id = 0;
|
||||
AssertFatal(UE_info->active[UE_id],
|
||||
"%s(): expected UE %d to be active\n",
|
||||
__func__,
|
||||
UE_id);
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu;
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu;
|
||||
|
||||
int TBS;
|
||||
int bwp_id=1;
|
||||
int UE_id = 0;
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
|
||||
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
|
||||
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
|
||||
"searchPsacesToAddModList is empty\n");
|
||||
|
||||
dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
|
||||
dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
|
||||
memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
|
||||
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
|
||||
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
|
||||
|
||||
pdsch_pdu_rel15->pduBitmap = 0;
|
||||
pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id];
|
||||
pdsch_pdu_rel15->pduIndex = 0;
|
||||
|
||||
// BWP
|
||||
pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
if (bwp->bwp_Common->genericParameters.cyclicPrefix) pdsch_pdu_rel15->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix;
|
||||
else pdsch_pdu_rel15->CyclicPrefix=0;
|
||||
|
||||
pdsch_pdu_rel15->NrOfCodewords = 1;
|
||||
int mcs = (mcsIndex!=NULL) ? *mcsIndex : 9;
|
||||
int current_harq_pid = UE_info->UE_sched_ctrl[UE_id].current_harq_pid;
|
||||
pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0);
|
||||
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
||||
pdsch_pdu_rel15->mcsIndex[0] = mcs;
|
||||
pdsch_pdu_rel15->mcsTable[0] = 0;
|
||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round];
|
||||
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->nrOfLayers = 1;
|
||||
pdsch_pdu_rel15->transmissionScheme = 0;
|
||||
pdsch_pdu_rel15->refPoint = 0; // Point A
|
||||
UE_info->mac_stats[UE_id].dlsch_rounds[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++;
|
||||
pdsch_pdu_rel15->dmrsConfigType = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
|
||||
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->SCID = 0;
|
||||
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 1;
|
||||
pdsch_pdu_rel15->dmrsPorts = 1;
|
||||
pdsch_pdu_rel15->resourceAlloc = 1;
|
||||
pdsch_pdu_rel15->rbStart = (rbStart!=NULL) ? *rbStart : 0;
|
||||
pdsch_pdu_rel15->rbSize = (rbSize!=NULL) ? *rbSize : pdsch_pdu_rel15->BWPSize;
|
||||
pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
|
||||
|
||||
int startSymbolAndLength=0;
|
||||
int time_domain_assignment=2;
|
||||
int StartSymbolIndex,NrOfSymbols;
|
||||
|
||||
AssertFatal(time_domain_assignment<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count,"time_domain_assignment %d>=%d\n",time_domain_assignment,bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count);
|
||||
startSymbolAndLength = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength,&StartSymbolIndex,&NrOfSymbols);
|
||||
pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
|
||||
pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
|
||||
|
||||
// k0 = *bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0;
|
||||
pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup,
|
||||
scc->dmrs_TypeA_Position,
|
||||
pdsch_pdu_rel15->NrOfSymbols);
|
||||
|
||||
dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t));
|
||||
|
||||
// bwp indicator
|
||||
int n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
|
||||
if (n_dl_bwp < 4)
|
||||
dci_pdu_rel15[0].bwp_indicator.val = bwp_id;
|
||||
else
|
||||
dci_pdu_rel15[0].bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212
|
||||
// frequency domain assignment
|
||||
if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation==NR_PDSCH_Config__resourceAllocation_resourceAllocationType1)
|
||||
dci_pdu_rel15[0].frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275));
|
||||
else
|
||||
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
|
||||
// time domain assignment
|
||||
dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV;
|
||||
// mcs and rv
|
||||
dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0];
|
||||
dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0];
|
||||
// harq pid and ndi
|
||||
dci_pdu_rel15[0].harq_pid = current_harq_pid;
|
||||
dci_pdu_rel15[0].ndi = UE_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
|
||||
dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator;
|
||||
// PDSCH to HARQ TI
|
||||
dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator;
|
||||
UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].feedback_slot = pucch_sched->ul_slot;
|
||||
UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1;
|
||||
// antenna ports
|
||||
dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0
|
||||
// dmrs sequence initialization
|
||||
dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID;
|
||||
LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n",
|
||||
dci_pdu_rel15[0].frequency_domain_assignment.val,
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
pdsch_pdu_rel15->rbSize,
|
||||
NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275),
|
||||
dci_pdu_rel15[0].time_domain_assignment.val,
|
||||
dci_pdu_rel15[0].vrb_to_prb_mapping.val,
|
||||
dci_pdu_rel15[0].mcs,
|
||||
dci_pdu_rel15[0].tb_scaling,
|
||||
dci_pdu_rel15[0].ndi,
|
||||
dci_pdu_rel15[0].rv);
|
||||
|
||||
NR_SearchSpace_t *ss;
|
||||
int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
|
||||
"searchPsacesToAddModList is empty\n");
|
||||
|
||||
int found=0;
|
||||
|
||||
for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
|
||||
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
|
||||
AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
|
||||
AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
|
||||
if (ss->searchSpaceType->present == target_ss) {
|
||||
found=1;
|
||||
break;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
/* find largest unallocated chunk */
|
||||
const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
int rbStart = 0;
|
||||
int tStart = 0;
|
||||
int rbSize = 0;
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
/* find largest unallocated RB region */
|
||||
do {
|
||||
/* advance to first free RB */
|
||||
while (tStart < bwpSize && vrb_map[tStart])
|
||||
tStart++;
|
||||
/* find maximum rbSize at current rbStart */
|
||||
int tSize = 1;
|
||||
while (tStart + tSize < bwpSize && !vrb_map[tStart + tSize])
|
||||
tSize++;
|
||||
if (tSize > rbSize) {
|
||||
rbStart = tStart;
|
||||
rbSize = tSize;
|
||||
}
|
||||
}
|
||||
AssertFatal(found==1,"Couldn't find an adequate searchspace\n");
|
||||
tStart += tSize;
|
||||
} while (tStart < bwpSize);
|
||||
|
||||
uint8_t nr_of_candidates, aggregation_level;
|
||||
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */);
|
||||
const int cid = coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][nr_mac->current_slot];
|
||||
sched_ctrl->num_total_bytes = 0;
|
||||
const int lcid = DL_SCH_LCID_DTCH;
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
/* update sched_ctrl->num_total_bytes so that postprocessor schedules data,
|
||||
* if available */
|
||||
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
|
||||
rnti,
|
||||
module_id,
|
||||
frame,
|
||||
slot,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
0,
|
||||
0);
|
||||
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
|
||||
|
||||
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
|
||||
uint8_t nr_of_candidates;
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space);
|
||||
sched_ctrl->coreset = get_coreset(
|
||||
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][RC.nrmac[module_id]->current_slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
int CCEIndex = allocate_nr_CCEs(nr_mac,
|
||||
bwp,
|
||||
coreset,
|
||||
aggregation_level,
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->coreset,
|
||||
sched_ctrl->aggregation_level,
|
||||
Y,
|
||||
m,
|
||||
nr_of_candidates);
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PDSCH\n", __func__);
|
||||
free(dci_pdu_rel15);
|
||||
return 0;
|
||||
}
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
AssertFatal(sched_ctrl->cce_index >= 0,
|
||||
"%s(): could not find CCE for UE %d\n",
|
||||
__func__,
|
||||
UE_id);
|
||||
|
||||
nr_configure_pdcch(nr_mac,
|
||||
pdcch_pdu_rel15,
|
||||
UE_info->rnti[UE_id],
|
||||
ss,
|
||||
coreset,
|
||||
scc,
|
||||
bwp,
|
||||
aggregation_level,
|
||||
CCEIndex);
|
||||
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");
|
||||
|
||||
int dci_formats[2];
|
||||
int rnti_types[2];
|
||||
|
||||
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
|
||||
dci_formats[0] = NR_DL_DCI_FORMAT_1_1;
|
||||
else
|
||||
dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
|
||||
sched_ctrl->rbStart = rbStart;
|
||||
sched_ctrl->rbSize = rbSize;
|
||||
sched_ctrl->time_domain_allocation = 2;
|
||||
sched_ctrl->mcsTableIdx = 0;
|
||||
sched_ctrl->mcs = 9;
|
||||
sched_ctrl->numDmrsCdmGrpsNoData = 1;
|
||||
|
||||
rnti_types[0] = NR_RNTI_C;
|
||||
|
||||
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id);
|
||||
|
||||
LOG_D(MAC, "DCI params: rnti %x, rnti_type %d, dci_format %d\n \
|
||||
coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
|
||||
pdcch_pdu_rel15->dci_pdu.RNTI[0],
|
||||
rnti_types[0],
|
||||
dci_formats[0],
|
||||
(unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
|
||||
pdcch_pdu_rel15->StartSymbolIndex,
|
||||
pdcch_pdu_rel15->DurationSymbols);
|
||||
|
||||
int x_Overhead = 0; // should be 0 for initialBWP
|
||||
nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu,x_Overhead,pdsch_pdu_rel15->numDmrsCdmGrpsNoData,0);
|
||||
|
||||
// Hardcode it for now
|
||||
TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0];
|
||||
if (UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0)
|
||||
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
||||
|
||||
LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d startSymbolAndLength %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n",
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
pdsch_pdu_rel15->rbSize,
|
||||
startSymbolAndLength,
|
||||
pdsch_pdu_rel15->StartSymbolIndex,
|
||||
pdsch_pdu_rel15->NrOfSymbols,
|
||||
pdsch_pdu_rel15->nrOfLayers,
|
||||
pdsch_pdu_rel15->NrOfCodewords,
|
||||
pdsch_pdu_rel15->mcsIndex[0],
|
||||
TBS);
|
||||
|
||||
free(dci_pdu_rel15);
|
||||
return TBS; //Return TBS in bytes
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
|
||||
vrb_map[rb + sched_ctrl->rbStart] = 1;
|
||||
}
|
||||
|
||||
void config_uldci(NR_BWP_Uplink_t *ubwp,
|
||||
@@ -564,231 +428,6 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,
|
||||
|
||||
}
|
||||
|
||||
|
||||
void configure_fapi_dl_Tx(module_id_t Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
nfapi_nr_pdu_t *tx_req,
|
||||
int tbs_bytes,
|
||||
int16_t pdu_index){
|
||||
|
||||
int CC_id = 0;
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
|
||||
|
||||
LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS (bytes): %d\n",
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
pdsch_pdu_rel15->rbSize,
|
||||
pdsch_pdu_rel15->StartSymbolIndex,
|
||||
pdsch_pdu_rel15->NrOfSymbols,
|
||||
pdsch_pdu_rel15->nrOfLayers,
|
||||
pdsch_pdu_rel15->NrOfCodewords,
|
||||
pdsch_pdu_rel15->mcsIndex[0],
|
||||
tbs_bytes);
|
||||
|
||||
dl_req->nPDUs+=2;
|
||||
|
||||
tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0];
|
||||
tx_req->PDU_index = nr_mac->pdu_index[0]++;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = tbs_bytes +2;
|
||||
|
||||
memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_info.DLSCH_pdu[0][0].payload[0], tbs_bytes);
|
||||
|
||||
nr_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
nr_mac->TX_req[CC_id].SFN = frameP;
|
||||
nr_mac->TX_req[CC_id].Slot = slotP;
|
||||
}
|
||||
|
||||
void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config){
|
||||
|
||||
LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest frame %d slot %d\n",frameP,slotP);
|
||||
|
||||
int post_padding = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0;
|
||||
int lcid, offset, i, header_length_last, TBS_bytes = 0;
|
||||
int UE_id = 0, CC_id = 0;
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
|
||||
//NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
//NR_ServingCellConfigCommon_t *scc=cc->ServingCellConfigCommon;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[gNB_mac->TX_req[CC_id].Number_of_PDUs];
|
||||
|
||||
mac_rlc_status_resp_t rlc_status;
|
||||
|
||||
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
|
||||
|
||||
if (UE_info->num_UEs ==0) return;
|
||||
|
||||
unsigned char sdu_lcids[NB_RB_MAX] = {0};
|
||||
uint16_t sdu_lengths[NB_RB_MAX] = {0};
|
||||
uint16_t rnti = UE_info->rnti[UE_id];
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES];
|
||||
|
||||
LOG_D(MAC, "Scheduling UE specific search space DCI type 1\n");
|
||||
|
||||
int ta_len = (ue_sched_ctl->ta_apply)?2:0;
|
||||
|
||||
TBS_bytes = configure_fapi_dl_pdu_phytest(
|
||||
module_idP,
|
||||
dl_req,
|
||||
pucch_sched,
|
||||
dlsch_config != NULL ? dlsch_config->mcsIndex : NULL,
|
||||
dlsch_config != NULL ? &dlsch_config->rbSize : NULL,
|
||||
dlsch_config != NULL ? &dlsch_config->rbStart : NULL);
|
||||
|
||||
if (TBS_bytes == 0)
|
||||
return;
|
||||
|
||||
lcid = DL_SCH_LCID_DTCH;
|
||||
|
||||
//for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
|
||||
|
||||
// TODO: check if the lcid is active
|
||||
|
||||
LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n",
|
||||
module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3);
|
||||
|
||||
//if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) {
|
||||
rlc_status = mac_rlc_status_ind(module_idP,
|
||||
rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
slotP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
0,
|
||||
0);
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
|
||||
LOG_I(MAC, "configure fapi due to data availability \n");
|
||||
|
||||
LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n",
|
||||
module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
|
||||
lcid, header_length_total, TBS_bytes);
|
||||
|
||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
|
||||
rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
|
||||
(char *)&mac_sdus[sdu_length_total],
|
||||
0,
|
||||
0);
|
||||
|
||||
LOG_W(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid);
|
||||
|
||||
sdu_lcids[num_sdus] = lcid;
|
||||
sdu_length_total += sdu_lengths[num_sdus];
|
||||
header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
|
||||
header_length_total += header_length_last;
|
||||
|
||||
num_sdus++;
|
||||
|
||||
//ue_sched_ctl->uplane_inactivity_timer = 0;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
LOG_D(MAC,"Configuring DL_TX in %d.%d\n", frameP, slotP);
|
||||
|
||||
// fill dlsch_buffer with random data
|
||||
for (i = 0; i < TBS_bytes; i++){
|
||||
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
|
||||
//((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff);
|
||||
}
|
||||
//Sending SDUs with size 1
|
||||
//Initialize elements of sdu_lcids and sdu_lengths
|
||||
sdu_lcids[0] = 0x3f; // DRB
|
||||
sdu_lengths[0] = TBS_bytes - ta_len - 3;
|
||||
header_length_total += 2 + (sdu_lengths[0] >= 128);
|
||||
sdu_length_total += sdu_lengths[0];
|
||||
num_sdus +=1;
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
if (frameP%100 == 0){
|
||||
LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes);
|
||||
for(int i = 0; i < 10; i++) {
|
||||
LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[CC_id][0][0].payload[0])[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total;
|
||||
|
||||
// there is at least one SDU or TA command
|
||||
// if (num_sdus > 0 ){
|
||||
if (ta_len + sdu_length_total + header_length_total > 0) {
|
||||
|
||||
// Check if there is data from RLC or CE
|
||||
if (TBS_bytes >= 2 + header_length_total + sdu_length_total + ta_len) {
|
||||
// we have to consider padding
|
||||
// padding param currently not in use
|
||||
//padding = TBS_bytes - header_length_total - sdu_length_total - ta_len - 1;
|
||||
post_padding = 1;
|
||||
} else {
|
||||
//padding = 0;
|
||||
post_padding = 0;
|
||||
}
|
||||
|
||||
offset = nr_generate_dlsch_pdu(module_idP,
|
||||
&UE_info->UE_sched_ctrl[UE_id],
|
||||
(unsigned char *) mac_sdus,
|
||||
(unsigned char *) gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0],
|
||||
num_sdus, //num_sdus
|
||||
sdu_lengths,
|
||||
sdu_lcids,
|
||||
255, // no drx
|
||||
NULL, // contention res id
|
||||
post_padding);
|
||||
|
||||
// Padding: fill remainder of DLSCH with 0
|
||||
if (post_padding > 0){
|
||||
for (int j = 0; j < (TBS_bytes - offset); j++)
|
||||
gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0][offset + j] = 0; // mac_pdu[offset + j] = 0;
|
||||
}
|
||||
|
||||
configure_fapi_dl_Tx(module_idP, frameP, slotP, dl_req, tx_req, TBS_bytes, gNB_mac->pdu_index[CC_id]);
|
||||
|
||||
if(IS_SOFTMODEM_NOS1){
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n \n", frameP, slotP, TBS_bytes);
|
||||
for(int i = 0; i < 10; i++) { // TBS_bytes dlsch_pdu_rel15->transport_block_size/8 6784/8
|
||||
LOG_I(MAC, "%x. ", mac_payload[i]);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
if (frameP%100 == 0){
|
||||
LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes);
|
||||
for(int i = 0; i < 10; i++) {
|
||||
LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else { // There is no data from RLC or MAC header, so don't schedule
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
|
||||
uint8_t hrq_id;
|
||||
@@ -980,7 +619,7 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
pusch_pdu->resource_alloc = 1; //type 1
|
||||
pusch_pdu->rb_start = 0;
|
||||
if (get_softmodem_params()->phy_test==1)
|
||||
pusch_pdu->rb_size = 50;
|
||||
pusch_pdu->rb_size = min(pusch_pdu->bwp_size,50);
|
||||
else
|
||||
pusch_pdu->rb_size = pusch_pdu->bwp_size;
|
||||
}
|
||||
|
||||
@@ -432,27 +432,17 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
|
||||
}
|
||||
|
||||
void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
int UE_id,
|
||||
int bwp_id,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
rnti_t rnti,
|
||||
NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
int nrOfLayers,
|
||||
uint8_t mcs,
|
||||
uint16_t rbSize,
|
||||
uint16_t rbStart,
|
||||
uint8_t numDmrsCdmGrpsNoData,
|
||||
nfapi_nr_dmrs_type_e dmrsConfigType,
|
||||
uint8_t table_idx,
|
||||
uint16_t R,
|
||||
uint8_t Qm,
|
||||
uint32_t TBS,
|
||||
int time_domain_assignment,
|
||||
int StartSymbolIndex,
|
||||
int NrOfSymbols,
|
||||
uint8_t aggregation_level,
|
||||
int CCEIndex,
|
||||
int harq_pid,
|
||||
int ndi,
|
||||
int round) {
|
||||
@@ -460,9 +450,10 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
const int bwp_id = sched_ctrl->active_bwp->bwp_Id;
|
||||
const int nrOfLayers = 1;
|
||||
const int mcs = sched_ctrl->mcs;
|
||||
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
|
||||
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
|
||||
@@ -487,7 +478,7 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
|
||||
|
||||
pdsch_pdu_rel15->pduBitmap = 0;
|
||||
pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id];
|
||||
pdsch_pdu_rel15->rnti = rnti;
|
||||
pdsch_pdu_rel15->pduIndex = nr_mac->pdu_index[0]++;
|
||||
|
||||
// BWP
|
||||
@@ -512,20 +503,19 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType;
|
||||
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->SCID = 0;
|
||||
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = numDmrsCdmGrpsNoData;
|
||||
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData;
|
||||
pdsch_pdu_rel15->dmrsPorts = 1;
|
||||
pdsch_pdu_rel15->resourceAlloc = 1;
|
||||
pdsch_pdu_rel15->rbStart = rbStart;
|
||||
pdsch_pdu_rel15->rbSize = rbSize;
|
||||
pdsch_pdu_rel15->rbStart = sched_ctrl->rbStart;
|
||||
pdsch_pdu_rel15->rbSize = sched_ctrl->rbSize;
|
||||
pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
|
||||
pdsch_pdu_rel15->targetCodeRate[0] = R;
|
||||
pdsch_pdu_rel15->qamModOrder[0] = Qm;
|
||||
pdsch_pdu_rel15->TBSize[0] = TBS;
|
||||
pdsch_pdu_rel15->mcsTable[0] = table_idx;
|
||||
pdsch_pdu_rel15->mcsTable[0] = sched_ctrl->mcsTableIdx;
|
||||
pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
|
||||
pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
|
||||
|
||||
// k0 = *bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0;
|
||||
pdsch_pdu_rel15->dlDmrsSymbPos =
|
||||
fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup,
|
||||
scc->dmrs_TypeA_Position,
|
||||
@@ -550,8 +540,8 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
275));
|
||||
else
|
||||
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
|
||||
// time domain assignment
|
||||
dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV;
|
||||
// time domain assignment: row index used instead of SLIV
|
||||
dci_pdu_rel15[0].time_domain_assignment.val = sched_ctrl->time_domain_allocation;
|
||||
// mcs and rv
|
||||
dci_pdu_rel15[0].mcs = mcs;
|
||||
dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0];
|
||||
@@ -562,7 +552,7 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
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
|
||||
dci_pdu_rel15[0].tpc = sched_ctrl->tpc1; // table 7.2.1-1 in 38.213
|
||||
// PUCCH resource indicator
|
||||
dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator;
|
||||
// PDSCH to HARQ TI
|
||||
@@ -587,18 +577,18 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
|
||||
nr_configure_pdcch(nr_mac,
|
||||
pdcch_pdu_rel15,
|
||||
UE_info->rnti[UE_id],
|
||||
ss,
|
||||
coreset,
|
||||
rnti,
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
scc,
|
||||
bwp,
|
||||
aggregation_level,
|
||||
CCEIndex);
|
||||
sched_ctrl->aggregation_level,
|
||||
sched_ctrl->cce_index);
|
||||
|
||||
int dci_formats[2];
|
||||
int rnti_types[2];
|
||||
|
||||
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
|
||||
if (sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats)
|
||||
dci_formats[0] = NR_DL_DCI_FORMAT_1_1;
|
||||
else
|
||||
dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
|
||||
@@ -618,17 +608,6 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
pdcch_pdu_rel15->StartSymbolIndex,
|
||||
pdcch_pdu_rel15->DurationSymbols);
|
||||
|
||||
// I don't know why the following is not needed, but in this case we don't
|
||||
// need additional calculations:
|
||||
//const uint16_t N_RE_prime = NR_NB_SC_PER_RB * N_sh_symb - N_PRB_DMRS - N_PRB_oh;
|
||||
//LOG_D(MAC,
|
||||
// "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n",
|
||||
// N_RE_prime,
|
||||
// N_sh_symb,
|
||||
// N_PRB_DMRS,
|
||||
// N_PRB_oh);
|
||||
//pdsch_pdu_rel15->nb_mod_symbols = N_RE_prime*pdsch_pdu_rel15->n_prb*pdsch_pdu_rel15->nb_codewords;
|
||||
|
||||
LOG_D(MAC,
|
||||
"DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d "
|
||||
"nb_layers %d nb_codewords %d mcs %d TBS: %d\n",
|
||||
@@ -735,10 +714,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 +733,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 +797,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 +823,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 +834,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 +842,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 +869,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 +899,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 +915,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,
|
||||
@@ -1608,6 +1685,20 @@ inline void add_nr_ue_list(NR_UE_list_t *listP, int UE_id) {
|
||||
*cur = UE_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a UE from NR_UE_list listP
|
||||
*/
|
||||
inline int remove_nr_ue_list(NR_UE_list_t *listP, int UE_id) {
|
||||
int *cur = &listP->head;
|
||||
while (*cur != -1 && *cur != UE_id)
|
||||
cur = &listP->next[*cur];
|
||||
AssertFatal(*cur != -1, "UE %d not found in UE_list\n", UE_id);
|
||||
int *next = &listP->next[*cur];
|
||||
*cur = listP->next[*cur];
|
||||
*next = -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -1686,15 +1777,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_frame = 0;
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_update = 31;
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_apply = false;
|
||||
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));
|
||||
@@ -1733,9 +1830,11 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
|
||||
|
||||
/* UE found, remove it */
|
||||
UE_id = i;
|
||||
|
||||
UE_info->num_UEs--;
|
||||
UE_info->active[UE_id] = FALSE;
|
||||
UE_info->rnti[UE_id] = 0;
|
||||
remove_nr_ue_list(&UE_info->list, UE_id);
|
||||
free(UE_info->UE_sched_ctrl[UE_id].sched_pucch);
|
||||
free(UE_info->UE_sched_ctrl[UE_id].sched_pusch);
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id],
|
||||
@@ -1817,50 +1916,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 +2219,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) {
|
||||
|
||||
@@ -214,12 +214,8 @@ void nr_process_mac_pdu(
|
||||
int UE_id = find_nr_UE_id(module_idP, rnti);
|
||||
RC.nrmac[module_idP]->UE_info.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
|
||||
log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n");
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
LOG_T(MAC, "%x.", (pdu_ptr + mac_subheader_len)[i]);
|
||||
|
||||
LOG_T(MAC, "\n");
|
||||
#endif
|
||||
if(IS_SOFTMODEM_NOS1){
|
||||
mac_rlc_data_ind(module_idP,
|
||||
@@ -322,40 +318,10 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
UE_info = &gNB_mac->UE_info;
|
||||
int target_snrx10 = gNB_mac->pusch_target_snrx10;
|
||||
|
||||
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[0];
|
||||
|
||||
// random access pusch with TC-RNTI
|
||||
if (ra->state == WAIT_Msg3) {
|
||||
if (sduP != NULL) { // if the CRC passed
|
||||
|
||||
if (ra->rnti != current_rnti) {
|
||||
LOG_E(MAC,
|
||||
"expected TC-RNTI %04x to match current RNTI %04x\n",
|
||||
ra->rnti,
|
||||
current_rnti);
|
||||
return;
|
||||
}
|
||||
free(ra->preambles.preamble_list);
|
||||
ra->state = RA_IDLE;
|
||||
LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti);
|
||||
const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti);
|
||||
UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup;
|
||||
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,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
bwpList->list.count);
|
||||
const int bwp_id = 1;
|
||||
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
|
||||
LOG_I(MAC,
|
||||
"[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
|
||||
"adding UE MAC Context UE_id %d/RNTI %04x\n",
|
||||
gnb_mod_idP,
|
||||
current_rnti,
|
||||
UE_id,
|
||||
ra->rnti);
|
||||
}
|
||||
return;
|
||||
if (sduP != NULL) {
|
||||
T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP),
|
||||
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */,
|
||||
T_BUFFER(sduP, sdu_lenP));
|
||||
}
|
||||
|
||||
if (UE_id != -1) {
|
||||
@@ -385,6 +351,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
}
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
|
||||
LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n");
|
||||
for (int i = 0; i < sdu_lenP ; i++) {
|
||||
//harq_process_ul_ue->a[i] = (unsigned char) rand();
|
||||
@@ -392,6 +359,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
printf("%02x ",(unsigned char)sduP[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
#endif
|
||||
|
||||
if (sduP != NULL){
|
||||
@@ -401,6 +369,54 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!sduP) // check that CRC passed
|
||||
return;
|
||||
|
||||
/* we don't know this UE (yet). Check whether there is a ongoing RA (Msg 3)
|
||||
* and check the corresponding UE's RNTI match, in which case we activate
|
||||
* it. */
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
|
||||
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
|
||||
if (ra->state != WAIT_Msg3)
|
||||
continue;
|
||||
|
||||
// random access pusch with TC-RNTI
|
||||
if (ra->rnti != current_rnti) {
|
||||
LOG_W(MAC,
|
||||
"expected TC-RNTI %04x to match current RNTI %04x\n",
|
||||
ra->rnti,
|
||||
current_rnti);
|
||||
continue;
|
||||
}
|
||||
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,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
bwpList->list.count);
|
||||
const int bwp_id = 1;
|
||||
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
|
||||
LOG_I(MAC,
|
||||
"[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
|
||||
"adding UE MAC Context UE_id %d/RNTI %04x\n",
|
||||
gnb_mod_idP,
|
||||
current_rnti,
|
||||
UE_id,
|
||||
ra->rnti);
|
||||
// re-initialize ta update variables afrer RA procedure completion
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP;
|
||||
|
||||
free(ra->preambles.preamble_list);
|
||||
ra->state = RA_IDLE;
|
||||
LOG_I(MAC,
|
||||
"reset RA state information for RA-RNTI %04x/index %d\n",
|
||||
ra->rnti,
|
||||
i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -82,7 +80,13 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd);
|
||||
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
|
||||
/* \brief default preprocessor */
|
||||
void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd);
|
||||
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, uint8_t slots_per_frame);
|
||||
|
||||
/////// Random Access MAC-PHY interface functions and primitives ///////
|
||||
|
||||
@@ -126,42 +130,37 @@ uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
|
||||
|
||||
/////// Phy test scheduler ///////
|
||||
|
||||
/* \brief preprocessor for phytest: schedules UE_id 0 with fixed MCS on all
|
||||
* freq resources */
|
||||
void nr_preprocessor_phytest(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd);
|
||||
|
||||
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframeP);
|
||||
|
||||
void nr_fill_nfapi_dl_pdu(int Mod_id,
|
||||
int UE_id,
|
||||
int bwp_id,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
rnti_t rnti,
|
||||
NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
int nrOfLayers,
|
||||
uint8_t mcs,
|
||||
uint16_t rbSize,
|
||||
uint16_t rbStart,
|
||||
uint8_t numDmrsCdmGrpsNoData,
|
||||
nfapi_nr_dmrs_type_e dmrsConfigType,
|
||||
uint8_t table_idx,
|
||||
uint16_t R,
|
||||
uint8_t Qm,
|
||||
uint32_t tbs,
|
||||
int time_domain_assignment,
|
||||
int StartSymbolIndex,
|
||||
int NrOfSymbols,
|
||||
uint8_t aggregation_level,
|
||||
int CCEIndex,
|
||||
int harq_pid,
|
||||
int ndi,
|
||||
int round);
|
||||
|
||||
int configure_fapi_dl_pdu_phytest(int Mod_id,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
uint8_t *mcsIndex,
|
||||
uint16_t *rbSize,
|
||||
uint16_t *rbStart);
|
||||
void 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,
|
||||
@@ -171,20 +170,6 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,
|
||||
int time_domain_assignment, uint8_t tpc,
|
||||
int n_ubwp, int bwp_id);
|
||||
|
||||
void configure_fapi_dl_Tx(module_id_t Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
nfapi_nr_pdu_t *tx_req,
|
||||
int tbs_bytes,
|
||||
int16_t pdu_index);
|
||||
|
||||
void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config);
|
||||
|
||||
void nr_schedule_pusch(int Mod_idP,
|
||||
int UE_id,
|
||||
int num_slots_per_tdd,
|
||||
@@ -198,12 +183,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 +228,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 +317,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);
|
||||
@@ -366,6 +374,8 @@ int binomial(int n, int k);
|
||||
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
|
||||
|
||||
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id);
|
||||
|
||||
|
||||
/* \brief Function to indicate a received SDU on ULSCH.
|
||||
@param Mod_id Instance ID of gNB
|
||||
|
||||
@@ -82,6 +82,11 @@ void mac_top_init_gNB(void)
|
||||
|
||||
RC.nrmac[i]->ul_handle = 0;
|
||||
|
||||
if (get_softmodem_params()->phy_test)
|
||||
RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest;
|
||||
else
|
||||
RC.nrmac[i]->pre_processor_dl = nr_simple_dlsch_preprocessor;
|
||||
|
||||
}//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
|
||||
|
||||
AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n");
|
||||
|
||||
@@ -68,6 +68,9 @@
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
#include "NR_TAG.h"
|
||||
|
||||
#include <openair3/UICC/usim_interface.h>
|
||||
|
||||
|
||||
/* Defs */
|
||||
#define MAX_NUM_BWP 2
|
||||
#define MAX_NUM_CORESET 2
|
||||
@@ -188,9 +191,9 @@ typedef struct {
|
||||
/// Template for RA computations
|
||||
NR_RA_t ra[NR_NB_RA_PROC_MAX];
|
||||
/// VRB map for common channels
|
||||
uint8_t vrb_map[275];
|
||||
uint16_t vrb_map[275];
|
||||
/// VRB map for common channels and retransmissions by PHICH
|
||||
uint8_t vrb_map_UL[275];
|
||||
uint16_t vrb_map_UL[275];
|
||||
/// number of subframe allocation pattern available for MBSFN sync area
|
||||
uint8_t num_sf_allocation_pattern;
|
||||
///Number of active SSBs
|
||||
@@ -274,10 +277,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 +320,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 +348,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
|
||||
@@ -350,7 +375,7 @@ typedef struct {
|
||||
/// Retransmission-related information
|
||||
NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES];
|
||||
|
||||
uint16_t ta_timer;
|
||||
uint16_t ta_frame;
|
||||
int16_t ta_update;
|
||||
bool ta_apply;
|
||||
uint8_t tpc0;
|
||||
@@ -364,7 +389,11 @@ typedef struct {
|
||||
} NR_UE_sched_ctrl_t;
|
||||
|
||||
typedef struct {
|
||||
boolean_t fiveG_connected;
|
||||
uicc_t *uicc;
|
||||
} NRUEcontext_t;
|
||||
|
||||
typedef struct {
|
||||
int lc_bytes_tx[64];
|
||||
int lc_bytes_rx[64];
|
||||
int dlsch_rounds[8];
|
||||
@@ -377,6 +406,7 @@ typedef struct {
|
||||
} NR_mac_stats_t;
|
||||
|
||||
|
||||
|
||||
/*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in
|
||||
* the scheduler and to keep "classes" of users. */
|
||||
typedef struct {
|
||||
@@ -384,14 +414,18 @@ typedef struct {
|
||||
int next[MAX_MOBILES_PER_GNB];
|
||||
} 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;
|
||||
int num_UEs;
|
||||
|
||||
bool active[MAX_MOBILES_PER_GNB];
|
||||
rnti_t rnti[MAX_MOBILES_PER_GNB];
|
||||
NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB];
|
||||
@@ -403,6 +437,11 @@ typedef struct {
|
||||
uint8_t UE_beam_index[MAX_MOBILES_PER_GNB];
|
||||
} NR_UE_info_t;
|
||||
|
||||
typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd);
|
||||
|
||||
/*! \brief top level eNB MAC structure */
|
||||
typedef struct gNB_MAC_INST_s {
|
||||
/// Ethernet parameters for northbound midhaul interface
|
||||
@@ -465,6 +504,9 @@ typedef struct gNB_MAC_INST_s {
|
||||
int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
|
||||
/// current slot
|
||||
int current_slot;
|
||||
|
||||
/// DL preprocessor for differentiated scheduling
|
||||
nr_pp_impl_dl pre_processor_dl;
|
||||
} gNB_MAC_INST;
|
||||
|
||||
#endif /*__LAYER2_NR_MAC_GNB_H__ */
|
||||
|
||||
@@ -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;
|
||||
@@ -1035,7 +1025,7 @@ pdcp_data_ind(
|
||||
pushNotifiedFIFO(&pdcp_sdu_list, new_sdu_p);
|
||||
|
||||
/* Print octets of incoming data in hexadecimal form */
|
||||
LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n",
|
||||
LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n",
|
||||
sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t),
|
||||
sdu_buffer_sizeP - payload_offset);
|
||||
//util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset);
|
||||
@@ -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"
|
||||
|
||||
@@ -156,9 +150,9 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
|
||||
nas_nlh_tx->nlmsg_len = sizeToWrite;
|
||||
ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0);
|
||||
} // PDCP_USE_NETLINK
|
||||
|
||||
AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]);
|
||||
|
||||
AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]);
|
||||
|
||||
if( LOG_DEBUGFLAG(DEBUG_PDCP) )
|
||||
log_dump(PDCP, pdcpData, min(sizeToWrite,30) , LOG_DUMP_CHAR,
|
||||
"Printing first bytes of PDCP SDU before removing it from the list: \n");
|
||||
@@ -202,6 +196,7 @@ int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) {
|
||||
//} // PDCP_USE_NETLINK
|
||||
|
||||
//AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
|
||||
|
||||
//AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
|
||||
delNotifiedFIFO_elt (sdu_p);
|
||||
pdcp_nb_sdu_sent ++;
|
||||
@@ -503,11 +498,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;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ void (*rlc_rrc_data_conf)(
|
||||
const protocol_ctxt_t *const ctxtP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const rlc_tx_status_t statusP);
|
||||
const rlc_tx_status_t statusP) __attribute__ ((aligned(32)));
|
||||
|
||||
typedef void (rrc_data_ind_cb_t)(
|
||||
const protocol_ctxt_t *const ctxtP,
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include "nr_pdcp_ue_manager.h"
|
||||
#include "NR_RadioBearerConfig.h"
|
||||
#include "NR_RLC-BearerConfig.h"
|
||||
@@ -43,6 +46,7 @@ static uint64_t pdcp_optmask;
|
||||
/* rlc_data_req queue - begin */
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/* NR PDCP and RLC both use "big locks". In some cases a thread may do
|
||||
@@ -92,6 +96,7 @@ static void *rlc_data_req_thread(void *_)
|
||||
{
|
||||
int i;
|
||||
|
||||
pthread_setname_np(pthread_self(), "RLC queue");
|
||||
while (1) {
|
||||
if (pthread_mutex_lock(&q.m) != 0) abort();
|
||||
while (q.length == 0)
|
||||
@@ -203,6 +208,7 @@ static void *enb_tun_read_thread(void *_)
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
int rb_id = 1;
|
||||
pthread_setname_np( pthread_self(),"enb_tun_read");
|
||||
|
||||
while (1) {
|
||||
len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD);
|
||||
@@ -247,7 +253,7 @@ static void *ue_tun_read_thread(void *_)
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
int rb_id = 1;
|
||||
|
||||
pthread_setname_np( pthread_self(),"ue_tun_read");
|
||||
while (1) {
|
||||
len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD);
|
||||
if (len == -1) {
|
||||
@@ -368,7 +374,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)
|
||||
|
||||
@@ -922,6 +922,7 @@ static missing_data_t next_missing(nr_rlc_entity_am_t *entity,
|
||||
*/
|
||||
ret.sn_start = entity->rx_next;
|
||||
ret.so_start = 0;
|
||||
ret.next = cur;
|
||||
goto set_end_different_sdu;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -3295,7 +3295,10 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz30;
|
||||
if (rrc_inst->nr_scg_ssb_freq > 2016666) //FR2
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz120;
|
||||
else
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz30;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.quantityConfigSet_r15 = 1;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.ext1 = calloc(1, sizeof(struct LTE_MeasObjectNR_r15__ext1));
|
||||
|
||||
@@ -3306,7 +3309,11 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
if (MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15 == NULL) exit(1);
|
||||
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->present = LTE_MeasObjectNR_r15__ext1__bandNR_r15_PR_setup;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 78;
|
||||
if (rrc_inst->nr_scg_ssb_freq > 2016666) //FR2
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 261;
|
||||
else
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 78;
|
||||
|
||||
ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj2);
|
||||
}
|
||||
|
||||
@@ -4020,7 +4027,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt
|
||||
MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6;
|
||||
//<<<<<<< HEAD
|
||||
MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB
|
||||
|
||||
if (rrc_inst->carrier[0].sib1->tdd_Config!=NULL) {
|
||||
@@ -4635,6 +4641,7 @@ rrc_eNB_process_MeasurementReport(
|
||||
|
||||
case 7:
|
||||
LOG_D(RRC, "NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe);
|
||||
printf("NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -88,6 +88,12 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
|
||||
}
|
||||
|
||||
/* TODO BCCH SIB1 SIBs */
|
||||
if ((Srb_id & RAB_OFFSET ) == BCCH) {
|
||||
memcpy(&buffer_pP[0],
|
||||
RC.rrc[Mod_idP]->carrier[CC_id].SIB1_MBMS,
|
||||
RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_MBMS);
|
||||
|
||||
}
|
||||
|
||||
/* CCCH */
|
||||
if( (Srb_id & RAB_OFFSET ) == CCCH) {
|
||||
@@ -114,4 +120,4 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,6 +200,10 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) {
|
||||
mib->message.choice.mib->spare.bits_unused = 7; // This makes a spare of 1 bits
|
||||
|
||||
mib->message.choice.mib->ssb_SubcarrierOffset = (carrier->ssb_SubcarrierOffset)&15;
|
||||
/*
|
||||
* The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables
|
||||
* the reverse allocation is in nr_ue_decode_mib()
|
||||
*/
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero;
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero;
|
||||
AssertFatal(scc->ssbSubcarrierSpacing != NULL, "scc->ssbSubcarrierSpacing is null\n");
|
||||
@@ -265,10 +269,6 @@ uint8_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 ;
|
||||
struct NR_SIB1 *sib1 ;
|
||||
int i;
|
||||
struct NR_PLMN_IdentityInfo nr_plmn_info;
|
||||
|
||||
// TODO : Add support for more than one PLMN
|
||||
//int num_plmn = configuration->num_plmn;
|
||||
@@ -276,31 +276,29 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
struct NR_PLMN_Identity nr_plmn[num_plmn];
|
||||
NR_MCC_MNC_Digit_t nr_mcc_digit[num_plmn][3];
|
||||
NR_MCC_MNC_Digit_t nr_mnc_digit[num_plmn][3];
|
||||
memset(nr_plmn,0,sizeof(nr_plmn));
|
||||
memset(nr_mcc_digit,0,sizeof(nr_mcc_digit));
|
||||
memset(nr_mnc_digit,0,sizeof(nr_mnc_digit));
|
||||
|
||||
// struct NR_UAC_BarringInfoSet nr_uac_BarringInfoSet;
|
||||
sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t));
|
||||
memset(sib1_message,0,sizeof(NR_BCCH_DL_SCH_Message_t));
|
||||
NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t));
|
||||
carrier->siblock1 = sib1_message;
|
||||
sib1_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1;
|
||||
sib1_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1));
|
||||
memset(sib1_message->message.choice.c1,0,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1));
|
||||
sib1_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1;
|
||||
sib1_message->message.choice.c1->choice.systemInformationBlockType1 = CALLOC(1,sizeof(struct NR_SIB1));
|
||||
sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1;
|
||||
memset(sib1,0,sizeof(struct NR_SIB1));
|
||||
|
||||
struct NR_SIB1 *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1;
|
||||
sib1->cellSelectionInfo = CALLOC(1,sizeof(struct NR_SIB1__cellSelectionInfo));
|
||||
memset(sib1->cellSelectionInfo,0,sizeof(struct NR_SIB1__cellSelectionInfo));
|
||||
sib1->cellSelectionInfo->q_RxLevMin = -50;
|
||||
memset(&nr_plmn_info.plmn_IdentityList,0,sizeof(struct NR_PLMN_IdentityInfo__plmn_IdentityList));
|
||||
asn_set_empty(&nr_plmn_info.plmn_IdentityList.list);
|
||||
memset(&nr_plmn_info,0,sizeof(struct NR_PLMN_IdentityInfo));
|
||||
memset(nr_plmn,0,num_plmn*sizeof(struct NR_PLMN_Identity));
|
||||
|
||||
for (i = 0; i < num_plmn; ++i) {
|
||||
struct NR_PLMN_IdentityInfo *nr_plmn_info=CALLOC(1,sizeof(struct NR_PLMN_IdentityInfo));
|
||||
asn_set_empty(&nr_plmn_info->plmn_IdentityList.list);
|
||||
for (int i = 0; i < num_plmn; ++i) {
|
||||
nr_mcc_digit[i][0] = (configuration->mcc[i]/100)%10;
|
||||
nr_mcc_digit[i][1] = (configuration->mcc[i]/10)%10;
|
||||
nr_mcc_digit[i][2] = (configuration->mcc[i])%10;
|
||||
nr_plmn[i].mcc = CALLOC(1,sizeof(struct NR_MCC));
|
||||
memset(nr_plmn[i].mcc,0,sizeof(struct NR_MCC));
|
||||
asn_set_empty(&nr_plmn[i].mcc->list);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][0]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][1]);
|
||||
@@ -308,26 +306,23 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
nr_mnc_digit[i][0] = (configuration->mnc[i]/100)%10;
|
||||
nr_mnc_digit[i][1] = (configuration->mnc[i]/10)%10;
|
||||
nr_mnc_digit[i][2] = (configuration->mnc[i])%10;
|
||||
memset(&nr_plmn[i].mnc,0,sizeof(NR_MNC_t));
|
||||
nr_plmn[i].mnc.list.size=0;
|
||||
nr_plmn[i].mnc.list.count=0;
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][0]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][1]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][2]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn_info.plmn_IdentityList.list, &nr_plmn[i]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn_info->plmn_IdentityList.list, &nr_plmn[i]);
|
||||
}//end plmn loop
|
||||
|
||||
nr_plmn_info.cellIdentity.buf = MALLOC(8);
|
||||
memset(nr_plmn_info.cellIdentity.buf,0,8);
|
||||
nr_plmn_info.cellIdentity.buf[0]= (configuration->cell_identity >> 20) & 0xff;
|
||||
nr_plmn_info.cellIdentity.buf[1]= (configuration->cell_identity >> 12) & 0xff;
|
||||
nr_plmn_info.cellIdentity.buf[2]= (configuration->cell_identity >> 4) & 0xff;
|
||||
nr_plmn_info.cellIdentity.buf[3]= (configuration->cell_identity << 4) & 0xff;
|
||||
nr_plmn_info.cellIdentity.size= 4;
|
||||
nr_plmn_info.cellIdentity.bits_unused= 4;
|
||||
nr_plmn_info.cellReservedForOperatorUse = 0;
|
||||
memset(&sib1->cellAccessRelatedInfo,0,sizeof(NR_CellAccessRelatedInfo_t));
|
||||
ASN_SEQUENCE_ADD(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list, &nr_plmn_info);
|
||||
nr_plmn_info->cellIdentity.buf = CALLOC(1,8);
|
||||
nr_plmn_info->cellIdentity.buf[0]= (configuration->cell_identity >> 20) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[1]= (configuration->cell_identity >> 12) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[2]= (configuration->cell_identity >> 4) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[3]= (configuration->cell_identity << 4) & 0xff;
|
||||
nr_plmn_info->cellIdentity.size= 4;
|
||||
nr_plmn_info->cellIdentity.bits_unused= 4;
|
||||
nr_plmn_info->cellReservedForOperatorUse = 0;
|
||||
ASN_SEQUENCE_ADD(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list, nr_plmn_info);
|
||||
#if 0
|
||||
sib1->uac_BarringInfo = CALLOC(1, sizeof(struct NR_SIB1__uac_BarringInfo));
|
||||
memset(sib1->uac_BarringInfo, 0, sizeof(struct NR_SIB1__uac_BarringInfo));
|
||||
@@ -340,11 +335,12 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
ASN_SEQUENCE_ADD(&sib1->uac_BarringInfo->uac_BarringInfoSetList, &nr_uac_BarringInfoSet);
|
||||
#endif
|
||||
//encode SIB1 to data
|
||||
carrier->SIB1=(uint8_t *) malloc16(128);
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message,
|
||||
NULL,
|
||||
(void *)sib1_message,
|
||||
carrier->SIB1,
|
||||
100);
|
||||
128);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
@@ -578,3 +574,8 @@ void do_SpCellConfig(gNB_RRC_INST *rrc,
|
||||
spconfig->reconfigurationWithSync = CALLOC(1,sizeof(struct NR_ReconfigurationWithSync));
|
||||
}
|
||||
|
||||
|
||||
int do_DLInformationTransfer_NR (void * p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
#include <openair2/RRC/LTE/MESSAGES/asn1_msg.h>
|
||||
#include <openair2/RRC/NR/nr_rrc_proto.h>
|
||||
|
||||
void rrc_gNB_process_NGAP_DOWNLINK_NAS (void ) {
|
||||
do_DLInformationTransfer(0,NULL,0,0,NULL);
|
||||
// send it as DL data
|
||||
/*
|
||||
rrc_data_req (
|
||||
&ctxt,
|
||||
srb_id,
|
||||
(*rrc_eNB_mui)++,
|
||||
SDU_CONFIRM_NO,
|
||||
length,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void rrc_gNB_send_NGAP_NAS_FIRST_REQ(void ) {
|
||||
// We are noCore only now
|
||||
// create message that should come from 5GC
|
||||
|
||||
// send it dow
|
||||
rrc_gNB_process_NGAP_DOWNLINK_NAS();
|
||||
}
|
||||
|
||||
void nr_rrc_rx_tx() {
|
||||
// check timers
|
||||
|
||||
// check if UEs are lost, to remove them from upper layers
|
||||
|
||||
//
|
||||
|
||||
}
|
||||
@@ -93,7 +93,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
|
||||
|
||||
int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m);
|
||||
|
||||
|
||||
void nr_rrc_rx_tx(void);
|
||||
|
||||
/**\brief RRC eNB task.
|
||||
\param void *args_p Pointer on arguments to start the task. */
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
|
||||
#include "executables/softmodem-common.h"
|
||||
#include <openair2/RRC/NR/rrc_gNB_UE_context.h>
|
||||
#include <openair2/X2AP/x2ap_eNB.h>
|
||||
|
||||
//#define XER_PRINT
|
||||
|
||||
@@ -178,10 +179,11 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge(
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
|
||||
static void init_NR_SI(gNB_RRC_INST *rrc) {
|
||||
static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration) {
|
||||
LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__);
|
||||
rrc->carrier.MIB = (uint8_t *) malloc16(4);
|
||||
rrc->carrier.sizeof_MIB = do_MIB_NR(rrc,0);
|
||||
rrc->carrier.sizeof_SIB1 = do_SIB1_NR(&rrc->carrier,configuration);
|
||||
LOG_I(NR_RRC,"Done init_NR_SI\n");
|
||||
rrc_mac_config_req_gNB(rrc->module_id,
|
||||
rrc->carrier.ssb_SubcarrierOffset,
|
||||
@@ -271,7 +273,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
|
||||
rrc->carrier.pucch_TargetSNRx10 = configuration->pucch_TargetSNRx10;
|
||||
/// System Information INIT
|
||||
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Checking release \n",PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt));
|
||||
init_NR_SI(rrc);
|
||||
init_NR_SI(rrc, configuration);
|
||||
rrc_init_nr_global_param();
|
||||
openair_nr_rrc_on(&ctxt);
|
||||
return 0;
|
||||
@@ -317,8 +319,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
@@ -6,6 +6,7 @@
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define MAC_LTE_DLT 147
|
||||
#define DLT_IPV4 228
|
||||
/********************************************************/
|
||||
/* Definitions and descriptions come from:
|
||||
http://wiki.wireshark.org/Development/LibpcapFileFormat */
|
||||
@@ -29,20 +30,4 @@ typedef struct pcaprec_hdr_s {
|
||||
unsigned int orig_len; /* actual length of packet */
|
||||
} pcaprec_hdr_t;
|
||||
|
||||
/* Context information for every MAC PDU that will be logged */
|
||||
typedef struct MAC_Context_Info_t {
|
||||
unsigned short radioType;
|
||||
unsigned char direction;
|
||||
unsigned char rntiType;
|
||||
unsigned short rnti;
|
||||
unsigned short ueid;
|
||||
unsigned char isRetx;
|
||||
unsigned char crcStatusOK;
|
||||
|
||||
unsigned short sysFrameNumber;
|
||||
unsigned short subFrameNumber;
|
||||
|
||||
unsigned int subframesSinceCaptureStart;
|
||||
} MAC_Context_Info_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -73,7 +73,7 @@ typedef guint8 gboolean;
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define OPT_PARAMS_DESC { \
|
||||
{"type" , CONFIG_HLP_TYPEMON, 0, strptr:&in_type, defstrval:"none", TYPE_STRING, 0}, \
|
||||
{"type" , CONFIG_HLP_TYPEMON, 0, strptr:(char**)&in_type, defstrval:"none", TYPE_STRING, 0}, \
|
||||
{"ip" , CONFIG_HLP_L2MONIP, 0, strptr:(char**)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, 0}, \
|
||||
{"path" , CONFIG_HLP_L2MONPATH, 0, strptr:(char**)&in_path,defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, 0}, \
|
||||
}
|
||||
|
||||
+108
-107
@@ -90,6 +90,7 @@ what about the implementation
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "opt.h"
|
||||
#include "common/utils/system.h"
|
||||
@@ -99,8 +100,6 @@ int opt_enabled=0;
|
||||
//static unsigned char g_PDUBuffer[1600];
|
||||
//static unsigned int g_PDUOffset;
|
||||
|
||||
static char in_ip[128]={0};
|
||||
static char in_path[128]={0};
|
||||
FILE *file_fd = NULL;
|
||||
pcap_hdr_t file_header = {
|
||||
0xa1b2c3d4, /* magic number */
|
||||
@@ -108,10 +107,14 @@ pcap_hdr_t file_header = {
|
||||
0, /* timezone */
|
||||
0, /* sigfigs - apparently all tools do this */
|
||||
65535, /* snaplen - this should be long enough */
|
||||
MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */
|
||||
DLT_IPV4
|
||||
//MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */
|
||||
};
|
||||
|
||||
trace_mode_t opt_type = OPT_NONE;
|
||||
static char *in_type=NULL;
|
||||
static char *in_path=NULL;
|
||||
static char *in_ip=NULL;
|
||||
static unsigned int subframesSinceCaptureStart;
|
||||
|
||||
static int g_socksd = -1;/* UDP socket used for sending frames */
|
||||
@@ -131,8 +134,80 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
guint8 oob_event, guint8 oob_event_value,
|
||||
uint8_t *pdu_buffer, unsigned int pdu_buffer_size);
|
||||
|
||||
static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
|
||||
const unsigned char *PDU, unsigned int length);
|
||||
unsigned short checksum(unsigned short *ptr, int length) {
|
||||
int sum = 0;
|
||||
u_short answer = 0;
|
||||
unsigned short *w = ptr;
|
||||
int nleft = length;
|
||||
|
||||
while(nleft > 1) {
|
||||
sum += *w++;
|
||||
nleft -= 2;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xFFFF);
|
||||
sum += (sum >> 16);
|
||||
answer = ~sum;
|
||||
return(answer);
|
||||
}
|
||||
|
||||
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
|
||||
static int MAC_LTE_PCAP_WritePDU(const uint8_t *PDU,
|
||||
unsigned int length) {
|
||||
pcaprec_hdr_t packet_header;
|
||||
// IPv4 header
|
||||
typedef struct ip_hdr {
|
||||
unsigned char ip_verlen; // 4-bit IPv4 version 4-bit header length (in 32-bit words)
|
||||
unsigned char ip_tos; // IP type of service
|
||||
unsigned short ip_totallength; // Total length
|
||||
unsigned short ip_id; // Unique identifier
|
||||
unsigned short ip_offset; // Fragment offset field
|
||||
unsigned char ip_ttl; // Time to live
|
||||
unsigned char ip_protocol; // Protocol(TCP,UDP etc)
|
||||
unsigned short ip_checksum; // IP checksum
|
||||
unsigned int ip_srcaddr; // Source address
|
||||
unsigned int ip_destaddr; // Source address
|
||||
} IPV4_HDR;
|
||||
// Define the UDP header
|
||||
typedef struct udp_hdr {
|
||||
unsigned short src_portno; // Source port no.
|
||||
unsigned short dst_portno; // Dest. port no.
|
||||
unsigned short udp_length; // Udp packet length
|
||||
unsigned short udp_checksum; // Udp checksum (optional)
|
||||
} UDP_HDR;
|
||||
IPV4_HDR IPheader= {0};
|
||||
IPheader.ip_verlen = (4 << 4) | (sizeof(IPV4_HDR) / sizeof(uint32_t));
|
||||
IPheader.ip_totallength = htons(sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length);
|
||||
IPheader.ip_ttl = 8; // Time-to-live is eight
|
||||
IPheader.ip_protocol = IPPROTO_UDP;
|
||||
IPheader.ip_srcaddr = inet_addr(in_ip);
|
||||
IPheader.ip_destaddr = inet_addr(in_ip);
|
||||
IPheader.ip_checksum = checksum((unsigned short *)&IPheader, sizeof(IPV4_HDR));
|
||||
// Initialize the UDP header
|
||||
UDP_HDR UDPheader;
|
||||
UDPheader.src_portno = htons( PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
UDPheader.dst_portno = htons( PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
UDPheader.udp_length = htons(sizeof(UDP_HDR) + length);
|
||||
UDPheader.udp_checksum = 0;
|
||||
/****************************************************************/
|
||||
/* PCAP Header */
|
||||
/* TODO: Timestamp might want to be relative to a more sensible
|
||||
base time... */
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
packet_header.ts_sec = tv.tv_sec;
|
||||
packet_header.ts_usec = tv.tv_usec;
|
||||
packet_header.incl_len =sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length;
|
||||
packet_header.orig_len =sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length;
|
||||
/***************************************************************/
|
||||
/* Now write everything to the file */
|
||||
fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd);
|
||||
fwrite(&IPheader, sizeof(IPV4_HDR), 1, file_fd);
|
||||
fwrite(&UDPheader, sizeof(UDP_HDR), 1, file_fd);
|
||||
fwrite(PDU, 1, length, file_fd);
|
||||
fflush(file_fd);
|
||||
return length;
|
||||
}
|
||||
|
||||
static void *opt_listener_thread(void *arg) {
|
||||
ssize_t ret;
|
||||
@@ -198,7 +273,6 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) {
|
||||
}
|
||||
|
||||
threadCreate(&opt_listener.thread, opt_listener_thread, NULL, "flexran", -1, OAI_PRIORITY_RT_LOW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -321,67 +395,20 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
frameOffset += pdu_buffer_size;
|
||||
}
|
||||
|
||||
/* Send out the data over the UDP socket */
|
||||
bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0,
|
||||
(const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr));
|
||||
if ( opt_type == OPT_WIRESHARK )
|
||||
/* Send out the data over the UDP socket */
|
||||
bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0,
|
||||
(const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr));
|
||||
else
|
||||
bytesSent = MAC_LTE_PCAP_WritePDU(frameBuffer, frameOffset);
|
||||
|
||||
if (bytesSent != frameOffset) {
|
||||
LOG_W(OPT, "sendto() failed (not a thread-safe func)- expected %d bytes, got %ld (errno=%d)\n",
|
||||
LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n",
|
||||
frameOffset, bytesSent, errno);
|
||||
//exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
|
||||
static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
|
||||
const uint8_t *PDU,
|
||||
unsigned int length)
|
||||
{
|
||||
pcaprec_hdr_t packet_header;
|
||||
uint8_t context_header[256];
|
||||
int offset = 0;
|
||||
unsigned short tmp16;
|
||||
/*****************************************************************/
|
||||
/* Context information (same as written by UDP heuristic clients */
|
||||
context_header[offset++] = context->radioType;
|
||||
context_header[offset++] = context->direction;
|
||||
context_header[offset++] = context->rntiType;
|
||||
/* RNTI */
|
||||
context_header[offset++] = MAC_LTE_RNTI_TAG;
|
||||
tmp16 = htons(context->rnti);
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
/* UEId */
|
||||
context_header[offset++] = MAC_LTE_UEID_TAG;
|
||||
tmp16 = htons(context->ueid);
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
/* Subframe number */
|
||||
context_header[offset++] = MAC_LTE_FRAME_SUBFRAME_TAG;
|
||||
tmp16 = htons(context->subFrameNumber);
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
/* CRC Status */
|
||||
context_header[offset++] = MAC_LTE_CRC_STATUS_TAG;
|
||||
context_header[offset++] = context->crcStatusOK;
|
||||
/* Data tag immediately preceding PDU */
|
||||
context_header[offset++] = MAC_LTE_PAYLOAD_TAG;
|
||||
/****************************************************************/
|
||||
/* PCAP Header */
|
||||
/* TODO: Timestamp might want to be relative to a more sensible
|
||||
base time... */
|
||||
packet_header.ts_sec = context->subframesSinceCaptureStart / 1000;
|
||||
packet_header.ts_usec = (context->subframesSinceCaptureStart % 1000) * 1000;
|
||||
packet_header.incl_len = offset + length;
|
||||
packet_header.orig_len = offset + length;
|
||||
/***************************************************************/
|
||||
/* Now write everything to the file */
|
||||
fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd);
|
||||
fwrite(context_header, 1, offset, file_fd);
|
||||
fwrite(PDU, 1, length, file_fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include <common/ran_context.h>
|
||||
extern RAN_CONTEXT_t RC;
|
||||
#include <openair1/PHY/phy_extern_ue.h>
|
||||
@@ -389,7 +416,6 @@ extern RAN_CONTEXT_t RC;
|
||||
void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
|
||||
int oob_event_value) {
|
||||
MAC_Context_Info_t pdu_context;
|
||||
int radioType=FDD_RADIO;
|
||||
LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n",
|
||||
direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber);
|
||||
@@ -405,53 +431,41 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p
|
||||
|
||||
switch (opt_type) {
|
||||
case OPT_WIRESHARK :
|
||||
if (g_socksd == -1) {
|
||||
if (g_socksd == -1)
|
||||
return;
|
||||
}
|
||||
|
||||
SendFrame( radioType,
|
||||
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
|
||||
rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
|
||||
1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
|
||||
oob_event,oob_event_value,
|
||||
pdu_buffer, pdu_buffer_size);
|
||||
break;
|
||||
|
||||
case OPT_PCAP:
|
||||
if (file_fd == NULL) {
|
||||
if (file_fd == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
pdu_context.radioType = radioType;
|
||||
pdu_context.direction = (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK
|
||||
: DIRECTION_UPLINK;
|
||||
pdu_context.rntiType = rntiType;
|
||||
pdu_context.rnti = rnti;
|
||||
pdu_context.ueid = ueid;
|
||||
pdu_context.isRetx = 0;
|
||||
pdu_context.crcStatusOK =1;
|
||||
pdu_context.sysFrameNumber = sysFrameNumber;
|
||||
pdu_context.subFrameNumber = subFrameNumber;
|
||||
pdu_context.subframesSinceCaptureStart = subframesSinceCaptureStart++;
|
||||
MAC_LTE_PCAP_WritePDU( &pdu_context, pdu_buffer, pdu_buffer_size);
|
||||
break;
|
||||
|
||||
case OPT_TSHARK:
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
SendFrame( radioType,
|
||||
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
|
||||
rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
|
||||
1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
|
||||
oob_event,oob_event_value,
|
||||
pdu_buffer, pdu_buffer_size);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int init_opt(void)
|
||||
{
|
||||
char *in_type=NULL;
|
||||
int init_opt(void) {
|
||||
in_type=malloc(200);
|
||||
in_ip=malloc(200);
|
||||
in_path=malloc(200);
|
||||
paramdef_t opt_params[] = OPT_PARAMS_DESC ;
|
||||
checkedparam_t opt_checkParams[] = OPTPARAMS_CHECK_DESC;
|
||||
uint16_t in_port=0;
|
||||
config_set_checkfunctions(opt_params, opt_checkParams,
|
||||
sizeof(opt_params)/sizeof(paramdef_t));
|
||||
config_get( opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX);
|
||||
|
||||
subframesSinceCaptureStart = 0;
|
||||
int tmptype = config_get_processedint( &(opt_params[OPTTYPE_IDX]));
|
||||
|
||||
@@ -462,25 +476,21 @@ int init_opt(void)
|
||||
} else if (tmptype == OPT_PCAP && strlen(in_path) > 0) {
|
||||
opt_type = OPT_PCAP;
|
||||
opt_enabled=1;
|
||||
LOG_I(OPT,"Enabling OPT for PCAP with the following file %s \n",in_path);
|
||||
} else if (tmptype == OPT_WIRESHARK && strlen(in_ip) > 0) {
|
||||
opt_enabled=1;
|
||||
opt_type = OPT_WIRESHARK;
|
||||
LOG_I(OPT,"Enabling OPT for wireshark for local interface %s\n",in_ip);
|
||||
} else {
|
||||
LOG_E(OPT,"Invalid OPT configuration\n");
|
||||
config_printhelp(opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX);
|
||||
}
|
||||
|
||||
in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT;
|
||||
|
||||
// trace_mode
|
||||
switch (opt_type) {
|
||||
case OPT_WIRESHARK:
|
||||
|
||||
LOG_I(OPT,"mode Wireshark: ip %s port %d\n", in_ip, PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
/* Create local server socket only if using localhost address */
|
||||
if (strcmp(in_ip, "127.0.0.1") == 0) {
|
||||
opt_create_listener_socket(in_ip, in_port);
|
||||
if (strncmp(in_ip, "127.0.0.1", 4) == 0) {
|
||||
opt_create_listener_socket(in_ip, PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
}
|
||||
|
||||
g_socksd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
@@ -493,11 +503,12 @@ int init_opt(void)
|
||||
|
||||
/* Get remote IP address from the function argument */
|
||||
g_serv_addr.sin_family = AF_INET;
|
||||
g_serv_addr.sin_port = htons(in_port);
|
||||
g_serv_addr.sin_port = htons(PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
g_serv_addr.sin_addr.s_addr = inet_addr(in_ip);
|
||||
break;
|
||||
|
||||
case OPT_PCAP:
|
||||
LOG_I(OPT,"mode PCAB : path is %s \n",in_path);
|
||||
file_fd = fopen(in_path, "w");
|
||||
|
||||
if (file_fd == NULL) {
|
||||
@@ -516,19 +527,9 @@ int init_opt(void)
|
||||
|
||||
default:
|
||||
opt_type = OPT_NONE;
|
||||
LOG_W(OPT, "supported Option\n");
|
||||
LOG_E(OPT,"Unsupported or unknown mode %d \n", opt_type);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( opt_type == OPT_WIRESHARK )
|
||||
LOG_E(OPT,"mode Wireshark: ip %s port %d\n", in_ip, in_port);
|
||||
else if (opt_type == OPT_PCAP)
|
||||
LOG_E(OPT,"mode PCAB : path is %s \n",in_path);
|
||||
else
|
||||
LOG_E(OPT,"Unsupported or unknown mode %d \n", opt_type);
|
||||
|
||||
// mac_info = (mac_info*)malloc16(sizeof(mac_lte_info));
|
||||
// memset(mac_info, 0, sizeof(mac_lte_info)+pdu_buffer_size + 8);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user