Change in osmo-gsm-tester[master]: amarisoft_enb: add NR support

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

srs_andre gerrit-no-reply at lists.osmocom.org
Tue May 4 15:37:12 UTC 2021


srs_andre has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-gsm-tester/+/24126 )


Change subject: amarisoft_enb: add NR support
......................................................................

amarisoft_enb: add NR support

this patch adds the ability to configure NR cells with
Amarisoft eNB. It adds the new DRB-NR template and updates
the normal enb.cfg template to allow using it as LTE only
or with NR cells (5G NSA).

Change-Id: Ia27bbc6db5920ce14bacabe8043601aa2adaa5fe
---
M doc/examples/4g_srsLTE/defaults.conf
M src/osmo_gsm_tester/obj/enb.py
M src/osmo_gsm_tester/obj/enb_amarisoft.py
A src/osmo_gsm_tester/templates/amarisoft_drb_nr.cfg.tmpl
M src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl
M src/osmo_gsm_tester/templates/amarisoft_rf_driver.cfg.tmpl
M sysmocom/defaults.conf
7 files changed, 933 insertions(+), 14 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/26/24126/1

diff --git a/doc/examples/4g_srsLTE/defaults.conf b/doc/examples/4g_srsLTE/defaults.conf
index 4a3b4c4..1d1f286 100644
--- a/doc/examples/4g_srsLTE/defaults.conf
+++ b/doc/examples/4g_srsLTE/defaults.conf
@@ -12,6 +12,7 @@
   mnc: 70
   transmission_mode: 1
   num_cells: 1
+  num_nr_cells: 0
   enable_measurements: false
   a1_report_type: rsrp
   a1_report_value: -105
diff --git a/src/osmo_gsm_tester/obj/enb.py b/src/osmo_gsm_tester/obj/enb.py
index 252fa14..e976753 100644
--- a/src/osmo_gsm_tester/obj/enb.py
+++ b/src/osmo_gsm_tester/obj/enb.py
@@ -68,12 +68,18 @@
         'cell_list[].ncell_list[].pci': schema.UINT,
         'cell_list[].ncell_list[].dl_earfcn': schema.UINT,
         'cell_list[].scell_list[]': schema.UINT,
+        'cell_list[].nr_scell_list[]': schema.UINT,
         'cell_list[].dl_earfcn': schema.UINT,
         'cell_list[].root_seq_idx': schema.UINT,
         'cell_list[].tac': schema.UINT,
         'cell_list[].dl_rfemu.type': schema.STR,
         'cell_list[].dl_rfemu.addr': schema.IPV4,
         'cell_list[].dl_rfemu.ports[]': schema.UINT,
+        'num_nr_cells': schema.UINT,
+        'nr_cell_list[].rf_port': schema.UINT,
+        'nr_cell_list[].cell_id': schema.UINT,
+        'nr_cell_list[].band': schema.UINT,
+        'nr_cell_list[].dl_nr_arfcn': schema.UINT,
         }
     for key, val in run_node.RunNode.schema().items():
         resource_schema['run_node.%s' % key] = val
@@ -98,9 +104,11 @@
             self.set_name('%s_%s' % (name, self._run_node.run_addr()))
         self._txmode = 0
         self._id = None
+        self._ran_config = "lte" # Used to determine whether we are in NSA
         self._duplex = None
         self._num_prb = 0
         self._num_cells = None
+        self._num_nr_cells = None
         self._epc = None
         self.gen_conf = None
         self.gr_broker = GrBroker.ref()
@@ -126,10 +134,11 @@
 
     def calc_required_zmq_ports(self, cfg_values):
         cell_list = cfg_values['enb']['cell_list']
-        return len(cell_list) * self.num_ports() # *2 if MIMO
+        nr_cell_list = cfg_values['enb']['nr_cell_list']
+        return len(cell_list) * self.num_ports() + len(nr_cell_list) # *2 if LTE MIMO
 
     def calc_required_zmq_ports_joined_earfcn(self, cfg_values):
-        #gr_broker will join the earfcns, so we need to count uniqe earfcns:
+        #gr_broker will join the earfcns, so we need to count unique earfcns (only implemented for LTE):
         cell_list = cfg_values['enb']['cell_list']
         earfcn_li = []
         [earfcn_li.append(int(cell['dl_earfcn'])) for cell in cell_list if int(cell['dl_earfcn']) not in earfcn_li]
@@ -142,6 +151,10 @@
         for cell in cell_list:
             cell[port_name] = base_port + port_offset
             port_offset += self.num_ports()
+        nr_cell_list = cfg_values['enb']['nr_cell_list']
+        for nr_cell in nr_cell_list:
+            nr_cell[port_name] = base_port + port_offset
+            port_offset += 1
         # TODO: do we need to assign cell_list back?
 
     def assign_enb_zmq_ports_joined_earfcn(self, cfg_values, port_name, base_port):
@@ -176,7 +189,9 @@
         config.overlay(values, dict(enb={ 'mme_addr': self._epc.addr() }))
         config.overlay(values, dict(enb={ 'gtp_bind_addr': self._gtp_bind_addr }))
         self._num_cells = int(values['enb'].get('num_cells', None))
-        assert self._num_cells
+        self._num_nr_cells = int(values['enb'].get('num_nr_cells', None))
+        assert self._num_cells is not None
+        assert self._num_nr_cells is not None
 
         # adjust cell_list to num_cells length:
         len_cell_list = len(values['enb']['cell_list'])
@@ -231,6 +246,9 @@
     def num_cells(self):
         return self._num_cells
 
