From 6b8a59cb689fab9caacc03cc995878435f63ac21 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 8 Jan 2025 13:40:58 +0100 Subject: [PATCH 01/14] gNB: add support for NTN parameter ta-CommonDrift-r17 --- openair2/GNB_APP/RRC_nr_paramsvalues.h | 2 ++ openair2/GNB_APP/gnb_config.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index be2fd03542..10af856770 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -132,6 +132,7 @@ #define GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VY "velocityVY-r17" #define GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VZ "velocityVZ-r17" #define GNB_CONFIG_STRING_TA_COMMON "ta-Common-r17" +#define GNB_CONFIG_STRING_TA_COMMONDRIFT "ta-CommonDrift-r17" #define CARRIERBANDWIDTH_OKVALUES {11,18,24,25,31,32,38,51,52,65,66,78,79,93,106,107,121,132,133,135,160,162,189,216,217,245,264,270,273} @@ -257,6 +258,7 @@ {GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VY,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->velocityVY_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \ {GNB_CONFIG_STRING_EPHEMERIS_VELOCITY_VZ,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->velocityVZ_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \ {GNB_CONFIG_STRING_TA_COMMON,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ta_Info_r17->ta_Common_r17,.defint64val=-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_TA_COMMONDRIFT,NULL,0,.i64ptr=scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17,.defint64val=0,TYPE_INT64,0}, \ {GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,.defintval=-1,TYPE_INT64,0}} #define SCC_PATTERN2_STRING_CONFIG "pattern2" diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index a57d2e0287..6bb0b7880d 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -185,6 +185,7 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) scc->ext2->ntn_Config_r17->ephemerisInfo_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17)); scc->ext2->ntn_Config_r17->ta_Info_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17)); + scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17)); scc->ext2->ntn_Config_r17->ephemerisInfo_r17->present = NR_EphemerisInfo_r17_PR_positionVelocity_r17; scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 = @@ -505,7 +506,12 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap) free(scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17); scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = NULL; } + if (*scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 == 0) { + free(scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17); + scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 = NULL; + } if (scc->ext2->ntn_Config_r17->ta_Info_r17->ta_Common_r17 == -1) { + free(scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17); free(scc->ext2->ntn_Config_r17->ta_Info_r17); scc->ext2->ntn_Config_r17->ta_Info_r17 = NULL; } From e7122ad7892376b06c7db634ed011a41c4c9a9f6 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 8 Jan 2025 13:50:49 +0100 Subject: [PATCH 02/14] NR UE: fix application of NTN TA information --- executables/nr-ue.c | 43 ++++++++++++++------- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 1 + 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 213263978a..f5ce6cdd4c 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -814,6 +814,33 @@ static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) { return rem_samples + next_slot_first_symbol; } +static inline void apply_ntn_config(PHY_VARS_NR_UE *UE, + NR_DL_FRAME_PARMS *fp, + int slot_nr, + bool *update_ntn_system_information, + int *duration_rx_to_tx, + int *timing_advance, + int *ntn_koffset) +{ + if (*update_ntn_system_information) { + *update_ntn_system_information = false; + + *duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX + UE->ntn_config_message->ntn_config_params.cell_specific_k_offset; + UE->timing_advance = fp->samples_per_subframe * UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms; + *timing_advance += + fp->get_samples_slot_timestamp(slot_nr, + fp, + UE->ntn_config_message->ntn_config_params.cell_specific_k_offset - *ntn_koffset); + *ntn_koffset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset; + + LOG_I(PHY, + "cell_specific_k_offset = %d ms, ntn_total_time_advance_ms = %f ms (%d samples)\n", + *ntn_koffset, + UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms, + UE->timing_advance); + } +} + void *UE_thread(void *arg) { //this thread should be over the processing thread to keep in real time @@ -869,7 +896,6 @@ void *UE_thread(void *arg) readFrame(UE, &tmp, true); } - double ntn_ta_common = 0; int ntn_koffset = 0; int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX; @@ -1000,16 +1026,6 @@ void *UE_thread(void *arg) absolute_slot++; TracyCFrameMark; - if (update_ntn_system_information) { - update_ntn_system_information = false; - int ta_offset = UE->frame_parms.samples_per_subframe * (UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms - ntn_ta_common); - - UE->timing_advance += ta_offset; - ntn_ta_common = UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms; - ntn_koffset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset; - timing_advance = ntn_koffset * (UE->frame_parms.samples_per_subframe >> mac->current_UL_BWP->scs); - } - if (UE->ntn_config_message->update) { UE->ntn_config_message->update = false; update_ntn_system_information = true; @@ -1129,10 +1145,9 @@ void *UE_thread(void *arg) newTx); stream_status = STREAM_STATUS_SYNCED; tx_wait_for_dlsch[slot] = 0; + // apply new duration next run to avoid thread dead lock - if (update_ntn_system_information) { - duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX + UE->ntn_config_message->ntn_config_params.cell_specific_k_offset; - } + apply_ntn_config(UE, fp, slot_nr, &update_ntn_system_information, &duration_rx_to_tx, &timing_advance, &ntn_koffset); } return NULL; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index aa00daf9c9..6a65adafa7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -3617,6 +3617,7 @@ static void schedule_ntn_config_command(fapi_nr_dl_config_request_t *dl_config, { fapi_nr_dl_ntn_config_command_pdu *ntn_config_command_pdu = &dl_config->dl_config_list[dl_config->number_pdus].ntn_config_command_pdu; ntn_config_command_pdu->cell_specific_k_offset = mac->ntn_ta.cell_specific_k_offset; + ntn_config_command_pdu->ntn_ta_commondrift = mac->ntn_ta.ntn_ta_commondrift; ntn_config_command_pdu->N_common_ta_adj = mac->ntn_ta.N_common_ta_adj; ntn_config_command_pdu->N_UE_TA_adj = mac->ntn_ta.N_UE_TA_adj; ntn_config_command_pdu->ntn_total_time_advance_ms = (mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj) * 2; From f1ca3066a0fe441bc95d30546621ed410c715c39 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 8 Jan 2025 13:56:53 +0100 Subject: [PATCH 03/14] NR UE: add command line parameter ntn-initial-time-drift to compensate time drift during initial sync The value of ntn_init_time_drift is used at initial sync to compensate for the time drift during initial sync detection. To perform the initial time and frequency sync, the OAI UE currently takes a snapshot of two frames and then performes PSS correlation, SSS detection and MIB decoding. Doing this takes much time, several tens of ms. During that time, the DL timing drifts so much, that we immediatedly lose sync again. Therefore the current OAI UE implementation needs to know the drift rate to compensate for this drift, as we are "blind" while performing the initial sync. To my undestanding, commercial UEs simply have a faster initial sync, so the DL timing will not drift away too much while performing that initial sync. --- executables/nr-ue.c | 5 +++-- executables/nr-uesoftmodem.h | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index f5ce6cdd4c..f19f6a15b6 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -896,6 +896,7 @@ void *UE_thread(void *arg) readFrame(UE, &tmp, true); } + double ntn_init_time_drift = get_nrUE_params()->ntn_init_time_drift; int ntn_koffset = 0; int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX; @@ -984,8 +985,8 @@ void *UE_thread(void *arg) syncInFrame(UE, &sync_timestamp, intialSyncOffset); openair0_write_reorder_clear_context(&UE->rfdevice); if (get_nrUE_params()->time_sync_I) - // ntn_ta_commondrift is in µs/s, max_pos_acc * time_sync_I is in samples/frame - UE->max_pos_acc = mac->ntn_ta.ntn_ta_commondrift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I; + // ntn_init_time_drift is in µs/s, max_pos_acc * time_sync_I is in samples/frame + UE->max_pos_acc = ntn_init_time_drift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I; else UE->max_pos_acc = 0; shiftForNextFrame = -(UE->init_sync_frame + trashed_frames + 2) * UE->max_pos_acc * get_nrUE_params()->time_sync_I; // compensate for the time drift that happened during initial sync diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 90e32d651b..f7e3b42a72 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -12,6 +12,7 @@ #define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n" #define CONFIG_HLP_TIME_SYNC_P "coefficient for Proportional part of time sync PI controller\n" #define CONFIG_HLP_TIME_SYNC_I "coefficient for Integrating part of time sync PI controller\n" +#define CONFIG_HLP_NTN_INIT_TIME_DRIFT "Initial NTN DL time drift (feeder link and service link), given in µs/s\n" #define CONFIG_HLP_AUTONOMOUS_TA "Autonomously update TA based on DL drift (useful if main contribution to DL drift is movement, e.g. LEO satellite)\n" #define CONFIG_HLP_AGC "Rx Gain control used for UE\n" @@ -62,6 +63,7 @@ {"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \ {"time-sync-P", CONFIG_HLP_TIME_SYNC_P, 0, .dblptr=&(nrUE_params.time_sync_P), .defdblval=0.5, TYPE_DOUBLE, 0}, \ {"time-sync-I", CONFIG_HLP_TIME_SYNC_I, 0, .dblptr=&(nrUE_params.time_sync_I), .defdblval=0.0, TYPE_DOUBLE, 0}, \ + {"ntn-initial-time-drift", CONFIG_HLP_NTN_INIT_TIME_DRIFT, 0, .dblptr=&(nrUE_params.ntn_init_time_drift), .defdblval=0.0, TYPE_DOUBLE, 0}, \ {"autonomous-ta", CONFIG_HLP_AUTONOMOUS_TA, PARAMFLAG_BOOL, .iptr=&(nrUE_params.autonomous_ta), .defintval=0, TYPE_INT, 0}, \ {"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \ } @@ -85,6 +87,7 @@ typedef struct { int ssb_start_subcarrier; double time_sync_P; double time_sync_I; + double ntn_init_time_drift; int autonomous_ta; int agc; char *usrp_args; From 9b7e39b16febacce923dd6ef550c55bc2015a8d4 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 8 Jan 2025 14:05:36 +0100 Subject: [PATCH 04/14] NR UE: fix writeTimestamp inconsistencies The "writeTimestamp inconsistencies" are coming from the fact that during the actual processing we write `N_TA_offset` samples _and_ `NR_UE_CAPABILITY_SLOT_RX_TO_TX` slots ahead, but both was not corrently considered in readFrame() and syncInFrame(). Therefore, there was always a warning about a gap in write timestamps as soon the actual processing starts. --- executables/nr-ue.c | 61 +++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index f19f6a15b6..c08ebe00f4 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -491,9 +491,10 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action) openair0_timestamp writeTimestamp = proc->timestamp_tx; int writeBlockSize = rxtxD->writeBlockSize; - if ( writeBlockSize > fp->get_samples_per_slot(proc->nr_slot_tx, fp)) { - // if writeBlockSize gets longer that slot size, fill with dummy - const int dummyBlockSize = writeBlockSize - fp->get_samples_per_slot(proc->nr_slot_tx, fp); + // if writeBlockSize gets longer that slot size, fill with dummy + 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); AssertFatal(tmp == dummyBlockSize, ""); @@ -741,29 +742,32 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) } void *rxp[NB_ANTENNAS_RX]; + if (toTrash) + for (int i = 0; i < fp->nb_antennas_rx; i++) + rxp[i] = malloc16(fp->get_samples_per_slot(0, fp) * 4); for (int x = 0; x < num_frames * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; x++) { // two frames for initial sync for (int slot = 0; slot < fp->slots_per_subframe; slot++) { - for (int i = 0; i < fp->nb_antennas_rx; i++) { - if (toTrash) - rxp[i] = malloc16(fp->get_samples_per_slot(slot, fp) * 4); - else + if (!toTrash) + for (int i = 0; i < fp->nb_antennas_rx; i++) rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4 * ((x * fp->samples_per_subframe) + fp->get_samples_slot_timestamp(slot, fp, 0)); - } int read_block_size = fp->get_samples_per_slot(slot, fp); int tmp = UE->rfdevice.trx_read_func(&UE->rfdevice, timestamp, rxp, read_block_size, fp->nb_antennas_rx); UEscopeCopy(UE, ueTimeDomainSamplesBeforeSync, rxp[0], sizeof(c16_t), 1, read_block_size, 0); AssertFatal(read_block_size == tmp, ""); - if (IS_SOFTMODEM_RFSIM) - dummyWrite(UE, *timestamp, fp->get_samples_per_slot(slot, fp)); - if (toTrash) - for (int i = 0; i < fp->nb_antennas_rx; i++) - free(rxp[i]); + if (IS_SOFTMODEM_RFSIM) { + const openair0_timestamp writeTimestamp = *timestamp + fp->get_samples_slot_timestamp(slot, fp, NR_UE_CAPABILITY_SLOT_RX_TO_TX) - UE->N_TA_offset; + dummyWrite(UE, writeTimestamp, fp->get_samples_per_slot(slot, fp)); + } } } + + if (toTrash) + for (int i = 0; i < fp->nb_antennas_rx; i++) + free(rxp[i]); } static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, openair0_timestamp rx_offset) @@ -774,27 +778,18 @@ static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, opena LOG_I(PHY, "Resynchronizing RX by %ld samples\n", rx_offset); - if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) { - // Resynchonize by slot (will work with numerology 1 only) - for (int size = rx_offset; size > 0; size -= fp->samples_per_subframe / 2) { - int unitTransfer = size > fp->samples_per_subframe / 2 ? fp->samples_per_subframe / 2 : size; - int tmp = - UE->rfdevice.trx_read_func(&UE->rfdevice, timestamp, (void **)UE->common_vars.rxdata, unitTransfer, fp->nb_antennas_rx); - DevAssert(unitTransfer == tmp); - } - } else { - *timestamp += fp->get_samples_per_slot(1, fp); - for (int size = rx_offset; size > 0; size -= fp->samples_per_subframe) { - int unitTransfer = size > fp->samples_per_subframe ? fp->samples_per_subframe : size; - // we write before read because gNB waits for UE to write and both executions halt - // this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot - if (IS_SOFTMODEM_RFSIM) - dummyWrite(UE, *timestamp, unitTransfer); - int res = - UE->rfdevice.trx_read_func(&UE->rfdevice, timestamp, (void **)UE->common_vars.rxdata, unitTransfer, fp->nb_antennas_rx); - DevAssert(unitTransfer == res); - *timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write + int slot = 0; + int size = rx_offset; + while (size > 0) { + const int unitTransfer = min(fp->get_samples_per_slot(slot, fp), size); + const int res = UE->rfdevice.trx_read_func(&UE->rfdevice, timestamp, (void **)UE->common_vars.rxdata, unitTransfer, fp->nb_antennas_rx); + DevAssert(unitTransfer == res); + if (IS_SOFTMODEM_RFSIM) { + const openair0_timestamp writeTimestamp = *timestamp + fp->get_samples_slot_timestamp(slot, fp, NR_UE_CAPABILITY_SLOT_RX_TO_TX) - UE->N_TA_offset; + dummyWrite(UE, writeTimestamp, unitTransfer); } + slot = (slot + 1) % fp->slots_per_subframe; + size -= unitTransfer; } } From be2ed0791195bdba1bb0f88ce5b2904f7a163579 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 8 Jan 2025 14:11:05 +0100 Subject: [PATCH 05/14] NR UE: add MAC state UE_RECEIVING_SIB ensuring to start RA only after successfully receiving SIBs --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 4 +++- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 10 +++++++--- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 2 +- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 732b4738b5..57792ac2ee 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -937,6 +937,8 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, mac->get_sib1 = true; else if (sched_sib == 2) mac->get_otherSI = true; + else if (sched_sib == 0 && mac->state == UE_RECEIVING_SIB) + mac->state = UE_PERFORMING_RA; nr_ue_decode_mib(mac, cc_idP); ret = pthread_mutex_unlock(&mac->if_mutex); AssertFatal(!ret, "mutex failed %d\n", ret); @@ -1690,7 +1692,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t case T300_EXPIRY: reset_ra(mac, false); reset_mac_inst(mac); - mac->state = UE_SYNC; // still in sync but need to restart RA + mac->state = UE_PERFORMING_RA; // still in sync but need to restart RA break; case RE_ESTABLISHMENT: reset_mac_inst(mac); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 55120dca96..24fefe47af 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -165,7 +165,7 @@ // Define the UE L2 states with X-Macro #define NR_UE_L2_STATES \ UE_STATE(UE_NOT_SYNC) \ - UE_STATE(UE_SYNC) \ + UE_STATE(UE_RECEIVING_SIB) \ UE_STATE(UE_PERFORMING_RA) \ UE_STATE(UE_CONNECTED) \ UE_STATE(UE_DETACHING) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 70e3019701..4108ebb6e4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -1041,7 +1041,7 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac) { LOG_W(NR_MAC, "Triggering new RA procedure for UE with RNTI %x\n", mac->crnti); - mac->state = UE_SYNC; + mac->state = UE_PERFORMING_RA; reset_ra(mac, false); mac->ra.msg3_C_RNTI = true; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index c7ceeeab8e..eedc18971b 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -223,10 +223,14 @@ void nr_ue_decode_mib(NR_UE_MAC_INST_t *mac, int cc_id) if (mac->first_sync_frame == -1) mac->first_sync_frame = frame; - if(get_softmodem_params()->phy_test) + if (get_softmodem_params()->phy_test) mac->state = UE_CONNECTED; - else if(mac->state == UE_NOT_SYNC) - mac->state = UE_SYNC; + else if (mac->state == UE_NOT_SYNC) { + if (IS_SA_MODE(get_softmodem_params())) + mac->state = UE_RECEIVING_SIB; + else + mac->state = UE_PERFORMING_RA; + } } static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 6a65adafa7..8f6dc4cc8c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1565,7 +1565,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) uint32_t gNB_index = ul_info->gNB_index; RA_config_t *ra = &mac->ra; - if(mac->state > UE_NOT_SYNC && mac->state < UE_CONNECTED) { + if (mac->state == UE_PERFORMING_RA) { nr_ue_get_rach(mac, cc_id, frame_tx, gNB_index, slot_tx); nr_ue_prach_scheduler(mac, frame_tx, slot_tx); } From 3fce7688aadb630e6bd7916e13f69406897b2730 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 9 Jan 2025 10:34:52 +0100 Subject: [PATCH 06/14] rfsimulator: update earth radius for LEO simulation to match UE position in ue.conf file --- radio/rfsimulator/apply_channelmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/rfsimulator/apply_channelmod.c b/radio/rfsimulator/apply_channelmod.c index 91ad8b070d..cb8e75abdf 100644 --- a/radio/rfsimulator/apply_channelmod.c +++ b/radio/rfsimulator/apply_channelmod.c @@ -56,7 +56,7 @@ void rxAddInput(const c16_t *input_sig, - The ground station is located at the North Pole (positive Zaxis), and the satellite starts from the initial elevation angle 0° in the second quadrant of the YZplane. - Satellite moves in the clockwise direction in its circular orbit. */ - const double radius_earth = 6371e3; // m + const double radius_earth = 6377900; // m const double radius_sat = radius_earth + channelDesc->sat_height; const double GM_earth = 3.986e14; // m^3/s^2 const double w_sat = sqrt(GM_earth / (radius_sat * radius_sat * radius_sat)); // rad/s From cf0a1d6db4b9016d576e42da8728206c3a852004 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 9 Jan 2025 10:37:29 +0100 Subject: [PATCH 07/14] update conf files for NTN LEO scenario Also added a dedicated conf file for NTN LEO, that can be used for CI. --- .../gnb.sa.band66.ntn.25prb.rfsim.conf | 10 +- .../gnb.sa.band66.ntn.leo.25prb.rfsim.conf | 301 ++++++++++++++++++ .../gnb.sa.band66.fr1.24PRB.usrpx300.conf | 27 +- .../gnb.sa.band66.fr1.25PRB.usrpx300.conf | 22 +- targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf | 4 +- 5 files changed, 352 insertions(+), 12 deletions(-) create mode 100644 ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf diff --git a/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf index 4e88f02b91..76957182e1 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf @@ -148,7 +148,7 @@ gNBs = #ext2 #ntn_Config_r17 cellSpecificKoffset_r17 = 478; - ta-Common-r17 = 29314900; + ta-Common-r17 = 29314900; # 119.37 ms positionX-r17 = 0; positionY-r17 = 0; positionZ-r17 = 32433846; @@ -196,8 +196,11 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; +# ulsch_max_frame_inactivity = 0; pusch_TargetSNRx10 = 150; pucch_TargetSNRx10 = 200; + dl_max_mcs = 9; + ul_max_mcs = 9; } ); @@ -205,7 +208,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - prach_dtx_threshold = 120; + prach_dtx_threshold = 150; pucch0_dtx_threshold = 150; ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } @@ -244,7 +247,7 @@ rfsimulator : serveraddr = "server"; serverport = 4043; options = (); #("saviq"); or/and "chanmod" - modelname = "AWGN"; + prop_delay = 238.74; IQfile = "/tmp/rfsimulator.iqs"; }; @@ -277,4 +280,3 @@ log_config : ngap_log_level ="debug"; f1ap_log_level ="debug"; }; - diff --git a/ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf new file mode 100644 index 0000000000..2cd1186dcd --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf @@ -0,0 +1,301 @@ +Active_gNBs = ( "5G-GOA-gNB"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "5G-GOA-gNB"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + nr_cellid = 12345678L; + + ////////// Physical parameters: + + sib1_tda = 5; + min_rxtxtime = 6; + num_dlharq = 32; + num_ulharq = 32; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 2150.43 MHz + 14 PRBs@15kHz SCS (same as initial BWP), points to Subcarrier 0 of RB#10 of SSB block + absoluteFrequencySSB = 430590; + dl_frequencyBand = 66; + # this is 2150.43 MHz + dl_absoluteFrequencyPointA = 430086; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 0; + dl_carrierBandwidth = 25; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=25 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 0; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 2; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 66; + # this is 1750.43 MHz + ul_absoluteFrequencyPointA = 350086; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 0; + ul_carrierBandwidth = 25; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 0; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 0; +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; + + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 0; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 0; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + + #ext2 + #ntn_Config_r17 + cellSpecificKoffset_r17 = 40; + ta-Common-r17 = 2317000; # 9.435 ms + ta-CommonDrift-r17 = -230000; # -46 µs/s + positionX-r17 = 0; + positionY-r17 = -2166908; # -2816980.4 m + positionZ-r17 = 4910784; # 6384019.2 m + velocityVX-r17 = 0; + velocityVY-r17 = 115246; # 6914.76 m/s + velocityVZ-r17 = 50853; # 3051.18 m/s + } + + ); + + TIMERS : + { + sr_ProhibitTimer = 0; + sr_TransMax = 64; + sr_ProhibitTimer_v1700 = 512; + t300 = 2000; + t301 = 2000; + t319 = 2000; + }; + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "192.168.71.132"; }); + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/26"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/26"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; +# ulsch_max_frame_inactivity = 0; + pusch_TargetSNRx10 = 150; + pucch_TargetSNRx10 = 200; + dl_max_mcs = 9; + ul_max_mcs = 9; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 150; + pucch0_dtx_threshold = 150; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + sf_extension = 0; + eNB_instances = [0]; + sdr_addrs = "type=x300"; + clock_src = "internal"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = 4043; + options = ("chanmod"); #("saviq"); or/and "chanmod" + prop_delay = 20; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +channelmod = { + max_chan=10; + modellist="modellist_rfsimu_1"; + modellist_rfsimu_1 = ( + { + model_name = "rfsimu_channel_enB0" + type = "SAT_LEO_TRANS"; + noise_power_dB = -100; + }, + { + model_name = "rfsimu_channel_ue0" + type = "SAT_LEO_TRANS"; + noise_power_dB = -100; + } + ); +}; + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf index 144e7d042b..b0bbbf1671 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf @@ -35,6 +35,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; # disable_harq = 1; +# num_dlharq = 32; +# num_ulharq = 32; servingCellConfigCommon = ( { @@ -163,8 +165,25 @@ gNBs = #ext2 #ntn_Config_r17 -# cellSpecificKoffset_r17 = 478; # GEO satellite -# cellSpecificKoffset_r17 = 40; # LEO satellite +# GEO satellite +# cellSpecificKoffset_r17 = 478; +# ta-Common-r17 = 29314900; # 119.37 ms +# positionX-r17 = 0; +# positionY-r17 = 0; +# positionZ-r17 = 32433846; +# velocityVX-r17 = 0; +# velocityVY-r17 = 0; +# velocityVZ-r17 = 0; +# LEO satellite +# cellSpecificKoffset_r17 = 40; +# ta-Common-r17 = 2317000; # 9.435 ms +# ta-CommonDrift-r17 = -230000; # -46 µs/s +# positionX-r17 = 0; +# positionY-r17 = -2166908; # -2816980.4 m +# positionZ-r17 = 4910784; # 6384019.2 m +# velocityVX-r17 = 0; +# velocityVY-r17 = 115246; # 6914.76 m/s +# velocityVZ-r17 = 50853; # 3051.18 m/s } ); @@ -208,6 +227,8 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 150; pucch_TargetSNRx10 = 200; +# dl_max_mcs = 9; +# ul_max_mcs = 9; } ); @@ -215,7 +236,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - prach_dtx_threshold = 120; + prach_dtx_threshold = 150; pucch0_dtx_threshold = 150; ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf index fdb60c73fb..4fc4a07c21 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf @@ -35,6 +35,8 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; # disable_harq = 1; +# num_dlharq = 32; +# num_ulharq = 32; servingCellConfigCommon = ( { @@ -163,15 +165,25 @@ gNBs = #ext2 #ntn_Config_r17 -# cellSpecificKoffset_r17 = 478; # GEO satellite -# cellSpecificKoffset_r17 = 40; # LEO satellite -# ta-Common-r17 = 29314900; +# GEO satellite +# cellSpecificKoffset_r17 = 478; +# ta-Common-r17 = 29314900; # 119.37 ms # positionX-r17 = 0; # positionY-r17 = 0; # positionZ-r17 = 32433846; # velocityVX-r17 = 0; # velocityVY-r17 = 0; # velocityVZ-r17 = 0; +# LEO satellite +# cellSpecificKoffset_r17 = 40; +# ta-Common-r17 = 2317000; # 9.435 ms +# ta-CommonDrift-r17 = -230000; # -46 µs/s +# positionX-r17 = 0; +# positionY-r17 = -2166908; # -2816980.4 m +# positionZ-r17 = 4910784; # 6384019.2 m +# velocityVX-r17 = 0; +# velocityVY-r17 = 115246; # 6914.76 m/s +# velocityVZ-r17 = 50853; # 3051.18 m/s } ); @@ -215,6 +227,8 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 150; pucch_TargetSNRx10 = 200; +# dl_max_mcs = 9; +# ul_max_mcs = 9; } ); @@ -222,7 +236,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - prach_dtx_threshold = 120; + prach_dtx_threshold = 150; pucch0_dtx_threshold = 150; ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf index 115104e8f1..4cea93ea46 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf @@ -11,4 +11,6 @@ position0 = { x = 0.0; y = 0.0; z = 6377900.0; -} \ No newline at end of file +} + +@include "channelmod_rfsimu_LEO_satellite.conf" From acac0b21bf6e9445a807eafaa2c93a33e121fe82 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 9 Jan 2025 11:52:36 +0100 Subject: [PATCH 08/14] update description how to run NTN scenarios in RUNMODEM.md --- doc/RUNMODEM.md | 78 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 16 deletions(-) diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index e6a715a29a..d027f8553e 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -221,15 +221,49 @@ Or by providing this the the command line parameters: ### gNB -The main parameter to cope with the large NTN propagation delay is the cellSpecificKoffset. -This parameter is the scheduling offset used for the timing relationships that are modified for NTN (see TS 38.213). +The main parameters to cope with the large NTN propagation delay are cellSpecificKoffset, ta-Common, ta-CommonDrift and the ephemeris data (satellite position and velocity vectors). + +The parameter `cellSpecificKoffset_r17` is the scheduling offset used for the timing relationships that are modified for NTN (see TS 38.213). The unit of the field Koffset is number of slots for a given subcarrier spacing of 15 kHz. -This parameter can be provided to the gNB in the conf file as `cellSpecificKoffset_r17` in the section `servingCellConfigCommon`. +The parameter `ta-Common-r17` is used to provide the propagation delay between the reference point (at the gNB) and the satellite. +The granularity of ta-Common is 4.072 × 10^(-3) µs. Values are given in unit of corresponding granularity. + +The parameter `ta-CommonDrift-r17` indicates the drift rate of the common TA. +The granularity of ta-CommonDrift is 0.2 × 10^(-3) µs/s. Values are given in unit of corresponding granularity. + +The satellite position and velocity vartors are provided using the following parameters: + +`positionX-r17`, `positionY-r17`, `positionZ-r17`: +X, Y, Z coordinate of satellite position state vector in ECEF. Unit is meter. +Step of 1.3 m. Actual value = field value * 1.3. + +`velocityVX-r17`, `velocityVY-r17`, `velocityVZ-r17`: +X, Y, Z coordinate of satellite velocity state vector in ECEF. Unit is meter/second. +Step of 0.06 m/s. Actual value = field value * 0.06. + +These parameters can be provided to the gNB in the conf file in the section `servingCellConfigCommon`: ``` ... - cellSpecificKoffset_r17 = 478; # GEO satellite -# cellSpecificKoffset_r17 = 40; # LEO satellite +# GEO satellite + cellSpecificKoffset_r17 = 478; + ta-Common-r17 = 29314900; # 119.37 ms + positionX-r17 = 0; + positionY-r17 = 0; + positionZ-r17 = 32433846; + velocityVX-r17 = 0; + velocityVY-r17 = 0; + velocityVZ-r17 = 0; +# LEO satellite +# cellSpecificKoffset_r17 = 40; +# ta-Common-r17 = 2317000; # 9.435 ms +# ta-CommonDrift-r17 = -230000; # -46 µs/s +# positionX-r17 = 0; +# positionY-r17 = -2166908; # -2816980.4 m +# positionZ-r17 = 4910784; # 6384019.2 m +# velocityVX-r17 = 0; +# velocityVY-r17 = 115246; # 6914.76 m/s +# velocityVZ-r17 = 50853; # 3051.18 m/s ... ``` @@ -262,10 +296,11 @@ To enable this feature, the `disable_harq` flag has to be added to the gNB conf ... ``` -So with these modifications to the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf` an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this: +The settings for a transparent GEO satellite scenario are already provided in the file `ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf`. +Using this conf file, an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this: ``` cd cmake_targets -sudo ./ran_build/build/nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf --rfsim --rfsimulator.prop_delay 238.74 +sudo ./ran_build/build/nr-softmodem -O ../ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf --rfsim ``` To configure NTN gNB with 32 HARQ processes in downlink and uplink, add these settings in conf files under section `gNBs.[0]` @@ -281,32 +316,43 @@ To simulate a LEO satellite channel model with rfsimulator in UL (DL is simulate @include "channelmod_rfsimu_LEO_satellite.conf" ``` -So with these modifications to the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf` an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, trasparent LEO satellite 5G NR NTN is this: +The settings for a transparent LEO satellite scenario are already provided in the file `ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf`. +Using this conf file, an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, trasparent LEO satellite 5G NR NTN is this: ``` cd cmake_targets -sudo ./ran_build/build/nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf --rfsim --rfsimulator.prop_delay 20 +sudo ./ran_build/build/nr-softmodem -O ../ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf --rfsim ``` ### NR UE -At UE side, there are two main parameters to cope with the large NTN propagation delay, cellSpecificKoffset and ta-Common. -`cellSpecificKoffset` is the same as for gNB and can be provided to the UE via command line parameter `--ntn-koffset`. -`ta-Common` is a common timing advance and can be provided to the UE via command line parameter `--ntn-ta-common` in milliseconds. +At UE side, only few parameters have to be provided, as the UE receives most relevant parameters via SIB19 from the gNB. +But to calculate the UE specific TA, the UE position has to be provided in the `ue.conf` file. +Also the LEO channel model has to be configured, e.g. by using an `@include` statement, just like on the gNB side: +``` +... +position0 = { + x = 0.0; + y = 0.0; + z = 6377900.0; +} + +@include "channelmod_rfsimu_LEO_satellite.conf" +``` So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this: ``` cd cmake_targets -sudo ./ran_build/build/nr-uesoftmodem --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 238.74 --ntn-koffset 478 --ntn-ta-common 477.48 +sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 238.74 ``` -For LEO satellites a third parameter specifying the NTN propagation delay drift has ben added, ta-CommonDrift. -`ta-CommonDrift` provides the drift rate of the common timing advance and can be provided to the UE via command line parameter `--ntn-ta-commondrift` in microseconds per second. +For LEO satellite scenarios, the parameter `--ntn-initial-time-drift` must be provided via command line, as the UE needs this value to compensate for the time drift during initial sync, before SIB19 was received. +This parameter provides the drift rate of the complete DL timing (incl. feeder link and service link) in µs/s. Also, to perform an autonomous TA update based on the DL drift, the boolean parameter `--autonomous-ta` should be added in case of a LEO satellite scenario. So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent LEO satellite 5G NR NTN is this: ``` cd cmake_targets -sudo ./ran_build/build/nr-uesoftmodem --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/channelmod_rfsimu_LEO_satellite.conf --time-sync-I 0.2 --ntn-koffset 40 --ntn-ta-common 37.74 --ntn-ta-commondrift -50 --autonomous-ta +sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod --time-sync-I 0.1 --ntn-initial-time-drift -46 --autonomous-ta ``` # Specific OAI modes From f1ae1025ad5e92d9d1263064944f33db3eaf2a68 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 3 Feb 2025 15:13:51 +0000 Subject: [PATCH 09/14] fix: ta-Common is a round-trip-time, not a one-way delay --- ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf | 2 +- .../conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf | 2 +- doc/RUNMODEM.md | 4 ++-- nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h | 4 ++-- openair2/LAYER2/NR_MAC_UE/config_ue.c | 7 +++---- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 6 +++--- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 2 +- .../CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf | 2 +- .../CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf | 2 +- .../CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf | 2 +- .../CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf | 2 +- .../CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf | 4 ++-- .../CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf | 4 ++-- 13 files changed, 21 insertions(+), 22 deletions(-) diff --git a/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf index 76957182e1..393a3d57ef 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf @@ -148,7 +148,7 @@ gNBs = #ext2 #ntn_Config_r17 cellSpecificKoffset_r17 = 478; - ta-Common-r17 = 29314900; # 119.37 ms + ta-Common-r17 = 58629666; # 238.74 ms positionX-r17 = 0; positionY-r17 = 0; positionZ-r17 = 32433846; diff --git a/ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf index 2cd1186dcd..d7d086f52e 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf @@ -149,7 +149,7 @@ gNBs = #ext2 #ntn_Config_r17 cellSpecificKoffset_r17 = 40; - ta-Common-r17 = 2317000; # 9.435 ms + ta-Common-r17 = 4634000; # 18.87 ms ta-CommonDrift-r17 = -230000; # -46 µs/s positionX-r17 = 0; positionY-r17 = -2166908; # -2816980.4 m diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index d027f8553e..1aeee6a4dd 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -247,7 +247,7 @@ These parameters can be provided to the gNB in the conf file in the section `ser ... # GEO satellite cellSpecificKoffset_r17 = 478; - ta-Common-r17 = 29314900; # 119.37 ms + ta-Common-r17 = 58629666; # 238.74 ms positionX-r17 = 0; positionY-r17 = 0; positionZ-r17 = 32433846; @@ -256,7 +256,7 @@ These parameters can be provided to the gNB in the conf file in the section `ser velocityVZ-r17 = 0; # LEO satellite # cellSpecificKoffset_r17 = 40; -# ta-Common-r17 = 2317000; # 9.435 ms +# ta-Common-r17 = 4634000; # 18.87 ms # ta-CommonDrift-r17 = -230000; # -46 µs/s # positionX-r17 = 0; # positionY-r17 = -2166908; # -2816980.4 m diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index b8228778b6..0cdede0725 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -556,9 +556,9 @@ typedef struct { } fapi_nr_ta_command_pdu; typedef struct { - // N_common_ta_adj represents common propagation delay received in SIB19 (ms) + // N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms) double N_common_ta_adj; - // N_UE_TA_adj calculated propagation delay from UE and SAT (ms) + // N_UE_TA_adj calculated round-trip-time between UE and SAT (ms) double N_UE_TA_adj; // drift rate of common ta in µs/s double ntn_ta_commondrift; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 57792ac2ee..1baa26304f 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -246,7 +246,7 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, } -// computes delay between ue and sat based on SIB19 ephemeris data +// computes round-trip-time between ue and sat based on SIB19 ephemeris data static double calculate_ue_sat_ta(const position_t *position_params, NR_PositionVelocity_r17_t *sat_pos) { // get UE position coordinates @@ -259,9 +259,8 @@ static double calculate_ue_sat_ta(const position_t *position_params, NR_Position double posy_0 = (double)sat_pos->positionY_r17 * 1.3; double posz_0 = (double)sat_pos->positionZ_r17 * 1.3; - double distance = sqrt(pow(posx - posx_0, 2) + pow(posy - posy_0, 2) + pow(posz - posz_0, 2)); - // this computation will ensure 3 decimal precision - double ta_ms = round(((distance / SPEED_OF_LIGHT) * 1000) * 1000.0) / 1000.0; + double distance = 2 * sqrt(pow(posx - posx_0, 2) + pow(posy - posy_0, 2) + pow(posz - posz_0, 2)); + double ta_ms = (distance / SPEED_OF_LIGHT) * 1000; return ta_ms; } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 24fefe47af..1b4abe4fb8 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -554,9 +554,9 @@ typedef struct { } si_schedInfo_t; typedef struct ntn_timing_advance_components { - // N_common_ta_adj represents common propagation delay received in SIB19 (ms) + // N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms) double N_common_ta_adj; - // N_UE_TA_adj calculated propagation delay from UE and SAT (ms) + // N_UE_TA_adj calculated round-trip-time between UE and SAT (ms) double N_UE_TA_adj; // drift rate of common ta in µs/s double ntn_ta_commondrift; @@ -682,7 +682,7 @@ static inline int GET_NTN_UE_K_OFFSET(const ntn_timing_advance_componets_t *ntn_ static inline double GET_COMPLETE_TIME_ADVANCE_MS(const ntn_timing_advance_componets_t *ntn_ta) { - return (ntn_ta->N_common_ta_adj + ntn_ta->N_UE_TA_adj) * 2; + return ntn_ta->N_common_ta_adj + ntn_ta->N_UE_TA_adj; } static inline long GET_DURATION_RX_TO_TX(const ntn_timing_advance_componets_t *ntn_ta) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 8f6dc4cc8c..94986c48b4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -3620,7 +3620,7 @@ static void schedule_ntn_config_command(fapi_nr_dl_config_request_t *dl_config, ntn_config_command_pdu->ntn_ta_commondrift = mac->ntn_ta.ntn_ta_commondrift; ntn_config_command_pdu->N_common_ta_adj = mac->ntn_ta.N_common_ta_adj; ntn_config_command_pdu->N_UE_TA_adj = mac->ntn_ta.N_UE_TA_adj; - ntn_config_command_pdu->ntn_total_time_advance_ms = (mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj) * 2; + ntn_config_command_pdu->ntn_total_time_advance_ms = mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj; dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_NTN_CONFIG_PARAMS; dl_config->number_pdus += 1; } diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf index b206be672a..c883a63d02 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf @@ -148,7 +148,7 @@ gNBs = #ext2 #ntn_Config_r17 cellSpecificKoffset_r17 = 478; //GEO - ta-Common-r17 = 29319745; + ta-Common-r17 = 58629666; # 238.74 ms positionX-r17 = 0; positionY-r17 = 0; positionZ-r17 = 32433846; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf index 60489ea6c2..67be3dbb44 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf @@ -148,7 +148,7 @@ gNBs = #ext2 #ntn_Config_r17 cellSpecificKoffset_r17 = 478; //GEO - ta-Common-r17 = 29319745; + ta-Common-r17 = 58629666; # 238.74 ms positionX-r17 = 0; positionY-r17 = 0; positionZ-r17 = 32433846; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf index edcee7ee98..5a14f4fae6 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf @@ -147,7 +147,7 @@ gNBs = #ext2 #ntn_Config_r17 cellSpecificKoffset_r17 = 478; //GEO - ta-Common-r17 = 29319745; + ta-Common-r17 = 58629666; # 238.74 ms positionX-r17 = 0; positionY-r17 = 0; positionZ-r17 = 32433846; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf index 67f8eb6e85..c4213eb0d3 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf @@ -147,7 +147,7 @@ gNBs = #ext2 #ntn_Config_r17 cellSpecificKoffset_r17 = 478; //GEO - ta-Common-r17 = 29319745; + ta-Common-r17 = 58629666; # 238.74 ms positionX-r17 = 0; positionY-r17 = 0; positionZ-r17 = 32433846; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf index b0bbbf1671..013ca6663b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf @@ -167,7 +167,7 @@ gNBs = #ntn_Config_r17 # GEO satellite # cellSpecificKoffset_r17 = 478; -# ta-Common-r17 = 29314900; # 119.37 ms +# ta-Common-r17 = 58629666; # 238.74 ms # positionX-r17 = 0; # positionY-r17 = 0; # positionZ-r17 = 32433846; @@ -176,7 +176,7 @@ gNBs = # velocityVZ-r17 = 0; # LEO satellite # cellSpecificKoffset_r17 = 40; -# ta-Common-r17 = 2317000; # 9.435 ms +# ta-Common-r17 = 4634000; # 18.87 ms # ta-CommonDrift-r17 = -230000; # -46 µs/s # positionX-r17 = 0; # positionY-r17 = -2166908; # -2816980.4 m diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf index 4fc4a07c21..c9dfd6c58a 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf @@ -167,7 +167,7 @@ gNBs = #ntn_Config_r17 # GEO satellite # cellSpecificKoffset_r17 = 478; -# ta-Common-r17 = 29314900; # 119.37 ms +# ta-Common-r17 = 58629666; # 238.74 ms # positionX-r17 = 0; # positionY-r17 = 0; # positionZ-r17 = 32433846; @@ -176,7 +176,7 @@ gNBs = # velocityVZ-r17 = 0; # LEO satellite # cellSpecificKoffset_r17 = 40; -# ta-Common-r17 = 2317000; # 9.435 ms +# ta-Common-r17 = 4634000; # 18.87 ms # ta-CommonDrift-r17 = -230000; # -46 µs/s # positionX-r17 = 0; # positionY-r17 = -2166908; # -2816980.4 m From b3581ce1b8c70fdcf060b86ef877c7fb2d4d94af Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 3 Feb 2025 16:59:42 +0000 Subject: [PATCH 10/14] NR UE: simplify calculation of next_tx_slot_and_frame by moving up assignment of duration_rx_to_tx --- executables/nr-ue.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index c08ebe00f4..e03278766c 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -1110,6 +1110,9 @@ void *UE_thread(void *arg) shiftForNextFrame = ret; pushNotifiedFIFO(&UE->dl_actors[curMsg.proc.nr_slot_rx % NUM_DL_ACTORS].fifo, newRx); + // apply new duration next run to avoid thread dead lock + apply_ntn_config(UE, fp, slot_nr, &update_ntn_system_information, &duration_rx_to_tx, &timing_advance, &ntn_koffset); + // Start TX slot processing here. It runs in parallel with RX slot processing // in current code, DURATION_RX_TO_TX constant is the limit to get UL data to encode from a RX slot notifiedFIFO_elt_t *newTx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0, 0, processSlotTX); @@ -1123,16 +1126,9 @@ void *UE_thread(void *arg) int slot = curMsgTx->proc.nr_slot_tx; int slot_and_frame = slot + curMsgTx->proc.frame_tx * UE->frame_parms.slots_per_frame; - + int next_tx_slot_and_frame = absolute_slot + duration_rx_to_tx + 1; int wait_for_prev_slot = stream_status == STREAM_STATUS_SYNCED ? 1 : 0; - int next_duration_rx_to_tx = - update_ntn_system_information - ? NR_UE_CAPABILITY_SLOT_RX_TO_TX + UE->ntn_config_message->ntn_config_params.cell_specific_k_offset - : duration_rx_to_tx; - int next_nr_slot_tx = (absolute_slot + next_duration_rx_to_tx) % nb_slot_frame; - int next_frame_tx = ((absolute_slot + next_duration_rx_to_tx) / nb_slot_frame) % MAX_FRAME_NUMBER; - int next_tx_slot_and_frame = next_nr_slot_tx + next_frame_tx * UE->frame_parms.slots_per_frame + 1; dynamic_barrier_t *next_barrier = &UE->process_slot_tx_barriers[next_tx_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]; curMsgTx->next_barrier = next_barrier; dynamic_barrier_update(&UE->process_slot_tx_barriers[slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS], @@ -1141,9 +1137,6 @@ void *UE_thread(void *arg) newTx); stream_status = STREAM_STATUS_SYNCED; tx_wait_for_dlsch[slot] = 0; - - // apply new duration next run to avoid thread dead lock - apply_ntn_config(UE, fp, slot_nr, &update_ntn_system_information, &duration_rx_to_tx, &timing_advance, &ntn_koffset); } return NULL; From 2b4ca7e47da90c6feeaad57c03a8c37ef5e593f4 Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Fri, 31 Jan 2025 17:10:33 +0100 Subject: [PATCH 11/14] cellbarredNTN indicates notbarred in SIB1 if NTN access is available 38.331 release 18 section 5.2.2.4.2 indicates that to access NTN, cellbarredNTN in SIB1 should be set to notbarred. --- openair2/RRC/NR/nr_rrc_config.c | 34 +++++++++++++++++++++++++++++---- openair2/RRC/NR_UE/rrc_UE.c | 20 ++++++++++++++++++- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 18487e9657..b186c4ca04 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -2303,6 +2303,19 @@ static long get_NR_UE_TimersAndConstants_t319(const nr_mac_timers_t *timer_confi } } +static bool is_ntn_band(int band) +{ + // TS 3GPP 38.101-5 V1807 Section 5.2.2 + if (band >= 254 && band <= 256) // FR1 NTN + return true; + + // TS 3GPP 38.101-5 V1807 Section 5.2.3 + if (band >= 510 && band <= 512) // FR2 NTN + return true; + + return false; +} + NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, const f1ap_plmn_t *plmn, uint64_t cellID, @@ -2401,12 +2414,26 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, asn1cSeqAdd(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo);*/ - // sib19 scheduling info - // ensure ntn-config is initialized - if (scc->ext2 && scc->ext2->ntn_Config_r17) { + const NR_FreqBandIndicatorNR_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + if (is_ntn_band(band)) { sib1->nonCriticalExtension = CALLOC(1, sizeof(struct NR_SIB1_v1610_IEs)); sib1->nonCriticalExtension->nonCriticalExtension = CALLOC(1, sizeof(struct NR_SIB1_v1630_IEs)); sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, sizeof(struct NR_SIB1_v1700_IEs)); + // If cell provides NTN access, set cellBarredNTN to notBarred. + struct NR_SIB1_v1700_IEs *sib1_v1700 = sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension; + sib1_v1700->cellBarredNTN_r17 = CALLOC(1, sizeof(long)); + *sib1_v1700->cellBarredNTN_r17 = NR_SIB1_v1700_IEs__cellBarredNTN_r17_notBarred; + } + + // sib19 scheduling info + // ensure ntn-config is initialized + if (scc->ext2 && scc->ext2->ntn_Config_r17) { + if (sib1->nonCriticalExtension == NULL) + sib1->nonCriticalExtension = CALLOC(1, sizeof(struct NR_SIB1_v1610_IEs)); + if (sib1->nonCriticalExtension->nonCriticalExtension == NULL) + sib1->nonCriticalExtension->nonCriticalExtension = CALLOC(1, sizeof(struct NR_SIB1_v1630_IEs)); + if (sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension == NULL) + sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, sizeof(struct NR_SIB1_v1700_IEs)); struct NR_SI_SchedulingInfo_v1700 *sib_v17_scheduling_info = CALLOC(1, sizeof(struct NR_SI_SchedulingInfo_v1700)); @@ -2438,7 +2465,6 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, frequencyInfoDL->frequencyBandList.list.array[i]; } - const NR_FreqBandIndicatorNR_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; frequency_range_t frequency_range = band > 256 ? FR2 : FR1; sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = get_ssb_offset_to_pointA(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB, scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA, diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 26b9f51046..9d3d6d7111 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -308,6 +308,20 @@ static void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info, } } +static void verify_NTN_access(const NR_UE_RRC_SI_INFO *SI_info, const NR_SIB1_v1700_IEs_t *sib1_v1700) +{ + // SIB1 indicates if NTN access is present in the cell + bool ntn_access = false; + if (sib1_v1700 && sib1_v1700->cellBarredNTN_r17 + && *sib1_v1700->cellBarredNTN_r17 == NR_SIB1_v1700_IEs__cellBarredNTN_r17_notBarred) + ntn_access = true; + + uint32_t sib19_mask = 1 << NR_SIB_TypeInfo_v1700__sibType_r17__type1_r17_sibType19; + int sib19_present = SI_info->SInfo_r17.default_otherSI_map_r17 & sib19_mask; + + AssertFatal(!ntn_access || sib19_present, "NTN cell, but SIB19 not configured.\n"); +} + static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_info, NR_SIB1_t *sib1) { if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) @@ -321,15 +335,19 @@ static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_inf nr_rrc_ue_prepare_RRCSetupRequest(rrc); } + NR_SIB1_v1700_IEs_t *sib1_v1700 = NULL; NR_SI_SchedulingInfo_v1700_t *si_SchedInfo_v1700 = NULL; if (sib1->nonCriticalExtension && sib1->nonCriticalExtension->nonCriticalExtension && sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension) { - si_SchedInfo_v1700 = sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->si_SchedulingInfo_v1700; + sib1_v1700 = sib1->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension; + si_SchedInfo_v1700 = sib1_v1700->si_SchedulingInfo_v1700; } // configure default SI nr_rrc_configure_default_SI(SI_info, sib1->si_SchedulingInfo, si_SchedInfo_v1700); + verify_NTN_access(SI_info, sib1_v1700); + // configure timers and constant nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1); // RRC storage of SIB1 timers and constants (eg needed in re-establishment) From 48c8d67393c6f904490b5a6e21dc03b9081ae240 Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Wed, 5 Feb 2025 14:00:58 +0100 Subject: [PATCH 12/14] Removed b66 NTN and enabled B254 NTN conf file in CI --- ...=> gnb.sa.band254.u0.25prb.rfsim.ntn.conf} | 16 +- .../docker-compose.yaml | 6 +- .../gnb.sa.band254.ntn.mu0.25prb.rfsim.conf | 280 ------------------ 3 files changed, 11 insertions(+), 291 deletions(-) rename ci-scripts/conf_files/{gnb.sa.band66.ntn.25prb.rfsim.conf => gnb.sa.band254.u0.25prb.rfsim.ntn.conf} (97%) delete mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf diff --git a/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf similarity index 97% rename from ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf rename to ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf index 393a3d57ef..a9256ebfa1 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf @@ -28,11 +28,11 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL - # this is 2150.43 MHz + 14 PRBs@15kHz SCS (same as initial BWP), points to Subcarrier 0 of RB#10 of SSB block - absoluteFrequencySSB = 430590; - dl_frequencyBand = 66; - # this is 2150.43 MHz - dl_absoluteFrequencyPointA = 430086; + # GSCN 6221 + absoluteFrequencySSB = 497770; + dl_frequencyBand = 254; + # this is 2486.15 MHz + dl_absoluteFrequencyPointA = 497230; #scs-SpecificCarrierList dl_offstToCarrier = 0; # subcarrierSpacing @@ -52,9 +52,9 @@ gNBs = #uplinkConfigCommon #frequencyInfoUL - ul_frequencyBand = 66; - # this is 1750.43 MHz - ul_absoluteFrequencyPointA = 350086; + ul_frequencyBand = 254; + # this is 1612.65 MHz + ul_absoluteFrequencyPointA = 322530; #scs-SpecificCarrierList ul_offstToCarrier = 0; # subcarrierSpacing diff --git a/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml index 6017a69ed9..193b3a9064 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml @@ -86,7 +86,7 @@ services: cap_drop: - ALL environment: - USE_ADDITIONAL_OPTIONS: --rfsim --rfsimulator.prop_delay 238.74 --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: --rfsim --log_config.global_log_options level,nocolor,time ASAN_OPTIONS: detect_leaks=0 depends_on: - oai-ext-dn @@ -94,7 +94,7 @@ services: public_net: ipv4_address: 192.168.71.140 volumes: - - ../../conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf + - ../../conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf:/opt/oai-gnb/etc/gnb.conf healthcheck: test: /bin/bash -c "pgrep nr-softmodem" interval: 10s @@ -110,7 +110,7 @@ services: - NET_ADMIN # for interface bringup - NET_RAW # for ping environment: - USE_ADDITIONAL_OPTIONS: --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 238.74 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 238.74 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time depends_on: - oai-gnb networks: diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf deleted file mode 100644 index c883a63d02..0000000000 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf +++ /dev/null @@ -1,280 +0,0 @@ -Active_gNBs = ( "5G-GOA-gNB"); -# Asn1_verbosity, choice in: none, info, annoying -Asn1_verbosity = "none"; - -gNBs = -( - { - ////////// Identification parameters: - gNB_ID = 0xe00; - gNB_name = "5G-GOA-gNB"; - - // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = 1; - plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); - nr_cellid = 12345678L; - - ////////// Physical parameters: - - sib1_tda = 5; - min_rxtxtime = 6; - disable_harq = 1; - - servingCellConfigCommon = ( - { - #spCellConfigCommon - - physCellId = 0; - -# downlinkConfigCommon - #frequencyInfoDL - # GSCN 6221 = 497770, (GSCN 6215 - 497290) - absoluteFrequencySSB = 497770; - dl_frequencyBand = 254; - # this is 2486.9 MHz - dl_absoluteFrequencyPointA = 497380; - #scs-SpecificCarrierList - dl_offstToCarrier = 0; -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_subcarrierSpacing = 0; - dl_carrierBandwidth = 25; - #initialDownlinkBWP - #genericParameters - # this is RBstart=0,L=25 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6600; -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - initialDLBWPsubcarrierSpacing = 0; - #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 0; - initialDLBWPsearchSpaceZero = 0; - - #uplinkConfigCommon - #frequencyInfoUL - ul_frequencyBand = 254; - # this is 1613.4 MHz - ul_absoluteFrequencyPointA = 322680; - #scs-SpecificCarrierList - ul_offstToCarrier = 0; -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_subcarrierSpacing = 0; - ul_carrierBandwidth = 25; - pMax = 20; - #initialUplinkBWP - #genericParameters - initialULBWPlocationAndBandwidth = 6600; -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - initialULBWPsubcarrierSpacing = 0; - #rach-ConfigCommon - #rach-ConfigGeneric - prach_ConfigurationIndex = 98; -#prach_msg1_FDM -#0 = one, 1=two, 2=four, 3=eight - prach_msg1_FDM = 0; - prach_msg1_FrequencyStart = 0; - zeroCorrelationZoneConfig = 13; - preambleReceivedTargetPower = -118; -#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) - preambleTransMax = 6; -#powerRampingStep -# 0=dB0,1=dB2,2=dB4,3=dB6 - powerRampingStep = 1; -#ra_ReponseWindow -#1,2,4,8,10,20,40,80 - ra_ResponseWindow = 4; -#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; -#one (0..15) 4,8,12,16,...60,64 - ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; -#ra_ContentionResolutionTimer -#(0..7) 8,16,24,32,40,48,56,64 - ra_ContentionResolutionTimer = 7; - rsrp_ThresholdSSB = 19; -#prach-RootSequenceIndex_PR -#1 = 839, 2 = 139 - prach_RootSequenceIndex_PR = 2; - prach_RootSequenceIndex = 1; - # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex - # - msg1_SubcarrierSpacing = 0; -# restrictedSetConfig -# 0=unrestricted, 1=restricted type A, 2=restricted type B - restrictedSetConfig = 0; - - msg3_DeltaPreamble = 1; - p0_NominalWithGrant =-90; - -# pucch-ConfigCommon setup : -# pucchGroupHopping -# 0 = neither, 1= group hopping, 2=sequence hopping - pucchGroupHopping = 0; - hoppingId = 40; - p0_nominal = -90; - - ssb_PositionsInBurst_Bitmap = 1; - -# ssb_periodicityServingCell -# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 - ssb_periodicityServingCell = 2; - -# dmrs_TypeA_position -# 0 = pos2, 1 = pos3 - dmrs_TypeA_Position = 0; - -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - subcarrierSpacing = 0; - - - #tdd-UL-DL-ConfigurationCommon -# subcarrierSpacing -# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - referenceSubcarrierSpacing = 0; - # pattern1 - # dl_UL_TransmissionPeriodicity - # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 - dl_UL_TransmissionPeriodicity = 6; - nrofDownlinkSlots = 7; - nrofDownlinkSymbols = 6; - nrofUplinkSlots = 2; - nrofUplinkSymbols = 4; - - ssPBCH_BlockPower = -25; - - #ext2 - #ntn_Config_r17 - cellSpecificKoffset_r17 = 478; //GEO - ta-Common-r17 = 58629666; # 238.74 ms - positionX-r17 = 0; - positionY-r17 = 0; - positionZ-r17 = 32433846; - velocityVX-r17 = 0; - velocityVY-r17 = 0; - velocityVZ-r17 = 0; - } - - ); - - TIMERS : - { - sr_ProhibitTimer = 0; - sr_TransMax = 64; - sr_ProhibitTimer_v1700 = 512; - t300 = 2000; - t301 = 2000; - t319 = 2000; - }; - - # ------- SCTP definitions - SCTP : - { - # Number of streams to use in input/output - SCTP_INSTREAMS = 2; - SCTP_OUTSTREAMS = 2; - }; - - - ////////// AMF parameters: - amf_ip_address = ({ ipv4 = "192.168.71.132"; }); - - NETWORK_INTERFACES : - { - GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/26"; - GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/26"; - GNB_PORT_FOR_S1U = 2152; # Spec 2152 - }; - - } -); - -MACRLCs = ( -{ - num_cc = 1; - tr_s_preference = "local_L1"; - tr_n_preference = "local_RRC"; - pusch_TargetSNRx10 = 150; - pucch_TargetSNRx10 = 200; -} -); - -L1s = ( -{ - num_cc = 1; - tr_n_preference = "local_mac"; - prach_dtx_threshold = 120; - pucch0_dtx_threshold = 150; - ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 -} -); - -RUs = ( - { - local_rf = "yes"; - nb_tx = 1; - nb_rx = 1; - att_tx = 0; - att_rx = 0; - bands = [7]; - max_pdschReferenceSignalPower = -27; - max_rxgain = 114; - sf_extension = 0; - eNB_instances = [0]; - sdr_addrs = "type=x300"; - clock_src = "internal"; - # if_freq = 3700000000L; - # if_offset = 1000000; - } -); - -THREAD_STRUCT = ( - { - #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; - #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" - worker_config = "WORKER_DISABLE"; - } -); - -rfsimulator : -{ - serveraddr = "server"; - serverport = 4043; - options = (); #("saviq"); or/and "chanmod" - modelname = "AWGN"; - IQfile = "/tmp/rfsimulator.iqs"; -}; - -security = { - # preferred ciphering algorithms - # the first one of the list that an UE supports in chosen - # valid values: nea0, nea1, nea2, nea3 - ciphering_algorithms = ( "nea0" ); - - # preferred integrity algorithms - # the first one of the list that an UE supports in chosen - # valid values: nia0, nia1, nia2, nia3 - integrity_algorithms = ( "nia2", "nia0" ); - - # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter - # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' - drb_ciphering = "yes"; - drb_integrity = "no"; -}; - -log_config : -{ - global_log_level ="info"; - hw_log_level ="info"; - phy_log_level ="info"; - mac_log_level ="info"; - rlc_log_level ="info"; - pdcp_log_level ="info"; - rrc_log_level ="info"; - ngap_log_level ="debug"; - f1ap_log_level ="debug"; -}; - From 11b87d8744b5eacdb6b4ae3c834924433f0dc3b2 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 10 Feb 2025 11:32:35 +0000 Subject: [PATCH 13/14] NR UE: RRC layer now explicitly tells MAC layer when the RA procedure can be started --- openair2/COMMON/rrc_messages_types.h | 2 ++ openair2/LAYER2/NR_MAC_UE/config_ue.c | 10 ++++++---- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 4 ++-- openair2/RRC/NR_UE/L2_interface_ue.c | 10 ++++++---- openair2/RRC/NR_UE/rrc_UE.c | 15 ++++++++++----- openair2/RRC/NR_UE/rrc_defs.h | 2 ++ 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 7eba8f3467..5dc1e27f93 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -477,9 +477,11 @@ typedef struct { } nr_mac_rrc_config_mib_t; typedef struct { NR_SIB1_t *sib1; + bool can_start_ra; } nr_mac_rrc_config_sib1_t; typedef struct { NR_SIB19_r17_t *sib19; + bool can_start_ra; } nr_mac_rrc_config_other_sib_t; #endif /* RRC_MESSAGES_TYPES_H_ */ diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 1baa26304f..ed13b4e8a9 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -936,8 +936,6 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, mac->get_sib1 = true; else if (sched_sib == 2) mac->get_otherSI = true; - else if (sched_sib == 0 && mac->state == UE_RECEIVING_SIB) - mac->state = UE_PERFORMING_RA; nr_ue_decode_mib(mac, cc_idP); ret = pthread_mutex_unlock(&mac->if_mutex); AssertFatal(!ret, "mutex failed %d\n", ret); @@ -1756,7 +1754,7 @@ static void configure_si_schedulingInfo(NR_UE_MAC_INST_t *mac, } } -void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1) +void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1, bool can_start_ra) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -1792,6 +1790,8 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *si AssertFatal(mac->current_UL_BWP, "Couldn't find DL-BWP0\n"); configure_timeAlignmentTimer(&mac->time_alignment_timer, mac->timeAlignmentTimerCommon, mac->current_UL_BWP->scs); } + if (mac->state == UE_RECEIVING_SIB && can_start_ra) + mac->state = UE_PERFORMING_RA; // Setup the SSB to Rach Occasions mapping according to the config build_ssb_to_ro_map(mac); @@ -1802,7 +1802,7 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *si AssertFatal(!ret, "mutex failed %d\n", ret); } -void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19) +void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19, bool can_start_ra) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -1815,6 +1815,8 @@ void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19) configure_ntn_ta(mac->ue_id, &mac->ntn_ta, ntn_Config_r17); } + if (mac->state == UE_RECEIVING_SIB && can_start_ra) + mac->state = UE_PERFORMING_RA; ret = pthread_mutex_unlock(&mac->if_mutex); AssertFatal(!ret, "mutex failed %d\n", ret); } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index dfda03e011..f5f9d0df36 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -85,10 +85,10 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, NR_MIB_t *mibP, int sched_sib1); -void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1); +void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1, bool can_start_ra); struct position; /* forward declaration */ -void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19_r17); +void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19_r17, bool can_start_ra); void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause); diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index cc97b448b5..b6aa5f0463 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -138,12 +138,14 @@ void process_msg_rcc_to_mac(MessageDef *msg) break; case NR_MAC_RRC_CONFIG_SIB1: { NR_SIB1_t *sib1 = NR_MAC_RRC_CONFIG_SIB1(msg).sib1; - nr_rrc_mac_config_req_sib1(ue_id, 0, sib1); + bool can_start_ra = NR_MAC_RRC_CONFIG_SIB1(msg).can_start_ra; + nr_rrc_mac_config_req_sib1(ue_id, 0, sib1, can_start_ra); SEQUENCE_free(&asn_DEF_NR_SIB1, NR_MAC_RRC_CONFIG_SIB1(msg).sib1, ASFM_FREE_EVERYTHING); } break; - case NR_MAC_RRC_CONFIG_OTHER_SIB: - nr_rrc_mac_config_other_sib(ue_id, NR_MAC_RRC_CONFIG_OTHER_SIB(msg).sib19); - break; + case NR_MAC_RRC_CONFIG_OTHER_SIB: { + bool can_start_ra = NR_MAC_RRC_CONFIG_OTHER_SIB(msg).can_start_ra; + nr_rrc_mac_config_other_sib(ue_id, NR_MAC_RRC_CONFIG_OTHER_SIB(msg).sib19, can_start_ra); + } break; default: LOG_E(NR_MAC, "Unexpected msg from RRC: %d\n", ITTI_MSG_ID(msg)); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 9d3d6d7111..60f5a5e079 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -165,8 +165,9 @@ static void set_DRB_status(NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id, NR_R rrc->status_DRBs[drb_id - 1] = status; } -static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, instance_t ue_id) +static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, NR_UE_RRC_INST_t *rrc) { + instance_t ue_id = rrc->ue_id; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN); // Dump contents @@ -253,6 +254,7 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, if (sib19) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_OTHER_SIB); asn_copy(&asn_DEF_NR_SIB19_r17, (void **)&NR_MAC_RRC_CONFIG_OTHER_SIB(msg).sib19, sib19); + NR_MAC_RRC_CONFIG_OTHER_SIB(msg).can_start_ra = rrc->is_NTN_UE; itti_send_msg_to_task(TASK_MAC_UE, ue_id, msg); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT); @@ -308,7 +310,7 @@ static void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info, } } -static void verify_NTN_access(const NR_UE_RRC_SI_INFO *SI_info, const NR_SIB1_v1700_IEs_t *sib1_v1700) +static bool verify_NTN_access(const NR_UE_RRC_SI_INFO *SI_info, const NR_SIB1_v1700_IEs_t *sib1_v1700) { // SIB1 indicates if NTN access is present in the cell bool ntn_access = false; @@ -320,6 +322,8 @@ static void verify_NTN_access(const NR_UE_RRC_SI_INFO *SI_info, const NR_SIB1_v1 int sib19_present = SI_info->SInfo_r17.default_otherSI_map_r17 & sib19_mask; AssertFatal(!ntn_access || sib19_present, "NTN cell, but SIB19 not configured.\n"); + + return ntn_access && sib19_present; } static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_info, NR_SIB1_t *sib1) @@ -346,7 +350,7 @@ static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_inf // configure default SI nr_rrc_configure_default_SI(SI_info, sib1->si_SchedulingInfo, si_SchedInfo_v1700); - verify_NTN_access(SI_info, sib1_v1700); + rrc->is_NTN_UE = verify_NTN_access(SI_info, sib1_v1700); // configure timers and constant nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1); @@ -354,6 +358,7 @@ static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_inf UPDATE_IE(rrc->timers_and_constants.sib1_TimersAndConstants, sib1->ue_TimersAndConstants, NR_UE_TimersAndConstants_t); MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_SIB1); NR_MAC_RRC_CONFIG_SIB1(msg).sib1 = sib1; + NR_MAC_RRC_CONFIG_SIB1(msg).can_start_ra = !rrc->is_NTN_UE; itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg); } @@ -414,7 +419,7 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe SEQUENCE_free(&asn_DEF_NR_SystemInformation, si, 1); } else { LOG_I(NR_RRC, "[UE %ld] Decoding dedicatedSystemInformationDelivery\n", rrc->ue_id); - nr_decode_SI(SI_info, si, rrc->ue_id); + nr_decode_SI(SI_info, si, rrc); } } if (rec_1530->otherConfig) { @@ -976,7 +981,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: LOG_I(NR_RRC, "[UE %ld] Decoding SI\n", rrc->ue_id); NR_SystemInformation_t *si = bcch_message->message.choice.c1->choice.systemInformation; - nr_decode_SI(SI_info, si, rrc->ue_id); + nr_decode_SI(SI_info, si, rrc); break; case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: default: diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index fb320853e2..29c03afd5f 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -241,6 +241,8 @@ typedef struct NR_UE_RRC_INST_s { bool reconfig_after_reestab; //Sidelink params NR_SL_PreconfigurationNR_r16_t *sl_preconfig; + // NTN params + bool is_NTN_UE; } NR_UE_RRC_INST_t; #endif From 0bc46a22c62c9a1e4b5d28f7a68798d1c02f67d0 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 10 Feb 2025 12:02:21 +0000 Subject: [PATCH 14/14] move NTN LEO config to band 254 and update doc/RUNMODEM.md --- ...gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf} | 18 +++++++++--------- doc/RUNMODEM.md | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) rename ci-scripts/conf_files/{gnb.sa.band66.ntn.leo.25prb.rfsim.conf => gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf} (97%) diff --git a/ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf similarity index 97% rename from ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf rename to ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf index d7d086f52e..7a47d90975 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf @@ -29,11 +29,11 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL - # this is 2150.43 MHz + 14 PRBs@15kHz SCS (same as initial BWP), points to Subcarrier 0 of RB#10 of SSB block - absoluteFrequencySSB = 430590; - dl_frequencyBand = 66; - # this is 2150.43 MHz - dl_absoluteFrequencyPointA = 430086; + # GSCN 6221 + absoluteFrequencySSB = 497770; + dl_frequencyBand = 254; + # this is 2486.15 MHz + dl_absoluteFrequencyPointA = 497230; #scs-SpecificCarrierList dl_offstToCarrier = 0; # subcarrierSpacing @@ -53,9 +53,9 @@ gNBs = #uplinkConfigCommon #frequencyInfoUL - ul_frequencyBand = 66; - # this is 1750.43 MHz - ul_absoluteFrequencyPointA = 350086; + ul_frequencyBand = 254; + # this is 1612.65 MHz + ul_absoluteFrequencyPointA = 322530; #scs-SpecificCarrierList ul_offstToCarrier = 0; # subcarrierSpacing @@ -89,7 +89,7 @@ gNBs = #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR #1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; -#oneHalf (0..15) 4,8,12,16,...60,64 +#one (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer #(0..7) 8,16,24,32,40,48,56,64 diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 1aeee6a4dd..b24b4940e5 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -296,11 +296,11 @@ To enable this feature, the `disable_harq` flag has to be added to the gNB conf ... ``` -The settings for a transparent GEO satellite scenario are already provided in the file `ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf`. +The settings for a transparent GEO satellite scenario are already provided in the file `ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf`. Using this conf file, an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this: ``` cd cmake_targets -sudo ./ran_build/build/nr-softmodem -O ../ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf --rfsim +sudo ./ran_build/build/nr-softmodem -O ../ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf --rfsim ``` To configure NTN gNB with 32 HARQ processes in downlink and uplink, add these settings in conf files under section `gNBs.[0]` @@ -316,11 +316,11 @@ To simulate a LEO satellite channel model with rfsimulator in UL (DL is simulate @include "channelmod_rfsimu_LEO_satellite.conf" ``` -The settings for a transparent LEO satellite scenario are already provided in the file `ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf`. +The settings for a transparent LEO satellite scenario are already provided in the file `ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf`. Using this conf file, an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, trasparent LEO satellite 5G NR NTN is this: ``` cd cmake_targets -sudo ./ran_build/build/nr-softmodem -O ../ci-scripts/conf_files/gnb.sa.band66.ntn.leo.25prb.rfsim.conf --rfsim +sudo ./ran_build/build/nr-softmodem -O ../ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn-leo.conf --rfsim ``` ### NR UE @@ -342,7 +342,7 @@ position0 = { So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this: ``` cd cmake_targets -sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 238.74 +sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 238.74 ``` For LEO satellite scenarios, the parameter `--ntn-initial-time-drift` must be provided via command line, as the UE needs this value to compensate for the time drift during initial sync, before SIB19 was received. @@ -352,7 +352,7 @@ Also, to perform an autonomous TA update based on the DL drift, the boolean para So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent LEO satellite 5G NR NTN is this: ``` cd cmake_targets -sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod --time-sync-I 0.1 --ntn-initial-time-drift -46 --autonomous-ta +sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod --time-sync-I 0.1 --ntn-initial-time-drift -46 --autonomous-ta ``` # Specific OAI modes