enb: Add cell_list attribute

It allows configuring each cell_list up to a maximum of 'num_cells'.

Change-Id: I4fd30a3e37789b76bfaddc2beba1815154daab7f
diff --git a/src/osmo_gsm_tester/obj/enb.py b/src/osmo_gsm_tester/obj/enb.py
index d1f8687..340ea3a 100644
--- a/src/osmo_gsm_tester/obj/enb.py
+++ b/src/osmo_gsm_tester/obj/enb.py
@@ -38,6 +38,7 @@
         self.set_name('%s_%s' % (name, self._addr))
         self._txmode = 0
         self._num_prb = 0
+        self._num_cells = None
         self._epc = None
 
     def configure(self, config_specifics_li):
@@ -56,6 +57,25 @@
         assert self._epc is not None
         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
+
+        # adjust cell_list to num_cells length:
+        len_cell_list = len(values['enb']['cell_list'])
+        if len_cell_list >= self._num_cells:
+            values['enb']['cell_list'] = values['enb']['cell_list'][:self._num_cells]
+        else:
+            raise log.Error('enb.cell_list items (%d) < enb.num_cells (%d) attribute!' % (len_cell_list, self._num_cells))
+        # adjust scell list (to only contain values available in cell_list):
+        cell_id_list = [c['cell_id'] for c in values['enb']['cell_list']]
+        for i in range(len(values['enb']['cell_list'])):
+            scell_list_old = values['enb']['cell_list'][i]['scell_list']
+            scell_list_new = []
+            for scell_id in scell_list_old:
+                if scell_id in cell_id_list:
+                    scell_list_new.append(scell_id)
+            values['enb']['cell_list'][i]['scell_list'] = scell_list_new
+
         return values
 
     def num_ports(self):
diff --git a/src/osmo_gsm_tester/obj/enb_amarisoft.py b/src/osmo_gsm_tester/obj/enb_amarisoft.py
index 1772173..996af19 100644
--- a/src/osmo_gsm_tester/obj/enb_amarisoft.py
+++ b/src/osmo_gsm_tester/obj/enb_amarisoft.py
@@ -165,8 +165,6 @@
             self.remote_log_file = remote_run_dir.child(AmarisoftENB.LOGFILE)
 
         values = super().configure(['amarisoft', 'amarisoftenb'])
-        self._num_cells = int(values['enb'].get('num_cells', None))
-        assert self._num_cells
 
         # Convert parsed boolean string to Python boolean:
         self.enable_measurements = util.str2bool(values['enb'].get('enable_measurements', 'false'))
diff --git a/src/osmo_gsm_tester/obj/enb_srs.py b/src/osmo_gsm_tester/obj/enb_srs.py
index 9364375..c9721d1 100644
--- a/src/osmo_gsm_tester/obj/enb_srs.py
+++ b/src/osmo_gsm_tester/obj/enb_srs.py
@@ -190,9 +190,6 @@
 
         self._additional_args = values['enb'].get('additional_args', '').split()
 
-        self._num_cells = int(values['enb'].get('num_cells', None))
-        assert self._num_cells
-
         # We need to set some specific variables programatically here to match IP addresses:
         if self._conf.get('rf_dev_type') == 'zmq':
             base_srate = num_prb2base_srate(self.num_prb())
diff --git a/src/osmo_gsm_tester/resource.py b/src/osmo_gsm_tester/resource.py
index bcdbb94..efb7d5a 100644
--- a/src/osmo_gsm_tester/resource.py
+++ b/src/osmo_gsm_tester/resource.py
@@ -91,7 +91,6 @@
         'enb[].gtp_bind_addr': schema.IPV4,
         'enb[].num_prb': schema.UINT,
         'enb[].transmission_mode': schema.LTE_TRANSMISSION_MODE,
-        'enb[].num_cells': schema.UINT,
         'enb[].rf_dev_type': schema.STR,
         'enb[].rf_dev_args': schema.STR,
         'enb[].additional_args': schema.STR,
@@ -108,6 +107,10 @@
         'enb[].a3_report_value': schema.INT,
         'enb[].a3_hysteresis': schema.INT,
         'enb[].a3_time_to_trigger': schema.INT,
+        'enb[].num_cells': schema.UINT,
+        'enb[].cell_list[].cell_id': schema.UINT,
+        'enb[].cell_list[].scell_list[]': schema.UINT,
+        'enb[].cell_list[].dl_earfcn': schema.UINT,
         'arfcn[].arfcn': schema.INT,
         'arfcn[].band': schema.BAND,
         'modem[].type': schema.STR,
diff --git a/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl b/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl
index a56e58d..11704b6 100644
--- a/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl
+++ b/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl
@@ -55,36 +55,23 @@
 
   /* list of cells */
   cell_list: [
-  {
-    // First cell
-    dl_earfcn: 2850,
-    rf_port: 0,
-    cell_id: 0x01,
-    n_id_cell: 1,
-    tac: 0x0001,
-    root_sequence_index: 204, /* PRACH root sequence index */
 
-% if enb.get('num_cells') == '2':
-    scell_list: [
-      { cell_id: 0x02, cross_carrier_scheduling: false, scheduling_cell_id: 0x01, ul_allowed: true},
-    ],
-% endif
-  },
-% if enb.get('num_cells') == '2':
+%for cell in enb.cell_list:
   {
-    // Second Cell
-    dl_earfcn: 3050,
-    rf_port: 1,
-    cell_id: 0x02,
-    n_id_cell: 2,
+    dl_earfcn: ${cell.dl_earfcn},
+    rf_port: ${loop.index},
+    cell_id: ${cell.cell_id},
+    n_id_cell: ${loop.index + 1},
     tac: 0x0001,
-    root_sequence_index: 205,
+    root_sequence_index: ${loop.index + 204}, /* PRACH root sequence index */
 
     scell_list: [
-      { cell_id: 0x01, cross_carrier_scheduling: false, scheduling_cell_id: 0x02, ul_allowed: true},
+%for scell_id in cell.scell_list:
+      { cell_id: ${scell_id}, cross_carrier_scheduling: false, scheduling_cell_id: ${cell.cell_id}, ul_allowed: true},
+%endfor
     ],
   },
-% endif
+%endfor
   ], /* cell_list */
 
   /* default cell parameters */