+    def num_nr_cells(self):
+        return self._num_nr_cells
+
 ########################
 # PUBLIC - INTERNAL API
 ########################
@@ -280,6 +298,13 @@
                 rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx + 1, ul_rem_addr, cell['zmq_enb_peer_port'] + 1)
             idx += self.num_ports()
 
+        # Only single antenna supported for NR cells
+        nr_cell_list = cfg_values['enb']['nr_cell_list']
+        for nr_cell in nr_cell_list:
+            rf_dev_args += ',tx_port%u=tcp://%s:%u' % (idx, self.addr(), nr_cell['zmq_enb_bind_port'] + 0)
+            rf_dev_args += ',rx_port%u=tcp://%s:%u' % (idx, ul_rem_addr, nr_cell['zmq_enb_peer_port'] + 0)
+            idx += 1
+
         rf_dev_args += ',id=enb,base_srate=' + str(base_srate)
         return rf_dev_args
 
@@ -300,6 +325,14 @@
             if self.num_ports() > 1:
                 rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx + 1, self.addr(), cell['zmq_ue_peer_port'] + 1)
             idx += self.num_ports()
+
+        # NR cells again only with single antenna support
+        nr_cell_list = self.gen_conf['enb']['nr_cell_list']
+        for nr_cell in nr_cell_list:
+            rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx, ue.addr(), nr_cell['zmq_ue_bind_port'] + 0)
+            rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx, self.addr(), nr_cell['zmq_ue_peer_port'] + 0)
+            idx += 1
+
         # remove trailing comma:
         if rf_dev_args[0] == ',':
             return rf_dev_args[1:]
diff --git a/src/osmo_gsm_tester/obj/enb_amarisoft.py b/src/osmo_gsm_tester/obj/enb_amarisoft.py
index 405ed68..34ab5c1 100644
--- a/src/osmo_gsm_tester/obj/enb_amarisoft.py
+++ b/src/osmo_gsm_tester/obj/enb_amarisoft.py
@@ -22,6 +22,7 @@
 
 from ..core import log, util, config, template, process, remote
 from ..core import schema
+from ..core.event_loop import MainLoop
 from . import enb
 from . import rfemu
 
@@ -33,12 +34,16 @@
 
     config_schema = {
         'log_options': schema.STR,
+        'nr_bandwidth': schema.INT,
         }
     schema.register_config_schema('amarisoftenb', config_schema)
 
 def rf_type_valid(rf_type_str):
     return rf_type_str in ('uhd', 'zmq', 'sdr')
 
+def ran_type_valid(ran_type_str):
+    return ran_type_str in ('lte', '5g_nsa')
+
 class AmarisoftENB(enb.eNodeB):
 
     REMOTE_DIR = '/osmo-gsm-tester-amarisoftenb'
@@ -48,6 +53,7 @@
     CFGFILE_SIB23 = 'amarisoft_sib23.asn'
     CFGFILE_RF = 'amarisoft_rf_driver.cfg'
     CFGFILE_DRB = 'amarisoft_drb.cfg'
+    CFGFILE_DRB_NR = 'amarisoft_drb_nr.cfg'
     LOGFILE = 'lteenb.log'
     PHY_SIGNAL_FILE = 'lteenb.log.bin'
 
@@ -63,6 +69,7 @@
         self.config_sib23_file = None
         self.config_rf_file = None
         self.config_drb_file = None
+        self.config_drb_nr_file = None
         self.log_file = None
         self.process = None
         self.rem_host = None
@@ -72,8 +79,11 @@
         self.remote_config_sib23_file = None
         self.remote_config_rf_file = None
         self.remote_config_drb_file = None
+        self.remote_config_drb_nr_file = None
         self.remote_log_file = None
         self.enable_measurements = False
+        self.nr_bandwidth = None
+        self.ran_type = None
         self.testenv = testenv
         if not rf_type_valid(conf.get('rf_dev_type', None)):
             raise log.Error('Invalid rf_dev_type=%s' % conf.get('rf_dev_type', None))
@@ -131,8 +141,8 @@
         self.process.launch()
 
     def stop(self):
-        # Not implemented
-        pass
+        # Allow for some time to flush logs
+        MainLoop.sleep(5)
 
     def gen_conf_file(self, path, filename, values):
         self.dbg('AmarisoftENB ' + filename + ':\n' + pprint.pformat(values))
@@ -151,6 +161,7 @@
         self.config_sib23_file = self.run_dir.child(AmarisoftENB.CFGFILE_SIB23)
         self.config_rf_file = self.run_dir.child(AmarisoftENB.CFGFILE_RF)
         self.config_drb_file = self.run_dir.child(AmarisoftENB.CFGFILE_DRB)
+        self.config_drb_nr_file = self.run_dir.child(AmarisoftENB.CFGFILE_DRB_NR)
         self.log_file = self.run_dir.child(AmarisoftENB.LOGFILE)
         self.phy_signal_file = self.run_dir.child(AmarisoftENB.PHY_SIGNAL_FILE)
 
@@ -165,6 +176,7 @@
             self.remote_config_sib23_file = remote_run_dir.child(AmarisoftENB.CFGFILE_SIB23)
             self.remote_config_rf_file = remote_run_dir.child(AmarisoftENB.CFGFILE_RF)
             self.remote_config_drb_file = remote_run_dir.child(AmarisoftENB.CFGFILE_DRB)
+            self.remote_config_drb_nr_file = remote_run_dir.child(AmarisoftENB.CFGFILE_DRB_NR)
             self.remote_log_file = remote_run_dir.child(AmarisoftENB.LOGFILE)
             self.remote_phy_signal_file = remote_run_dir.child(AmarisoftENB.PHY_SIGNAL_FILE)
 
@@ -176,6 +188,17 @@
 
         config.overlay(values, dict(enb={'enable_dl_awgn': util.str2bool(values['enb'].get('enable_dl_awgn', 'false'))}))
 
+        self.nr_bandwidth = int(values['enb'].get('nr_bandwidth', 10))
+        config.overlay(values, dict(enb={'nr_bandwidth': self.nr_bandwidth}))
+
+        if (self._num_cells > 0):
+            if (self._num_nr_cells <= 0):
+                self.ran_type = "lte"
+            else:
+                self.ran_type = "nsa"
+        else:
+            raise log.Error('5G SA not supported yet')
+
         # Remove EEA0 from cipher list, if specified, as it's always assumed as default
         cipher_list = values['enb'].get('cipher_list', None)
         if "eea0" in cipher_list: cipher_list.remove("eea0")
@@ -237,6 +260,7 @@
         self.gen_conf_file(self.config_sib23_file, AmarisoftENB.CFGFILE_SIB23, values)
         self.gen_conf_file(self.config_rf_file, AmarisoftENB.CFGFILE_RF, values)
         self.gen_conf_file(self.config_drb_file, AmarisoftENB.CFGFILE_DRB, values)
+        self.gen_conf_file(self.config_drb_nr_file, AmarisoftENB.CFGFILE_DRB_NR, values)
 
         if not self._run_node.is_local():
             self.rem_host.recreate_remote_dir(self.remote_inst)
@@ -247,6 +271,7 @@
             self.rem_host.scp('scp-cfg-sib23-to-remote', self.config_sib23_file, self.remote_config_sib23_file)
             self.rem_host.scp('scp-cfg-rr-to-remote', self.config_rf_file, self.remote_config_rf_file)
             self.rem_host.scp('scp-cfg-drb-to-remote', self.config_drb_file, self.remote_config_drb_file)
+            self.rem_host.scp('scp-cfg-drb-nr-to-remote', self.config_drb_nr_file, self.remote_config_drb_nr_file)
 
     def ue_add(self, ue):
         if self.ue is not None:
@@ -279,11 +304,17 @@
         rfemu_obj = rfemu.get_instance_by_type(rfemu_cfg['type'], rfemu_cfg)
         return rfemu_obj
 
+    def get_nr_bandwidth(self):
+        return self.nr_bandwidth
+
     def ue_max_rate(self, downlink=True, num_carriers=1):
-        if self._duplex == 'fdd':
-            return self.ue_max_rate_fdd(downlink, num_carriers)
+        if self.ran_type == 'lte':
+            if self._duplex == 'fdd':
+                return self.ue_max_rate_fdd(downlink, num_carriers)
+            else:
+                return self.ue_max_rate_tdd(downlink, num_carriers)
         else:
-            return self.ue_max_rate_tdd(downlink, num_carriers)
+            return self.ue_max_rate_nsa_tdd(downlink)
 
     def ue_max_rate_fdd(self, downlink, num_carriers):
         # The max rate for a single UE per PRB configuration in TM1 with MCS 28 QAM64
@@ -323,7 +354,7 @@
         return max_rate
 
     def ue_max_rate_tdd(self, downlink, num_carriers):
-        # Max rate calculation for TDD depends on the acutal TDD configuration
+        # Max rate calculation for TDD depends on the actual TDD configuration
         # See: https://www.sharetechnote.com/html/Handbook_LTE_ThroughputCalculationExample_TDD.html
         # and https://i0.wp.com/www.techtrained.com/wp-content/uploads/2017/09/Blog_Post_1_TDD_Max_Throughput_Theoretical.jpg
         max_phy_rate_tdd_uldl_config0_sp0 = { 6 : 1.5e6,
@@ -333,8 +364,21 @@
                                75 : 18.4e6,
                                100 : 54.5e6 }
         if downlink:
-            max_rate = max_phy_rate_tdd_uldl_config0_sp0[self.num_prb()]
+            return max_phy_rate_tdd_uldl_config0_sp0[self.num_prb()]
         else:
             return 1e6 # dummy value, we need to replace that later
 
+    def ue_max_rate_nsa_tdd(self, downlink):
+        # Max rate calculation based on https://5g-tools.com/5g-nr-throughput-calculator/
+        # Only FR1 15kHz SCS, QAM64, 6 DL slots, 3 UL slots
+        max_phy_rate_nsa_dl_fr1_15khz = { 10: 18.4e6,
+                                          20: 38.0e6 }
+        max_phy_rate_nsa_ul_fr1_15khz = { 10: 10.7e6,
+                                          20: 23.0e6 }
+
+        if downlink:
+            return max_phy_rate_nsa_dl_fr1_15khz[self.get_nr_bandwidth()]
+        else:
+            return max_phy_rate_nsa_ul_fr1_15khz[self.get_nr_bandwidth()]
+
 # vim: expandtab tabstop=4 shiftwidth=4
diff --git a/src/osmo_gsm_tester/templates/amarisoft_drb_nr.cfg.tmpl b/src/osmo_gsm_tester/templates/amarisoft_drb_nr.cfg.tmpl
new file mode 100644
index 0000000..82f3b8c
--- /dev/null
+++ b/src/osmo_gsm_tester/templates/amarisoft_drb_nr.cfg.tmpl
@@ -0,0 +1,423 @@
+/* DRB configuration for each QCI value.
+   QCI characteristics in TS 23.203 table 6.1.7 */
+[
+  /**************************************** GBR */
+  {
+    qci: 1, /* UM - real time (RTP for VOIP) */
+    use_for_en_dc: false,
+    pdcp_config: {
+      discardTimer: 100, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 12,
+      pdcp_SN_SizeDL: 12,
+      statusReportRequired: false,
+      outOfOrderDelivery: false,
+      t_Reordering: 0,
+      /* ROHC header compression */
+      /*
+      headerCompression: {
+        maxCID: 15,
+        profile0x0001: true, // RTP profile
+        profile0x0002: true, // UDP profile
+        profile0x0004: false, // IP profile
+      },
+      */
+    },
+    rlc_config: {
+      ul_um: {
+        sn_FieldLength: 6,
+      },
+      dl_um: {
+        sn_FieldLength: 6,
+        t_Reassembly: 50,
+      },
+    },
+    logical_channel_config: {
+      priority: 7,
+      prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 1,
+    },
+  },
+  {
+    qci: 2, /* UM - real time (video) */
+    pdcp_config: {
+      discardTimer: 150, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: false,
+      outOfOrderDelivery: false,
+      t_Reordering: 0,
+    },
+    rlc_config: {
+      ul_um: {
+        sn_FieldLength: 12,
+      },
+      dl_um: {
+        sn_FieldLength: 12,
+        t_Reassembly: 50,
+      },
+    },
+    logical_channel_config: {
+      priority: 8,
+      prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 1,
+    },
+  },
+  {
+    qci: 3, /* UM - real time (gaming) */
+    pdcp_config: {
+      discardTimer: 100, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: false,
+      outOfOrderDelivery: false,
+      t_Reordering: 0,
+    },
+    rlc_config: {
+      ul_um: {
+        sn_FieldLength: 12,
+      },
+      dl_um: {
+        sn_FieldLength: 12,
+        t_Reassembly: 50,
+      },
+    },
+    logical_channel_config: {
+      priority: 7,
+      prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 2,
+    },
+  },
+  {
+    qci: 4, /* AM - Non-Conversational Video (Buffered Streaming) */
+    pdcp_config: {
+      discardTimer: 0, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: true,
+      outOfOrderDelivery: false,
+    },
+    rlc_config: {
+      ul_am: {
+        sn_FieldLength: 18,
+        t_PollRetransmit: 80, /* in ms */
+        pollPDU: 64,
+        pollByte: 125, /* in kBytes, 0 means infinity */
+        maxRetxThreshold: 4,
+      },
+      dl_am: {
+        sn_FieldLength: 18,
+        t_Reassembly: 80, /* in ms */
+        t_StatusProhibit: 10, /* in ms */
+      },
+    },
+    logical_channel_config: {
+      priority: 9,
+      prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 3,
+    },
+  },
+  {
+    qci: 65, /* UM - real time (MC-PTT voice) */
+    use_for_en_dc: false,
+    pdcp_config: {
+      discardTimer: 100, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 12,
+      pdcp_SN_SizeDL: 12,
+      statusReportRequired: false,
+      outOfOrderDelivery: false,
+      t_Reordering: 0,
+      /* ROHC header compression */
+      /*
+      headerCompression: {
+        maxCID: 15,
+        profile0x0001: true, // RTP profile
+        profile0x0002: true, // UDP profile
+        profile0x0004: false, // IP profile
+      },
+      */
+    },
+    rlc_config: {
+      ul_um: {
+        sn_FieldLength: 6,
+      },
+      dl_um: {
+        sn_FieldLength: 6,
+        t_Reassembly: 50,
+      },
+    },
+    logical_channel_config: {
+      priority: 5,
+      prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 4,
+    },
+  },
+  {
+    qci: 66, /* UM - real time (non MC-PTT voice) */
+    use_for_en_dc: false,
+    pdcp_config: {
+      discardTimer: 150, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: false,
+      outOfOrderDelivery: false,
+      t_Reordering: 0,
+    },
+    rlc_config: {
+      ul_um: {
+        sn_FieldLength: 12,
+      },
+      dl_um: {
+        sn_FieldLength: 12,
+        t_Reassembly: 50,
+      },
+    },
+    logical_channel_config: {
+      priority: 7,
+      prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 4,
+    },
+  },
+  {
+    qci: 67, /* UM - Mission Critical Video user plane */
+    use_for_en_dc: false,
+    pdcp_config: {
+      discardTimer: 100, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: false,
+      outOfOrderDelivery: false,
+      t_Reordering: 0,
+    },
+    rlc_config: {
+      ul_um: {
+        sn_FieldLength: 12,
+      },
+      dl_um: {
+        sn_FieldLength: 12,
+        t_Reassembly: 50,
+      },
+    },
+    logical_channel_config: {
+      priority: 6,
+      prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 5,
+    },
+  },
+  /**************************************** non GBR */
+  {
+    qci: 5, /* AM - high priority (SIP) */
+    use_for_en_dc: false,
+    pdcp_config: {
+      discardTimer: 0, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: true,
+      outOfOrderDelivery: false,
+    },
+    rlc_config: {
+      ul_am: {
+        sn_FieldLength: 18,
+        t_PollRetransmit: 80, /* in ms */
+        pollPDU: 64,
+        pollByte: 125, /* in kBytes, 0 means infinity */
+        maxRetxThreshold: 4,
+      },
+      dl_am: {
+        sn_FieldLength: 18,
+        t_Reassembly: 80, /* in ms */
+        t_StatusProhibit: 10, /* in ms */
+      },
+    },
+    logical_channel_config: {
+      priority: 6,
+      prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 4,
+    },
+  },
+  {
+    qci: 6, /* AM - Video (buffered streaming) */
+    pdcp_config: {
+      discardTimer: 0, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: true,
+      outOfOrderDelivery: false,
+    },
+    rlc_config: {
+      ul_am: {
+        sn_FieldLength: 18,
+        t_PollRetransmit: 80, /* in ms */
+        pollPDU: 64,
+        pollByte: 125, /* in kBytes, 0 means infinity */
+        maxRetxThreshold: 4,
+      },
+      dl_am: {
+        sn_FieldLength: 18,
+        t_Reassembly: 80, /* in ms */
+        t_StatusProhibit: 10, /* in ms */
+      },
+    },
+    logical_channel_config: {
+      priority: 10,
+      prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 5,
+    },
+  },
+  {
+    qci: 7, /* UM - voice, video (live streaming), interactive gaming */
+    pdcp_config: {
+      discardTimer: 100, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: false,
+      outOfOrderDelivery: false,
+      t_Reordering: 0,
+    },
+    rlc_config: {
+      ul_um: {
+        sn_FieldLength: 12,
+      },
+      dl_um: {
+        sn_FieldLength: 12,
+        t_Reassembly: 50,
+      },
+    },
+    logical_channel_config: {
+      priority: 11,
+      prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 6,
+    },
+  },
+  {
+    qci: 8, /* AM - best effort (Internet traffic) */
+    pdcp_config: {
+      discardTimer: 0, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: true,
+      outOfOrderDelivery: false,
+    },
+    rlc_config: {
+      ul_am: {
+        sn_FieldLength: 18,
+        t_PollRetransmit: 80, /* in ms */
+        pollPDU: 64,
+        pollByte: 125, /* in kBytes, 0 means infinity */
+        maxRetxThreshold: 4,
+      },
+      dl_am: {
+        sn_FieldLength: 18,
+        t_Reassembly: 80, /* in ms */
+        t_StatusProhibit: 10, /* in ms */
+      },
+    },
+    logical_channel_config: {
+      priority: 12,
+      prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 7,
+    },
+  },
+  {
+    qci: 9, /* AM - best effort (Internet traffic) */
+    pdcp_config: {
+      discardTimer: 0, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: true,
+      outOfOrderDelivery: false,
+    },
+    rlc_config: {
+      ul_am: {
+        sn_FieldLength: 18,
+        t_PollRetransmit: 80, /* in ms */
+        pollPDU: 64,
+        pollByte: 125, /* in kBytes, 0 means infinity */
+        maxRetxThreshold: 4,
+      },
+      dl_am: {
+        sn_FieldLength: 18,
+        t_Reassembly: 80, /* in ms */
+        t_StatusProhibit: 10, /* in ms */
+      },
+    },
+    logical_channel_config: {
+      priority: 13,
+      prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 7,
+    },
+  },
+  {
+    qci: 69, /* AM - high priority (MC-PTT signalling) */
+    use_for_en_dc: false,
+    pdcp_config: {
+      discardTimer: 0, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: true,
+      outOfOrderDelivery: false,
+    },
+    rlc_config: {
+      ul_am: {
+        sn_FieldLength: 18,
+        t_PollRetransmit: 80, /* in ms */
+        pollPDU: 64,
+        pollByte: 125, /* in kBytes, 0 means infinity */
+        maxRetxThreshold: 4,
+      },
+      dl_am: {
+        sn_FieldLength: 18,
+        t_Reassembly: 80, /* in ms */
+        t_StatusProhibit: 10, /* in ms */
+      },
+    },
+    logical_channel_config: {
+      priority: 4,
+      prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 4,
+    },
+  },
+  {
+    qci: 70, /* AM - MC data */
+    use_for_en_dc: false,
+    pdcp_config: {
+      discardTimer: 0, /* in ms, 0 means infinity */
+      pdcp_SN_SizeUL: 18,
+      pdcp_SN_SizeDL: 18,
+      statusReportRequired: true,
+      outOfOrderDelivery: false,
+    },
+    rlc_config: {
+      ul_am: {
+        sn_FieldLength: 18,
+        t_PollRetransmit: 80, /* in ms */
+        pollPDU: 64,
+        pollByte: 125, /* in kBytes, 0 means infinity */
+        maxRetxThreshold: 4,
+      },
+      dl_am: {
+        sn_FieldLength: 18,
+        t_Reassembly: 80, /* in ms */
+        t_StatusProhibit: 10, /* in ms */
+      },
+    },
+    logical_channel_config: {
+      priority: 11,
+      prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
+      bucketSizeDuration: 100, /* in ms */
+      logicalChannelGroup: 5,
+    },
+  },
+]
diff --git a/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl b/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl
index 2c6fcc0..241eed2 100644
--- a/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl
+++ b/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl
@@ -1,6 +1,5 @@
-/* lteenb configuration file version 2018-10-18
- * Copyright (C) 2015-2018 Amarisoft
- */
+/* OGT templated version of the lteenb configuration file for 4G and 5G NSA */
+
 {
 
 %if enb.license_server_addr != '0.0.0.0':
@@ -64,10 +63,15 @@
   /* high 20 bits of SIB1.cellIdentifier */
   enb_id: ${enb.id},
 
+% if int(enb.num_nr_cells) > 0:
+  nr_support: true,
+% endif
+
   /* list of cells */
   cell_list: [
 
 %for cell in enb.cell_list:
+%if loop.index == 0:
   {
     dl_earfcn: ${cell.dl_earfcn},
     rf_port: ${cell.rf_port},
@@ -87,10 +91,32 @@
       { cell_id: ${scell_id}, cross_carrier_scheduling: false, scheduling_cell_id: ${cell.cell_id}, ul_allowed: true},
 %endfor
     ],
+
+    nr_scell_list: [
+%for nr_scell_id in cell.nr_scell_list:
+      { cell_id: ${nr_scell_id} },
+%endfor
+    ],
   },
+%endif
 %endfor
   ], /* cell_list */
 
+  nr_cell_list: [
+
+%for nr_cell in enb.nr_cell_list:
+  %if loop.index == 0:
+    {
+      rf_port: ${nr_cell.rf_port},
+      cell_id: ${nr_cell.cell_id},
+      band: ${nr_cell.band},
+      dl_nr_arfcn: ${nr_cell.dl_nr_arfcn},
+    },
+  %endif
+%endfor
+
+  ], /* nr_cell_list */
+
   /* default cell parameters */
   cell_default: {
     /* Broadcasted PLMN identities */
@@ -143,6 +169,9 @@
        computed from the reported CQI */
     /* pdsch_mcs: 12, */
 
+    prach_config_index: 4, /* subframe 4 every 10 ms */
+    prach_freq_offset: 0, /* -1 means automatic */
+
     /* PUSCH dedicated config (currently same for all UEs) */
     pusch_dedicated: {
       beta_offset_ack_index: 9,
@@ -154,7 +183,11 @@
     pusch_msg3_mcs: 0,
 
     /* this CQI value is assumed when none is received from the UE */
+% if enb.num_prb == 6:
     initial_cqi: 5,
+% else:
+    initial_cqi: 3,
+% endif
 
     /* if defined, force the PUSCH MCS for all UEs. Otherwise it is
        computed from the last received SRS/PUSCH. */
@@ -162,6 +195,9 @@
 
     transmission_mode: ${enb.transmission_mode},
 
+    dl_256qam: true,
+    ul_64qam: true,
+
     /* Scheduling request period (ms). Must be >= 40 for HD-FDD */
     sr_period: 20,
 
@@ -188,6 +224,9 @@
         // tdd_ack_nack_feedback_mode_r10: "cs",
 % endif
 
+        n1_pucch_sr_count: 11, /* increase if more UEs are needed */
+        cqi_pucch_n_rb: 1, /* increase if more UEs are needed */
+
         /* number of PUCCH 1b CS resources. It determines
            the maximum number of UEs that can be scheduled in one TTI
            using carrier aggregation with PUCCH 1b CS ack/nack feedback. */
@@ -266,6 +305,12 @@
         a3_offset: ${enb.a3_report_value},
         a3_hysteresis: ${enb.a3_hysteresis},
         a3_time_to_trigger: ${enb.a3_time_to_trigger},
+        // NR events hard-coded
+        nr_b1_report_type: "rsrp",
+        nr_b1_rsrp: -100,
+        nr_b1_hysteresis: 0,
+        nr_b1_time_to_trigger: 100,
+        nr_rsrp_filter_coeff: 3
     },
 
     /* measurement gap configuration */
@@ -276,4 +321,355 @@
     ho_from_meas: true,
 % endif
   },
-}
+
+   nr_cell_default: {
+    subcarrier_spacing: 15, /* kHz */
+    ssb_subcarrier_spacing: 30,
+    bandwidth: ${enb.nr_bandwidth}, /* MHz */
+    n_antenna_dl: 1,
+    n_antenna_ul: 1,
+
+    /* force the timing TA offset (optional) */
+    n_timing_advance_offset: 0,
+
+    tdd_ul_dl_config: {
+      pattern1: {
+        period: 10,
+        dl_slots: 6,
+        dl_symbols: 0,
+        ul_slots: 3,
+        ul_symbols: 0,
+      },
+    },
+    ssb_pos_bitmap: "10000000",
+    ssb_period: 20, /* in ms */
+    n_id_cell: 500,
+
+    root_sequence_index: 1, /* PRACH root sequence index */
+
+    /* Scheduling request period (slots). */
+    sr_period: 40,
+
+    dmrs_type_a_pos: 2,
+
+    /* 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: {
+      prach_config_index: 0,
+      msg1_subcarrier_spacing: 15, /* kHz */
+      msg1_fdm: 1,
+% if int(enb.nr_bandwidth) == 10:
+      msg1_frequency_start: 1,
+% else:
+      msg1_frequency_start: 3,
+% endif
+      zero_correlation_zone_config: 0,
+      preamble_received_target_power: -110, /* in dBm */
+      preamble_trans_max: 7,
+      power_ramping_step: 4, /* in dB */
+      ra_response_window: 10, /* in slots */
+      restricted_set_config: "unrestricted_set",
+      ra_contention_resolution_timer: 64, /* in ms */
+      ssb_per_prach_occasion: 1,
+      cb_preambles_per_ssb: 8,
+    },
+
+    pdcch: {
+      common_coreset: {
+        rb_start: -1, /* -1 to have the maximum bandwidth */
+        l_crb: -1, /* -1 means all the bandwidth */
+        duration: 1,
+        precoder_granularity: "sameAsREG_bundle",
+        //dmrs_scid: 0,
+      },
+
+      dedicated_coreset: {
+        rb_start: -1, /* -1 to have the maximum bandwidth */
+        l_crb: -1, /* -1 means all the bandwidth */
+        duration: 1,
+        precoder_granularity: "sameAsREG_bundle",
+        //dmrs_scid: 0,
+      },
+
+      css: {
+        n_candidates: [ 1, 1, 1, 0, 0 ],
+      },
+      rar_al_index: 2,
+
+      uss: {
+        n_candidates: [ 0, 2, 1, 0, 0 ],
+        dci_0_1_and_1_1: false,
+        force_dci_0_0: true, // Forces DCI format 0_0 for Uplink
+        force_dci_1_0: true, // Forces DCI format 1_0 for Downlink
+      },
+      al_index: 1,
+    },
+
+    pdsch: {
+      mapping_type: "typeA",
+      start_symb: 1,
+      n_symb: 13,
+      dmrs_add_pos: 1,
+      dmrs_type: 1,
+      dmrs_max_len: 1,
+      k0: 0, /* delay in slots from DCI to PDSCH */
+      /* delay in slots from PDSCH to PUCCH/PUSCH ACK/NACK */
+      k1: [ 8, 7, 6, 6, 5, 4],
+      mcs_table: "qam64",
+
+      rar_mcs: 2,
+      /* If defined, force the PDSCH MCS for all UEs. Otherwise it is computed
+       * based on DL channel quality estimation */
+      /* mcs: 24, */
+    },
+
+    csi_rs: {
+      nzp_csi_rs_resource: [
+        {
+          csi_rs_id: 0,
+          n_ports: 1,
+          frequency_domain_allocation: "row2",
+          bitmap: "100000000000",
+          cdm_type: "no_cdm",
+          density: 1,
+          first_symb: 4,
+          rb_start: 0,
+          l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
+          power_control_offset: 0, /* dB */
+          power_control_offset_ss: 0, /* dB */
+          scrambling_id: 0,
+          period: 80,
+          offset: 1, /* != 0 to avoid collision with SSB */
+          qcl_info_periodic_csi_rs: 0,
+        },
+#define USE_TRS        
+#ifdef USE_TRS
+        /* TRS : period of 40 ms, slots 1 & 2, symbols 4 and 8 */
+        {
+          csi_rs_id: 1,
+          n_ports: 1,
+          frequency_domain_allocation: "row1",
+          bitmap: "0001",
+          cdm_type: "no_cdm",
+          density: 3,
+          first_symb: 4,
+          rb_start: 0,
+          l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
+          power_control_offset: 0, /* dB */
+          power_control_offset_ss: 0, /* dB */
+          scrambling_id: 0,
+          period: 40,
+          offset: 11,
+          qcl_info_periodic_csi_rs: 0,
+        },
+        {
+          csi_rs_id: 2,
+          n_ports: 1,
+          frequency_domain_allocation: "row1",
+          bitmap: "0001",
+          cdm_type: "no_cdm",
+          density: 3,
+          first_symb: 8,
+          rb_start: 0,
+          l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
+          power_control_offset: 0, /* dB */
+          power_control_offset_ss: 0, /* dB */
+          scrambling_id: 0,
+          period: 40,
+          offset: 11,
+          qcl_info_periodic_csi_rs: 0,
+        },
+        {
+          csi_rs_id: 3,
+          n_ports: 1,
+          frequency_domain_allocation: "row1",
+          bitmap: "0001",
+          cdm_type: "no_cdm",
+          density: 3,
+          first_symb: 4,
+          rb_start: 0,
+          l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
+          power_control_offset: 0, /* dB */
+          power_control_offset_ss: 0, /* dB */
+          scrambling_id: 0,
+          period: 40,
+          offset: 12,
+          qcl_info_periodic_csi_rs: 0,
+        },
+        {
+          csi_rs_id: 4,
+          n_ports: 1,
+          frequency_domain_allocation: "row1",
+          bitmap: "0001",
+          cdm_type: "no_cdm",
+          density: 3,
+          first_symb: 8,
+          rb_start: 0,
+          l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
+          power_control_offset: 0, /* dB */
+          power_control_offset_ss: 0, /* dB */
+          scrambling_id: 0,
+          period: 40,
+          offset: 12,
+          qcl_info_periodic_csi_rs: 0,
+        },
+#endif
+      ],
+      nzp_csi_rs_resource_set: [
+        {
+          csi_rs_set_id: 0,
+          nzp_csi_rs_resources: [ 0 ],
+          repetition: false,
+        },
+#ifdef USE_TRS
+        {
+          csi_rs_set_id: 1,
+          nzp_csi_rs_resources: [ 1, 2, 3, 4 ],
+          repetition: false,
+          trs_info: true,
+        },
+#endif
+      ],
+      
+     csi_im_resource: [
+        {
+          csi_im_id: 0,
+          pattern: 1,
+          subcarrier_location: 8,
+          symbol_location: 8,
+          rb_start: 0,
+          l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
+          period: 80,
+          offset: 1, /* != 0 to avoid collision with SSB */
+        },
+      ],
+      csi_im_resource_set: [
+        {
+          csi_im_set_id: 0,
+          csi_im_resources: [ 0 ],
+        }
+      ],
+      /* ZP CSI-RS to set the CSI-IM REs to zero */
+      zp_csi_rs_resource: [
+        {
+          csi_rs_id: 0,
+          frequency_domain_allocation: "row4",
+          bitmap: "100",
+          n_ports: 4,
+          cdm_type: "fd_cdm2",
+          first_symb: 8,
+          density: 1,
+          rb_start: 0,
+          l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
+          period: 80,
+          offset: 1,
+        },
+      ],
+      p_zp_csi_rs_resource_set: [
+        {
+          zp_csi_rs_resources: [ 0 ],
+        },
+      ],
+
+      csi_resource_config: [
+        {
+          csi_rsc_config_id: 0,
+          nzp_csi_rs_resource_set_list: [ 0 ],
+          resource_type: "periodic",
+        },
+        {
+          csi_rsc_config_id: 1,
+          csi_im_resource_set_list: [ 0 ],
+          resource_type: "periodic",
+        },
+#ifdef USE_TRS
+        {
+          csi_rsc_config_id: 2,
+          nzp_csi_rs_resource_set_list: [ 1 ],
+          resource_type: "periodic",
+        },
+#endif
+      ],
+      csi_report_config: [
+        {
+          resources_for_channel_measurement: 0,
+          csi_im_resources_for_interference: 1,
+          report_config_type: "periodic",
+          period: 80,
+          report_quantity: "CRI_RI_PMI_CQI",
+          cqi_table: 2,
+          subband_size: "value1",
+        },
+      ],
+    },
+    
+    pucch: {
+      pucch_group_hopping: "neither",
+      hopping_id: -1, /* -1 = n_cell_id */
+      p0_nominal: -90,
+        pucch1: {
+          n_cs: 3,
+          n_occ: 3,
+          freq_hopping: false,
+        },
+        pucch2: {
+          n_symb: 2,
+          n_prb: 1,
+          freq_hopping: false,
+          simultaneous_harq_ack_csi: false, 
+          max_code_rate: 0.25,
+        },
+    },
+
+    pusch: {
+      mapping_type: "typeA",
+      n_symb: 14,
+      dmrs_add_pos: 1,
+      dmrs_type: 1,
+      dmrs_max_len: 1,
+      tf_precoding: false,
+      mcs_table: "qam64", /* without transform precoding */
+      mcs_table_tp: "qam64", /* with transform precoding */
+      ldpc_max_its: 5,
+      k2: 4, /* delay in slots from DCI to PUSCH */
+      p0_nominal_with_grant: -90,
+      msg3_k2: 5,
+      msg3_mcs: 4,
+      msg3_delta_power: 0, /* in dB */
+      beta_offset_ack_index: 9,
+
+      /* hardcoded scheduling parameters */
+      n_dmrs_cdm_groups: 1,
+      n_layer: 1,
+      /* if defined, force the PUSCH MCS for all UEs. Otherwise it is
+       computed from the last received PUSCH. */
+      //mcs: 16,
+      //max_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: [${', '.join(list(dict.fromkeys(enb.cipher_list))).split("eea")[1] if len(list(dict.fromkeys(enb.cipher_list))) > 0 else ''}],
+    integ_algo_pref: [${', '.join(list(dict.fromkeys(enb.integrity_list))).split("eia")[1]}],
+
+    inactivity_timer: ${enb.inactivity_timer},
+
+    drb_config: "amarisoft_drb_nr.cfg",
+  },
+}
\ No newline at end of file
diff --git a/src/osmo_gsm_tester/templates/amarisoft_rf_driver.cfg.tmpl b/src/osmo_gsm_tester/templates/amarisoft_rf_driver.cfg.tmpl
index 36d34ad..f2942d7 100644
--- a/src/osmo_gsm_tester/templates/amarisoft_rf_driver.cfg.tmpl
+++ b/src/osmo_gsm_tester/templates/amarisoft_rf_driver.cfg.tmpl
@@ -15,6 +15,26 @@
 tx_gain: ${trx.tx_gain}, /* TX gain (in dB) B2x0: 0 to 89.8 dB */
 rx_gain: ${trx.rx_gain}, /* RX gain (in dB) B2x0: 0 to 73 dB */
 
