Merge branch 'integration_2025_w19' into 'develop'
Integration: `2025.w19` Closes #852, #952, and #957 See merge request oai/openairinterface5g!3427 * !3409 Correctly handle minimum RB condition in MAC * !3421 Fix DMRS for PUCCH format 2 * !3424 limit the number of HARQ processes in case of DCI00 and 10 * !3116 ue txData more contextual, but still global as it is entangled with usrp driver * !3408 Handling 2 search spaces per slot in SIB1 * !3419 PRACH configuration index warning * !3429 CI: Add `-l` option for the UL iperf test * !3381 Add 5GMM Authentication Failure enc/dec lib and unit test
This commit is contained in:
@@ -108,7 +108,7 @@
|
||||
<testCase id="000033">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/UDP/40M)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 40M -t 30</iperf_args>
|
||||
<iperf_args>-u -b 40M -t 30 -l 1428</iperf_args>
|
||||
<svr_id>oc-cn5g-20897-aerial</svr_id>
|
||||
<id>up2-aerial</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
|
||||
+15
-11
@@ -504,7 +504,7 @@ static int nr_ue_slot_select(const fapi_nr_config_request_t *cfg, int nr_slot)
|
||||
return NR_DOWNLINK_SLOT;
|
||||
}
|
||||
|
||||
static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action)
|
||||
static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **txp)
|
||||
{
|
||||
PHY_VARS_NR_UE *UE = rxtxD->UE;
|
||||
const fapi_nr_config_request_t *cfg = &UE->nrUE_config;
|
||||
@@ -514,10 +514,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action)
|
||||
if (UE->sl_mode == 2)
|
||||
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
|
||||
|
||||
void *txp[NB_ANTENNAS_TX];
|
||||
int slot = proc->nr_slot_tx;
|
||||
for (int i = 0; i < fp->nb_antennas_tx; i++)
|
||||
txp[i] = (void *)&UE->common_vars.txData[i][fp->get_samples_slot_timestamp(slot, fp, 0)];
|
||||
|
||||
radio_tx_burst_flag_t flags = TX_BURST_INVALID;
|
||||
|
||||
@@ -551,7 +548,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action)
|
||||
const int maxWriteBlockSize = fp->get_samples_per_slot(proc->nr_slot_tx, fp);
|
||||
while (writeBlockSize > maxWriteBlockSize) {
|
||||
const int dummyBlockSize = min(writeBlockSize - maxWriteBlockSize, maxWriteBlockSize);
|
||||
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, dummyBlockSize, fp->nb_antennas_tx, flags);
|
||||
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, (void **)txp, dummyBlockSize, fp->nb_antennas_tx, flags);
|
||||
AssertFatal(tmp == dummyBlockSize, "");
|
||||
|
||||
writeTimestamp += dummyBlockSize;
|
||||
@@ -567,7 +564,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action)
|
||||
nr_fo_compensation(ul_freq_offset, fp->samples_per_subframe, writeTimestamp, txp[i], txp[i], writeBlockSize);
|
||||
}
|
||||
|
||||
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, writeBlockSize, fp->nb_antennas_tx, flags);
|
||||
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, (void **)txp, writeBlockSize, fp->nb_antennas_tx, flags);
|
||||
AssertFatal(tmp == writeBlockSize, "");
|
||||
}
|
||||
|
||||
@@ -583,6 +580,14 @@ void processSlotTX(void *arg)
|
||||
if (UE->if_inst)
|
||||
UE->if_inst->slot_indication(UE->Mod_id, true);
|
||||
|
||||
LOG_D(PHY, "SlotTx %d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type);
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
|
||||
c16_t *txp[fp->nb_antennas_tx];
|
||||
for (int i = 0; i < fp->nb_antennas_tx; i++) {
|
||||
txp[i] = UE->common_vars.txData[i] + fp->get_samples_slot_timestamp(proc->nr_slot_tx, fp, 0);
|
||||
}
|
||||
|
||||
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT) {
|
||||
if (UE->sl_mode == 2 && proc->tx_slot_type == NR_SIDELINK_SLOT) {
|
||||
// trigger L2 to run ue_sidelink_scheduler thru IF module
|
||||
@@ -608,7 +613,7 @@ void processSlotTX(void *arg)
|
||||
AssertFatal((phy_data.sl_tx_action >= SL_NR_CONFIG_TYPE_TX_PSBCH &&
|
||||
phy_data.sl_tx_action < SL_NR_CONFIG_TYPE_TX_MAXIMUM), "Incorrect SL TX Action Scheduled\n");
|
||||
|
||||
phy_procedures_nrUE_SL_TX(UE, proc, &phy_data);
|
||||
phy_procedures_nrUE_SL_TX(UE, proc, &phy_data, txp);
|
||||
|
||||
sl_tx_action = true;
|
||||
}
|
||||
@@ -630,12 +635,12 @@ void processSlotTX(void *arg)
|
||||
}
|
||||
dynamic_barrier_join(rxtxD->next_barrier);
|
||||
|
||||
phy_procedures_nrUE_TX(UE, proc, &phy_data);
|
||||
phy_procedures_nrUE_TX(UE, proc, &phy_data, txp);
|
||||
}
|
||||
} else {
|
||||
dynamic_barrier_join(rxtxD->next_barrier);
|
||||
}
|
||||
RU_write(rxtxD, sl_tx_action);
|
||||
RU_write(rxtxD, sl_tx_action, txp);
|
||||
TracyCZoneEnd(ctx);
|
||||
}
|
||||
|
||||
@@ -723,7 +728,7 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
|
||||
if (phy_data->dlsch[0].active && phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_) {
|
||||
// indicate to tx thread to wait for DLSCH decoding
|
||||
if (phy_data->dlsch[0].dlsch_config.k1_feedback) { // if feedback is 0 there is no HARQ associated with this DLSCH
|
||||
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
|
||||
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % fp->slots_per_frame;
|
||||
tx_wait_for_dlsch[ack_nack_slot]++;
|
||||
}
|
||||
}
|
||||
@@ -1020,7 +1025,6 @@ void *UE_thread(void *arg)
|
||||
notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch);
|
||||
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg);
|
||||
*syncMsg = (syncData_t){0};
|
||||
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
|
||||
if (UE->UE_scan_carrier) {
|
||||
// Get list of GSCN in this band for UE's bandwidth and center frequency.
|
||||
LOG_W(PHY, "UE set to scan all GSCN in current bandwidth\n");
|
||||
|
||||
@@ -275,7 +275,7 @@ uint32_t get_samples_slot_timestamp(int slot, const NR_DL_FRAME_PARMS *fp, unsig
|
||||
for(unsigned int idx_slot = 0; idx_slot < slot; idx_slot++)
|
||||
samp_count += fp->get_samples_per_slot(idx_slot, fp);
|
||||
} else {
|
||||
for(unsigned int idx_slot = slot; idx_slot < slot+sl_ahead; idx_slot++)
|
||||
for (unsigned int idx_slot = slot; idx_slot < slot + sl_ahead; idx_slot++)
|
||||
samp_count += fp->get_samples_per_slot(idx_slot, fp);
|
||||
}
|
||||
return samp_count;
|
||||
|
||||
@@ -930,12 +930,13 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
|
||||
int l2 = pucch_pdu->start_symbol_index;
|
||||
int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
|
||||
uint16_t starting_prb = pucch_pdu->prb_start + pucch_pdu->bwp_start;
|
||||
int re_offset[nb_symbols];
|
||||
re_offset[0] =
|
||||
(12 * (pucch_pdu->prb_start + pucch_pdu->bwp_start) + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
|
||||
if (nb_symbols==2) {
|
||||
if (pucch_pdu->freq_hop_flag )
|
||||
re_offset[1] = (12*(pucch_pdu->second_hop_prb+pucch_pdu->bwp_start) + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size ;
|
||||
re_offset[0] = (12 * starting_prb + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
|
||||
if (nb_symbols == 2) {
|
||||
if (pucch_pdu->freq_hop_flag)
|
||||
re_offset[1] = (12 * (pucch_pdu->second_hop_prb + pucch_pdu->bwp_start) + frame_parms->first_carrier_offset)
|
||||
% frame_parms->ofdm_symbol_size;
|
||||
else
|
||||
re_offset[1] = re_offset[0];
|
||||
}
|
||||
@@ -1074,10 +1075,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n",
|
||||
slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id);
|
||||
#endif
|
||||
uint32_t *sGold = gold_cache(x2, pucch_pdu->prb_start / 4 + ngroup / 2);
|
||||
uint32_t *sGold = gold_cache(x2, starting_prb / 4 + ngroup / 2);
|
||||
// Compute pilot conjugate
|
||||
c16_t pil_dmrs[nb_re_dmrs] __attribute__((aligned(32)));
|
||||
uint8_t *sGold8 = (uint8_t *)(sGold + pucch_pdu->prb_start / 4);
|
||||
uint8_t *sGold8 = (uint8_t *)(sGold + starting_prb / 4);
|
||||
for (int group = 0; group < nb_re_dmrs; group += 4)
|
||||
*(simde__m128i *)(pil_dmrs + group) = oai_mm_conj(byte2m128i[*sGold8++]);
|
||||
|
||||
|
||||
@@ -826,8 +826,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12;
|
||||
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("PDCCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, slot=%d, symbol %d\n",
|
||||
gNB_id,
|
||||
printf("PDCCH Channel Estimation : ch_offset %d, OFDM size %d, Ncp=%d, slot=%d, symbol %d\n",
|
||||
ch_offset,
|
||||
ue->frame_parms.ofdm_symbol_size,
|
||||
ue->frame_parms.Ncp,
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
// - idft for short sequence assumes we are transmitting starting in symbol 0 of a PRACH slot
|
||||
// - Assumes that PRACH SCS is same as PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below
|
||||
// - Preamble index different from 0 is not detected by gNB
|
||||
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot){
|
||||
|
||||
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot, c16_t **txData)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp=&ue->frame_parms;
|
||||
fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config;
|
||||
fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu;
|
||||
@@ -66,7 +66,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
|
||||
c16_t prachF_tmp[(4688 + 4 * 24576) * 4] __attribute__((aligned(32))) = {0};
|
||||
|
||||
int Ncp = 0;
|
||||
int prach_start, prach_sequence_length, prach_len, dftlen, mu, n_ra_prb, k, prachStartSymbol, sample_offset_slot;
|
||||
int prach_start, prach_sequence_length, prach_len, dftlen, mu, n_ra_prb, k, prachStartSymbol;
|
||||
|
||||
fd_occasion = prach_pdu->num_ra;
|
||||
prach_len = 0;
|
||||
@@ -98,23 +98,22 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
|
||||
}
|
||||
|
||||
if (prachStartSymbol == 0) {
|
||||
sample_offset_slot = 0;
|
||||
prach_start = 0;
|
||||
} else if (fp->slots_per_subframe == 1) {
|
||||
if (prachStartSymbol <= 7)
|
||||
sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0);
|
||||
prach_start =
|
||||
(fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0);
|
||||
else
|
||||
sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 2) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0) * 2;
|
||||
prach_start = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 2)
|
||||
+ (fp->ofdm_symbol_size + fp->nb_prefix_samples0) * 2;
|
||||
} else {
|
||||
if (slot % (fp->slots_per_subframe / 2) == 0)
|
||||
sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0);
|
||||
prach_start =
|
||||
(fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0);
|
||||
else
|
||||
sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol;
|
||||
prach_start = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol;
|
||||
}
|
||||
|
||||
prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot;
|
||||
|
||||
//printf("prachstartsymbold %d, sample_offset_slot %d, prach_start %d\n",prachStartSymbol, sample_offset_slot, prach_start);
|
||||
|
||||
// First compute physical root sequence
|
||||
/************************************************************************
|
||||
* 4G and NR NCS tables are slightly different and depend on prach format
|
||||
@@ -506,13 +505,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
|
||||
LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d\n", Mod_id, fp->N_RB_UL, prach_start, prach_len);
|
||||
#endif
|
||||
|
||||
memcpy(ue->common_vars.txData[0] + prach_start, prach, sizeof(c16_t) * prach_len);
|
||||
memcpy(txData[0] + prach_start, prach, sizeof(c16_t) * prach_len);
|
||||
|
||||
#ifdef PRACH_WRITE_OUTPUT_DEBUG
|
||||
LOG_M("prach_tx0.m", "prachtx0", prach + (Ncp << 1), prach_len - Ncp, 1, 1);
|
||||
LOG_M("Prach_txsig.m", "txs", (int16_t *)(&ue->common_vars.txdata[0][prach_start]), 2 * (prach_start + prach_len), 1, 1)
|
||||
LOG_M("Prach_txsig.m", "txs", (int16_t *)(&txdata[0][prach_start]), 2 * (prach_start + prach_len), 1, 1)
|
||||
#endif
|
||||
|
||||
return signal_energy((int *)prach, 256);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF,
|
||||
c16_t **txdata,
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
|
||||
|
||||
@@ -315,7 +316,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
int G,
|
||||
uint32_t nvar);
|
||||
|
||||
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot);
|
||||
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot, c16_t **txData);
|
||||
|
||||
void dump_nrdlsch(PHY_VARS_NR_UE *ue,uint8_t gNB_id,uint8_t nr_slot_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid);
|
||||
void nr_a_sum_b(c16_t *input_x, c16_t *input_y, unsigned short nb_rb);
|
||||
|
||||
@@ -828,25 +828,17 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF,
|
||||
c16_t **txdata,
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
const int tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
|
||||
int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL;
|
||||
|
||||
c16_t **txdata = UE->common_vars.txData;
|
||||
for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT; i++) {
|
||||
if (was_symbol_used[i] == false)
|
||||
continue;
|
||||
for(int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
txdataF[ap],
|
||||
frame_parms->symbol_rotation[linktype],
|
||||
slot,
|
||||
N_RB,
|
||||
i,
|
||||
1);
|
||||
for (int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
apply_nr_rotation_TX(frame_parms, txdataF[ap], frame_parms->symbol_rotation[linktype], slot, N_RB, i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -855,25 +847,20 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
if (frame_parms->Ncp == 1) { // extended cyclic prefix
|
||||
for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP; i++) {
|
||||
if (was_symbol_used[i] == false) {
|
||||
memset(&txdata[ap][tx_offset + (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples) * i],
|
||||
memset(&txdata[ap][(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples) * i],
|
||||
0,
|
||||
(frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * sizeof(int32_t));
|
||||
continue;
|
||||
}
|
||||
PHY_ofdm_mod((int *)&txdataF[ap][frame_parms->ofdm_symbol_size * i],
|
||||
(int *)&txdata[ap][tx_offset + frame_parms->ofdm_symbol_size * i],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
(int *)&txdata[ap][frame_parms->ofdm_symbol_size * i],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
}
|
||||
} else { // normal cyclic prefix
|
||||
nr_normal_prefix_mod(txdataF[ap],
|
||||
&txdata[ap][tx_offset],
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
frame_parms,
|
||||
slot,
|
||||
was_symbol_used);
|
||||
nr_normal_prefix_mod(txdataF[ap], txdata[ap], NR_NUMBER_OF_SYMBOLS_PER_SLOT, frame_parms, slot, was_symbol_used);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -578,7 +578,6 @@ typedef struct nr_phy_data_tx_s {
|
||||
// Sidelink Rx action decided by MAC
|
||||
sl_nr_tx_config_type_enum_t sl_tx_action;
|
||||
sl_nr_tx_config_psbch_pdu_t psbch_vars;
|
||||
|
||||
} nr_phy_data_tx_t;
|
||||
|
||||
typedef struct nr_phy_data_s {
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
@param proc Pointer to RXn-TXnp4 proc information
|
||||
@param phy_data
|
||||
*/
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp);
|
||||
|
||||
int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
|
||||
@@ -98,10 +98,6 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
|
||||
void processSlotTX(void *arg);
|
||||
|
||||
/*! \brief UE PRACH procedures.
|
||||
*/
|
||||
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc);
|
||||
|
||||
int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
|
||||
|
||||
/*! \brief UL time alignment procedures for TA application
|
||||
@@ -160,7 +156,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu);
|
||||
|
||||
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
|
||||
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp);
|
||||
/*! \brief This function prepares the sl indication to pass to the MAC
|
||||
*/
|
||||
void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind,
|
||||
|
||||
@@ -81,6 +81,8 @@ static const unsigned int gain_table[31] = {100, 112, 126, 141, 158, 178,
|
||||
359, 398, 447, 501, 562, 631, 708, 794, 891, 1000, 1122,
|
||||
1258, 1412, 1585, 1778, 1995, 2239, 2512, 2818, 3162};
|
||||
|
||||
static void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txData);
|
||||
|
||||
void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
|
||||
fapi_nr_dci_indication_t *dci_ind,
|
||||
fapi_nr_rx_indication_t *rx_ind,
|
||||
@@ -268,7 +270,7 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx)
|
||||
}
|
||||
}
|
||||
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data)
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp)
|
||||
{
|
||||
const int slot_tx = proc->nr_slot_tx;
|
||||
const int frame_tx = proc->frame_tx;
|
||||
@@ -306,12 +308,13 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
||||
&ue->frame_parms,
|
||||
ue->frame_parms.nb_antennas_tx,
|
||||
(c16_t **)txdataF,
|
||||
txp,
|
||||
link_type_ul,
|
||||
was_symbol_used);
|
||||
stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS);
|
||||
}
|
||||
|
||||
nr_ue_prach_procedures(ue, proc);
|
||||
nr_ue_prach_procedures(ue, proc, txp);
|
||||
|
||||
LOG_D(PHY, "****** end TX-Chain for AbsSubframe %d.%d ******\n", proc->frame_tx, proc->nr_slot_tx);
|
||||
|
||||
@@ -977,7 +980,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN);
|
||||
|
||||
uint8_t nb_symb_pdcch = phy_pdcch_config->nb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.duration : 0;
|
||||
for (uint16_t l=0; l<nb_symb_pdcch; l++) {
|
||||
int first_symb_pdcch = phy_pdcch_config->nb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.StartSymbolIndex : 0;
|
||||
int last_symb_pdcch = first_symb_pdcch + nb_symb_pdcch;
|
||||
for (int l = first_symb_pdcch; l < last_symb_pdcch; l++) {
|
||||
nr_slot_fep(ue, fp, proc->nr_slot_rx, l, rxdataF, link_type_dl, 0, ue->common_vars.rxdata);
|
||||
}
|
||||
|
||||
@@ -987,10 +992,8 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
|
||||
|
||||
uint8_t dci_cnt = 0;
|
||||
for(int n_ss = 0; n_ss<phy_pdcch_config->nb_search_space; n_ss++) {
|
||||
for (uint16_t l=0; l<nb_symb_pdcch; l++) {
|
||||
|
||||
for (int l = first_symb_pdcch; l < last_symb_pdcch; l++) {
|
||||
// note: this only works if RBs for PDCCH are contigous!
|
||||
|
||||
nr_pdcch_channel_estimation(ue,
|
||||
proc,
|
||||
l,
|
||||
@@ -1000,7 +1003,6 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
|
||||
pdcch_est_size,
|
||||
pdcch_dl_ch_estimates,
|
||||
rxdataF);
|
||||
|
||||
}
|
||||
dci_cnt = dci_cnt + nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss, rxdataF);
|
||||
}
|
||||
@@ -1179,7 +1181,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
|
||||
// todo:
|
||||
// - power control as per 38.213 ch 7.4
|
||||
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc)
|
||||
static void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txData)
|
||||
{
|
||||
int gNB_id = proc->gNB_id;
|
||||
int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp
|
||||
@@ -1208,7 +1210,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc)
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
|
||||
|
||||
start_meas_nr_ue_phy(ue, PRACH_GEN_STATS);
|
||||
prach_power = generate_nr_prach(ue, gNB_id, frame_tx, nr_slot_tx);
|
||||
prach_power = generate_nr_prach(ue, gNB_id, frame_tx, nr_slot_tx, txData);
|
||||
stop_meas_nr_ue_phy(ue, PRACH_GEN_STATS);
|
||||
if (cpumeas(CPUMEAS_GETSTATE)) {
|
||||
LOG_D(PHY,
|
||||
|
||||
@@ -264,7 +264,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
|
||||
return sampleShift;
|
||||
}
|
||||
|
||||
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data)
|
||||
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp)
|
||||
{
|
||||
int slot_tx = proc->nr_slot_tx;
|
||||
int frame_tx = proc->frame_tx;
|
||||
@@ -313,7 +313,7 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc
|
||||
was_symbol_used[i] = true;
|
||||
if (tx_action) {
|
||||
LOG_D(NR_PHY, "Sending Uplink data \n");
|
||||
nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF, link_type_sl, was_symbol_used);
|
||||
nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF, txp, link_type_sl, was_symbol_used);
|
||||
}
|
||||
|
||||
LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
|
||||
@@ -134,7 +134,7 @@ int main(int argc, char **argv){
|
||||
get_softmodem_params()->sl_mode = 0;
|
||||
double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0;
|
||||
double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs=-1, bw;
|
||||
int i, l, aa, aarx, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
|
||||
int i, l, aa, aarx, trial, n_frames = 1, rx_prach_start; //, ntrials=1;
|
||||
c16_t **txdata;
|
||||
int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0;
|
||||
uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0;
|
||||
@@ -666,14 +666,17 @@ int main(int argc, char **argv){
|
||||
ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
|
||||
UE->X_u);
|
||||
|
||||
generate_nr_prach(UE, 0, frame, slot);
|
||||
int prach_start = subframe * frame_parms->samples_per_subframe;
|
||||
int slot_start = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
c16_t *tx[frame_parms->nb_antennas_rx];
|
||||
for (int i = 0; i < frame_parms->nb_antennas_rx; i++)
|
||||
tx[i] = txdata[i] + slot_start;
|
||||
generate_nr_prach(UE, 0, frame, slot, tx);
|
||||
|
||||
/* tx_lev_dB not used later, no need to set */
|
||||
//tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
|
||||
|
||||
prach_start = subframe*frame_parms->samples_per_subframe;
|
||||
|
||||
#ifdef NR_PRACH_DEBUG
|
||||
#ifdef NR_PRACH_DEBUG
|
||||
LOG_M("txsig0.m", "txs0", &txdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("txsig0_frame.m","txs0", txdata[0],frame_parms->samples_per_frame,1,1);
|
||||
#endif
|
||||
@@ -750,8 +753,9 @@ int main(int argc, char **argv){
|
||||
|
||||
for (i = 0; i< frame_parms->samples_per_subframe; i++) {
|
||||
for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
|
||||
((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
|
||||
((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
|
||||
c16_t *tmp = (c16_t *)ru->common.rxdata[aa] + rx_prach_start + i;
|
||||
tmp->r = (short)(.167 * (r_re[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)));
|
||||
tmp->i = (short)(.167 * (r_im[aa][i] + (iqim * r_re[aa][i]) + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -765,15 +769,10 @@ int main(int argc, char **argv){
|
||||
|
||||
for (l = 0; l < frame_parms->symbols_per_slot; l++) {
|
||||
for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
|
||||
nr_slot_fep_ul(frame_parms,
|
||||
(int32_t *)ru->common.rxdata[aa],
|
||||
(int32_t *)ru->common.rxdataF[aa],
|
||||
l,
|
||||
slot,
|
||||
ru->N_TA_offset);
|
||||
}
|
||||
}
|
||||
|
||||
nr_slot_fep_ul(frame_parms, ru->common.rxdata[aa], ru->common.rxdataF[aa], l, slot, ru->N_TA_offset);
|
||||
}
|
||||
}
|
||||
|
||||
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, slot, prachOccasion, frame, slot);
|
||||
|
||||
for (int i = 0; i < ru->nb_rx; ++i)
|
||||
|
||||
@@ -576,8 +576,11 @@ int main(int argc, char **argv)
|
||||
proc.frame_rx,
|
||||
proc.nr_slot_rx,
|
||||
sl_uerx->sl_config.sl_sync_source.rx_slss_id);
|
||||
|
||||
phy_procedures_nrUE_SL_TX(UE_TX, &proc, &phy_data_tx);
|
||||
int slot_start = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
c16_t *tx[frame_parms->nb_antennas_rx];
|
||||
for (int i = 0; i < frame_parms->nb_antennas_rx; i++)
|
||||
tx[i] = UE_TX->common_vars.txData[i] + slot_start;
|
||||
phy_procedures_nrUE_SL_TX(UE_TX, &proc, &phy_data_tx, tx);
|
||||
|
||||
for (SNR = snr0; SNR >= snr1 && !stop; SNR -= 1) {
|
||||
for (int trial = 0; trial < n_trials && !stop; trial++) {
|
||||
|
||||
@@ -190,8 +190,7 @@ int main(int argc, char *argv[])
|
||||
corr_level_t corr_level = CORR_LEVEL_LOW;
|
||||
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
|
||||
|
||||
//unsigned char frame_type = 0;
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
// unsigned char frame_type = 0;
|
||||
int loglvl = OAILOG_WARNING;
|
||||
uint16_t nb_symb_sch = 12;
|
||||
int start_symbol = 0;
|
||||
@@ -612,11 +611,9 @@ int main(int argc, char *argv[])
|
||||
UL_INFO.crc_ind.number_crcs = 0;
|
||||
gNB->max_ldpc_iterations = max_ldpc_iterations;
|
||||
gNB->pusch_thres = -20;
|
||||
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
|
||||
|
||||
frame_parms->N_RB_DL = N_RB_DL;
|
||||
frame_parms->N_RB_UL = N_RB_UL;
|
||||
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
|
||||
gNB->frame_parms.N_RB_DL = N_RB_DL;
|
||||
gNB->frame_parms.N_RB_UL = N_RB_UL;
|
||||
gNB->frame_parms.Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
|
||||
|
||||
AssertFatal((gNB->if_inst = NR_IF_Module_init(0)) != NULL, "Cannot register interface");
|
||||
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||
@@ -682,8 +679,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
// UE dedicated configuration
|
||||
nr_mac_add_test_ue(RC.nrmac[0], rnti, secondaryCellGroup);
|
||||
frame_parms->nb_antennas_tx = 1;
|
||||
frame_parms->nb_antennas_rx = n_rx;
|
||||
gNB->frame_parms.nb_antennas_tx = 1;
|
||||
gNB->frame_parms.nb_antennas_rx = n_rx;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
cfg->carrier_config.num_tx_ant.value = 1;
|
||||
cfg->carrier_config.num_rx_ant.value = n_rx;
|
||||
@@ -712,7 +709,7 @@ int main(int argc, char *argv[])
|
||||
n_rx,
|
||||
channel_model,
|
||||
sampling_frequency / 1e6,
|
||||
frame_parms->ul_CarrierFreq,
|
||||
gNB->frame_parms.ul_CarrierFreq,
|
||||
tx_bandwidth,
|
||||
DS_TDL,
|
||||
maxDoppler,
|
||||
@@ -732,7 +729,7 @@ int main(int argc, char *argv[])
|
||||
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE**));
|
||||
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*));
|
||||
PHY_vars_UE_g[0][0] = UE;
|
||||
memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
UE->frame_parms = gNB->frame_parms;
|
||||
UE->frame_parms.nb_antennas_tx = n_tx;
|
||||
UE->frame_parms.nb_antennas_rx = 0;
|
||||
UE->nrLDPC_coding_interface = gNB->nrLDPC_coding_interface;
|
||||
@@ -865,7 +862,7 @@ int main(int argc, char *argv[])
|
||||
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);
|
||||
uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb);
|
||||
|
||||
double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);
|
||||
double ts = 1.0 / (gNB->frame_parms.subcarrier_spacing * gNB->frame_parms.ofdm_symbol_size);
|
||||
|
||||
/* -T option enable PTRS */
|
||||
if(enable_ptrs) {
|
||||
@@ -897,7 +894,7 @@ int main(int argc, char *argv[])
|
||||
unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, unav_res, mod_order, precod_nbr_layers);
|
||||
printf("[ULSIM]: VALUE OF G: %u, TBS: %u\n", available_bits, TBS);
|
||||
|
||||
int frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
int frame_length_complex_samples = gNB->frame_parms.samples_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
for (int aatx=0; aatx<n_tx; aatx++) {
|
||||
s_re[aatx] = calloc(1,frame_length_complex_samples*sizeof(double));
|
||||
s_im[aatx] = calloc(1,frame_length_complex_samples*sizeof(double));
|
||||
@@ -911,13 +908,15 @@ int main(int argc, char *argv[])
|
||||
//for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
|
||||
int read_errors=0;
|
||||
|
||||
int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
|
||||
int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
|
||||
int slot_offset = gNB->frame_parms.get_samples_slot_timestamp(slot, &gNB->frame_parms, 0);
|
||||
int slot_length = slot_offset - gNB->frame_parms.get_samples_slot_timestamp(slot - 1, &gNB->frame_parms, 0);
|
||||
|
||||
if (input_fd != NULL) {
|
||||
// 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
|
||||
AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing);
|
||||
|
||||
AssertFatal(gNB->frame_parms.subcarrier_spacing == 30000,
|
||||
"only 30 kHz for file input for now (%d)\n",
|
||||
gNB->frame_parms.subcarrier_spacing);
|
||||
|
||||
if (params_from_file) {
|
||||
fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET);
|
||||
read_errors+=fread((void*)&n_rnti,sizeof(int16_t),1,input_fd);
|
||||
@@ -942,7 +941,7 @@ int main(int argc, char *argv[])
|
||||
printf("harq_pid %d\n",harq_pid);
|
||||
}
|
||||
fseek(input_fd,file_offset*sizeof(int16_t)*2,SEEK_SET);
|
||||
for (int irx=0; irx<frame_parms->nb_antennas_rx; irx++) {
|
||||
for (int irx = 0; irx < gNB->frame_parms.nb_antennas_rx; irx++) {
|
||||
fseek(input_fd,irx*(slot_length+15)*sizeof(int16_t)*2,SEEK_SET); // matlab adds samlples to the end to emulate channel delay
|
||||
read_errors += fread((void *)&rxdata[irx][slot_offset-delay], sizeof(int16_t), slot_length<<1, input_fd);
|
||||
if (read_errors==0) {
|
||||
@@ -1115,10 +1114,10 @@ int main(int argc, char *argv[])
|
||||
srs_pdu->rnti = n_rnti;
|
||||
srs_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
srs_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
srs_pdu->subcarrier_spacing = frame_parms->subcarrier_spacing;
|
||||
srs_pdu->subcarrier_spacing = gNB->frame_parms.subcarrier_spacing;
|
||||
srs_pdu->num_ant_ports = n_tx == 4 ? 2 : n_tx == 2 ? 1 : 0;
|
||||
srs_pdu->sequence_id = 40;
|
||||
srs_pdu->time_start_position = frame_parms->symbols_per_slot - 1;
|
||||
srs_pdu->time_start_position = gNB->frame_parms.symbols_per_slot - 1;
|
||||
srs_pdu->config_index = rrc_get_max_nr_csrs(srs_pdu->bwp_size, srs_pdu->bandwidth_index);
|
||||
srs_pdu->resource_type = NR_SRS_Resource__resourceType_PR_periodic;
|
||||
srs_pdu->t_srs = 1;
|
||||
@@ -1197,7 +1196,7 @@ int main(int argc, char *argv[])
|
||||
srs_config_pdu->rnti = n_rnti;
|
||||
srs_config_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
srs_config_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
srs_config_pdu->subcarrier_spacing = frame_parms->subcarrier_spacing;
|
||||
srs_config_pdu->subcarrier_spacing = gNB->frame_parms.subcarrier_spacing;
|
||||
srs_config_pdu->num_ant_ports = n_tx == 4 ? 2 : n_tx == 2 ? 1 : 0;
|
||||
srs_config_pdu->config_index = rrc_get_max_nr_csrs(srs_config_pdu->bwp_size, srs_config_pdu->bandwidth_index);
|
||||
srs_config_pdu->sequence_id = 40;
|
||||
@@ -1214,8 +1213,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
/////////////////////////phy_procedures_nr_ue_TX///////////////////////
|
||||
///////////
|
||||
|
||||
phy_procedures_nrUE_TX(UE, &UE_proc, &phy_data);
|
||||
int slot_start = UE->frame_parms.get_samples_slot_timestamp(slot, &UE->frame_parms, 0);
|
||||
c16_t *tx[UE->frame_parms.nb_antennas_tx];
|
||||
for (int i = 0; i < UE->frame_parms.nb_antennas_tx; i++)
|
||||
tx[i] = UE->common_vars.txData[i] + slot_start;
|
||||
phy_procedures_nrUE_TX(UE, &UE_proc, &phy_data, tx);
|
||||
|
||||
if (n_trials == 1) {
|
||||
LOG_M("txsig0.m", "txs0", &UE->common_vars.txData[0][slot_offset], slot_length, 1, 1 | log_format);
|
||||
@@ -1229,13 +1231,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
///////////
|
||||
////////////////////////////////////////////////////
|
||||
tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
tx_offset = gNB->frame_parms.get_samples_slot_timestamp(slot, &gNB->frame_parms, 0);
|
||||
txlev_sum = 0;
|
||||
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) {
|
||||
atxlev[aa] = signal_energy(
|
||||
(int32_t *)&UE->common_vars.txData[aa][tx_offset + 5 * frame_parms->ofdm_symbol_size
|
||||
+ 4 * frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
|
||||
atxlev[aa] =
|
||||
signal_energy((int32_t *)&UE->common_vars
|
||||
.txData[aa][tx_offset + 5 * gNB->frame_parms.ofdm_symbol_size
|
||||
+ 4 * gNB->frame_parms.nb_prefix_samples + gNB->frame_parms.nb_prefix_samples0],
|
||||
gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.nb_prefix_samples);
|
||||
|
||||
txlev_sum += atxlev[aa];
|
||||
|
||||
@@ -1248,11 +1251,16 @@ int main(int argc, char *argv[])
|
||||
if (input_fd == NULL) {
|
||||
// Justification of division by precod_nbr_layers:
|
||||
// When the channel is the identity matrix, the results in terms of SNR should be almost equal for 2x2 and 4x4.
|
||||
sigma_dB = 10 * log10((double)txlev_sum / precod_nbr_layers * ((double)frame_parms->ofdm_symbol_size / (12 * nb_rb))) - SNR;
|
||||
sigma_dB =
|
||||
10 * log10((double)txlev_sum / precod_nbr_layers * ((double)gNB->frame_parms.ofdm_symbol_size / (12 * nb_rb))) - SNR;
|
||||
sigma = pow(10, sigma_dB / 10);
|
||||
|
||||
if (n_trials == 1)
|
||||
printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n", sigma, sigma_dB, 10 * log10((double)txlev_sum), (double)(double)frame_parms->ofdm_symbol_size / (12 * nb_rb));
|
||||
printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n",
|
||||
sigma,
|
||||
sigma_dB,
|
||||
10 * log10((double)txlev_sum),
|
||||
(double)(double)gNB->frame_parms.ofdm_symbol_size / (12 * nb_rb));
|
||||
|
||||
for (i = 0; i < slot_length; i++) {
|
||||
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) {
|
||||
@@ -1262,7 +1270,17 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0);
|
||||
add_noise(rxdata, (const double **) r_re, (const double **) r_im, sigma, slot_length, slot_offset, ts, delay, pdu_bit_map, PUSCH_PDU_BITMAP_PUSCH_PTRS, frame_parms->nb_antennas_rx);
|
||||
add_noise(rxdata,
|
||||
(const double **)r_re,
|
||||
(const double **)r_im,
|
||||
sigma,
|
||||
slot_length,
|
||||
slot_offset,
|
||||
ts,
|
||||
delay,
|
||||
pdu_bit_map,
|
||||
PUSCH_PDU_BITMAP_PUSCH_PTRS,
|
||||
gNB->frame_parms.nb_antennas_rx);
|
||||
|
||||
} /*End input_fd */
|
||||
|
||||
@@ -1298,15 +1316,25 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (n_trials == 1 && round == 0) {
|
||||
LOG_M("rxsig0.m", "rx0", &rxdata[0][slot_offset], slot_length, 1, 1 | log_format);
|
||||
LOG_M("rxsigF0.m", "rxsF0", gNB->common_vars.rxdataF[0][0], 14 * frame_parms->ofdm_symbol_size, 1, 1 | log_format);
|
||||
LOG_M("rxsigF0.m", "rxsF0", gNB->common_vars.rxdataF[0][0], 14 * gNB->frame_parms.ofdm_symbol_size, 1, 1 | log_format);
|
||||
if (precod_nbr_layers > 1) {
|
||||
LOG_M("rxsig1.m", "rx1", &rxdata[1][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("rxsigF1.m", "rxsF1", gNB->common_vars.rxdataF[0][1], 14 * frame_parms->ofdm_symbol_size, 1, 1 | log_format);
|
||||
LOG_M("rxsigF1.m", "rxsF1", gNB->common_vars.rxdataF[0][1], 14 * gNB->frame_parms.ofdm_symbol_size, 1, 1 | log_format);
|
||||
if (precod_nbr_layers == 4) {
|
||||
LOG_M("rxsig2.m", "rx2", &rxdata[2][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("rxsig3.m", "rx3", &rxdata[3][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("rxsigF2.m", "rxsF2", gNB->common_vars.rxdataF[0][2], 14 * frame_parms->ofdm_symbol_size, 1, 1 | log_format);
|
||||
LOG_M("rxsigF3.m", "rxsF3", gNB->common_vars.rxdataF[0][3], 14 * frame_parms->ofdm_symbol_size, 1, 1 | log_format);
|
||||
LOG_M("rxsigF2.m",
|
||||
"rxsF2",
|
||||
gNB->common_vars.rxdataF[0][2],
|
||||
14 * gNB->frame_parms.ofdm_symbol_size,
|
||||
1,
|
||||
1 | log_format);
|
||||
LOG_M("rxsigF3.m",
|
||||
"rxsF3",
|
||||
gNB->common_vars.rxdataF[0][3],
|
||||
14 * gNB->frame_parms.ofdm_symbol_size,
|
||||
1,
|
||||
1 | log_format);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1317,8 +1345,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
LOG_M("chestF0.m",
|
||||
"chF0",
|
||||
&pusch_vars->ul_ch_estimates[0][start_symbol * frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
&pusch_vars->ul_ch_estimates[0][start_symbol * gNB->frame_parms.ofdm_symbol_size],
|
||||
gNB->frame_parms.ofdm_symbol_size,
|
||||
1,
|
||||
1 | log_format);
|
||||
|
||||
@@ -1332,8 +1360,8 @@ int main(int argc, char *argv[])
|
||||
if (precod_nbr_layers == 2) {
|
||||
LOG_M("chestF3.m",
|
||||
"chF3",
|
||||
&pusch_vars->ul_ch_estimates[3][start_symbol * frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
&pusch_vars->ul_ch_estimates[3][start_symbol * gNB->frame_parms.ofdm_symbol_size],
|
||||
gNB->frame_parms.ofdm_symbol_size,
|
||||
1,
|
||||
1 | log_format);
|
||||
|
||||
@@ -1348,20 +1376,20 @@ int main(int argc, char *argv[])
|
||||
if (precod_nbr_layers == 4) {
|
||||
LOG_M("chestF5.m",
|
||||
"chF5",
|
||||
&pusch_vars->ul_ch_estimates[5][start_symbol * frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
&pusch_vars->ul_ch_estimates[5][start_symbol * gNB->frame_parms.ofdm_symbol_size],
|
||||
gNB->frame_parms.ofdm_symbol_size,
|
||||
1,
|
||||
1 | log_format);
|
||||
LOG_M("chestF10.m",
|
||||
"chF10",
|
||||
&pusch_vars->ul_ch_estimates[10][start_symbol * frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
&pusch_vars->ul_ch_estimates[10][start_symbol * gNB->frame_parms.ofdm_symbol_size],
|
||||
gNB->frame_parms.ofdm_symbol_size,
|
||||
1,
|
||||
1 | log_format);
|
||||
LOG_M("chestF15.m",
|
||||
"chF15",
|
||||
&pusch_vars->ul_ch_estimates[15][start_symbol * frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
&pusch_vars->ul_ch_estimates[15][start_symbol * gNB->frame_parms.ofdm_symbol_size],
|
||||
gNB->frame_parms.ofdm_symbol_size,
|
||||
1,
|
||||
1 | log_format);
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
{CONFIG_STRING_MACRLC_UL_MAX_MCS, HLP_MACRLC_UL_MAX_MCS, 0, .u8ptr=NULL, .defintval=28, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX, HLP_MACRLC_DL_HARQ_MAX, 0, .u8ptr=NULL, .defintval=4, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX, HLP_MACRLC_UL_HARQ_MAX, 0, .u8ptr=NULL, .defintval=4, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_MIN_GRANT_PRB, HLP_MACRLC_MIN_GRANT_PRB, 0, .u8ptr=NULL, .defintval=5, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_MIN_GRANT_PRB, HLP_MACRLC_MIN_GRANT_PRB, 0, .u16ptr=NULL, .defintval=5, TYPE_UINT16, 0}, \
|
||||
{CONFIG_STRING_MACRLC_IDENTITY_PM, HLP_MACRLC_IDENTITY_PM, PARAMFLAG_BOOL, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \
|
||||
{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS_F1U, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
{CONFIG_STRING_MACRLC_TRANSPORT_S_SHM_PREFIX, NULL, 0, .strptr=NULL, .defstrval="nvipc", TYPE_STRING, 0}, \
|
||||
|
||||
@@ -379,7 +379,7 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc, uint64_t *ssb_bitmap, int N
|
||||
initialUplinkBWP->genericParameters.subcarrierSpacing = mu_ul;
|
||||
|
||||
struct NR_SetupRelease_RACH_ConfigCommon *rach_ConfigCommon = initialUplinkBWP->rach_ConfigCommon;
|
||||
rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex = 98;
|
||||
rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex = mu_ul == 3 ? 52 : 98;
|
||||
rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM = NR_RACH_ConfigGeneric__msg1_FDM_one;
|
||||
rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart = 0;
|
||||
rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig = 13;
|
||||
@@ -504,7 +504,8 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
|
||||
}
|
||||
|
||||
// fix SS0 and Coreset0
|
||||
NR_PDCCH_ConfigCommon_t *pdcch_cc = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup;
|
||||
NR_DownlinkConfigCommon_t *dlcc = scc->downlinkConfigCommon;
|
||||
NR_PDCCH_ConfigCommon_t *pdcch_cc = dlcc->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup;
|
||||
if((int)*pdcch_cc->searchSpaceZero == -1) {
|
||||
free(pdcch_cc->searchSpaceZero);
|
||||
pdcch_cc->searchSpaceZero = NULL;
|
||||
@@ -520,18 +521,26 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
|
||||
scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA = NULL;
|
||||
}
|
||||
|
||||
NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
|
||||
long config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
|
||||
frequency_range_t freq_range = get_freq_range_from_arfcn(dlcc->frequencyInfoDL->absoluteFrequencyPointA);
|
||||
frame_type_t frame_type = get_frame_type((int)*dlcc->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
nr_prach_info_t prach_info = get_nr_prach_occasion_info_from_index(config_index, freq_range, frame_type);
|
||||
AssertFatal(prach_info.start_symbol + prach_info.N_t_slot * prach_info.N_dur < 14,
|
||||
"PRACH with configuration index %ld goes to the last symbol of the slot, for optimal performance pick another index. "
|
||||
"See Tables 6.3.3.2-2 to 6.3.3.2-4 in 38.211\n",
|
||||
config_index);
|
||||
// default value for msg3 precoder is NULL (0 means enabled)
|
||||
if (*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder!=0) {
|
||||
free(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder);
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NULL;
|
||||
if (*rach_ConfigCommon->msg3_transformPrecoder != 0) {
|
||||
free(rach_ConfigCommon->msg3_transformPrecoder);
|
||||
rach_ConfigCommon->msg3_transformPrecoder = NULL;
|
||||
}
|
||||
|
||||
frame_type_t frame_type = get_frame_type((int)*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
|
||||
// prepare DL Allocation lists
|
||||
nr_rrc_config_dl_tda(scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList,
|
||||
frame_type, scc->tdd_UL_DL_ConfigurationCommon,
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||
nr_rrc_config_dl_tda(dlcc->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList,
|
||||
frame_type,
|
||||
scc->tdd_UL_DL_ConfigurationCommon,
|
||||
dlcc->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||
|
||||
if (frame_type == FDD) {
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_TDD_UL_DL_ConfigCommon, scc->tdd_UL_DL_ConfigurationCommon);
|
||||
@@ -540,9 +549,9 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
|
||||
fix_tdd_pattern(scc);
|
||||
}
|
||||
|
||||
if ((int)*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing == -1) {
|
||||
free(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing);
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing=NULL;
|
||||
if ((int)*rach_ConfigCommon->msg1_SubcarrierSpacing == -1) {
|
||||
free(rach_ConfigCommon->msg1_SubcarrierSpacing);
|
||||
rach_ConfigCommon->msg1_SubcarrierSpacing = NULL;
|
||||
}
|
||||
|
||||
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1
|
||||
@@ -1685,7 +1694,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
ul_bler_options->harq_round_max = 1;
|
||||
else
|
||||
ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr);
|
||||
RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr);
|
||||
RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u16ptr);
|
||||
RC.nrmac[j]->identity_pm = *(MacRLC_ParamList.paramarray[j][MACRLC_IDENTITY_PM_IDX].u8ptr);
|
||||
// PRB Blacklist
|
||||
uint16_t prbbl[MAX_BWP_SIZE] = {0};
|
||||
|
||||
@@ -810,8 +810,6 @@ static void config_sched_ctrlCommon(gNB_MAC_INST *nr_mac)
|
||||
fill_coresetZero(sched_ctrlCommon->coreset, &type0_PDCCH_CSS_config);
|
||||
nr_mac->cset0_bwp_start = type0_PDCCH_CSS_config.cset_start_rb;
|
||||
nr_mac->cset0_bwp_size = type0_PDCCH_CSS_config.num_rbs;
|
||||
sched_ctrlCommon->sched_pdcch =
|
||||
set_pdcch_structure(NULL, sched_ctrlCommon->search_space, sched_ctrlCommon->coreset, scc, NULL, &type0_PDCCH_CSS_config);
|
||||
}
|
||||
|
||||
void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config)
|
||||
|
||||
@@ -1047,7 +1047,7 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra
|
||||
NR_RA_t *ra = UE->ra;
|
||||
DevAssert(ra->Msg3_tda_id >= 0 && ra->Msg3_tda_id < 16);
|
||||
|
||||
uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes
|
||||
uint16_t msg3_nb_rb = max(8, mac->min_grant_prb); // sdu has 6 or 8 bytes
|
||||
|
||||
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
||||
NR_UE_ServingCell_Info_t *sc_info = &UE->sc_info;
|
||||
@@ -1057,14 +1057,6 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra
|
||||
int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &ra->msg3_startsymb, &ra->msg3_nbSymb);
|
||||
|
||||
LOG_I(NR_MAC,
|
||||
"UE %04x: Msg3 scheduled at %d.%d (%d.%d TDA %u)\n",
|
||||
UE->rnti,
|
||||
ra->Msg3_frame,
|
||||
ra->Msg3_slot,
|
||||
current_frame,
|
||||
current_slot,
|
||||
ra->Msg3_tda_id);
|
||||
const int buffer_index = ul_buffer_index(ra->Msg3_frame,
|
||||
ra->Msg3_slot,
|
||||
mac->frame_structure.numb_slots_frame,
|
||||
@@ -1099,6 +1091,16 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra
|
||||
ra->msg3_nb_rb = msg3_nb_rb;
|
||||
ra->msg3_first_rb = rbStart;
|
||||
ra->msg3_bwp_start = bwpStart;
|
||||
LOG_I(NR_MAC,
|
||||
"UE %04x: Msg3 scheduled at %d.%d (%d.%d TDA %u) start %d RBs %d\n",
|
||||
UE->rnti,
|
||||
ra->Msg3_frame,
|
||||
ra->Msg3_slot,
|
||||
current_frame,
|
||||
current_slot,
|
||||
ra->Msg3_tda_id,
|
||||
ra->msg3_first_rb,
|
||||
ra->msg3_nb_rb);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -344,6 +344,7 @@ static uint32_t get_tbs_bch(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
|
||||
static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac,
|
||||
int CC_id,
|
||||
NR_sched_pdcch_t *pdcch,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
int time_domain_allocation,
|
||||
NR_pdsch_dmrs_t *dmrs_parms,
|
||||
@@ -374,7 +375,7 @@ static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac,
|
||||
gNB_mac->sched_ctrlCommon->aggregation_level,
|
||||
nr_of_candidates,
|
||||
beam,
|
||||
&gNB_mac->sched_ctrlCommon->sched_pdcch,
|
||||
pdcch,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
0);
|
||||
|
||||
@@ -388,7 +389,7 @@ static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac,
|
||||
// Mark the corresponding RBs as used
|
||||
fill_pdcch_vrb_map(gNB_mac,
|
||||
CC_id,
|
||||
&gNB_mac->sched_ctrlCommon->sched_pdcch,
|
||||
pdcch,
|
||||
gNB_mac->sched_ctrlCommon->cce_index,
|
||||
gNB_mac->sched_ctrlCommon->aggregation_level,
|
||||
beam);
|
||||
@@ -615,20 +616,26 @@ void schedule_nr_sib1(module_id_t module_idP,
|
||||
|
||||
default_table_type_t table_type = get_default_table_type(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern);
|
||||
// assuming normal CP
|
||||
NR_tda_info_t tda_info = get_info_from_tda_tables(table_type, time_domain_allocation, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, true);
|
||||
NR_tda_info_t tda_info = get_info_from_tda_tables(table_type, time_domain_allocation, scc->dmrs_TypeA_Position, true);
|
||||
|
||||
AssertFatal((tda_info.startSymbolIndex + tda_info.nrOfSymbols) < 14, "SIB1 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n", time_domain_allocation);
|
||||
AssertFatal((tda_info.startSymbolIndex + tda_info.nrOfSymbols) < 14,
|
||||
"SIB1 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n",
|
||||
time_domain_allocation);
|
||||
|
||||
NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc,
|
||||
NULL,
|
||||
&tda_info,
|
||||
1);
|
||||
NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, NULL, &tda_info, 1);
|
||||
|
||||
NR_sched_pdcch_t sched_pdcch = set_pdcch_structure(NULL,
|
||||
gNB_mac->sched_ctrlCommon->search_space,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
scc,
|
||||
NULL,
|
||||
type0_PDCCH_CSS_config);
|
||||
|
||||
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0];
|
||||
// Configure sched_ctrlCommon for SIB1
|
||||
uint32_t TBS = schedule_control_sib1(gNB_mac,
|
||||
CC_id,
|
||||
&sched_pdcch,
|
||||
type0_PDCCH_CSS_config,
|
||||
time_domain_allocation,
|
||||
&dmrs_parms,
|
||||
@@ -641,7 +648,7 @@ void schedule_nr_sib1(module_id_t module_idP,
|
||||
int pdu_index = gNB_mac->pdu_index[0]++;
|
||||
nr_fill_nfapi_dl_SIB_pdu(gNB_mac,
|
||||
&gNB_mac->sched_ctrlCommon->sched_pdsch,
|
||||
&gNB_mac->sched_ctrlCommon->sched_pdcch,
|
||||
&sched_pdcch,
|
||||
gNB_mac->sched_ctrlCommon->search_space,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
gNB_mac->sched_ctrlCommon->aggregation_level,
|
||||
|
||||
@@ -2208,6 +2208,67 @@ static void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
}
|
||||
}
|
||||
|
||||
static void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info, bool dci_00_10)
|
||||
{
|
||||
int nrofHARQ = get_nrofHARQ_ProcessesForPDSCH(sc_info);
|
||||
// limit the number of HARQ PIDs to 16 in case of common search space
|
||||
if (dci_00_10 && nrofHARQ > 16)
|
||||
nrofHARQ = 16;
|
||||
// add all available DL HARQ processes for this UE
|
||||
AssertFatal(sched_ctrl->available_dl_harq.len == sched_ctrl->feedback_dl_harq.len
|
||||
&& sched_ctrl->available_dl_harq.len == sched_ctrl->retrans_dl_harq.len,
|
||||
"HARQ lists have different lengths (%d/%d/%d)\n",
|
||||
sched_ctrl->available_dl_harq.len,
|
||||
sched_ctrl->feedback_dl_harq.len,
|
||||
sched_ctrl->retrans_dl_harq.len);
|
||||
if (sched_ctrl->available_dl_harq.len == 0) {
|
||||
create_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ);
|
||||
for (int harq = 0; harq < nrofHARQ; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_dl_harq, harq);
|
||||
create_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ);
|
||||
create_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ);
|
||||
} else if (sched_ctrl->available_dl_harq.len == nrofHARQ) {
|
||||
LOG_D(NR_MAC, "nrofHARQ %d already configured\n", nrofHARQ);
|
||||
} else {
|
||||
const int old_nrofHARQ = sched_ctrl->available_dl_harq.len;
|
||||
AssertFatal(nrofHARQ > old_nrofHARQ,
|
||||
"cannot resize HARQ list to be smaller (nrofHARQ %d, old_nrofHARQ %d)\n",
|
||||
nrofHARQ, old_nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ);
|
||||
for (int harq = old_nrofHARQ; harq < nrofHARQ; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_dl_harq, harq);
|
||||
resize_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ);
|
||||
}
|
||||
}
|
||||
|
||||
static void create_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info, bool dci_00_10)
|
||||
{
|
||||
int nrofHARQ = get_nrofHARQ_ProcessesForPUSCH(sc_info);
|
||||
// limit the number of HARQ PIDs to 16 in case of common search space
|
||||
if (dci_00_10 && nrofHARQ > 16)
|
||||
nrofHARQ = 16;
|
||||
if (sched_ctrl->available_ul_harq.len == 0) {
|
||||
create_nr_list(&sched_ctrl->available_ul_harq, nrofHARQ);
|
||||
for (int harq = 0; harq < nrofHARQ; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
|
||||
create_nr_list(&sched_ctrl->feedback_ul_harq, nrofHARQ);
|
||||
create_nr_list(&sched_ctrl->retrans_ul_harq, nrofHARQ);
|
||||
} else if (sched_ctrl->available_ul_harq.len == nrofHARQ) {
|
||||
LOG_D(NR_MAC, "nrofHARQ %d already configured\n", nrofHARQ);
|
||||
} else {
|
||||
const int old_nrofHARQ = sched_ctrl->available_ul_harq.len;
|
||||
AssertFatal(nrofHARQ > old_nrofHARQ,
|
||||
"cannot resize HARQ list to be smaller (nrofHARQ %d, old_nrofHARQ %d)\n",
|
||||
nrofHARQ, old_nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->available_ul_harq, nrofHARQ);
|
||||
for (int harq = old_nrofHARQ; harq < nrofHARQ; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
|
||||
resize_nr_list(&sched_ctrl->feedback_ul_harq, nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->retrans_ul_harq, nrofHARQ);
|
||||
}
|
||||
}
|
||||
|
||||
// main function to configure parameters of current BWP
|
||||
void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
@@ -2397,8 +2458,6 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
sc_info->nrofHARQ_ProcessesForPUSCH_r17 = pusch_servingcellconfig->ext3->nrofHARQ_ProcessesForPUSCH_r17;
|
||||
}
|
||||
}
|
||||
create_dl_harq_list(sched_ctrl, sc_info);
|
||||
create_ul_harq_list(sched_ctrl, sc_info);
|
||||
}
|
||||
|
||||
if (CellGroup && CellGroup->physicalCellGroupConfig)
|
||||
@@ -2461,6 +2520,10 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
DL_BWP->dci_format = NR_DL_DCI_FORMAT_1_0;
|
||||
}
|
||||
|
||||
bool format_00_10 = DL_BWP->dci_format == NR_DL_DCI_FORMAT_1_0; // if DL is 10 UL is surely 00
|
||||
create_dl_harq_list(sched_ctrl, sc_info, format_00_10);
|
||||
create_ul_harq_list(sched_ctrl, sc_info, format_00_10);
|
||||
|
||||
set_max_fb_time(UL_BWP, DL_BWP);
|
||||
set_sched_pucch_list(sched_ctrl, UL_BWP, scc, &nr_mac->frame_structure);
|
||||
|
||||
@@ -2522,11 +2585,6 @@ NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroup
|
||||
/* Set default BWPs */
|
||||
AssertFatal(UE->sc_info.n_ul_bwp <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", UE->sc_info.n_ul_bwp);
|
||||
|
||||
/* get Number of HARQ processes for this UE */
|
||||
// pdsch_servingcellconfig == NULL in SA -> will create default (8) number of HARQ processes
|
||||
create_dl_harq_list(sched_ctrl, &UE->sc_info);
|
||||
create_ul_harq_list(sched_ctrl, &UE->sc_info);
|
||||
|
||||
// initialize LCID structure
|
||||
seq_arr_init(&sched_ctrl->lc_config, sizeof(nr_lc_config_t));
|
||||
return UE;
|
||||
@@ -2615,61 +2673,6 @@ void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl)
|
||||
free(sched_ctrl->sched_pucch);
|
||||
}
|
||||
|
||||
void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info)
|
||||
{
|
||||
const int nrofHARQ = get_nrofHARQ_ProcessesForPDSCH(sc_info);
|
||||
// add all available DL HARQ processes for this UE
|
||||
AssertFatal(sched_ctrl->available_dl_harq.len == sched_ctrl->feedback_dl_harq.len
|
||||
&& sched_ctrl->available_dl_harq.len == sched_ctrl->retrans_dl_harq.len,
|
||||
"HARQ lists have different lengths (%d/%d/%d)\n",
|
||||
sched_ctrl->available_dl_harq.len,
|
||||
sched_ctrl->feedback_dl_harq.len,
|
||||
sched_ctrl->retrans_dl_harq.len);
|
||||
if (sched_ctrl->available_dl_harq.len == 0) {
|
||||
create_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ);
|
||||
for (int harq = 0; harq < nrofHARQ; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_dl_harq, harq);
|
||||
create_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ);
|
||||
create_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ);
|
||||
} else if (sched_ctrl->available_dl_harq.len == nrofHARQ) {
|
||||
LOG_D(NR_MAC, "nrofHARQ %d already configured\n", nrofHARQ);
|
||||
} else {
|
||||
const int old_nrofHARQ = sched_ctrl->available_dl_harq.len;
|
||||
AssertFatal(nrofHARQ > old_nrofHARQ,
|
||||
"cannot resize HARQ list to be smaller (nrofHARQ %d, old_nrofHARQ %d)\n",
|
||||
nrofHARQ, old_nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ);
|
||||
for (int harq = old_nrofHARQ; harq < nrofHARQ; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_dl_harq, harq);
|
||||
resize_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ);
|
||||
}
|
||||
}
|
||||
|
||||
void create_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info)
|
||||
{
|
||||
int nrofHARQ = get_nrofHARQ_ProcessesForPUSCH(sc_info);
|
||||
if (sched_ctrl->available_ul_harq.len == 0) {
|
||||
create_nr_list(&sched_ctrl->available_ul_harq, nrofHARQ);
|
||||
for (int harq = 0; harq < nrofHARQ; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
|
||||
create_nr_list(&sched_ctrl->feedback_ul_harq, nrofHARQ);
|
||||
create_nr_list(&sched_ctrl->retrans_ul_harq, nrofHARQ);
|
||||
} else if (sched_ctrl->available_ul_harq.len == nrofHARQ) {
|
||||
LOG_D(NR_MAC, "nrofHARQ %d already configured\n", nrofHARQ);
|
||||
} else {
|
||||
const int old_nrofHARQ = sched_ctrl->available_ul_harq.len;
|
||||
AssertFatal(nrofHARQ > old_nrofHARQ,
|
||||
"cannot resize HARQ list to be smaller (nrofHARQ %d, old_nrofHARQ %d)\n",
|
||||
nrofHARQ, old_nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->available_ul_harq, nrofHARQ);
|
||||
for (int harq = old_nrofHARQ; harq < nrofHARQ; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
|
||||
resize_nr_list(&sched_ctrl->feedback_ul_harq, nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->retrans_ul_harq, nrofHARQ);
|
||||
}
|
||||
}
|
||||
|
||||
void reset_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
int harq;
|
||||
while ((harq = sched_ctrl->feedback_dl_harq.head) >= 0) {
|
||||
|
||||
@@ -1968,7 +1968,7 @@ static void pf_ul(module_id_t module_id,
|
||||
const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols);
|
||||
while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap))
|
||||
rbStart++;
|
||||
if (rbStart + min_rb >= bwpSize) {
|
||||
if (rbStart + min_rb > bwpSize) {
|
||||
LOG_D(NR_MAC,
|
||||
"[UE %04x][%4d.%2d] could not allocate continuous UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n",
|
||||
UE->rnti,
|
||||
@@ -2121,7 +2121,7 @@ static void pf_ul(module_id_t module_id,
|
||||
while (rbStart + max_rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + max_rbSize] & slbitmap))
|
||||
max_rbSize++;
|
||||
|
||||
if (rbStart + min_rb >= bwpSize || max_rbSize < min_rb) {
|
||||
if (rbStart + min_rb > bwpSize || max_rbSize < min_rb) {
|
||||
reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n",
|
||||
|
||||
@@ -348,10 +348,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
const uint8_t ul_cqi,
|
||||
const uint16_t rssi);
|
||||
|
||||
void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info);
|
||||
|
||||
void create_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info);
|
||||
|
||||
void reset_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
void reset_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
@@ -908,7 +908,7 @@ typedef struct gNB_MAC_INST_s {
|
||||
bool first_MIB;
|
||||
NR_bler_options_t dl_bler;
|
||||
NR_bler_options_t ul_bler;
|
||||
uint8_t min_grant_prb;
|
||||
uint16_t min_grant_prb;
|
||||
bool identity_pm;
|
||||
int precoding_matrix_size[NR_MAX_NB_LAYERS];
|
||||
int fapi_beam_index[MAX_NUM_OF_SSB];
|
||||
|
||||
@@ -11,6 +11,7 @@ add_library(fgs_5gmm_lib OBJECT
|
||||
RegistrationComplete.c
|
||||
FGSUplinkNasTransport.c
|
||||
FGSDeregistrationRequestUEOriginating.c
|
||||
fgmm_authentication_failure.c
|
||||
)
|
||||
|
||||
target_link_libraries(fgs_5gmm_lib PUBLIC fgs_5gmm_ies_lib)
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "fgmm_authentication_failure.h"
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h> // For htons and ntohs
|
||||
#include <stdlib.h> // For malloc and free
|
||||
#include "fgmm_lib.h"
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
#include "common/utils/utils.h"
|
||||
|
||||
#define MIN_AUTH_FAILURE_LEN 1
|
||||
#define AUTH_FAILURE_PARAM_LEN 16
|
||||
#define AUTH_FAIL_PARAM_IEI 0x30
|
||||
|
||||
/** @brief Encode Authentication Failure (8.2.4 of 3GPP TS 24.501) */
|
||||
int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *msg)
|
||||
{
|
||||
if (buffer->len < MIN_AUTH_FAILURE_LEN) {
|
||||
PRINT_NAS_ERROR("Missing mandatory IE in Authentication Failure");
|
||||
return -1; // missing mandatory IE
|
||||
}
|
||||
// 5GMM cause (Mandatory)
|
||||
int encoded = encode_fgs_nas_cause(buffer, &msg->cause);
|
||||
// Authentication failure parameter (see 8.2.4.2 3GPP TS 24.501)
|
||||
if (msg->cause == Synch_failure) {
|
||||
// Authentication failure parameter shall be present with cause Synch Failure
|
||||
if (msg->authentication_failure_param.len == 0) {
|
||||
PRINT_NAS_ERROR("Authentication Failure Cause is synch failure but Authentication Failure Parameter is not available");
|
||||
return -1;
|
||||
}
|
||||
if (buffer->len - encoded < msg->authentication_failure_param.len + 2) {
|
||||
PRINT_NAS_ERROR("Invalid buffer for encoding of Authentication Failure Parameter");
|
||||
return -1;
|
||||
}
|
||||
// Encode the IEI
|
||||
buffer->buf[encoded++] = AUTH_FAIL_PARAM_IEI;
|
||||
buffer->buf[encoded++] = msg->authentication_failure_param.len;
|
||||
for (int i = 0; i < msg->authentication_failure_param.len; i++) {
|
||||
buffer->buf[encoded++] = msg->authentication_failure_param.buf[i];
|
||||
}
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/** @brief Decode Authentication Failure (8.2.4 of 3GPP TS 24.501) */
|
||||
int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffer)
|
||||
{
|
||||
if (buffer->len < MIN_AUTH_FAILURE_LEN) {
|
||||
return -1; // missing mandatory IE
|
||||
}
|
||||
byte_array_t ba = *buffer; // Local copy of buffer
|
||||
// 5GMM Cause (Mandatory)
|
||||
uint32_t decoded = decode_fgs_nas_cause(&msg->cause, buffer);
|
||||
// Authentication Failure Parameters (Optional)
|
||||
if (msg->cause == Synch_failure) {
|
||||
uint8_t iei = buffer->buf[decoded++];
|
||||
if (iei == AUTH_FAIL_PARAM_IEI) {
|
||||
msg->authentication_failure_param.len = ba.buf[decoded++];
|
||||
if (msg->authentication_failure_param.len > AUTH_FAILURE_PARAM_LEN - 2) { // maximum length of contents is 14 octets
|
||||
PRINT_NAS_ERROR("Length of Authentication Failure Parameter contents is too large");
|
||||
return -1;
|
||||
}
|
||||
msg->authentication_failure_param.buf = malloc_or_fail(msg->authentication_failure_param.len);
|
||||
for (int i = 0; i < msg->authentication_failure_param.len; i++) {
|
||||
msg->authentication_failure_param.buf[i] = buffer->buf[decoded++];
|
||||
}
|
||||
}
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
bool eq_fgmm_auth_failure(const fgmm_auth_failure_t *a, const fgmm_auth_failure_t *b)
|
||||
{
|
||||
_NAS_EQ_CHECK_INT(a->cause, b->cause);
|
||||
eq_byte_array(&a->authentication_failure_param, &b->authentication_failure_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
void free_fgmm_auth_failure(const fgmm_auth_failure_t *msg)
|
||||
{
|
||||
free(msg->authentication_failure_param.buf);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef FGMM_AUTH_FAILURE_H
|
||||
#define FGMM_AUTH_FAILURE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "fgmm_lib.h"
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
|
||||
typedef struct {
|
||||
// 5GMM cause (Mandatory)
|
||||
cause_id_t cause;
|
||||
// Authentication failure parameter (Optional)
|
||||
byte_array_t authentication_failure_param;
|
||||
} fgmm_auth_failure_t;
|
||||
|
||||
int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffer);
|
||||
int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *msg);
|
||||
bool eq_fgmm_auth_failure(const fgmm_auth_failure_t *a, const fgmm_auth_failure_t *b);
|
||||
void free_fgmm_auth_failure(const fgmm_auth_failure_t *msg);
|
||||
|
||||
#endif /* FGMM_AUTH_FAILURE_H */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "NasKeySetIdentifier.h"
|
||||
|
||||
#ifndef FGS_AUTHENTICATION_REQUEST_H_
|
||||
#define FGS_AUTHENTICATION_REQUEST_H_
|
||||
|
||||
typedef struct {
|
||||
// NAS key set identifier (Mandatory)
|
||||
NasKeySetIdentifier ngKSI;
|
||||
// ABBA (Mandatory)
|
||||
int abba;
|
||||
} fgs_authentication_request_t;
|
||||
|
||||
#endif /* ! defined(FGS_AUTHENTICATION_REQUEST_H_) */
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
|
||||
#define GPRS_TIMER_LENGTH 3 // octets
|
||||
#define FGS_NAS_CAUSE_LENGTH 1
|
||||
|
||||
/**
|
||||
* Encode PDU Session Status and PDU session reactivation result (optional IEs)
|
||||
@@ -158,3 +159,27 @@ int decode_eap_msg_ie(const byte_array_t *buffer)
|
||||
PRINT_NAS_ERROR("EAP message IE in NAS Service Reject is not handled\n");
|
||||
return eap_msg_len + 2; // content length + 2 octets for the length IE
|
||||
}
|
||||
|
||||
int encode_fgs_nas_cause(byte_array_t *buffer, const cause_id_t *cause)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
if (buffer->len < FGS_NAS_CAUSE_LENGTH)
|
||||
return -1;
|
||||
|
||||
buffer->buf[encoded++] = *cause;
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
int decode_fgs_nas_cause(cause_id_t *cause, const byte_array_t *buffer)
|
||||
{
|
||||
int decoded = 0;
|
||||
|
||||
if (buffer->len < FGS_NAS_CAUSE_LENGTH)
|
||||
return -1; // nothing to decode
|
||||
|
||||
*cause = buffer->buf[decoded++];
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
@@ -165,5 +165,7 @@ int encode_gprs_timer_ie(byte_array_t *buffer, nas_service_IEI_t iei, const gprs
|
||||
int decode_gprs_timer_ie(gprs_timer_t *timer, const byte_array_t *buffer);
|
||||
bool eq_gprs_timer(const gprs_timer_t *a, const gprs_timer_t *b);
|
||||
int decode_eap_msg_ie(const byte_array_t *buffer);
|
||||
int encode_fgs_nas_cause(byte_array_t *buffer, const cause_id_t *cause);
|
||||
int decode_fgs_nas_cause(cause_id_t *cause, const byte_array_t *buffer);
|
||||
|
||||
#endif /* FGS_LIB_H */
|
||||
@@ -12,6 +12,7 @@ target_link_libraries(fgs_lib PUBLIC
|
||||
fgs_5gsm_lib
|
||||
fgs_5gmm_ies_lib
|
||||
nas_common_ies_lib
|
||||
ds
|
||||
)
|
||||
|
||||
target_include_directories(fgs_lib PUBLIC . 5GMM/MSG 5GMM/IES)
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "RegistrationComplete.h"
|
||||
#include "RegistrationRequest.h"
|
||||
#include "fgs_service_request.h"
|
||||
#include "fgmm_authentication_failure.h"
|
||||
|
||||
/* Message types defintions for:
|
||||
(a) 5GS Mobility Management (5GMM) (IDs 0x41 - 0x68)
|
||||
@@ -222,6 +223,7 @@ typedef struct {
|
||||
fgs_service_request_msg_t service_request;
|
||||
fgmm_identity_response_msg fgs_identity_response;
|
||||
fgs_authentication_response_msg fgs_auth_response;
|
||||
fgmm_auth_failure_t fgmm_auth_failure;
|
||||
fgs_deregistration_request_ue_originating_msg fgs_deregistration_request_ue_originating;
|
||||
fgs_security_mode_complete_msg fgs_security_mode_complete;
|
||||
registration_complete_msg registration_complete;
|
||||
|
||||
@@ -73,6 +73,11 @@ int mm_msg_encode(const fgmm_nas_message_plain_t *p, uint8_t *buffer, uint32_t l
|
||||
case FGS_AUTHENTICATION_RESPONSE:
|
||||
enc_msg = encode_fgs_authentication_response(&p->mm_msg.fgs_auth_response, buffer, len);
|
||||
break;
|
||||
case FGS_AUTHENTICATION_FAILURE: {
|
||||
byte_array_t ba = {.buf = buffer, .len = len};
|
||||
enc_msg = encode_fgmm_auth_failure(&ba, &p->mm_msg.fgmm_auth_failure);
|
||||
break;
|
||||
}
|
||||
case FGS_SECURITY_MODE_COMPLETE:
|
||||
enc_msg = encode_fgs_security_mode_complete(&p->mm_msg.fgs_security_mode_complete, buffer, len);
|
||||
break;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "fgs_service_request.h"
|
||||
#include "fgmm_service_accept.h"
|
||||
#include "fgmm_service_reject.h"
|
||||
#include "fgmm_authentication_failure.h"
|
||||
#include "nr_nas_msg.h"
|
||||
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||
@@ -230,11 +231,47 @@ static void test_service_reject(void)
|
||||
free_fgs_service_reject(&orig);
|
||||
}
|
||||
|
||||
/** @brief Test NAS Authentication Failure enc/dec */
|
||||
static void test_auth_failure(void)
|
||||
{
|
||||
// Dummy NAS Authentication Failure message
|
||||
uint8_t afp[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
|
||||
const fgmm_auth_failure_t orig = {
|
||||
.cause = Synch_failure,
|
||||
.authentication_failure_param.len = 6,
|
||||
.authentication_failure_param.buf = afp,
|
||||
};
|
||||
|
||||
// Expected encoded data
|
||||
uint8_t expected_enc[] = {0x15, 0x30, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
|
||||
|
||||
// Buffer
|
||||
uint8_t buf[16] = {0};
|
||||
byte_array_t buffer = {.buf = buf, .len = sizeof(buf)};
|
||||
|
||||
// Encode
|
||||
int encoded_length = encode_fgmm_auth_failure(&buffer, &orig);
|
||||
AssertFatal(encoded_length == sizeofArray(expected_enc), "encode_fgmm_auth_failure() failed\n");
|
||||
|
||||
// Compare the raw encoded buffer with expected encoded data
|
||||
AssertFatal(memcmp(buffer.buf, expected_enc, encoded_length) == 0, "Encoding mismatch!\n");
|
||||
|
||||
// Decode
|
||||
fgmm_auth_failure_t dec = {0};
|
||||
int decoded_length = decode_fgmm_auth_failure(&dec, &buffer);
|
||||
AssertFatal(decoded_length >= 0, "decode_fgmm_auth_failure() failed\n");
|
||||
|
||||
// Compare original and decoded messages
|
||||
AssertFatal(eq_fgmm_auth_failure(&orig, &dec), "test_auth_failure() failed: original and decoded messages do not match\n");
|
||||
free_fgmm_auth_failure(&dec);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_regression_registration_accept();
|
||||
test_service_request();
|
||||
test_service_accept();
|
||||
test_service_reject();
|
||||
test_auth_failure();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ target_link_libraries(nr_nas PUBLIC
|
||||
fgs_5gmm_ies_lib
|
||||
nas_common_ies_lib
|
||||
nas_utils
|
||||
ds
|
||||
)
|
||||
|
||||
target_include_directories(nr_nas PUBLIC . 5GS/)
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "RegistrationAccept.h"
|
||||
#include "SORTransparentContainer.h"
|
||||
#include "FGSIdentityResponse.h"
|
||||
#include "fgmm_authentication_request.h"
|
||||
#include "T.h"
|
||||
#include "aka_functions.h"
|
||||
#include "assertions.h"
|
||||
@@ -839,6 +840,58 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN
|
||||
free(res.value);
|
||||
}
|
||||
|
||||
/** @brief Send Authentication Failure message from the UE to the AMF to
|
||||
* indicate that authentication of the network has failed */
|
||||
static void generateAuthenticationFailure(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, cause_id_t cause)
|
||||
{
|
||||
int size = sizeof(fgmm_msg_header_t);
|
||||
fgmm_nas_message_plain_t plain = {0};
|
||||
|
||||
// Plain 5GMM header
|
||||
plain.header = set_mm_header(FGS_AUTHENTICATION_FAILURE, PLAIN_5GS_MSG);
|
||||
size += sizeof(plain.header);
|
||||
// 5GMM Cause (Mandatory)
|
||||
fgmm_auth_failure_t *mm_msg = &plain.mm_msg.fgmm_auth_failure;
|
||||
mm_msg->cause = cause;
|
||||
size += 1;
|
||||
initialNasMsg->nas_data = malloc_or_fail(size * sizeof(*initialNasMsg->nas_data));
|
||||
initialNasMsg->length = mm_msg_encode(&plain, initialNasMsg->nas_data, size);
|
||||
}
|
||||
|
||||
static void handle_fgmm_authentication_request(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, byte_array_t *buffer)
|
||||
{
|
||||
LOG_D(NAS, "Received NAS Authentication Request\n");
|
||||
fgs_authentication_request_t msg = {0};
|
||||
int size = 0;
|
||||
int decoded = 0;
|
||||
|
||||
// decode plain 5GMM message header
|
||||
fgmm_msg_header_t mm_header = {0};
|
||||
if ((decoded = decode_5gmm_msg_header(&mm_header, buffer->buf + size, buffer->len - size)) < 0) {
|
||||
LOG_E(NAS, "decode_5gmm_msg_header failure in NAS Authentication Request handling\n");
|
||||
return;
|
||||
}
|
||||
size += decoded;
|
||||
// NAS key set identifier (Mandatory)
|
||||
if ((decoded = decode_nas_key_set_identifier(&msg.ngKSI, 0, buffer->buf[decoded])) < 0) {
|
||||
LOG_E(NAS, "decode_nas_key_set_identifier failure in NAS Authentication Request handling\n");
|
||||
return;
|
||||
}
|
||||
size += decoded;
|
||||
if (!nas->ksi) {
|
||||
nas->ksi = malloc_or_fail(sizeof(*nas->ksi));
|
||||
*nas->ksi = msg.ngKSI.naskeysetidentifier;
|
||||
LOG_D(NAS, "Stored NAS Key Set Identifier %d\n", *nas->ksi);
|
||||
} else if (*nas->ksi == msg.ngKSI.naskeysetidentifier) {
|
||||
/* If the ngKSI value received is already associated with one
|
||||
of the 5G security contexts stored in the UE, send failure message */
|
||||
LOG_E(NAS, "Invalid NAS Key Set Identifier: send Authentication Failure\n");
|
||||
generateAuthenticationFailure(nas, initialNasMsg, ngKSI_already_in_use);
|
||||
return;
|
||||
}
|
||||
generateAuthenticationResp(nas, initialNasMsg, buffer->buf);
|
||||
}
|
||||
|
||||
int nas_itti_kgnb_refresh_req(instance_t instance, const uint8_t kgnb[32])
|
||||
{
|
||||
MessageDef *message_p;
|
||||
@@ -1720,9 +1773,11 @@ void *nas_nrue(void *args_p)
|
||||
case FGS_IDENTITY_REQUEST:
|
||||
generateIdentityResponse(&initialNasMsg, *(pdu_buffer + 3), nas->uicc);
|
||||
break;
|
||||
case FGS_AUTHENTICATION_REQUEST:
|
||||
generateAuthenticationResp(nas, &initialNasMsg, pdu_buffer);
|
||||
case FGS_AUTHENTICATION_REQUEST: {
|
||||
byte_array_t buffer = {.buf = pdu_buffer, .len = pdu_length};
|
||||
handle_fgmm_authentication_request(nas, &initialNasMsg, &buffer);
|
||||
break;
|
||||
}
|
||||
case FGS_SECURITY_MODE_COMMAND:
|
||||
handle_security_mode_command(nas, &initialNasMsg, pdu_buffer, pdu_length);
|
||||
break;
|
||||
|
||||
@@ -102,6 +102,8 @@ typedef struct {
|
||||
int t3448;
|
||||
// Timer t3446 in seconds (-1 = disabled)
|
||||
int t3446;
|
||||
/* NAS Key Set Identifier associated to the security context */
|
||||
uint8_t *ksi;
|
||||
} nr_ue_nas_t;
|
||||
|
||||
nr_ue_nas_t *get_ue_nas_info(module_id_t module_id);
|
||||
|
||||
Reference in New Issue
Block a user