/* lteenb configuration file version 2026-06-12
 * Copyright (C) 2019-2026 Amarisoft
 * NR SA FDD or TDD cell */


#define NR_TDD               1   // Values: 0 (NR FDD), 1(NR TDD)
#define FR2                  0   // Values: 0 (FR1), 1 (FR2)
#if FR2
#define UDC_TYPE             1   // Values: 0 (NO UDC), 1 (B2), 2 (A2), 3 (B4)  (refer to application note to identify your UDC type)
#define NR_TDD_CONFIG        10  // Values: FR1: 1, 2, 3, 4 (compatible with LTE TDD config 2) FR2: 10
#define NR_BANDWIDTH         100 // NR cell bandwidth
#define IF_ATTENUATION       -9  // Value: 10*log10(N_PORTS_COMBINER) + external eventual IF attenuators
#else
#define NR_TDD_CONFIG        2   // Values: FR1: 1, 2, 3, 4 (compatible with LTE TDD config 2) FR2: 10
#define NR_BANDWIDTH         30  // NR cell bandwidth
#endif
#define N_ANTENNA_DL         4   // Values: 1 (SISO), 2 (MIMO 2x2), 4 (MIMO 4x4)
#define N_ANTENNA_UL         4   // Values: 1, 2, 4
#define NR_LONG_PUCCH_FORMAT 0   // Values: 0 (automatic), 2, 3 or 4

/* define to 1 to enable periodic SRS with N_ANTENNA_UL ports. Uplink
   SU-MIMO is also enabled if N_ANTENNA_UL >= 2. Not all UEs support
   uplink SU-MIMO. */
#define USE_SRS             0

{
  //log_options: "all.level=debug,all.max_size=1",
  log_options: "all.level=error,all.max_size=0,s72.level=warn,nas.level=debug,ngap.level=debug,rrc.level=debug",

  log_filename: "/tmp/gnb0.log",

  /* Enable remote API and Web interface */
  com_addr: "[::]:9001",
  license_server: { server_addr: "10.50.0.8", tag: "gNB" },

  rf_driver: {
        name: "s72",
        /* COSMOS hosts run phc2sys -O 0: CLOCK_REALTIME is already TAI, so add nothing */
        tai_offset: 0,
        rf_ports: [{
            subcarrier_spacing: 30,
            max_pdu_size: 9000,
            /* vendor example values (trx_s72 2026-09-11 config.enb); ta3_max wide, like OCUDU's ta4_max 1960 */
            t1a_max_cp_dl: 400,
            t1a_max_up_dl: 200,
            t1a_min_cp_dl: 250,
            t1a_min_up_dl: 100,
            t1a_max_cp_ul: 400,
            t1a_min_cp_ul: 250,
            ta3_max: 300,
            transport: "ethernet",
            bind_interface: "DATA1a.4",   /* set by start72.sh (FH VLAN sub-iface) */
            remote_addr: "e8:c7:4f:25:89:39", /* O-RU fronthaul MAC */
        }],
  },
  tx_gain: 0, /* s72: power set at the RU */
  rx_gain: 0,

#if FR2 == 1 && UDC_TYPE != 0
  udc_ports: [
  {
    #if UDC_TYPE == 1  // B2 type
       #if N_ANTENNA_DL == 1  
          args: "/dev/ttyUSB0",
       #elif N_ANTENNA_DL == 2
          args: "/dev/ttyUSB0;/dev/ttyUSB1",
       #else    
          #error Unsupported number of MIMO layers in FR2
       #endif 
    #elif UDC_TYPE == 2  // A2 type
       #if N_ANTENNA_DL == 1
          args: "/dev/ttyACM0",
       #elif N_ANTENNA_DL == 2
          args: "/dev/ttyACM0;/dev/ttyACM1",
       #else
        #error Unsupported number of MIMO layers in FR2
       #endif
    #elif UDC_TYPE == 3  // B4 type
        args: "/dev/ttyUSB0",
    #else
       #warning No UDC used for FR2 testing
    #endif

    cmd: "udc-auto-cfg.sh",
  },
  ],
#endif

  amf_list: [
    {
      /* address of AMF for NGAP connection. Must be modified if the AMF runs on a different host. */
      amf_addr: "127.0.1.100",
      "5qi_dscp_mapping": [
        {
          "5qi": 1,
          dscp: 0x2e
        },
        {
          "5qi": 65,
          dscp: 0x2e
        }
      ]
    },
  ],
  /* GTP bind address (=address of the ethernet interface connected to
     the AMF). Must be modified if the AMF runs on a different host. */
  gtp_addr: "127.0.1.1",
#ifdef GTP_U_BUNDLING
  gtp_use_packet_bundling: true,
#endif

  gnb_id_bits: 28,
  gnb_id: 0x12345,

  en_dc_support: true,

  rf_ports: [
    {
      s72: {
        ud_comp_hdr: 0x91, /* BFP comp: 0x91=BF9, 0x81=BF8, 0xc1=BF12, 0=none */
        port_mapping_prach: [4, 5, 6, 7], /* LiteOn golden: PRACH eAxC 4,5,6,7 */
      },
    },
  ],

  /* list of cells */
  cell_list: [],

  nr_cell_list: [
  {
    /* 4 DL ports raise RSRP ~14 dB vs 1 port; advertise the SSB hotter so UE UL power compensates */
    manual_ref_signal_power: true,
    ss_pbch_block_power: -30,
    rf_port: 0,
    cell_id: 0x01,
#if NR_TDD == 1
#if FR2
    band: 257,
    dl_nr_arfcn: 2079167,  /* 28000.08 MHz */
    subcarrier_spacing: 120, /* kHz */
    ssb_pos_bitmap: "0100000000000000000000000000000000000000000000000000000000000000",

    rx_to_tx_latency: 9, /* slots */
#else
    band: 78,
    dl_nr_arfcn: 650000, /* carrier center NR-ARFCN */
    subcarrier_spacing: 30, /* kHz */
    ssb_subcarrier_spacing: 30,
    ssb_pos_bitmap: "10000000",
    rx_to_tx_latency: 8,
#endif
#else
#if NR_BANDWIDTH == 3
    band: 106,
    dl_nr_arfcn: 187500,  /* 937.5 */
    ssb_pos_bitmap: "0100",
#else
    band: 7,
    dl_nr_arfcn: 531000,  /* 2655 MHz */
    ssb_pos_bitmap: "1000",
#endif
    subcarrier_spacing: 15, /* kHz */
#endif
  },
  ], /* nr_cell_list */

  nr_cell_default: {
    bandwidth: NR_BANDWIDTH, /* MHz */
    n_antenna_dl: N_ANTENNA_DL,
    n_antenna_ul: N_ANTENNA_UL,

    /* force the timing TA offset (optional) */
//    n_timing_advance_offset: 39936,
    /* subframe offset to align with the LTE TDD pattern (optional) */
//    subframe_offset: 2,

#if NR_TDD == 1
    tdd_ul_dl_config: {
#if NR_TDD_CONFIG == 1
      pattern1: {
        period: 5, /* in ms */
        dl_slots: 7,
        dl_symbols: /* 6 */ 2,
        ul_slots: 2,
        ul_symbols: 2,
      },
#elif NR_TDD_CONFIG == 2
      pattern1: {
        period: 5, /* in ms - 15kHz: 5 slots, DDDSU */
        dl_slots: 3,
        dl_symbols: 10,
        ul_slots: 1,
        ul_symbols: 2,
      },
#elif NR_TDD_CONFIG == 3
      pattern1: {
        period: 5, /* in ms */
        dl_slots: 6,
        dl_symbols: 2,
        ul_slots: 3,
        ul_symbols: 2,
      },
#elif NR_TDD_CONFIG == 4
      pattern1: {
        period: 3, /* in ms */
        dl_slots: 3,
        dl_symbols: 6,
        ul_symbols: 4,
        ul_slots: 2,
      },
      pattern2: {
        period: 2, /* in ms */
        dl_slots: 4,
        dl_symbols: 0,
        ul_symbols: 0,
        ul_slots: 0,
      },
#elif NR_TDD_CONFIG == 10
      /* only for FR2 */
      pattern1: {
        period: 0.625, /* in ms */
        dl_slots: 3,
        dl_symbols: 10,
        ul_slots: 1,
        ul_symbols: 2,
      },
#endif
    },
#endif
    ssb_period: 20, /* in ms */
    n_id_cell: 500,

    plmn_list: [ {
      tac: 1,
      plmn: "00101",
      reserved: false,
      nssai: [
        {
         sst: 1,
        },
        /*{
         sst: 2,
        },
        {
         sst: 3,
         sd: 50,
        },*/
       ],
      },
    ],

    /*sib_sched_list: [
      {
        filename: "sib2_nr.asn",
        si_periodicity: 16,
      },
      {
        filename: "sib3_nr.asn",
        si_periodicity: 16,
      },
      {
        filename: "sib4_nr.asn",
        si_periodicity: 32,
      },
    ],
    sib9: {
      si_periodicity: 32
    },*/
    si_window_length: 40,

    cell_barred: false,
    intra_freq_reselection: true,
    q_rx_lev_min: -70,
    q_qual_min: -20,
    //p_max: 10, /* dBm */

    root_sequence_index: 1, /* PRACH root sequence index */

    /* Scheduling request period (slots). */
    sr_period: 40,

#if NR_BANDWIDTH == 3
    dmrs_type_a_pos: 3,
#else
    dmrs_type_a_pos: 2,
#endif

    /* to limit the number of HARQ feedback in UL, use pdsch_harq_ack_max;
       allows to workaround issues with SM-G977N for example */
    //pdsch_harq_ack_max: 2,

    prach: {
#if NR_TDD == 1
#if FR2
      prach_config_index: 149, /* format C0, every 4 frames */
      msg1_subcarrier_spacing: 120, /* kHz */
#else
#if NR_TDD_CONFIG == 4
      prach_config_index: 156, /* format B4, subframe 2 */
#else
      prach_config_index: 160, /* format B4, subframe 9 */
#endif
      msg1_subcarrier_spacing: 30, /* kHz */
#endif
#else
      prach_config_index: 16, /* subframe 1 every frame */
#endif
      msg1_fdm: 1,
      msg1_frequency_start: -1,
      zero_correlation_zone_config: 15,
      preamble_received_target_power: -110, /* in dBm */
      preamble_trans_max: 7,
      power_ramping_step: 4, /* in dB */
#if FR2 == 1
      ra_response_window: 40, /* in slots */
#elif NR_TDD == 1
      ra_response_window: 20, /* in slots */
#else
      ra_response_window: 10, /* in slots */
#endif
      restricted_set_config: "unrestricted_set",
      ra_contention_resolution_timer: 64, /* in ms */
      ssb_per_prach_occasion: 1,
      cb_preambles_per_ssb: 8,
    },

    pdcch: {
      search_space0_index: 0,

      dedicated_coreset: {
        rb_start: -1, /* -1 to have the maximum bandwidth */
        l_crb: -1, /* -1 means all the bandwidth */
        duration: 0, /* 0 means to automatically set it from the coreset bandwidth */
        precoder_granularity: "sameAsREG_bundle",
      },

      css: {
        n_candidates: [ 0, 0, 4, 0, 0 ],
      },
      rar_al_index: 2,
      si_al_index: 2,

      uss: {
        n_candidates: [ 0, 4, 0, 0, 0 ],
        dci_0_1_and_1_1: true,
      },
      al_index: 1,
    },

#if FR2
    k_min: 8,
#endif
    pdsch: {
      mapping_type: "typeA",
      dmrs_add_pos: 1,
      dmrs_type: 1,
      dmrs_max_len: 1,
      /* k0 delay in slots from DCI to PDSCH: automatic setting */
      /* k1 delay in slots from PDSCH to PUCCH/PUSCH ACK/NACK: automatic setting */
      mcs_table: "qam256",
      rar_mcs: 2,
      si_mcs: 6,
      /* If defined, force the PDSCH MCS for all UEs. Otherwise it is computed
       * based on DL channel quality estimation */
      /* mcs: 24, */
    },
    
    csi_rs: {
      resource_auto: {
        nzp_csi_rs_period: 80,
#if FR2
        trs_presence: false,
#endif
      },
      csi_report_config: [
        {
          report_config_type: "periodic",
          period: 80,
        },
      ],
    },
    
    pucch: {
      p0_nominal: -96,
      resource_auto: {
#if NR_LONG_PUCCH_FORMAT == 2
        formats: "format_0_and_2"
#elif NR_LONG_PUCCH_FORMAT == 3
        formats: "format_1_and_3"
#elif NR_LONG_PUCCH_FORMAT == 4
        formats: "format_1_and_4"
#endif
      }
    },

#if USE_SRS
    srs: {
      resource_auto: {
        codebook: {
          resource_type: "periodic",
          period: 80, /* in slots */
        }
      }
    },
#endif

    pusch: {
      mapping_type: "typeA",
      n_symb: 14,
      dmrs_add_pos: 1,
      dmrs_type: 1,
      dmrs_max_len: 1,
      tf_precoding: false,
      mcs_table: "qam256", /* without transform precoding */
      mcs_table_tp: "qam256", /* with transform precoding */
      ldpc_max_its: 5,
      /* k2, msg3_k2 delay in slots from DCI to PUSCH: automatic setting */
      p0_nominal_with_grant: -70, /* was -84: UE sat at PHR 38 dB, PUSCH SNR -3 */
      msg3_mcs: 4,
      msg3_delta_power: 0, /* in dB */
      beta_offset_ack_index: 9,
#if USE_SRS
      max_rank: N_ANTENNA_UL,
#endif

      /* if defined, force the PUSCH MCS for all UEs. Otherwise it is
       computed from the last received PUSCH. */
      /* mcs: 16, */
    },

    /* MAC configuration */
    mac_config: {
      msg3_max_harq_tx: 5,
      ul_max_harq_tx: 5, /* max number of HARQ transmissions for uplink */
      dl_max_harq_tx: 5, /* max number of HARQ transmissions for downlink */
      ul_max_consecutive_retx: 30, /* disconnect UE if reached */
      dl_max_consecutive_retx: 30, /* disconnect UE if reached */
      periodic_bsr_timer: 20,
      retx_bsr_timer: 320,
      periodic_phr_timer: 500,
      prohibit_phr_timer: 200,
      phr_tx_power_factor_change: "dB3",
      sr_prohibit_timer: 0, /* in ms, 0 to disable the timer */
      sr_trans_max: 64,
    },

    cipher_algo_pref: [],
    integ_algo_pref: [2, 1],

    inactivity_timer: 10000,

    drb_config: "drb_nr.cfg",
  },
}

