diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index 4245ec9ae560d2755971b8fab9d767767652de1d..753efdadaf5a67f2264bd12c99a02665cfa13b45 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -141,6 +141,53 @@ You can see all options by typing
 ./nr-uesoftmodem --help
 ```
 
+## How to run a NTN configuration
+
+### NTN channel
+
+A 5G NR NTN configuration only works in a non-terrestrial setup.
+Therefore either SDR boards and a dedicated NTN channel emulator are required, or RFsimulator has to be configured to simulate a NTN channel.
+
+As shown on the [rfsimulator page](../radio/rfsimulator/README.md), RFsimulator provides different possibilities.
+E.g. to perform a simple simulation of a satellite in geostationary orbit (GEO), these parameters should be added to both gNB and UE command lines:
+```
+--rfsimulator.prop_delay 238.74
+```
+
+### 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 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`.
+```
+...
+      cellSpecificKoffset_r17 = 478;
+...
+```
+
+Besides this, some timers, e.g. `sr_ProhibitTimer_v1700`, `t300`, `t301` and `t319`,  in the conf file section `gNBs.[0].TIMERS` might need to be extended.
+```
+...
+    TIMERS :
+    {
+      sr_ProhibitTimer       = 0;
+      sr_TransMax            = 64;
+      sr_ProhibitTimer_v1700 = 512;
+      t300                   = 2000;
+      t301                   = 2000;
+      t319                   = 2000;
+    };
+...
+```
+
+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, 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 --sa --rfsim --rfsimulator.prop_delay 238.74
+```
+
 # Specific OAI modes
 
 ## phy-test setup with OAI UE
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 9928d25557d3e97107cf6a4f651f4c6cd1a37a00..6f48f80ce98b7e8418b1bda384d7af899836b122 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -643,7 +643,17 @@ int main(int argc, char **argv)
                                 .minRXTXTIME = 6,
                                 .do_CSIRS = 0,
                                 .do_SRS = 0,
-                                .force_256qam_off = false};
+                                .force_256qam_off = false,
+                                .timer_config.sr_ProhibitTimer = 0,
+                                .timer_config.sr_TransMax = 64,
+                                .timer_config.sr_ProhibitTimer_v1700 = 0,
+                                .timer_config.t300 = 400,
+                                .timer_config.t301 = 400,
+                                .timer_config.t310 = 2000,
+                                .timer_config.n310 = 10,
+                                .timer_config.t311 = 3000,
+                                .timer_config.n311 = 1,
+                                .timer_config.t319 = 400};
 
   RC.nb_nr_macrlc_inst = 1;
   RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int));
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index ae2abbdc3d7b1c3d71728bb6f3bb4d81f1fa9fbe..0efdc9be39bd07708644f1921600f98869660ff4 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -607,7 +607,17 @@ int main(int argc, char *argv[])
                                 .minRXTXTIME = 0,
                                 .do_CSIRS = 0,
                                 .do_SRS = 0,
-                                .force_256qam_off = false};
+                                .force_256qam_off = false,
+                                .timer_config.sr_ProhibitTimer = 0,
+                                .timer_config.sr_TransMax = 64,
+                                .timer_config.sr_ProhibitTimer_v1700 = 0,
+                                .timer_config.t300 = 400,
+                                .timer_config.t301 = 400,
+                                .timer_config.t310 = 2000,
+                                .timer_config.n310 = 10,
+                                .timer_config.t311 = 3000,
+                                .timer_config.n311 = 1,
+                                .timer_config.t319 = 400};
 
   RC.nb_nr_macrlc_inst = 1;
   RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int));
diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h
index 14e8cb13defc1c0b2a1e29da545c8087bd6e93e7..16a5939fc5a0e66c8410733444594fb4d6a1cb02 100644
--- a/openair2/GNB_APP/RRC_nr_paramsvalues.h
+++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h
@@ -109,6 +109,7 @@
 #define GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2                             "nrofUplinkSymbols2"
 #define GNB_CONFIG_STRING_SSPBCHBLOCKPOWER                               "ssPBCH_BlockPower"
 
+#define GNB_CONFIG_STRING_CELLSPECIFICKOFFSET                            "cellSpecificKoffset_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}
 
@@ -232,6 +233,7 @@
 {GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots,.defint64val=-1,TYPE_INT64,0},\
 {GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols,.defint64val=-1,TYPE_INT64,0},\
 {GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,.i64ptr=&scc->ss_PBCH_BlockPower,.defint64val=20,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_CELLSPECIFICKOFFSET,NULL,0,.i64ptr=scc->ext2->ntn_Config_r17->cellSpecificKoffset_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}}
 
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 4a244fe34845fa72b3a2254af55c1305639f883c..1363e68aaa305fd47bac9ac966dac6193d15af21 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -214,7 +214,10 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
   //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n40.buf       = MALLOC(5);
   //ratematchpattern->subcarrierSpacing           = CALLOC(1,sizeof(NR_SubcarrierSpacing_t));
   //ratematchpatternid                            = CALLOC(1,sizeof(NR_RateMatchPatternId_t));
-  
+
+  scc->ext2 = CALLOC(1, sizeof(*scc->ext2));
+  scc->ext2->ntn_Config_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17));
+  scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17));
 }
 
 void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL,int N_RB_UL,int mu_dl,int mu_ul) {
@@ -406,6 +409,13 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
   // check pucch_ResourceConfig
   AssertFatal(*scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon < 2,
 	      "pucch_ResourceConfig should be 0 or 1 for now\n");
+
+  if(*scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 == 0) {
+    free(scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17);
+    free(scc->ext2->ntn_Config_r17);
+    free(scc->ext2);
+    scc->ext2 = NULL;
+  }
 }
 
 /* Function to allocate dedicated serving cell config strutures */
@@ -1249,6 +1259,35 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
   int tot_ant = config.pdsch_AntennaPorts.N1 * config.pdsch_AntennaPorts.N2 * config.pdsch_AntennaPorts.XP;
   AssertFatal(config.maxMIMO_layers != 0 && config.maxMIMO_layers <= tot_ant, "Invalid maxMIMO_layers %d\n", config.maxMIMO_layers);
 
+  paramdef_t Timers_Params[] = GNB_TIMERS_PARAMS_DESC;
+  char aprefix[MAX_OPTNAME_SIZE * 2 + 8];
+  sprintf(aprefix, "%s.[0].%s", GNB_CONFIG_STRING_GNB_LIST, GNB_CONFIG_STRING_TIMERS_CONFIG);
+  config_get(config_get_if(), Timers_Params, sizeofArray(Timers_Params), aprefix);
+
+  config.timer_config.sr_ProhibitTimer = *Timers_Params[GNB_TIMERS_SR_PROHIBIT_TIMER_IDX].iptr;
+  config.timer_config.sr_TransMax = *Timers_Params[GNB_TIMERS_SR_TRANS_MAX_IDX].iptr;
+  config.timer_config.sr_ProhibitTimer_v1700 = *Timers_Params[GNB_TIMERS_SR_PROHIBIT_TIMER_V1700_IDX].iptr;
+  config.timer_config.t300 = *Timers_Params[GNB_TIMERS_T300_IDX].iptr;
+  config.timer_config.t301 = *Timers_Params[GNB_TIMERS_T301_IDX].iptr;
+  config.timer_config.t310 = *Timers_Params[GNB_TIMERS_T310_IDX].iptr;
+  config.timer_config.n310 = *Timers_Params[GNB_TIMERS_N310_IDX].iptr;
+  config.timer_config.t311 = *Timers_Params[GNB_TIMERS_T311_IDX].iptr;
+  config.timer_config.n311 = *Timers_Params[GNB_TIMERS_N311_IDX].iptr;
+  config.timer_config.t319 = *Timers_Params[GNB_TIMERS_T319_IDX].iptr;
+  LOG_I(GNB_APP,
+        "sr_ProhibitTimer %d, sr_TransMax %d, sr_ProhibitTimer_v1700 %d, "
+        "t300 %d, t301 %d, t310 %d, n310 %d, t311 %d, n311 %d, t319 %d\n",
+        config.timer_config.sr_ProhibitTimer,
+        config.timer_config.sr_TransMax,
+        config.timer_config.sr_ProhibitTimer_v1700,
+        config.timer_config.t300,
+        config.timer_config.t301,
+        config.timer_config.t310,
+        config.timer_config.n310,
+        config.timer_config.t311,
+        config.timer_config.n311,
+        config.timer_config.t319);
+
   NR_ServingCellConfigCommon_t *scc = get_scc_config(cfg, config.minRXTXTIME);
   //xer_fprint(stdout, &asn_DEF_NR_ServingCellConfigCommon, scc);
   NR_ServingCellConfig_t *scd = get_scd_config(cfg);
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index 6491ddb755b138eb4c0c851deef202ea765939fe..94e854e301226b99752a44d96668c03e8669b80f 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -327,6 +327,51 @@ typedef enum {
 
 #define GNB_AMF_IPV4_ADDRESS_IDX          0
 
+/*---------------------------------------------------------------------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------------------------------------------------------------------*/
+/* TIMERS configuration parameters section name */
+#define GNB_CONFIG_STRING_TIMERS_CONFIG                  "TIMERS"
+
+/* TIMERS configuration parameters names   */
+#define GNB_CONFIG_STRING_TIMERS_SR_PROHIBIT_TIMER       "sr_ProhibitTimer"
+#define GNB_CONFIG_STRING_TIMERS_SR_TRANS_MAX            "sr_TransMax"
+#define GNB_CONFIG_STRING_TIMERS_SR_PROHIBIT_TIMER_V1700 "sr_ProhibitTimer_v1700"
+#define GNB_CONFIG_STRING_TIMERS_T300                    "t300"
+#define GNB_CONFIG_STRING_TIMERS_T301                    "t301"
+#define GNB_CONFIG_STRING_TIMERS_T310                    "t310"
+#define GNB_CONFIG_STRING_TIMERS_N310                    "n310"
+#define GNB_CONFIG_STRING_TIMERS_T311                    "t311"
+#define GNB_CONFIG_STRING_TIMERS_N311                    "n311"
+#define GNB_CONFIG_STRING_TIMERS_T319                    "t319"
+
+/*-------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            TIMERS configuration parameters                                                          */
+/*   optname                                          helpstr   paramflags    XXXptr       defXXXval         type           numelt     */
+/*-------------------------------------------------------------------------------------------------------------------------------------*/
+#define GNB_TIMERS_PARAMS_DESC {  \
+{GNB_CONFIG_STRING_TIMERS_SR_PROHIBIT_TIMER,          NULL,     0,            .iptr=NULL,  .defintval=0,     TYPE_INT,      0},       \
+{GNB_CONFIG_STRING_TIMERS_SR_TRANS_MAX,               NULL,     0,            .iptr=NULL,  .defintval=64,    TYPE_INT,      0},       \
+{GNB_CONFIG_STRING_TIMERS_SR_PROHIBIT_TIMER_V1700,    NULL,     0,            .iptr=NULL,  .defintval=0,     TYPE_INT,      0},       \
+{GNB_CONFIG_STRING_TIMERS_T300,                       NULL,     0,            .iptr=NULL,  .defintval=400,   TYPE_INT,      0},       \
+{GNB_CONFIG_STRING_TIMERS_T301,                       NULL,     0,            .iptr=NULL,  .defintval=400,   TYPE_INT,      0},       \
+{GNB_CONFIG_STRING_TIMERS_T310,                       NULL,     0,            .iptr=NULL,  .defintval=2000,  TYPE_INT,      0},       \
+{GNB_CONFIG_STRING_TIMERS_N310,                       NULL,     0,            .iptr=NULL,  .defintval=10,    TYPE_INT,      0},       \
+{GNB_CONFIG_STRING_TIMERS_T311,                       NULL,     0,            .iptr=NULL,  .defintval=3000,  TYPE_INT,      0},       \
+{GNB_CONFIG_STRING_TIMERS_N311,                       NULL,     0,            .iptr=NULL,  .defintval=1,     TYPE_INT,      0},       \
+{GNB_CONFIG_STRING_TIMERS_T319,                       NULL,     0,            .iptr=NULL,  .defintval=400,   TYPE_INT,      0},       \
+}
+
+#define GNB_TIMERS_SR_PROHIBIT_TIMER_IDX       0
+#define GNB_TIMERS_SR_TRANS_MAX_IDX            1
+#define GNB_TIMERS_SR_PROHIBIT_TIMER_V1700_IDX 2
+#define GNB_TIMERS_T300_IDX                    3
+#define GNB_TIMERS_T301_IDX                    4
+#define GNB_TIMERS_T310_IDX                    5
+#define GNB_TIMERS_N310_IDX                    6
+#define GNB_TIMERS_T311_IDX                    7
+#define GNB_TIMERS_N311_IDX                    8
+#define GNB_TIMERS_T319_IDX                    9
+
 /*---------------------------------------------------------------------------------------------------------------------------------------*/
 /*---------------------------------------------------------------------------------------------------------------------------------------*/
 /* SCTP configuration parameters section name */
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index e313cdb19093189be4052f44b064224767561b9b..e165a717f74ba58a09b71329fe047c87ba244136 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -97,6 +97,13 @@ void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers)
   }
 }
 
+int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc)
+{
+  if (scc->ext2 && scc->ext2->ntn_Config_r17 && scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17)
+    return *scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 << *scc->ssbSubcarrierSpacing;
+  return 0;
+}
+
 int precoding_weigths_generation(nfapi_nr_pm_list_t *mat,
                                  int pmiq,
                                  int L,
@@ -602,14 +609,19 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
               "SSB Bitmap type %d is not valid\n",
               scc->ssb_PositionsInBurst->present);
 
-  int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
-  if (*scc->ssbSubcarrierSpacing == 0)
-    n <<= 1; // to have enough room for feedback possibly beyond the frame we need a larger array at 15kHz SCS
-  nrmac->common_channels[0].vrb_map_UL = calloc(n * MAX_BWP_SIZE, sizeof(uint16_t));
-  nrmac->vrb_map_UL_size = n;
+  const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
+  const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
+  const int size = n << (int)ceil(log2((NTN_gNB_Koffset + 13) / n + 1)); // 13 is upper limit for max_fb_time
+
+  nrmac->vrb_map_UL_size = size;
+  nrmac->common_channels[0].vrb_map_UL = calloc(size * MAX_BWP_SIZE, sizeof(uint16_t));
   AssertFatal(nrmac->common_channels[0].vrb_map_UL,
               "could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n");
 
+  nrmac->UL_tti_req_ahead_size = size;
+  nrmac->UL_tti_req_ahead[0] = calloc(size, sizeof(nfapi_nr_ul_tti_request_t));
+  AssertFatal(nrmac->UL_tti_req_ahead[0], "could not allocate memory for nrmac->UL_tti_req_ahead[0]\n");
+
   LOG_I(NR_MAC, "Configuring common parameters from NR ServingCellConfig\n");
 
   config_common(nrmac, config->pdsch_AntennaPorts, config->pusch_AntennaPorts, scc);
@@ -677,7 +689,7 @@ void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_
 
   NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
-  NR_BCCH_DL_SCH_Message_t *sib1 = get_SIB1_NR(scc, plmn, cellID, tac);
+  NR_BCCH_DL_SCH_Message_t *sib1 = get_SIB1_NR(scc, plmn, cellID, tac, &nrmac->radio_config.timer_config);
   cc->sib1 = sib1;
   cc->sib1_bcch_length = encode_SIB1_NR(sib1, cc->sib1_bcch_pdu, sizeof(cc->sib1_bcch_pdu));
   AssertFatal(cc->sib1_bcch_length > 0, "could not encode SIB1\n");
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index 34a372247c0c2f2d1b9a7abed97073b33ae8bf65..dbd64f524ed9811995977f5214d6e2f153ba3ea3 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -68,7 +68,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
   NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon;
   const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
 
-  UL_tti_req_ahead_initialization(gNB, scc, num_slots, CC_idP, frameP, slotP, *scc->ssbSubcarrierSpacing);
+  UL_tti_req_ahead_initialization(gNB, num_slots, CC_idP, frameP, slotP);
 
   nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP];
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 7507207ac8ea9b2a7e55965dd2076efb92152aac..3f752dae232bfd5f6933de7984475f838d08c801 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -542,10 +542,10 @@ static void start_ra_contention_resolution_timer(NR_RA_t *ra, const long ra_Cont
   // ra-ContentionResolutionTimer ENUMERATED {sf8, sf16, sf24, sf32, sf40, sf48, sf56, sf64}
   // The initial value for the contention resolution timer.
   // Value sf8 corresponds to 8 subframes, value sf16 corresponds to 16 subframes, and so on.
-  // We add K2 because we start the timer in the DL slot that schedules Msg3/Msg3 retransmission
-  ra->contention_resolution_timer = ((((int)ra_ContentionResolutionTimer + 1) * 8) << scs) + K2;
-  LOG_D(NR_MAC,
-        "Starting RA Contention Resolution timer with %d ms + %d K2 (%d slots) duration\n",
+  // We add 2 * K2 because the timer runs from Msg2 transmission till Msg4 ACK reception
+  ra->contention_resolution_timer = ((((int)ra_ContentionResolutionTimer + 1) * 8) << scs) + 2 * K2;
+  LOG_I(NR_MAC,
+        "Starting RA Contention Resolution timer with %d ms + 2 * %d K2 (%d slots) duration\n",
         ((int)ra_ContentionResolutionTimer + 1) * 8,
         K2,
         ra->contention_resolution_timer);
@@ -580,8 +580,8 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
 
   NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList_Common;
   int mu = ul_bwp->scs;
-  uint8_t K2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
-  const int sched_frame = (frame + (slot + K2 >= nr_slots_per_frame[mu])) % 1024;
+  uint16_t K2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc);
+  const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
   const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
 
   if (is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) {
@@ -747,6 +747,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
 }
 
 static int get_feasible_msg3_tda(frame_type_t frame_type,
+                                 const NR_ServingCellConfigCommon_t *scc,
                                  int mu_delta,
                                  uint64_t ulsch_slot_bitmap[3],
                                  const NR_PUSCH_TimeDomainResourceAllocationList_t *tda_list,
@@ -761,12 +762,14 @@ static int get_feasible_msg3_tda(frame_type_t frame_type,
     return tda;
   }
 
+  const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
+
   // TDD
   DevAssert(tdd != NULL);
   uint8_t tdd_period_slot = slots_per_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
   for (int i = 0; i < tda_list->list.count; i++) {
     // check if it is UL
-    long k2 = *tda_list->list.array[i]->k2;
+    long k2 = *tda_list->list.array[i]->k2 + NTN_gNB_Koffset;
     int temp_slot = (slot + k2 + mu_delta) % slots_per_frame; // msg3 slot according to 8.3 in 38.213
     if (!is_xlsch_in_slot(ulsch_slot_bitmap[temp_slot / 64], temp_slot))
       continue;
@@ -820,10 +823,10 @@ static void nr_get_Msg3alloc(module_id_t module_id,
   int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
   SLIV2SL(startSymbolAndLength, &ra->msg3_startsymb, &ra->msg3_nbSymb);
 
-  long k2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
+  long k2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc);
   int abs_slot = current_slot + k2 + DELTA[mu];
   ra->Msg3_slot = abs_slot % n_slots_frame;
-  ra->Msg3_frame = (current_frame + (abs_slot / n_slots_frame)) % 1024;
+  ra->Msg3_frame = (current_frame + (abs_slot / n_slots_frame)) % MAX_FRAME_NUMBER;
 
   LOG_I(NR_MAC,
         "UE %04x: Msg3 scheduled at %d.%d (%d.%d k2 %ld TDA %u)\n",
@@ -1224,6 +1227,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
   }
 
   ra->Msg3_tda_id = get_feasible_msg3_tda(cc->frame_type,
+                                          scc,
                                           DELTA[ul_bwp->scs],
                                           nr_mac->ulsch_slot_bitmap,
                                           ul_bwp->tdaList_Common,
@@ -1464,7 +1468,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
   start_ra_contention_resolution_timer(
       ra,
       scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer,
-      *ra->UL_BWP.tdaList_Common->list.array[ra->Msg3_tda_id]->k2,
+      *ra->UL_BWP.tdaList_Common->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc),
       ra->UL_BWP.scs);
 
   if (ra->cfra) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index ca6d44d5b0e8d95b447b7061f574aa44a970b5a5..29b5fbe7137c6a443e552b35404812b6e431cd74 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -660,7 +660,7 @@ static void pf_dl(module_id_t module_id,
       }
 
       /* Check DL buffer and skip this UE if no bytes and no TA necessary */
-      if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 10) % 1024)
+      if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 100) % 1024)
         continue;
 
       /* Calculate coeff */
@@ -805,8 +805,8 @@ static void pf_dl(module_id_t module_id,
     // awaiting. Therefore, for the time being, we put a fixed overhead of 12
     // (for 4 PDUs) and optionally + 2 for TA. Once RLC gives the number of
     // PDUs, we replace with 3 * numPDUs
-    const int oh = 3 * 4 + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
-    //const int oh = 3 * sched_ctrl->dl_pdus_total + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
+    const int oh = 3 * 4 + 2 * (frame == (sched_ctrl->ta_frame + 100) % 1024);
+    //const int oh = 3 * sched_ctrl->dl_pdus_total + 2 * (frame == (sched_ctrl->ta_frame + 100) % 1024);
     nr_find_nb_rb(sched_pdsch->Qm,
                   sched_pdsch->R,
                   1, // no transform precoding for DL
@@ -958,7 +958,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
      * Possible improvement: take the periodicity from input file.
      * If such UE is not scheduled now, it will be by the preprocessor later.
      * If we add the CE, ta_apply will be reset */
-    if (frame == (sched_ctrl->ta_frame + 10) % 1024) {
+    if (frame == (sched_ctrl->ta_frame + 100) % 1024) {
       sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */
       LOG_D(NR_MAC, "[UE %04x][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE->rnti, frame, slot);
     }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 3eb9a9ce7b1bbdf4671f949c949a05ec11b16c02..6d6c6a20478854ab9b9a8b221e6b4ff2db72d0fb 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -60,6 +60,12 @@ void nr_preprocessor_phytest(module_id_t module_id,
   NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
   const int CC_id = 0;
 
+  /* return if all DL HARQ processes wait for feedback */
+  if (sched_ctrl->retrans_dl_harq.head == -1 && sched_ctrl->available_dl_harq.head == -1) {
+    LOG_D(NR_MAC, "[UE %04x][%4d.%2d] UE has no free DL HARQ process, skipping\n", UE->rnti, frame, slot);
+    return;
+  }
+
   const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
   NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp,
                                            sched_ctrl->search_space->searchSpaceType->present,
@@ -216,6 +222,12 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
   NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
   const int mu = ul_bwp->scs;
 
+  /* return if all UL HARQ processes wait for feedback */
+  if (sched_ctrl->retrans_ul_harq.head == -1 && sched_ctrl->available_ul_harq.head == -1) {
+    LOG_D(NR_MAC, "[UE %04x][%4d.%2d] UE has no free UL HARQ process, skipping\n", UE->rnti, frame, slot);
+    return false;
+  }
+
   NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = get_ul_tdalist(ul_bwp,
                                                                         sched_ctrl->coreset->controlResourceSetId,
                                                                         sched_ctrl->search_space->searchSpaceType->present,
@@ -227,8 +239,8 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
               "time domain assignment %d >= %d\n",
               temp_tda,
               tdaList->list.count);
-  int K2 = get_K2(tdaList, temp_tda, mu);
-  const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
+  int K2 = get_K2(tdaList, temp_tda, mu, scc);
+  const int sched_frame = frame + (slot + K2) / nr_slots_per_frame[mu];
   const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
   const int tda = get_ul_tda(nr_mac, scc, sched_frame, sched_slot);
   if (tda < 0)
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 1aeba91026536300b3244d61dd5c66344253b176..8ae9c3dcc57f41033700f1b56db73e0c349675ea 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -2546,15 +2546,16 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
 
 void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
                           const NR_UE_UL_BWP_t *ul_bwp,
-                          const NR_ServingCellConfigCommon_t *scc) {
-
+                          const NR_ServingCellConfigCommon_t *scc)
+{
+  const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
   const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
   const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
   const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
   const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame;
   // PUCCH list size is given by the number of UL slots in the PUCCH period
   // the length PUCCH period is determined by max_fb_time since we may need to prepare PUCCH for ACK/NACK max_fb_time slots ahead
-  const int list_size = n_ul_slots_period << (ul_bwp->max_fb_time/nr_slots_period);
+  const int list_size = n_ul_slots_period << (int)ceil(log2((ul_bwp->max_fb_time + NTN_gNB_Koffset) / nr_slots_period + 1));
   if(!sched_ctrl->sched_pucch) {
     sched_ctrl->sched_pucch = calloc(list_size, sizeof(*sched_ctrl->sched_pucch));
     sched_ctrl->sched_pucch_size = list_size;
@@ -3075,26 +3076,19 @@ int ul_buffer_index(int frame, int slot, int scs, int size)
   return abs_slot % size;
 }
 
-void UL_tti_req_ahead_initialization(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc, int n, int CCid, frame_t frameP, int slotP, int scs)
+void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP)
 {
 
-  if(gNB->UL_tti_req_ahead[CCid])
+  if(gNB->UL_tti_req_ahead[CCid][1].Slot == 1)
     return;
 
-  int size = n;
-  if (scs == 0)
-    size <<= 1; // to have enough room for feedback possibly beyond the frame we need a larger array at 15kHz SCS
-
-  gNB->UL_tti_req_ahead_size = size;
-  gNB->UL_tti_req_ahead[CCid] = calloc(size, sizeof(nfapi_nr_ul_tti_request_t));
-  AssertFatal(gNB->UL_tti_req_ahead[CCid], "could not allocate memory for RC.nrmac[]->UL_tti_req_ahead[]\n");
   /* fill in slot/frame numbers: slot is fixed, frame will be updated by scheduler
    * consider that scheduler runs sl_ahead: the first sl_ahead slots are
    * already "in the past" and thus we put frame 1 instead of 0! */
-  for (int i = 0; i < size; ++i) {
+  for (int i = 0; i < gNB->UL_tti_req_ahead_size; ++i) {
     int abs_slot = frameP * n + slotP + i;
-    nfapi_nr_ul_tti_request_t *req = &gNB->UL_tti_req_ahead[CCid][abs_slot % size];
-    req->SFN = abs_slot / n;
+    nfapi_nr_ul_tti_request_t *req = &gNB->UL_tti_req_ahead[CCid][abs_slot % gNB->UL_tti_req_ahead_size];
+    req->SFN = (abs_slot / n) % MAX_FRAME_NUMBER;
     req->Slot = abs_slot % n;
   }
 }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c
index 2e5fb0c7a19187b40625e9a33a143469797f0159..b4492ffa44cd5888b6c314b2516e84bf1b48d8c4 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c
@@ -512,8 +512,11 @@ static void nr_fill_nfapi_srs(int module_id,
 *********************************************************************/
 void nr_schedule_srs(int module_id, frame_t frame, int slot)
  {
-  /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+  const int CC_id = 0;
   gNB_MAC_INST *nrmac = RC.nrmac[module_id];
+  const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
+
+  /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
   NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
 
   NR_UEs_t *UE_info = &nrmac->UE_info;
@@ -571,14 +574,14 @@ void nr_schedule_srs(int module_id, frame_t frame, int slot)
       int max_k2 = 0;
       // avoid last one in the list (for msg3)
       for (int i = 0; i < num_tda - 1; i++) {
-        int k2 = get_K2(tdaList, i, current_BWP->scs);
+        int k2 = get_K2(tdaList, i, current_BWP->scs, scc);
         max_k2 = k2 > max_k2 ? k2 : max_k2;
       }
 
       // we are sheduling SRS max_k2 slot in advance for the presence of SRS to be taken into account when scheduling PUSCH
       const int n_slots_frame = nr_slots_per_frame[current_BWP->scs];
       const int sched_slot = (slot + max_k2) % n_slots_frame;
-      const int sched_frame = (frame + ((slot + max_k2) / n_slots_frame)) % 1024;
+      const int sched_frame = (frame + (slot + max_k2) / n_slots_frame) % MAX_FRAME_NUMBER;
 
       const uint16_t period = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present];
       const uint16_t offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index ac067044eb108ec7068b45ee2ba420321a185dde..b2a6827d04098e59efd1269f589b6385da84374c 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -211,8 +211,12 @@ void nr_csi_meas_reporting(int Mod_idP,
                            frame_t frame,
                            sub_frame_t slot)
 {
-  /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
+  const int CC_id = 0;
   gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
+  const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
+  const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
+
+  /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
   NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
 
   UE_iterator(nrmac->UE_info.list, UE ) {
@@ -242,8 +246,8 @@ void nr_csi_meas_reporting(int Mod_idP,
       // we schedule CSI reporting max_fb_time slots in advance
       int period, offset;
       csi_period_offset(csirep, NULL, &period, &offset);
-      const int sched_slot = (slot + ul_bwp->max_fb_time) % n_slots_frame;
-      const int sched_frame = (frame + ((slot + ul_bwp->max_fb_time) / n_slots_frame)) % 1024;
+      const int sched_slot = (slot + ul_bwp->max_fb_time + NTN_gNB_Koffset) % n_slots_frame;
+      const int sched_frame = (frame + ((slot + ul_bwp->max_fb_time + NTN_gNB_Koffset) / n_slots_frame)) % MAX_FRAME_NUMBER;
       // prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214
       if ((sched_frame * n_slots_frame + sched_slot - offset) % period != 0)
         continue;
@@ -260,7 +264,6 @@ void nr_csi_meas_reporting(int Mod_idP,
       AssertFatal(res_index < n,
                   "CSI pucch resource %ld not found among PUCCH resources\n", pucchcsires->pucch_Resource);
 
-      const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[0].ServingCellConfigCommon;
       const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
       AssertFatal(tdd || nrmac->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n");
       const int pucch_index = get_pucch_index(sched_frame, sched_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
@@ -974,7 +977,7 @@ static NR_UE_harq_t *find_harq(frame_t frame, sub_frame_t slot, NR_UE_info_t * U
     return NULL;
   NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid];
   /* old feedbacks we missed: mark for retransmission */
-  while (harq->feedback_frame != frame
+  while ((harq->feedback_frame - frame + 1024 ) % 1024 > 512 // harq->feedback_frame < frame, distance of 512 is boundary to decide if feedback_frame is in the past or future
          || (harq->feedback_frame == frame && harq->feedback_slot < slot)) {
     LOG_W(NR_MAC,
           "UE %04x expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the past)\n",
@@ -992,7 +995,9 @@ static NR_UE_harq_t *find_harq(frame_t frame, sub_frame_t slot, NR_UE_info_t * U
     harq = &sched_ctrl->harq_processes[pid];
   }
   /* feedbacks that we wait for in the future: don't do anything */
-  if (harq->feedback_slot > slot) {
+  if ((frame - harq->feedback_frame + 1024 ) % 1024 > 512 // harq->feedback_frame > frame, distance of 512 is boundary to decide if feedback_frame is in the past or future
+      || (harq->feedback_frame == frame && harq->feedback_slot > slot)) {
+
     LOG_W(NR_MAC,
           "UE %04x expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the future)\n",
           UE->rnti,
@@ -1237,8 +1242,10 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
    * called often, don't try to lock every time */
 
   const int CC_id = 0;
-  const int minfbtime = mac->radio_config.minRXTXTIME;
   const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon;
+  const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
+
+  const int minfbtime = mac->radio_config.minRXTXTIME + NTN_gNB_Koffset;
   const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
   const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
   const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
@@ -1261,13 +1268,13 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
 
   for (int f = 0; f < fb_size; f++) {
     // can't schedule ACKNACK before minimum feedback time
-    if(pdsch_to_harq_feedback[f] < minfbtime)
+    if((pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) < minfbtime)
       continue;
-    const int pucch_slot = (slot + pdsch_to_harq_feedback[f]) % n_slots_frame;
+    const int pucch_slot = (slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) % n_slots_frame;
     // check if the slot is UL
     if(pucch_slot%nr_slots_period < first_ul_slot_period)
       continue;
-    const int pucch_frame = (frame + ((slot + pdsch_to_harq_feedback[f]) / n_slots_frame)) & 1023;
+    const int pucch_frame = (frame + ((slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) / n_slots_frame)) % MAX_FRAME_NUMBER;
     // we store PUCCH resources according to slot, TDD configuration and size of the vector containing PUCCH structures
     const int pucch_index = get_pucch_index(pucch_frame, pucch_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
     NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
@@ -1346,7 +1353,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
       return pucch_index; // index of current PUCCH structure
     }
   }
-  LOG_D(NR_MAC, "DL %4d.%2d, Couldn't find scheduling occasion for this HARQ process\n", frame, slot);
+  LOG_W(NR_MAC, "DL %4d.%2d, Couldn't find scheduling occasion for this HARQ process\n", frame, slot);
   return -1;
 }
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index ecb28907769e9c1abd19208945b5dc92dfa280a3..820eba2b5bb66717a2ff3d1444c9d3f1c3a7024b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -1433,19 +1433,21 @@ void handle_nr_srs_measurements(const module_id_t module_id,
 
 long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList,
             int time_domain_assignment,
-            int mu) {
-
+            int mu,
+            const NR_ServingCellConfigCommon_t *scc)
+{
   /* we assume that this function is mutex-protected from outside */
   NR_PUSCH_TimeDomainResourceAllocation_t *tda = tdaList->list.array[time_domain_assignment];
+  const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
 
   if (tda->k2)
-    return *tda->k2;
+    return *tda->k2 + NTN_gNB_Koffset;
   else if (mu < 2)
-    return 1;
+    return 1 + NTN_gNB_Koffset;
   else if (mu == 2)
-    return 2;
+    return 2 + NTN_gNB_Koffset;
   else
-    return 3;
+    return 3 + NTN_gNB_Koffset;
 }
 
 static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, int CC_id,  NR_UE_info_t* UE, frame_t frame, sub_frame_t slot, uint32_t ulsch_max_frame_inactivity)
@@ -2084,13 +2086,13 @@ static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_
                                                                         sched_ctrl->coreset->controlResourceSetId,
                                                                         sched_ctrl->search_space->searchSpaceType->present,
                                                                         TYPE_C_RNTI_);
-  int K2 = get_K2(tdaList, temp_tda, mu);
-  const int sched_frame = (frame + (slot + K2 >= nr_slots_per_frame[mu])) & 1023;
+  int K2 = get_K2(tdaList, temp_tda, mu, scc);
+  const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
   const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
   const int tda = get_ul_tda(nr_mac, scc, sched_frame, sched_slot);
   if (tda < 0)
     return false;
-  DevAssert(K2 == get_K2(tdaList, tda, mu));
+  DevAssert(K2 == get_K2(tdaList, tda, mu, scc));
 
   if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
     return false;
@@ -2099,9 +2101,9 @@ static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_
   sched_ctrl->sched_pusch.frame = sched_frame;
   UE_iterator(nr_mac->UE_info.list, UE2) {
     NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl;
-    AssertFatal(K2 == get_K2(tdaList, tda, mu),
+    AssertFatal(K2 == get_K2(tdaList, tda, mu, scc),
                 "Different K2, %d(UE%d) != %ld(UE%04x)\n",
-		K2, 0, get_K2(tdaList, tda, mu), UE2->rnti);
+		K2, 0, get_K2(tdaList, tda, mu, scc), UE2->rnti);
     sched_ctrl->sched_pusch.slot = sched_slot;
     sched_ctrl->sched_pusch.frame = sched_frame;
   }
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 0fc1071c5fe307c854eec5118fa32d56c3681b64..a23e588a492427d48d52602460c7f2d8fa3922d3 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -37,6 +37,7 @@
 
 void set_cset_offset(uint16_t);
 void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers);
+int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc);
 
 void mac_top_init_gNB(ngran_node_t node_type,
                       NR_ServingCellConfigCommon_t *scc,
@@ -264,7 +265,8 @@ NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
 
 long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList,
             int time_domain_assignment,
-            int mu);
+            int mu,
+            const NR_ServingCellConfigCommon_t *scc);
 
 const NR_DMRS_UplinkConfig_t *get_DMRS_UplinkConfig(const NR_PUSCH_Config_t *pusch_Config, const NR_tda_info_t *tda_info);
 
@@ -418,7 +420,7 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options,
 
 int ul_buffer_index(int frame, int slot, int scs, int size);
 
-void UL_tti_req_ahead_initialization(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc, int n, int CCid, frame_t frameP, int slotP, int scs);
+void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP);
 
 void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP);
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 59a33556913db67c68646ba9ce92e32a74626dce..7fe0c8994eab147b58a73ac4af35161ea4e97cd3 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -128,6 +128,19 @@ typedef struct nr_pdsch_AntennaPorts_t {
   int XP;
 } nr_pdsch_AntennaPorts_t;
 
+typedef struct nr_mac_timers {
+  int sr_ProhibitTimer;
+  int sr_TransMax;
+  int sr_ProhibitTimer_v1700;
+  int t300;
+  int t301;
+  int t310;
+  int n310;
+  int t311;
+  int n311;
+  int t319;
+} nr_mac_timers_t;
+
 typedef struct nr_mac_config_t {
   int sib1_tda;
   nr_pdsch_AntennaPorts_t pdsch_AntennaPorts;
@@ -141,6 +154,7 @@ typedef struct nr_mac_config_t {
   int maxMIMO_layers;
   //int pusch_TargetSNRx10;
   //int pucch_TargetSNRx10;
+  nr_mac_timers_t timer_config;
 } nr_mac_config_t;
 
 typedef struct NR_preamble_ue {
@@ -422,7 +436,7 @@ typedef struct NR_sched_pdsch {
   int8_t dl_harq_pid;
 
   // pucch format allocation
-  uint8_t pucch_allocation;
+  uint16_t pucch_allocation;
 
   uint16_t pm_index;
   uint8_t nrOfLayers;
diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c
index 3b1791ad55c2582a4de42d6e56a4c32e6042797a..9bbd4f38b7f42385774683916b148a9ca6d1170c 100644
--- a/openair2/RRC/NR/nr_rrc_config.c
+++ b/openair2/RRC/NR/nr_rrc_config.c
@@ -1974,7 +1974,175 @@ void free_MeasurementTimingConfiguration(NR_MeasurementTimingConfiguration_t *mt
   ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, mtc);
 }
 
-NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, const f1ap_plmn_t *plmn, uint64_t cellID, int tac)
+static long get_NR_UE_TimersAndConstants_t300(const nr_mac_timers_t *timer_config)
+{
+  switch (timer_config->t300) {
+    case 100:
+      return NR_UE_TimersAndConstants__t300_ms100;
+    case 200:
+      return NR_UE_TimersAndConstants__t300_ms200;
+    case 300:
+      return NR_UE_TimersAndConstants__t300_ms300;
+    case 400:
+      return NR_UE_TimersAndConstants__t300_ms400;
+    case 600:
+      return NR_UE_TimersAndConstants__t300_ms600;
+    case 1000:
+      return NR_UE_TimersAndConstants__t300_ms1000;
+    case 1500:
+      return NR_UE_TimersAndConstants__t300_ms1500;
+    case 2000:
+      return NR_UE_TimersAndConstants__t300_ms2000;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for t300!\n");
+  }
+}
+
+static long get_NR_UE_TimersAndConstants_t301(const nr_mac_timers_t *timer_config)
+{
+  switch (timer_config->t301) {
+    case 100:
+      return NR_UE_TimersAndConstants__t301_ms100;
+    case 200:
+      return NR_UE_TimersAndConstants__t301_ms200;
+    case 300:
+      return NR_UE_TimersAndConstants__t301_ms300;
+    case 400:
+      return NR_UE_TimersAndConstants__t301_ms400;
+    case 600:
+      return NR_UE_TimersAndConstants__t301_ms600;
+    case 1000:
+      return NR_UE_TimersAndConstants__t301_ms1000;
+    case 1500:
+      return NR_UE_TimersAndConstants__t301_ms1500;
+    case 2000:
+      return NR_UE_TimersAndConstants__t301_ms2000;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for t301!\n");
+  }
+}
+
+static long get_NR_UE_TimersAndConstants_t310(const nr_mac_timers_t *timer_config)
+{
+  switch (timer_config->t310) {
+    case 0:
+      return NR_UE_TimersAndConstants__t310_ms0;
+    case 50:
+      return NR_UE_TimersAndConstants__t310_ms50;
+    case 100:
+      return NR_UE_TimersAndConstants__t310_ms100;
+    case 200:
+      return NR_UE_TimersAndConstants__t310_ms200;
+    case 500:
+      return NR_UE_TimersAndConstants__t310_ms500;
+    case 1000:
+      return NR_UE_TimersAndConstants__t310_ms1000;
+    case 2000:
+      return NR_UE_TimersAndConstants__t310_ms2000;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for t310!\n");
+  }
+}
+
+static long get_NR_UE_TimersAndConstants_n310(const nr_mac_timers_t *timer_config)
+{
+  switch (timer_config->n310) {
+    case 1:
+      return NR_UE_TimersAndConstants__n310_n1;
+    case 2:
+      return NR_UE_TimersAndConstants__n310_n2;
+    case 3:
+      return NR_UE_TimersAndConstants__n310_n3;
+    case 4:
+      return NR_UE_TimersAndConstants__n310_n4;
+    case 6:
+      return NR_UE_TimersAndConstants__n310_n6;
+    case 8:
+      return NR_UE_TimersAndConstants__n310_n8;
+    case 10:
+      return NR_UE_TimersAndConstants__n310_n10;
+    case 20:
+      return NR_UE_TimersAndConstants__n310_n20;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for n310!\n");
+  }
+}
+
+static long get_NR_UE_TimersAndConstants_t311(const nr_mac_timers_t *timer_config)
+{
+  switch (timer_config->t311) {
+    case 1000:
+      return NR_UE_TimersAndConstants__t311_ms1000;
+    case 3000:
+      return NR_UE_TimersAndConstants__t311_ms3000;
+    case 5000:
+      return NR_UE_TimersAndConstants__t311_ms5000;
+    case 10000:
+      return NR_UE_TimersAndConstants__t311_ms10000;
+    case 15000:
+      return NR_UE_TimersAndConstants__t311_ms15000;
+    case 20000:
+      return NR_UE_TimersAndConstants__t311_ms20000;
+    case 30000:
+      return NR_UE_TimersAndConstants__t311_ms30000;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for t311!\n");
+  }
+}
+
+static long get_NR_UE_TimersAndConstants_n311(const nr_mac_timers_t *timer_config)
+{
+  switch (timer_config->n311) {
+    case 1:
+      return NR_UE_TimersAndConstants__n311_n1;
+    case 2:
+      return NR_UE_TimersAndConstants__n311_n2;
+    case 3:
+      return NR_UE_TimersAndConstants__n311_n3;
+    case 4:
+      return NR_UE_TimersAndConstants__n311_n4;
+    case 5:
+      return NR_UE_TimersAndConstants__n311_n5;
+    case 6:
+      return NR_UE_TimersAndConstants__n311_n6;
+    case 8:
+      return NR_UE_TimersAndConstants__n311_n8;
+    case 10:
+      return NR_UE_TimersAndConstants__n311_n10;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for n311!\n");
+  }
+}
+
+static long get_NR_UE_TimersAndConstants_t319(const nr_mac_timers_t *timer_config)
+{
+  switch (timer_config->t319) {
+    case 100:
+      return NR_UE_TimersAndConstants__t319_ms100;
+    case 200:
+      return NR_UE_TimersAndConstants__t319_ms200;
+    case 300:
+      return NR_UE_TimersAndConstants__t319_ms300;
+    case 400:
+      return NR_UE_TimersAndConstants__t319_ms400;
+    case 600:
+      return NR_UE_TimersAndConstants__t319_ms600;
+    case 1000:
+      return NR_UE_TimersAndConstants__t319_ms1000;
+    case 1500:
+      return NR_UE_TimersAndConstants__t319_ms1500;
+    case 2000:
+      return NR_UE_TimersAndConstants__t319_ms2000;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for t319!\n");
+  }
+}
+
+NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
+                                      const f1ap_plmn_t *plmn,
+                                      uint64_t cellID,
+                                      int tac,
+                                      const nr_mac_timers_t *timer_config)
 {
   AssertFatal(cellID < (1l << 36), "cellID must fit within 36 bits, but is %lu\n", cellID);
 
@@ -2230,13 +2398,13 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, c
   // ue-TimersAndConstants
   sib1->ue_TimersAndConstants = CALLOC(1,sizeof(struct NR_UE_TimersAndConstants));
   AssertFatal(sib1->ue_TimersAndConstants != NULL, "out of memory\n");
-  sib1->ue_TimersAndConstants->t300 = NR_UE_TimersAndConstants__t300_ms400;
-  sib1->ue_TimersAndConstants->t301 = NR_UE_TimersAndConstants__t301_ms400;
-  sib1->ue_TimersAndConstants->t310 = NR_UE_TimersAndConstants__t310_ms2000;
-  sib1->ue_TimersAndConstants->n310 = NR_UE_TimersAndConstants__n310_n10;
-  sib1->ue_TimersAndConstants->t311 = NR_UE_TimersAndConstants__t311_ms3000;
-  sib1->ue_TimersAndConstants->n311 = NR_UE_TimersAndConstants__n311_n1;
-  sib1->ue_TimersAndConstants->t319 = NR_UE_TimersAndConstants__t319_ms400;
+  sib1->ue_TimersAndConstants->t300 = get_NR_UE_TimersAndConstants_t300(timer_config);
+  sib1->ue_TimersAndConstants->t301 = get_NR_UE_TimersAndConstants_t301(timer_config);
+  sib1->ue_TimersAndConstants->t310 = get_NR_UE_TimersAndConstants_t310(timer_config);
+  sib1->ue_TimersAndConstants->n310 = get_NR_UE_TimersAndConstants_n310(timer_config);
+  sib1->ue_TimersAndConstants->t311 = get_NR_UE_TimersAndConstants_t311(timer_config);
+  sib1->ue_TimersAndConstants->n311 = get_NR_UE_TimersAndConstants_n311(timer_config);
+  sib1->ue_TimersAndConstants->t319 = get_NR_UE_TimersAndConstants_t319(timer_config);
 
   // uac-BarringInfo
   /*sib1->uac_BarringInfo = CALLOC(1, sizeof(struct NR_SIB1__uac_BarringInfo));
@@ -2286,7 +2454,102 @@ static NR_PhysicalCellGroupConfig_t *configure_phy_cellgroup(void)
   return physicalCellGroupConfig;
 }
 
-static NR_MAC_CellGroupConfig_t *configure_mac_cellgroup(void)
+static long *get_sr_ProhibitTimer(const nr_mac_timers_t *timer_config)
+{
+  if (timer_config->sr_ProhibitTimer == 0)
+    return NULL;
+
+  long *ret = calloc(1, sizeof(*ret));
+  switch (timer_config->sr_ProhibitTimer) {
+    case 1:
+      *ret = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms1;
+      break;
+    case 2:
+      *ret = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms2;
+      break;
+    case 4:
+      *ret = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms4;
+      break;
+    case 8:
+      *ret = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms8;
+      break;
+    case 16:
+      *ret = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms16;
+      break;
+    case 32:
+      *ret = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms32;
+      break;
+    case 64:
+      *ret = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms64;
+      break;
+    case 128:
+      *ret = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms128;
+      break;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for sr_ProhibitTimer!\n");
+  }
+  return ret;
+}
+
+static long get_sr_TransMax(const nr_mac_timers_t *timer_config)
+{
+  switch (timer_config->sr_TransMax) {
+    case 4:
+      return NR_SchedulingRequestToAddMod__sr_TransMax_n4;
+    case 8:
+      return NR_SchedulingRequestToAddMod__sr_TransMax_n8;
+    case 16:
+      return NR_SchedulingRequestToAddMod__sr_TransMax_n16;
+    case 32:
+      return NR_SchedulingRequestToAddMod__sr_TransMax_n32;
+    case 64:
+      return NR_SchedulingRequestToAddMod__sr_TransMax_n64;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for sr_TransMax!\n");
+  }
+}
+
+static long *get_sr_ProhibitTimer_v1700(const nr_mac_timers_t *timer_config)
+{
+  if (timer_config->sr_ProhibitTimer_v1700 == 0)
+    return NULL;
+
+  long *ret = calloc(1, sizeof(*ret));
+  switch (timer_config->sr_ProhibitTimer_v1700) {
+    case 192:
+      *ret = NR_SchedulingRequestToAddModExt_v1700__sr_ProhibitTimer_v1700_ms192;
+      break;
+    case 256:
+      *ret = NR_SchedulingRequestToAddModExt_v1700__sr_ProhibitTimer_v1700_ms256;
+      break;
+    case 320:
+      *ret = NR_SchedulingRequestToAddModExt_v1700__sr_ProhibitTimer_v1700_ms320;
+      break;
+    case 384:
+      *ret = NR_SchedulingRequestToAddModExt_v1700__sr_ProhibitTimer_v1700_ms384;
+      break;
+    case 448:
+      *ret = NR_SchedulingRequestToAddModExt_v1700__sr_ProhibitTimer_v1700_ms448;
+      break;
+    case 512:
+      *ret = NR_SchedulingRequestToAddModExt_v1700__sr_ProhibitTimer_v1700_ms512;
+      break;
+    case 576:
+      *ret = NR_SchedulingRequestToAddModExt_v1700__sr_ProhibitTimer_v1700_ms576;
+      break;
+    case 640:
+      *ret = NR_SchedulingRequestToAddModExt_v1700__sr_ProhibitTimer_v1700_ms640;
+      break;
+    case 1082:
+      *ret = NR_SchedulingRequestToAddModExt_v1700__sr_ProhibitTimer_v1700_ms1082;
+      break;
+    default:
+      AssertFatal(1 == 0, "Invalid value configured for sr_ProhibitTimer_v1700!\n");
+  }
+  return ret;
+}
+
+static NR_MAC_CellGroupConfig_t *configure_mac_cellgroup(const nr_mac_timers_t *timer_config)
 {
   NR_MAC_CellGroupConfig_t * mac_CellGroupConfig = calloc(1, sizeof(*mac_CellGroupConfig));
   AssertFatal(mac_CellGroupConfig != NULL, "Couldn't allocate mac-CellGroupConfig. Out of memory!\n");
@@ -2307,10 +2570,22 @@ static NR_MAC_CellGroupConfig_t *configure_mac_cellgroup(void)
   mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList));
   struct NR_SchedulingRequestToAddMod *schedulingrequestlist = CALLOC(1,sizeof(*schedulingrequestlist));
   schedulingrequestlist->schedulingRequestId = 0;
-  schedulingrequestlist->sr_ProhibitTimer = NULL;
-  schedulingrequestlist->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n64;
+  schedulingrequestlist->sr_ProhibitTimer = get_sr_ProhibitTimer(timer_config);
+  schedulingrequestlist->sr_TransMax = get_sr_TransMax(timer_config);
   asn1cSeqAdd(&(mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list),schedulingrequestlist);
 
+  if (timer_config->sr_ProhibitTimer_v1700 != 0) {
+    mac_CellGroupConfig->ext4 = calloc(1, sizeof(*mac_CellGroupConfig->ext4));
+    mac_CellGroupConfig->ext4->schedulingRequestConfig_v1700 =
+        calloc(1, sizeof(*mac_CellGroupConfig->ext4->schedulingRequestConfig_v1700));
+    mac_CellGroupConfig->ext4->schedulingRequestConfig_v1700->schedulingRequestToAddModListExt_v1700 =
+        calloc(1, sizeof(*mac_CellGroupConfig->ext4->schedulingRequestConfig_v1700->schedulingRequestToAddModListExt_v1700));
+    struct NR_SchedulingRequestToAddModExt_v1700 *schedulingrequestlist_v1700 = calloc(1, sizeof(*schedulingrequestlist_v1700));
+    schedulingrequestlist_v1700->sr_ProhibitTimer_v1700 = get_sr_ProhibitTimer_v1700(timer_config);
+    asn1cSeqAdd(&(mac_CellGroupConfig->ext4->schedulingRequestConfig_v1700->schedulingRequestToAddModListExt_v1700->list),
+                schedulingrequestlist_v1700);
+  }
+
   mac_CellGroupConfig->skipUplinkTxDynamic=false;
   mac_CellGroupConfig->ext1 = NULL;
   return mac_CellGroupConfig;
@@ -2577,8 +2852,8 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid,
   cellGroupConfig->rlc_BearerToReleaseList = NULL;
 
   /* mac CellGroup Config */
-  cellGroupConfig->mac_CellGroupConfig = configure_mac_cellgroup();
-  
+  cellGroupConfig->mac_CellGroupConfig = configure_mac_cellgroup(&configuration->timer_config);
+
   cellGroupConfig->physicalCellGroupConfig = configure_phy_cellgroup();
 
   cellGroupConfig->spCellConfig = get_initial_SpCellConfig(uid, scc, servingcellconfigdedicated, configuration);
@@ -2791,7 +3066,7 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
   secondaryCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*secondaryCellGroup->rlc_BearerToAddModList));
   asn1cSeqAdd(&secondaryCellGroup->rlc_BearerToAddModList->list, RLC_BearerConfig);
 
-  secondaryCellGroup->mac_CellGroupConfig = configure_mac_cellgroup();
+  secondaryCellGroup->mac_CellGroupConfig = configure_mac_cellgroup(&configuration->timer_config);
   secondaryCellGroup->physicalCellGroupConfig = configure_phy_cellgroup();
   secondaryCellGroup->spCellConfig = calloc(1, sizeof(*secondaryCellGroup->spCellConfig));
   secondaryCellGroup->spCellConfig->servCellIndex = calloc(1, sizeof(*secondaryCellGroup->spCellConfig->servCellIndex));
diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h
index d469638fcf932d4ce3db111e9bb2a54e33cd7dea..d46363c7073641a4ea9a7327a02d64ee6697c01d 100644
--- a/openair2/RRC/NR/nr_rrc_config.h
+++ b/openair2/RRC/NR/nr_rrc_config.h
@@ -38,6 +38,9 @@
 struct nr_mac_config_t;
 typedef struct nr_mac_config_t nr_mac_config_t;
 
+struct nr_mac_timers;
+typedef struct nr_mac_timers nr_mac_timers_t;
+
 void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsch_TimeDomainAllocationList,
                           frame_type_t frame_type,
                           NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,
@@ -63,7 +66,11 @@ int encode_MeasurementTimingConfiguration(const struct NR_MeasurementTimingConfi
 void free_MeasurementTimingConfiguration(struct NR_MeasurementTimingConfiguration *mtc);
 
 #define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1
-NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, const f1ap_plmn_t *plmn, uint64_t cellID, int tac);
+NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
+                                      const f1ap_plmn_t *plmn,
+                                      uint64_t cellID,
+                                      int tac,
+                                      const nr_mac_timers_t *timer_config);
 void free_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1);
 int encode_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1, uint8_t *buffer, int max_buffer_size);
 
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 8273a3a82a23b50cdcc8ddd26efd974d5fdf3bbf..0ad01d6e939acd7a2bf59d8949309a8279331c04 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
@@ -161,10 +161,23 @@ gNBs =
       nrofUplinkSymbols                                             = 4;
 
       ssPBCH_BlockPower                                             = -25;
+
+  #ext2
+    #ntn_Config_r17
+#      cellSpecificKoffset_r17                                       = 478;
   }
 
   );
 
+    TIMERS :
+    {
+      sr_ProhibitTimer       = 0;
+      sr_TransMax            = 64;
+#      sr_ProhibitTimer_v1700 = 512;
+#      t300                   = 2000;
+#      t301                   = 2000;
+#      t319                   = 2000;
+    };
 
     # ------- SCTP definitions
     SCTP :
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 4e27d924deda05cd18cfec40662fc222eb1e59a7..f29bbf9cf66f3a8e3b2aa18ef7f03ce66dbf245b 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
@@ -161,10 +161,23 @@ gNBs =
       nrofUplinkSymbols                                             = 4;
 
       ssPBCH_BlockPower                                             = -25;
+
+  #ext2
+    #ntn_Config_r17
+#      cellSpecificKoffset_r17                                       = 478;
   }
 
   );
 
+    TIMERS :
+    {
+      sr_ProhibitTimer       = 0;
+      sr_TransMax            = 64;
+#      sr_ProhibitTimer_v1700 = 512;
+#      t300                   = 2000;
+#      t301                   = 2000;
+#      t319                   = 2000;
+    };
 
     # ------- SCTP definitions
     SCTP :