Commit 2667fd36 authored by Kirill Smelkov's avatar Kirill Smelkov

software/ors-amarisoft: enb: Start to generalize the code to handle multiple peer cells

As with Radio Units and cells organize a registry of peer cells and start to handle
that registry generally everywhere. The registry is still populated with only
LTE cells on enb and only NR cells on gnb, but the only place that is aware of
that is registry loading routine.

In the old code defaults were noticed for tac to be 1 if not provided, and so
those defaults are pushed to live in ORS now. ORS schemas are also updated
because that defaults were not declared there.

Generic switches to use peer/cell/lte directly which means that now it accepts
e_cell_id instead of cell_id as the name for full E-UTRAN cell identity. Full
backward compatibility is provided for ORS which implements translation of its
original schema to the new generic one.

Tests will be added later as full tests for generic MultiRU.

Rendered enb.cfg and gnb.cfg change a bit, but the changes are mostly due to
reordering of fields. The only change with semantic value is

    -          ssb_nr_arfcn: ,
    +          ssb_nr_arfcn: 520090,

in gnb.cfg .

The old configuration was invalid anyway because if it is only

              ssb_nr_arfcn: ,

then enb does not start with the following error:

    # ../lteenb gnb.cfg
    gnb.cfg:119: unexpected token: ','

Like with many other handover-related fields
https://tech-academy.amarisoft.com/lteenb.doc#prop.ncell_list.ssb_nr_arfcn
documents that ssb_nr_arfcn "Must be present" for Inter-gNB HO case. The old
code was erroneously doing `ncell.get(name, '')` with yielding empty string in
case a parameter is missing, which is corrected here.

--------

Appendix. Diff for rendered enb.cfg and gnb.cfg before and after this patch:

```
$ ./pythonwitheggs slapos-render-config.py && xdiff -w config/{old,out}
```