+rf_ports: [
+  % if trx.rf_dev_type == 'sdr':
+    {
+        sample_rate: 23.04,
+    },
+    {
+        sample_rate: 61.44,
+        dl_freq: 3502.8, // Moves NR DL LO frequency -5.76 MHz
+        ul_freq: 3502.8, // Moves NR UL LO frequency -5.76 MHz
+    }
+  % else:
+    {
+      sample_rate: ${enb.sample_rate},
+    },
+    {
+      sample_rate: ${enb.sample_rate},
+    }
+  % endif
+],
+
 // only the B210 requires a sample offset
 % if "b200" in trx.rf_dev_args:
 tx_time_offset: -150,
diff --git a/sysmocom/defaults.conf b/sysmocom/defaults.conf
index 8740d62..f85ebd5 100644
--- a/sysmocom/defaults.conf
+++ b/sysmocom/defaults.conf
@@ -114,6 +114,7 @@
   duplex: fdd
   transmission_mode: 1
   num_cells: 1
+  num_nr_cells: 0
   inactivity_timer: 20000
   enable_measurements: false
   enable_dl_awgn: false
@@ -147,6 +148,7 @@
      root_seq_idx: 205
      scell_list: []
      ncell_list: []
+  nr_cell_list: []
   cipher_list:
    - eea0
    - eea2

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-gsm-tester/+/24126
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-gsm-tester
Gerrit-Branch: master
Gerrit-Change-Id: Ia27bbc6db5920ce14bacabe8043601aa2adaa5fe
Gerrit-Change-Number: 24126
Gerrit-PatchSet: 1
Gerrit-Owner: srs_andre <andre at softwareradiosystems.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210504/2e44c422/attachment.htm>


More information about the gerrit-log mailing list