```diff
diff --git a/config/old/enb.cfg b/config/out/enb.cfg
index 1a2c41b6b..252c2e379 100644
--- a/config/old/enb.cfg
+++ b/config/out/enb.cfg
@@ -46,9 +46,9 @@
         // Inter-ENB HO
         {
           rat:          "eutra",
+          cell_id:      0x12345,  // -> 1
           n_id_cell:    35,
           dl_earfcn:    700,
-          cell_id:      0x12345,
           tac:          123,
         },
       ],
diff --git a/config/old/gnb.cfg b/config/out/gnb.cfg
index 635c4baf2..b401f3513 100644
--- a/config/old/gnb.cfg
+++ b/config/out/gnb.cfg
@@ -58,14 +58,14 @@
         // Inter-ENB HO
         {
           rat:          "nr",
+          nr_cell_id:   0x77712, // -> 1
+          gnb_id_bits:  22,
+          n_id_cell:    75,
           dl_nr_arfcn:  520000,
-          ssb_nr_arfcn: ,
+          band:         38,
+          ssb_nr_arfcn: 520090,
           ul_nr_arfcn:  520000,
-          n_id_cell:    75,
-          gnb_id_bits:  22,
-          nr_cell_id:   0x77712,
           tac:          321,
-          band:         38,
           ssb_subcarrier_spacing: 30,
           ssb_period: 20,
           ssb_offset: 0,
```
parent 7abb0b52
...@@ -9,8 +9,10 @@ ...@@ -9,8 +9,10 @@
{%- set ru_dict = {} %} {%- set ru_dict = {} %}
{%- set cell_dict = {} %} {%- set cell_dict = {} %}
{%- set peer_dict = {} %} {%- set peer_dict = {} %}
{%- set peercell_dict = {} %}
{%- do slaplte.load_ru_and_cell(ru_dict, cell_dict) %} {%- do slaplte.load_ru_and_cell(ru_dict, cell_dict) %}
{%- do slaplte.load_peer(peer_dict) %} {%- do slaplte.load_peer(peer_dict) %}
{%- do slaplte.load_peercell(peercell_dict) %}
{%- endif %} {%- endif %}
...@@ -26,24 +28,27 @@ ...@@ -26,24 +28,27 @@
{%- macro handover_config() %} {%- macro handover_config() %}
ncell_list: [ ncell_list: [
// Inter-ENB HO // Inter-ENB HO
{%- for _, ncell in slapparameter_dict.get('ncell_list', {})|dictsort %} {#- TODO: add info about peers as shared instances - one instance per peer *ENB*.
then query SlapOS Master about cells configured on that peer ENB and
put them as peers here #}
{%- for peercell_ref, ncell in peercell_dict|dictsort %}
{ {
{%- if do_lte %} {%- if ncell.cell_type == 'lte' %}
rat: "eutra", rat: "eutra",
n_id_cell: {{ ncell.get('pci', '') }}, cell_id: {{ ncell.e_cell_id }}, // -> {{ peercell_ref }}
dl_earfcn: {{ ncell.get('dl_earfcn', '') }}, n_id_cell: {{ ncell.pci }},
cell_id: {{ ncell.get('cell_id', '') }}, dl_earfcn: {{ ncell.dl_earfcn }},
tac: {{ ncell.get('tac', 1) }}, tac: {{ ncell.tac }},
{%- elif do_nr %} {%- elif ncell.cell_type == 'nr' %}
rat: "nr", rat: "nr",
dl_nr_arfcn: {{ ncell.get('dl_nr_arfcn', '') }}, nr_cell_id: {{ ncell.nr_cell_id }}, // -> {{ peercell_ref }}
ssb_nr_arfcn: {{ ncell.get('ssb_nr_arfcn', '') }}, gnb_id_bits: {{ ncell.gnb_id_bits }},
ul_nr_arfcn: {{ ncell.get('dl_nr_arfcn', '') }}, n_id_cell: {{ ncell.pci }},
n_id_cell: {{ ncell.get('pci', '') }}, dl_nr_arfcn: {{ ncell.dl_nr_arfcn }},
gnb_id_bits: {{ ncell.get('gnb_id_bits', '') }}, band: {{ ncell.nr_band }},
nr_cell_id: {{ ncell.get('nr_cell_id', '') }}, ssb_nr_arfcn: {{ ncell.ssb_nr_arfcn }},
tac: {{ ncell.get('tac', 1) }}, ul_nr_arfcn: {{ ncell.dl_nr_arfcn }}, {#- XXX assumes nr_band is TDD #}
band: {{ ncell.get('nr_band', '') }}, tac: {{ ncell.tac }},
ssb_subcarrier_spacing: 30, ssb_subcarrier_spacing: 30,
ssb_period: 20, ssb_period: 20,
ssb_offset: 0, ssb_offset: 0,
......
...@@ -82,21 +82,7 @@ ...@@ -82,21 +82,7 @@
"description": "Neighbour Cell Info", "description": "Neighbour Cell Info",
"patternProperties": { "patternProperties": {
".*": { ".*": {
"properties": { "$ref": "peer/cell/lte/input-schema.json"
"dl_earfcn": {
"$ref": "peer/cell/lte/input-schema.json#/properties/dl_earfcn"
},
"pci": {
"$ref": "peer/cell/lte/input-schema.json#/properties/pci"
},
"cell_id": {
"$ref": "peer/cell/lte/input-schema.json#/properties/e_cell_id"
},
"tac": {
"$ref": "peer/cell/lte/input-schema.json#/properties/tac"
}
},
"type": "object"
} }
}, },
"type": "object", "type": "object",
......
...@@ -44,7 +44,9 @@ offline = true ...@@ -44,7 +44,9 @@ offline = true
{%- import 'slaplte.jinja2' as slaplte with context %} {%- import 'slaplte.jinja2' as slaplte with context %}
{%- import 'ru_libinstance.jinja2.cfg' as rulib with context %} {%- import 'ru_libinstance.jinja2.cfg' as rulib with context %}
{%- set peer_dict = {} %} {%- set peer_dict = {} %}
{%- set peercell_dict = {} %}
{%- do slaplte.load_peer(peer_dict) %} {%- do slaplte.load_peer(peer_dict) %}
{%- do slaplte.load_peercell(peercell_dict) %}
{{ rulib.buildout() }} {{ rulib.buildout() }}
...@@ -218,6 +220,7 @@ extra-context = ...@@ -218,6 +220,7 @@ extra-context =
json ru_dict {{ rulib.ru_dict | tojson }} json ru_dict {{ rulib.ru_dict | tojson }}
json cell_dict {{ rulib.cell_dict | tojson }} json cell_dict {{ rulib.cell_dict | tojson }}
json peer_dict {{ peer_dict | tojson }} json peer_dict {{ peer_dict | tojson }}
json peercell_dict {{ peercell_dict | tojson }}
import-list = import-list =
rawfile slaplte.jinja2 {{ slaplte_template }} rawfile slaplte.jinja2 {{ slaplte_template }}
......
...@@ -136,7 +136,8 @@ ...@@ -136,7 +136,8 @@
"$ref": "peer/cell/lte/input-schema.json#/properties/e_cell_id" "$ref": "peer/cell/lte/input-schema.json#/properties/e_cell_id"
}, },
"tac": { "tac": {
"$ref": "peer/cell/lte/input-schema.json#/properties/tac" "$ref": "peer/cell/lte/input-schema.json#/properties/tac",
"default": "0x0001"
} }
}, },
"type": "object" "type": "object"
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
"enb_id": "0x1A2D0", "enb_id": "0x1A2D0",
"mme_list": {'1': {'mme_addr': '127.0.1.100'}}, "mme_list": {'1': {'mme_addr': '127.0.1.100'}},
"plmn_list": {"1": {'plmn': '00101'}}, "plmn_list": {"1": {'plmn': '00101'}},
"ncell_list": {},
"inactivity_timer": 10000, "inactivity_timer": 10000,
} %} } %}
{%- set ors_gnb_defaults = { {%- set ors_gnb_defaults = {
...@@ -34,6 +35,7 @@ ...@@ -34,6 +35,7 @@
"gnb_id_bits": 28, "gnb_id_bits": 28,
"amf_list": {'1': {'amf_addr': '127.0.1.100'}}, "amf_list": {'1': {'amf_addr': '127.0.1.100'}},
"plmn_list": {'1': {'plmn': '00101', 'tac': 100}}, "plmn_list": {'1': {'plmn': '00101', 'tac': 100}},
"ncell_list": {},
"inactivity_timer": 10000, "inactivity_timer": 10000,
} %} } %}
...@@ -94,6 +96,39 @@ ...@@ -94,6 +96,39 @@
{%- do cell_list.update({'CELL': cell}) %} {%- do cell_list.update({'CELL': cell}) %}
{#- translate ORS ncell_list to generic ncell_list #}
{%- set ncell_list_ors = slapparameter_dict.ncell_list %}
{%- set ncell_list = {} %}
{%- do slapparameter_dict.update({'ncell_list': ncell_list}) %}
{%- for k, ncell in ncell_list_ors|dictsort %}
{%- set peercell = {} %}
{%- macro _(name, default) %}
{%- if default is defined %}
{%- do peercell.update({name: default}) %}
{%- endif %}
{%- if name in ncell %}
{%- do peercell.update({name: ncell[name]}) %}
{%- endif %}
{%- endmacro %}
{%- if enb_mode == 'enb' %}
{%- if 'cell_id' in ncell %}
{%- do peercell.update({'e_cell_id': ncell.cell_id}) %}
{%- endif %}
{%- do _('pci') %}
{%- do _('dl_earfcn') %}
{%- do _('tac', '0x0001') %}
{%- elif enb_mode == 'gnb' %}
{%- do _('nr_cell_id') %}
{%- do _('gnb_id_bits') %}
{%- do _('pci') %}
{%- do _('dl_nr_arfcn') %}
{%- do _('ssb_nr_arfcn') %}
{%- do _('tac', 1) %}
{%- do _('nr_band') %}
{%- endif %}
{%- endfor %}
{#- backward compatibility: if ORS is running in gnb mode, and gnb_* parameters {#- backward compatibility: if ORS is running in gnb mode, and gnb_* parameters
are present, replace their generic enb_* counterparts with gnb_* ones #} are present, replace their generic enb_* counterparts with gnb_* ones #}
{%- if enb_mode == 'gnb' %} {%- if enb_mode == 'gnb' %}
......
...@@ -126,7 +126,8 @@ ...@@ -126,7 +126,8 @@
"$ref": "peer/cell/nr/input-schema.json#/properties/nr_band" "$ref": "peer/cell/nr/input-schema.json#/properties/nr_band"
}, },
"tac": { "tac": {
"$ref": "peer/cell/nr/input-schema.json#/properties/tac" "$ref": "peer/cell/nr/input-schema.json#/properties/tac",
"default": 1
} }
}, },
"type": "object" "type": "object"
......
{#- Package slaplte provides helpers for configuring Amarisoft LTE services in SlapOS. {#- Package slaplte provides helpers for configuring Amarisoft LTE services in SlapOS.
- load_ru_and_cell initializes RU and cell registries. - load_ru_and_cell initializes RU and cell registries.
- load_peercell initializes peer-cell registry.
- load_peer initializes peer registry. - load_peer initializes peer registry.
- ru_config emits RF driver configuration for specified Radio Units. - ru_config emits RF driver configuration for specified Radio Units.
...@@ -210,6 +211,24 @@ ...@@ -210,6 +211,24 @@
{%- endmacro %} {%- endmacro %}
{#- load_peercell initializes peer-cell registry.
peercell_dict keeps configured peer cells: {} peer cell reference -> peercell
#}
{%- macro load_peercell(peercell_dict) %}
{%- for ref, peercell in slapparameter_dict.ncell_list|dictsort %}
{%- if do_lte %}
{%- do peercell.update({'cell_type': 'lte'}) %}
{%- elif do_nr %}
{%- do peercell.update({'cell_type': 'nr'}) %}
{%- else %}
{%- do bug('unreachable') %}
{%- endif %}
{%- do peercell_dict.update({ref: peercell}) %}
{%- endfor %}
{%- endmacro %}
{#- ---- building configuration ---- #} {#- ---- building configuration ---- #}
{#- ru_config emits RF driver configuration for specified Radio Units. #} {#- ru_config emits RF driver configuration for specified Radio Units. #}
......
...@@ -88,7 +88,7 @@ def do(src, out, rat, slapparameter_dict): ...@@ -88,7 +88,7 @@ def do(src, out, rat, slapparameter_dict):
def do_enb(): def do_enb():
peer_lte = { peer_lte = {
'cell_id': '0x12345', 'e_cell_id': '0x12345',
'pci': 35, 'pci': 35,
'dl_earfcn': 700, 'dl_earfcn': 700,
'tac': 123, 'tac': 123,
...@@ -98,6 +98,7 @@ def do_enb(): ...@@ -98,6 +98,7 @@ def do_enb():
'gnb_id_bits': 22, 'gnb_id_bits': 22,
'dl_nr_arfcn': 520000, 'dl_nr_arfcn': 520000,
'nr_band': 38, 'nr_band': 38,
'ssb_nr_arfcn': 520090,
'pci': 75, 'pci': 75,
'tac': 321, 'tac': 321,
} }
......
...@@ -199,7 +199,7 @@ def test_gnb_conf1(self): ...@@ -199,7 +199,7 @@ def test_gnb_conf1(self):
conf_ncell = gnb_param_dict1['ncell_list'][k] conf_ncell = gnb_param_dict1['ncell_list'][k]
self.assertEqual(p['dl_nr_arfcn'], conf_ncell['dl_nr_arfcn']) self.assertEqual(p['dl_nr_arfcn'], conf_ncell['dl_nr_arfcn'])
self.assertEqual(p['ssb_nr_arfcn'], conf_ncell['ssb_nr_arfcn']) self.assertEqual(p['ssb_nr_arfcn'], conf_ncell['ssb_nr_arfcn'])
self.assertEqual(p['ul_nr_arfcn'], conf_ncell['dl_nr_arfcn']) self.assertEqual(p['ul_nr_arfcn'], conf_ncell['dl_nr_arfcn']) # assumes nr_band is TDD
self.assertEqual(p['n_id_cell'], conf_ncell['pci']) self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
self.assertEqual(p['gnb_id_bits'], conf_ncell['gnb_id_bits']) self.assertEqual(p['gnb_id_bits'], conf_ncell['gnb_id_bits'])
self.assertEqual(p['nr_cell_id'], int(conf_ncell['nr_cell_id'], 16)) self.assertEqual(p['nr_cell_id'], int(conf_ncell['nr_cell_id'], 16))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment