Commit 0e934459 authored by Joanne Hugé's avatar Joanne Hugé

Delete useless files

parent 77b89fef
# ORS Amarisoft software release
How to deploy from scratch
1. Install Amarisoft binaries in /opt/amarisoft/v20XX-XX-XX with folders:
* enb: needs to containt libraries from trx_sdr
* trx_sdr
* mme
2. Install ors playbook
3. Deploy this SR
## Generated buildout configurations and json input schemas
Since there are multiple ors-amarisoft softwares releases and software types, the following files are
generated with jinja2 templates with the render-templates script before being pushed to gitlab:
* instance-tdd-enb-input-schema.json
* instance-fdd-enb-input-schema.json
* software-fdd.cfg
* software-tdd.cfg.json
* instance-fdd-ue-nr-input-schema.json
* instance-tdd-gnb-input-schema.json
* instance-tdd-ue-nr-input-schema.json
* test/testFDD.py
* test/testTDD.py
* software-tdd.cfg
* instance-tdd-ue-lte-input-schema.json
* instance-fdd-gnb-input-schema.json
* software-fdd.cfg.json
* instance-fdd-ue-lte-input-schema.json
These files should not be modified directly, and the render-templates scripts should be run along
with update-hash before each commit.
## Services
We run 2 binaries from Amarisoft LTE stack:
* **lteenb** - eNodeB software is the server accepting connection from UI (user interfaces)
* **ltemme** - Mobile Management Entity in other words core network which handles orchestration of
eNodeBs in case UI switches from one to another
Those binaries are started in foreground, originaly in screen. We don't want the binaries inside one
screen because then we cannot easily control their resource usage. Thus we make 2 on-watch services.
### ENB / GNB
Is the eNodeB (4G) or gNodeB (5G). This binary handles the radio protocols and sends and receives
IQ samples to trx_sdr driver.
### MME
Is the core network. This binary keep track of UEs and to which eNodeB they are currently connected.
It reroutes traffic when UE switches between eNodeBs.
MME also serves as a service bus thus all services must register within MME.
## Gotchas!
**trx_sdr.so** provided from archive MUST be placed next to `lteenb` binary. This library is the
only one which does not follow standard `ld` path resolution.
**rf_driver** has to be compiled and installed. Inside trx_sdr/kernel folder issue `# make` to compile the
kernel module, and then `# ./init.sh` to create devices `/dev/sdr<N>` and insert compiled module.
#!{{ python_path }}
import json
import logging
from logging.handlers import RotatingFileHandler
import time
from websocket import create_connection
class enbWebSocket:
def __init__(self):
log_file = "{{ log_file }}"
self.logger = logging.getLogger('logger')
self.logger.setLevel(logging.INFO)
handler = RotatingFileHandler(log_file, maxBytes=30000, backupCount=2)
formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
handler.setFormatter(formatter)
self.logger.addHandler(handler)
if {{ testing }}:
return
self.ws_url = "ws://127.0.1.2:9001"
self.ws = create_connection(self.ws_url)
def close(self):
if {{ testing }}:
return
self.ws.close()
def send(self, msg):
self.ws.send(json.dumps(msg))
def recv(self, message_type):
for i in range(1,20):
r = json.loads(self.ws.recv())
if r['message'] == message_type:
return r
def stats(self):
if {{ testing }}:
r = {
'message': 'rf',
'rf_info': "CPRI: x16 HW SW\n"
}
else:
self.send({
"message": "rf",
"rf_info": True
})
r = self.recv('rf')
self.logger.info('RF info', extra={'data': json.dumps(r)})
if __name__ == '__main__':
ws = enbWebSocket()
try:
while True:
ws.stats()
time.sleep({{ stats_period }})
finally:
ws.close()
#!{{ python_path }}
import json
import logging
from logging.handlers import RotatingFileHandler
import time
from websocket import create_connection
class enbWebSocket:
def __init__(self):
log_file = "{{ log_file }}"
self.logger = logging.getLogger('logger')
self.logger.setLevel(logging.INFO)
handler = RotatingFileHandler(log_file, maxBytes=30000, backupCount=2)
formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
handler.setFormatter(formatter)
self.logger.addHandler(handler)
if {{ testing }}:
return
self.ws_url = "ws://127.0.1.2:9001"
self.ws = create_connection(self.ws_url)
def close(self):
if {{ testing }}:
return
self.ws.close()
def send(self, msg):
self.ws.send(json.dumps(msg))
def recv(self, message_type):
for i in range(1,20):
r = json.loads(self.ws.recv())
if r['message'] == message_type:
return r
def stats(self):
if {{ testing }}:
from random import randint
r = {
'message': 'stats',
'samples': {'rx': [
{'sat': 0, 'max': randint(-500,-100) / 10.0},
{'sat': 0, 'max': randint(-500,-100) / 10.0},
]}
}
else:
self.send({
"message": "stats",
"samples": True,
"rf": True
})
r = self.recv('stats')
self.logger.info('Samples stats', extra={'data': json.dumps(r)})
if __name__ == '__main__':
ws = enbWebSocket()
try:
while True:
ws.stats()
time.sleep({{ stats_period }})
finally:
ws.close()
Changelog
=========
Version 1.0.339 (2023-10-16)
-------------
* Lopcomm firmware update
* RRH reset (reboot) function added
* Fix cpri_tx_dbm parameter
* Print RRH IPv6 and firmware information
Version 1.0.336 (2023-09-25)
-------------
* Support on Lopcomm RRH via netconf
- Lopcomm firmware auto-upgrade and verification
- Up to 4T4R
- Netconf access verification promise
- PA output power alarm
- Default value added for B1
* fix some bugs
Version 1.0.332 (2023-09-04)
-------------
* Add 4G Intra eNB Handover
* Add public websocket URL protected by password
* Reorganize softwares: ORS now need to use software-tdd-ors or software-fdd-ors
* Support multiple cells for BBUs
Version 1.0.330 (2023-07-19)
-------------
* Change Slice Differentiator input parameter to hexadecimal representation
* Add TDD Configurations with maximum uplink
* Modify reference power signal to improve radio link over long distances
* Add Tracking Area Code (TAC) parameter to eNB
* Publish useful values:
- Frequency and band
- Current TX and RX gain
- Estimated TX power in dB and W based on https://handbook.rapid.space/rapidspace-ORS.tx.gain
- ORS frequency range rating
- ORS version
Version 1.0.326 (2023-06-14)
-------------
* Add DHCP for Lopcomm RU's M-plane
* Add support for FDD
* Add more parameters and tests for lopcomm RU
Version 1.0.323 (2023-05-17)
-------------
* Add support for first version of MCPTT (Mission Critical Push To Talk)
Version 1.0.321 (2023-05-05)
-------------
* Remove RRH options from ORS software releases
* Add custom TDD UL DL configuration
* Add time_to_trigger and a3_offset gNB XnAP and NGAP NR handover options
Version 1.0.320 (2023-04-26)
----------------------------
* Add support for inter gNB XnAP and NGAP NR handover
Version 1.0.317 (2023-04-18)
---------------------------
* Add support for inter gNB NR handover
Version 1.0.316 (2023-04-14)
----------------------------
* Remove enb-epc, gnb-epc and epc software types, the software types are now:
- enb
- gnb
- core-network (replaces epc software type)
Version 1.0.312 (2023-03-20)
----------------------------
* Add promise to test if reception is saturated
* Add gadget from SR to display on Monitor APP
* Add IMSI in connection parameters when SIM gets attached
* Add carrier control for Lopcomm RRH
Version 1.0.308 (2023-02-09)
----------------------------
* Add support for IPv6 in UEs if available
* Use latest amarisoft version on ORS if available
* Add gnb_id_bits parameter
* Use promises from slapos.toolbox repository
* Rotate and add timestamps in enb-output.log, gnb-output.log, mme-output.log etc...
* Add support for Lopcomm RRH
* Remove UE power emission limitation
{% if ru == "lopcomm" %}
dhcp-leasefile={{ directory['etc'] }}/dnsmasq.leases
port=5354
dhcp-range=::1,::1,constructor:{{ slap_configuration.get('tap-name', '') }},ra-names,64,5m
dhcp-host={{ slapparameter_dict.get('rrh_mac_addr', '00:0a:00:00:10:20') }},[{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) }}]
dhcp-option=option6:dns-server,[{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) + 1 }}],[{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) + 2 }}]
dhcp-option=option6:domain-search,bbu.local
# option 17 used for RU callhome
# dhcp-option=option6:17,[{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-addr', '')) }}]
log-queries
log-dhcp
log-facility={{ directory['home'] }}/var/log/dnsmasq.log
enable-ra
ra-param=adv-send-advert
ra-param=adv-managed-flag
ra-param=adv-other-config-flag
ra-param=adv-autonomous
{% else %}
interface={{ slap_configuration.get('tun-name', '') }}
port=5353
{%- set filtered_slave_instance_list = [] %}
{%- for slave_instance in slap_configuration.get('slave-instance-list', []) %}
{%- if slave_instance.get('_', '') != '' %}
{%- set slave = json_module.loads(slave_instance.pop('_')) %}
{%- else %}
{%- set slave = slave_instance %}
{%- endif %}
{%- if slave.get('subdomain', '') != '' %}
{%- do filtered_slave_instance_list.append(slave) %}
{%- endif %}
{%- endfor %}
{% for i, slave in enumerate(filtered_slave_instance_list) -%}
address=/{{ slave['subdomain'] }}.{{ slap_configuration['configuration'].get('local_domain', '') }}/{{ slave.get('ip', '') }}
{% endfor -%}
{% endif %}
{%- set cell_list = slapparameter_dict.get('cell_list', {'default': {}}) %}
{%- set cell_count = cell_list|length %}
{%- if slapparameter_dict.get('tdd_ul_dl_config', '[Configuration 2] 5ms 2UL 6DL (default)') == '[Configuration 2] 5ms 2UL 6DL (default)' %}
{%- set tdd_config = 2 %}
{%- elif slapparameter_dict.get('tdd_ul_dl_config', '[Configuration 2] 5ms 2UL 6DL (default)') == '[Configuration 6] 5ms 5UL 3DL (maximum uplink)' %}
{%- set tdd_config = 6 %}
{%- endif %}
{% if rf_mode == 'tdd' %}
#define TDD 1
{% else %}
#define TDD 0
{% endif %}
{%- if slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '1.4 MHz' %}
#define N_RB_DL 6
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '3 MHz' %}
#define N_RB_DL 15
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '5 MHz' %}
#define N_RB_DL 25
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '10 MHz' %}
#define N_RB_DL 50
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '15 MHz' %}
#define N_RB_DL 75
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '20 MHz' %}
#define N_RB_DL 100
{%- endif %}
#define N_ANTENNA_DL {{ slapparameter_dict.get('n_antenna_dl', slap_configuration['configuration.default_n_antenna_dl']) }}
#define N_ANTENNA_UL {{ slapparameter_dict.get('n_antenna_ul', slap_configuration['configuration.default_n_antenna_ul']) }}
{
{% if slapparameter_dict.get('log_phy_debug', False) %}
log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,s1ap.level=debug,s1ap.max_size=1,x2ap.level=debug,x2ap.max_size=1,rrc.level=debug,rrc.max_size=1,phy.level=debug,file.rotate=1G,file.path=/dev/null",
{% else %}
log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,s1ap.level=debug,s1ap.max_size=1,x2ap.level=debug,x2ap.max_size=1,rrc.level=debug,rrc.max_size=1,phy.level=info,file.rotate=1G,file.path=/dev/null",
{% endif %}
log_filename: "{{ directory['log'] }}/enb.log",
{% if ru == "lopcomm" %}
rf_driver: {
{%- if slapparameter_dict.get('disable_sdr', False) %}
name: "dummy",
{%- else %}
name: "sdr",
{%- endif %}
args: "dev0=
{%- for i, k in enumerate(cell_list) %}
{%- set cpri_port = cell_list[k].get('cpri_port_number', i) %}
{%- if i != 0 -%}
,
{%- endif -%}
/dev/sdr{{ slapparameter_dict.get('sdr_number', 0) }}@{{ cpri_port }}
{%- endfor -%}
",
cpri_mapping: "hw",
{%- set cpri_mult = slapparameter_dict.get('cpri_mult', 16) %}
cpri_mult: "
{%- for i, k in enumerate(cell_list) %}
{%- if i != 0 -%}
,
{%- endif -%}
{{ cpri_mult }}
{%- endfor -%}
",
cpri_rx_delay: "
{%- for i, k in enumerate(cell_list) %}
{%- if i != 0 -%}
,
{%- endif -%}
{{ cell_list[k].get('cpri_rx_delay', 0) }}
{%- endfor -%}
",
cpri_tx_delay: "
{%- for i, k in enumerate(cell_list) %}
{%- if i != 0 -%}
,
{%- endif -%}
{{ cell_list[k].get('cpri_tx_delay', 0) }}
{%- endfor -%}
",
cpri_tx_dbm: "
{%- for i, k in enumerate(cell_list) %}
{%- if i != 0 -%}
,
{%- endif -%}
{{ cell_list[k].get('cpri_tx_dbm', 0) }}
{%- endfor -%}
",
ifname: "
{%- if cell_count == 1 -%}
{{ slap_configuration.get('tap-name', '') }}
{%- else -%}
{%- for i, k in enumerate(cell_list) %}
{%- if i != 0 -%}
,
{%- endif -%}
{{ slap_configuration.get('tap-name', '') }}-{{ i }}
{%- endfor -%}
{%- endif -%}
",
},
tx_gain: 0,
rx_gain: 0,
{% elif bbu == "ors" %}
rf_driver: {
{%- if slapparameter_dict.get('disable_sdr', False) %}
name: "dummy",
{%- else %}
name: "sdr",
{%- endif %}
args: "dev0=/dev/sdr0",
{% if slapparameter_dict.get('gps_sync', False) %}
sync: "gps",
{% endif %}
rx_antenna:"tx_rx",
tdd_tx_mod: 1,
},
tx_gain: {{ tx_gain }},
rx_gain: {{ rx_gain }},
{% endif %}
{%- if slapparameter_dict.get('websocket_password', '') %}
com_addr: "[{{ gtp_addr_v6 }}]:{{ slap_configuration['configuration.com_ws_port'] }}",
com_auth: {
password: "{{ slapparameter_dict['websocket_password'] }}",
},
{%- else %}
com_addr: "{{ slap_configuration['configuration.com_addr'] }}:{{ slap_configuration['configuration.com_ws_port'] }}",
{%- endif %}
mme_list: [
{% if slapparameter_dict.get('mme_list', '') %}
{%- for i, k in enumerate(slapparameter_dict['mme_list']) %}
{%- if i == 0 %}
{
{%- else -%}
, {
{%- endif %}
mme_addr: "{{ slapparameter_dict['mme_list'][k]['mme_addr'] }}",
}
{%- endfor -%}
{% else %}
{
mme_addr: "{{ slap_configuration['configuration.mme_addr'] }}",
},
{% endif %}
],
{% if slapparameter_dict.get('mme_list', '') %}
{% if slapparameter_dict.get('gtp_addr') %}
gtp_addr: "{{ slapparameter_dict.get('gtp_addr') }}",
{% else %}
{% if slapparameter_dict.get('use_ipv4', False) %}
gtp_addr: "{{ gtp_addr_v6 }}",
{% else %}
gtp_addr: "{{ gtp_addr_v4 }}",
{% endif %}
{% endif %}
{% else %}
gtp_addr: "{{ slap_configuration['configuration.gtp_addr'] }}",
{% endif %}
enb_id: {{ slapparameter_dict.get('enb_id', '0x1A2D0') }},
cell_list: [
{%- for i, k in enumerate(cell_list) %}
{%- if i == 0 -%}
{
{%- else -%}
, {
{%- endif %}
rf_port: {{ i }},
cell_id: {{ cell_list[k].get('cell_id', slapparameter_dict.get('cell_id', '0x0' + i|string)) }},
tac: {{ cell_list[k].get('tac', slapparameter_dict.get('tac', '0x0001')) }},
n_id_cell: {{ cell_list[k].get('pci', slapparameter_dict.get('pci', i)) }},
root_sequence_index: {{ cell_list[k].get('root_sequence_index', slapparameter_dict.get('root_sequence_index', 204 + i)) }},
dl_earfcn: {{ cell_list[k].get('dl_earfcn', slapparameter_dict.get('dl_earfcn', earfcn)) }},
{%- if slapparameter_dict.get('ncell_list', '') %}
ncell_list: [
{%- for i, k in enumerate(slapparameter_dict['ncell_list']) %}
{%- if i == 0 -%}
{
{%- else -%}
, {
{%- endif %}
n_id_cell: {{ slapparameter_dict['ncell_list'][k].get('pci', '') }},
dl_earfcn: {{ slapparameter_dict['ncell_list'][k].get('dl_earfcn', '') }},
cell_id: {{ slapparameter_dict['ncell_list'][k].get('cell_id', '') }},
tac: {{ slapparameter_dict['ncell_list'][k].get('tac', 1) }},
}
{%- endfor -%}
],
{% endif %}
{%- set scell_list = [] %}
{%- for j, l in enumerate(cell_list) %}
{%- if j != i %}
{%- do scell_list.append([j, l]) %}
{%- endif %}
{%- endfor %}
scell_list: [
{%- for j, l in enumerate(scell_list) %}
{%- if j == 0 -%}
{
{%- else -%}
, {
{%- endif %}
cell_id: {{ cell_list[l[1]].get('cell_id', '0x0' + l[0]|string) }},
cross_carrier_scheduling: false,
}
{%- endfor %}
],
}
{%- endfor %}
],
cell_default: {
plmn_list: [
{%- if slapparameter_dict.get('plmn_list', '') %}
{%- for i, k in enumerate(slapparameter_dict['plmn_list']) %}
{%- if i == 0 -%}
{
{%- else -%}
, {
{%- endif %}
plmn: "{{ slapparameter_dict['plmn_list'][k]['plmn'] }}",
reserved: {{ str(slapparameter_dict['plmn_list'][k].get('reserved', false)).lower() }},
attach_without_pdn: {{ str(slapparameter_dict['plmn_list'][k].get('attach_without_pdn', false)).lower() }},
}
{%- endfor -%}
{% else %}
"00101",
{% endif %}
],
n_antenna_dl: N_ANTENNA_DL,
n_antenna_ul: N_ANTENNA_UL,
{% if bbu == "ors" %}
manual_ref_signal_power: true,
{% endif %}
#if TDD == 1
uldl_config: {{ tdd_config }},
sp_config: 7,
#endif
n_rb_dl: N_RB_DL,
cyclic_prefix: "normal",
phich_duration: "normal",
phich_resource: "1",
si_value_tag: 0,
cell_barred: false,
intra_freq_reselection: true,
q_rx_lev_min: -70,
si_window_length: 40,
sib_sched_list: [
{
filename: "{{ sib23_file }}",
si_periodicity: 16,
},
],
#if N_RB_DL == 6
si_coderate: 0.30,
#else
si_coderate: 0.20,
#endif
si_pdcch_format: 2,
n_symb_cch: 0,
pdsch_dedicated: {
#if N_ANTENNA_DL == 4
p_a: -6,
#elif N_ANTENNA_DL == 2
p_a: -3,
#else
p_a: 0,
#endif
p_b: -1,
},
#if N_RB_DL == 6
pdcch_format: 1,
#else
pdcch_format: 2,
#endif
#if N_RB_DL == 6
prach_config_index: 15,
#else
prach_config_index: 4,
#endif
prach_freq_offset: -1,
pucch_dedicated: {
n1_pucch_sr_count: 11,
cqi_pucch_n_rb: 1,
#if TDD == 1
tdd_ack_nack_feedback_mode: "multiplexing", /* TDD only */
#endif
},
pusch_dedicated: {
beta_offset_ack_index: 9,
beta_offset_ri_index: 6,
beta_offset_cqi_index: 6,
},
pusch_hopping_offset: -1,
pusch_msg3_mcs: 0,
#if N_RB_DL == 6
initial_cqi: 5,
#else
initial_cqi: 3,
#endif
dl_256qam: true,
ul_64qam: true,
sr_period: 20,
cqi_period: 40,
#if N_ANTENNA_DL >= 2
m_ri: 8,
transmission_mode: 3,
#endif
srs_dedicated: {
#if N_RB_DL == 6
srs_bandwidth_config: 7,
srs_bandwidth: 1,
#elif N_RB_DL == 15
srs_bandwidth_config: 6,
srs_bandwidth: 1,
#elif N_RB_DL == 25
srs_bandwidth_config: 3,
srs_bandwidth: 1,
#elif N_RB_DL == 50
srs_bandwidth_config: 2,
srs_bandwidth: 2,
#elif N_RB_DL == 75
srs_bandwidth_config: 2,
srs_bandwidth: 2,
#else
srs_bandwidth_config: 2,
srs_bandwidth: 3,
#endif
srs_subframe_config: 3,
srs_period: 40,
srs_hopping_bandwidth: 0,
},
mac_config: {
ul_max_harq_tx: 5,
dl_max_harq_tx: 5,
},
pusch_max_its: 6,
dpc: true,
dpc_pusch_snr_target: 25,
dpc_pucch_snr_target: 20,
cipher_algo_pref: [],
integ_algo_pref: [2, 1],
inactivity_timer: {{ slapparameter_dict.get('inactivity_timer', slap_configuration['configuration.default_lte_inactivity_timer']) }},
srb_config: [
{
id: 1,
maxRetxThreshold: 32,
t_Reordering: 45,
t_PollRetransmit: 60,
},
{
id: 2 ,
maxRetxThreshold: 32,
t_Reordering: 45,
t_PollRetransmit: 60,
}
],
#if defined(TDD) && TDD == 1
#define T_REORDERING 65
#else
#define T_REORDERING 35
#endif
drb_config: [
{
qci: 1,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 100,
pdcp_SN_Size: 7,
},
nr_pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 12,
pdcp_SN_SizeDL: 12,
statusReportRequired: false,
outOfOrderDelivery: false,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_um: {
sn_FieldLength: 5,
},
dl_um: {
sn_FieldLength: 5,
t_Reordering: T_REORDERING,
},
},
logical_channel_config: {
priority: 7,
prioritisedBitRate: 0,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 2,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 150,
pdcp_SN_Size: 12,
},
nr_pdcp_config: {
discardTimer: 150,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: false,
outOfOrderDelivery: false,
t_Reordering: 0,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_um: {
sn_FieldLength: 10,
},
dl_um: {
sn_FieldLength: 10,
t_Reordering: T_REORDERING,
},
},
logical_channel_config: {
priority: 9,
prioritisedBitRate: 0,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 3,
pdcp_config: {
discardTimer: 100,
pdcp_SN_Size: 12,
},
nr_pdcp_config: {
discardTimer: 100,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: false,
outOfOrderDelivery: false,
t_Reordering: 0,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_um: {
sn_FieldLength: 10,
},
dl_um: {
sn_FieldLength: 10,
t_Reordering: T_REORDERING,
},
},
logical_channel_config: {
priority: 8,
prioritisedBitRate: 0,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 4,
pdcp_config: {
discardTimer: 0,
statusReportRequired: true,
},
nr_pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_am: {
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 32,
},
dl_am: {
t_Reordering: T_REORDERING,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 10,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 65,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 100,
pdcp_SN_Size: 7,
},
nr_pdcp_config: {
discardTimer: 100,
pdcp_SN_SizeUL: 12,
pdcp_SN_SizeDL: 12,
statusReportRequired: false,
outOfOrderDelivery: false,
t_Reordering: 0,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_um: {
sn_FieldLength: 5,
},
dl_um: {
sn_FieldLength: 5,
t_Reordering: T_REORDERING,
},
},
logical_channel_config: {
priority: 5,
prioritisedBitRate: 0,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 66,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 150,
pdcp_SN_Size: 12,
},
nr_pdcp_config: {
discardTimer: 150,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: false,
outOfOrderDelivery: false,
t_Reordering: 0,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_um: {
sn_FieldLength: 10,
},
dl_um: {
sn_FieldLength: 10,
t_Reordering: T_REORDERING,
},
},
logical_channel_config: {
priority: 7,
prioritisedBitRate: 0,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 67,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 100,
pdcp_SN_Size: 12,
},
nr_pdcp_config: {
discardTimer: 100,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: false,
outOfOrderDelivery: false,
t_Reordering: 0,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_um: {
sn_FieldLength: 10,
},
dl_um: {
sn_FieldLength: 10,
t_Reordering: T_REORDERING,
},
},
logical_channel_config: {
priority: 6,
prioritisedBitRate: 0,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 5,
pdcp_config: {
discardTimer: 0,
statusReportRequired: true,
},
nr_pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_am: {
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 32,
},
dl_am: {
t_Reordering: T_REORDERING,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 6,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 6,
pdcp_config: {
discardTimer: 0,
statusReportRequired: true,
},
nr_pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_am: {
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 32,
},
dl_am: {
t_Reordering: T_REORDERING,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 12,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 2,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 7,
pdcp_config: {
discardTimer: 100,
pdcp_SN_Size: 12,
},
nr_pdcp_config: {
discardTimer: 100,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: false,
outOfOrderDelivery: false,
t_Reordering: 0,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_um: {
sn_FieldLength: 10,
},
dl_um: {
sn_FieldLength: 10,
t_Reordering: T_REORDERING,
},
},
logical_channel_config: {
priority: 13,
prioritisedBitRate: 0,
bucketSizeDuration: 100,
logicalChannelGroup: 2,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 8,
pdcp_config: {
discardTimer: 0,
statusReportRequired: true,
},
nr_pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_am: {
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 32,
},
dl_am: {
t_Reordering: T_REORDERING,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 14,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 2,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 9,
pdcp_config: {
discardTimer: 0,
statusReportRequired: true,
},
nr_pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
},
en_dc_split: {
type: "scg",
ul_data_threshold: 0
},
rlc_config: {
ul_am: {
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 32,
},
dl_am: {
t_Reordering: T_REORDERING,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 15,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 3,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 69,
pdcp_config: {
discardTimer: 0,
statusReportRequired: true,
},
nr_pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_am: {
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 32,
},
dl_am: {
t_Reordering: T_REORDERING,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 4,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
{
qci: 70,
pdcp_config: {
discardTimer: 0,
statusReportRequired: true,
},
nr_pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
restrict_to_ng_enb: true,
},
rlc_config: {
ul_am: {
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 32,
},
dl_am: {
t_Reordering: T_REORDERING,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 11,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 2,
logicalChannelSR_Mask: false,
logicalChannelSR_Prohibit: false,
},
},
],
meas_config_desc: {
a1_report_type: "rsrp",
a1_rsrp: -70,
a1_hysteresis: 0,
a1_time_to_trigger: 640,
a2_report_type: "rsrp",
a2_rsrp: -80,
a2_hysteresis: 0,
a2_time_to_trigger: 640,
a3_report_type: "rsrp",
a3_offset: {{ slapparameter_dict.get('lte_handover_a3_offset', 6) }},
a3_hysteresis: 0,
a3_time_to_trigger: {{ slapparameter_dict.get('lte_handover_a3_time_to_trigger', 480) }},
},
meas_gap_config: "gp0",
ho_from_meas: true,
},
}
{%- if slapparameter_dict.get('tdd_ul_dl_config', '5ms 2UL 7DL 4/6 (default)') == '5ms 2UL 7DL 4/6 (default)' %}
{%- set tdd_config = 1 %}
{%- elif slapparameter_dict.get('tdd_ul_dl_config', '5ms 2UL 7DL 4/6 (default)') == '2.5ms 1UL 3DL 2/10' %}
{%- set tdd_config = 2 %}
{%- elif slapparameter_dict.get('tdd_ul_dl_config', '5ms 2UL 7DL 4/6 (default)') == '5ms 8UL 1DL 2/10 (maximum uplink)' %}
{%- set tdd_config = 3 %}
{%- endif %}
#define N_ANTENNA_DL {{ slapparameter_dict.get('n_antenna_dl', slap_configuration['configuration.default_n_antenna_dl']) }}
{% if ru == "m2ru" %}
#define N_ANTENNA_UL {{ slapparameter_dict.get('n_antenna_ul', 1) }}
{% else %}
#define N_ANTENNA_UL {{ slapparameter_dict.get('n_antenna_ul', slap_configuration['configuration.default_n_antenna_dl']) }}
{% endif %}
{
{% if slapparameter_dict.get('log_phy_debug', False) %}
log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,ngap.level=debug,ngap.max_size=1,xnap.level=debug,xnap.max_size=1,rrc.level=debug,rrc.max_size=1,phy.level=debug,file.rotate=1G,file.path=/dev/null",
{% else %}
log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,ngap.level=debug,ngap.max_size=1,xnap.level=debug,xnap.max_size=1,rrc.level=debug,rrc.max_size=1,phy.level=info,file.rotate=1G,file.path=/dev/null",
{% endif %}
log_filename: "{{ directory['log'] }}/gnb.log",
{% if ru == "m2ru" %}
rf_driver: {
{%- if slapparameter_dict.get('disable_sdr', False) %}
name: "dummy",
{%- else %}
name: "sdr",
{%- endif %}
args: "dev0=/dev/sdr0@0",
cpri_mapping: "bf1",
cpri_mult: 16,
cpri_rx_delay: 11.0,
cpri_tx_delay: 0,
ifname: "cpri0",
cpri_tx_dbm: 42.0,
},
tx_gain: 0,
rx_gain: 0,
{% else %}
rf_driver: {
{%- if slapparameter_dict.get('disable_sdr', False) %}
name: "dummy",
{%- else %}
name: "sdr",
{%- endif %}
args: "dev0=/dev/sdr0",
{% if slapparameter_dict.get('gps_sync', False) %}
sync: "gps",
{% endif %}
rx_antenna: "tx_rx",
tdd_tx_mod: 1,
},
tx_gain: {{ tx_gain }},
rx_gain: {{ rx_gain }},
{% endif %}
{%- if slapparameter_dict.get('websocket_password', '') %}
com_addr: "[{{ gtp_addr_v6 }}]:{{ slap_configuration['configuration.com_ws_port'] }}",
com_auth: {
password: "{{ slapparameter_dict['websocket_password'] }}",
},
{%- else %}
com_addr: "{{ slap_configuration['configuration.com_addr'] }}:{{ slap_configuration['configuration.com_ws_port'] }}",
{%- endif %}
amf_list: [
{% if slapparameter_dict.get('amf_list', '') %}
{%- for i, k in enumerate(slapparameter_dict['amf_list']) %}
{%- if i == 0 %}
{
{%- else -%}
, {
{%- endif %}
amf_addr: "{{ slapparameter_dict['amf_list'][k]['amf_addr'] }}",
}
{%- endfor -%}
{% else %}
{
amf_addr: "{{ slap_configuration['configuration.amf_addr'] }}",
},
{% endif %}
],
{% if slapparameter_dict.get('xn_peers', '') %}
xn_peers: [
{%- for k in slapparameter_dict['xn_peers'] -%}
"{{ slapparameter_dict['xn_peers'][k]['xn_addr'] }}",
{%- endfor -%}
],
{% endif %}
{% if slapparameter_dict.get('amf_list', '') %}
{% if slapparameter_dict.get('use_ipv4', False) %}
gtp_addr: "{{ gtp_addr_v4 }}",
{% else %}
gtp_addr: "{{ gtp_addr_v6 }}",
{% endif %}
{% else %}
gtp_addr: "{{ slap_configuration['configuration.gtp_addr'] }}",
{% endif %}
gnb_id_bits: {{ slapparameter_dict.get('gnb_id_bits', 28) }},
gnb_id: {{ slapparameter_dict.get('gnb_id', '0x12345') }},
en_dc_support: true,
cell_list: [],
nr_cell_list: [
{
rf_port: 0,
cell_id: {{ slapparameter_dict.get('cell_id', '0x01') }},
band: {{ nr_band }},
dl_nr_arfcn: {{ nr_arfcn }},
subcarrier_spacing: 30,
ssb_pos_bitmap: "{{ slapparameter_dict.get('ssb_pos_bitmap', slap_configuration['configuration.default_nr_ssb_pos_bitmap']) }}",
{%- if slapparameter_dict.get('ncell_list', '') %}
ncell_list: [
{%- for i, k in enumerate(slapparameter_dict['ncell_list']) %}
{%- if i == 0 -%}
{
{%- else -%}
, {
{%- endif %}
rat: "nr",
dl_nr_arfcn: {{ slapparameter_dict['ncell_list'][k].get('dl_nr_arfcn', '') }},
ssb_nr_arfcn: {{ slapparameter_dict['ncell_list'][k].get('ssb_nr_arfcn', '') }},
ul_nr_arfcn: {{ slapparameter_dict['ncell_list'][k].get('dl_nr_arfcn', '') }},
n_id_cell: {{ slapparameter_dict['ncell_list'][k].get('pci', '') }},
gnb_id_bits: {{ slapparameter_dict['ncell_list'][k].get('gnb_id_bits', '') }},
nr_cell_id: {{ slapparameter_dict['ncell_list'][k].get('nr_cell_id', '') }},
tac: {{ slapparameter_dict['ncell_list'][k].get('tac', 1) }},
band: {{ slapparameter_dict['ncell_list'][k].get('nr_band', '') }},
ssb_subcarrier_spacing: 30,
ssb_period: 20,
ssb_offset: 0,
ssb_duration: 1,
}
{%- endfor -%}
],
{% endif %}
},
],
nr_cell_default: {
bandwidth: {{ slapparameter_dict.get('nr_bandwidth', slap_configuration['configuration.default_nr_bandwidth']) }},
n_antenna_dl: N_ANTENNA_DL,
n_antenna_ul: N_ANTENNA_UL,
{%- if bbu == "ors" %}
manual_ref_signal_power: true,
{%- if one_watt == "True" %}
ss_pbch_block_power: {{ (tx_gain | int) - 54 }},
{%- else %}
ss_pbch_block_power: {{ (tx_gain | int) - 35 }},
{%- endif -%}
{%- endif %}
{% if tdd_config == 1 %}
tdd_ul_dl_config: {
pattern1: {
period: 5,
dl_slots: 7,
dl_symbols: 6,
ul_slots: 2,
ul_symbols: 4,
},
},
{% elif tdd_config == 2 %}
tdd_ul_dl_config: {
pattern1: {
period: 2.5,
dl_slots: 3,
dl_symbols: 10,
ul_slots: 1,
ul_symbols: 2,
},
},
{% elif tdd_config == 3 %}
tdd_ul_dl_config: {
pattern1: {
period: 5, /* in ms */
dl_slots: 1,
dl_symbols: 10,
ul_slots: 8,
ul_symbols: 2,
},
},
{% endif %}
ssb_period: 20,
n_id_cell: {{ slapparameter_dict.get('pci', 500) }},
plmn_list: [
{%- if slapparameter_dict.get('plmn_list', '') %}
{%- for i, k in enumerate(slapparameter_dict['plmn_list']) %}
{%- if i == 0 -%}
{
{%- else -%}
, {
{%- endif %}
plmn: "{{ slapparameter_dict['plmn_list'][k]['plmn'] }}",
tac: {{ slapparameter_dict['plmn_list'][k].get('tac', 100) }},
{%- if slapparameter_dict['plmn_list'][k].get('ranac', '') %}
ranac: {{ slapparameter_dict['plmn_list'][k]['ranac'] }},
{%- endif %}
reserved: {{ str(slapparameter_dict['plmn_list'][k].get('reserved', false)).lower() }},
nssai: [
{%- if slapparameter_dict.get('nssai', '') %}
{%- for j, k in enumerate(slapparameter_dict['nssai']) %}
{%- if j == 0 %}
{
{%- else -%}
, {
{%- endif %}
sst: {{ slapparameter_dict['nssai'][k]['sst'] }},
{%- if slapparameter_dict['nssai'][k].get('sd', '') %}
sd: {{ slapparameter_dict['nssai'][k]['sd'] }},
{%- endif %}
}
{%- endfor -%}
{% else %}
{
sst: 1,
},
{% endif %}
],
}
{%- endfor -%}
{% else %}
{
plmn: "00101",
tac: 100,
reserved: false,
nssai: [
{%- if slapparameter_dict.get('nssai', '') %}
{%- for j, k in enumerate(slapparameter_dict['nssai']) %}
{%- if j == 0 %}
{
{%- else -%}
, {
{%- endif %}
sst: {{ slapparameter_dict['nssai'][k]['sst'] }},
{%- if slapparameter_dict['nssai'][k].get('sd', '') %}
sd: {{ slapparameter_dict['nssai'][k]['sd'] }},
{%- endif %}
}
{%- endfor -%}
{% else %}
{
sst: 1,
},
{% endif %}
],
},
{%- endif %}
],
si_window_length: 40,
cell_barred: false,
intra_freq_reselection: true,
q_rx_lev_min: -70,
q_qual_min: -20,
root_sequence_index: 1,
sr_period: 40,
dmrs_type_a_pos: 2,
prach: {
prach_config_index: 160,
msg1_subcarrier_spacing: 30,
msg1_fdm: 1,
{% if ru == "m2ru" %}
msg1_frequency_start: 0,
{% else %}
msg1_frequency_start: -1,
{% endif %}
zero_correlation_zone_config: 15,
preamble_received_target_power: -110,
preamble_trans_max: 7,
power_ramping_step: 4,
ra_response_window: 20,
restricted_set_config: "unrestricted_set",
ra_contention_resolution_timer: 64,
ssb_per_prach_occasion: 1,
cb_preambles_per_ssb: 8,
},
pdcch: {
{% if ru == "m2ru" %}
n_rb_coreset0: 48,
n_symb_coreset0: 1,
{% endif %}
search_space0_index: 0,
dedicated_coreset: {
rb_start: -1,
l_crb: -1,
{% if ru == "m2ru" %}
duration: 1,
{% else %}
duration: 0,
{% endif %}
precoder_granularity: "sameAsREG_bundle",
},
css: {
n_candidates: [ 0, 0, 4, 0, 0 ],
},
rar_al_index: 2,
si_al_index: 2,
{% if tdd_config == 3 %}
uss: {
n_candidates: [ 0, 8, 1, 0, 0 ],
dci_0_1_and_1_1: true,
},
{% else %}
uss: {
n_candidates: [ 0, 2, 1, 0, 0 ],
dci_0_1_and_1_1: true,
},
{% endif %}
al_index: 1,
},
pdsch: {
mapping_type: "typeA",
dmrs_add_pos: 1,
dmrs_type: 1,
dmrs_max_len: 1,
{% if ru == "m2ru" %}
k0: 0,
k1: [ 8, 7, 7, 6, 5, 4, 12, 11 ],
{% elif tdd_config == 3 %}
k1: [4, 11],
{% endif %}
mcs_table: "qam256",
rar_mcs: 2,
si_mcs: 6,
},
csi_rs: {
nzp_csi_rs_resource: [
{
csi_rs_id: 0,
#if N_ANTENNA_DL == 1
n_ports: 1,
frequency_domain_allocation: "row2",
bitmap: "100000000000",
cdm_type: "no_cdm",
#elif N_ANTENNA_DL == 2
n_ports: 2,
frequency_domain_allocation: "other",
bitmap: "100000",
cdm_type: "fd_cdm2",
#elif N_ANTENNA_DL == 4
n_ports: 4,
frequency_domain_allocation: "row4",
bitmap: "100",
cdm_type: "fd_cdm2",
#elif N_ANTENNA_DL == 8
n_ports: 8,
frequency_domain_allocation: "other",
bitmap: "110011",
cdm_type: "fd_cdm2",
#else
#error unsupported number of DL antennas
#endif
density: 1,
first_symb: 4,
rb_start: 0,
l_crb: -1,
power_control_offset: 0,
power_control_offset_ss: 0,
period: 80,
offset: 1,
qcl_info_periodic_csi_rs: 0,
},
{% if tdd_config != 3 %}
{
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,
power_control_offset: 0,
power_control_offset_ss: 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,
power_control_offset: 0,
power_control_offset_ss: 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,
power_control_offset: 0,
power_control_offset_ss: 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,
power_control_offset: 0,
power_control_offset_ss: 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,
},
{% if tdd_config != 3 %}
{
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,
period: 80,
offset: 1,
},
],
csi_im_resource_set: [
{
csi_im_set_id: 0,
csi_im_resources: [ 0 ],
}
],
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,
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",
},
{% if tdd_config != 3 %}
{
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",
#if N_ANTENNA_DL > 1
codebook_config: {
codebook_type: "type1",
sub_type: "typeI_SinglePanel",
#if N_ANTENNA_DL == 2
#elif N_ANTENNA_DL == 4
n1: 2,
n2: 1,
codebook_mode: 1,
#elif N_ANTENNA_DL == 8
n1: 4,
n2: 1,
codebook_mode: 1,
#endif
},
#endif
cqi_table: 2,
subband_size: "value1",
},
],
},
pucch: {
dpc_snr_target: 25,
pucch_group_hopping: "neither",
hopping_id: -1,
p0_nominal: -90,
pucch1: {
n_cs: 3,
n_occ: 3,
freq_hopping: true,
},
pucch2: {
n_symb: 2,
n_prb: 1,
freq_hopping: true,
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: "qam256",
mcs_table_tp: "qam256",
ldpc_max_its: 5,
{% if ru == "m2ru" %}
k2: 4,
msg3_k2: 7,
{% elif tdd_config == 3 %}
k2: [11, 12, 4, 5, 6, 7, 7, 8],
msg3_k2: 7,
{% endif %}
p0_nominal_with_grant: -84,
msg3_mcs: 4,
msg3_delta_power: 0,
beta_offset_ack_index: 9,
},
mac_config: {
msg3_max_harq_tx: 5,
ul_max_harq_tx: 5,
dl_max_harq_tx: 5,
ul_max_consecutive_retx: 30,
dl_max_consecutive_retx: 30,
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,
sr_trans_max: 64,
},
cipher_algo_pref: [],
integ_algo_pref: [2, 1],
inactivity_timer: {{ slapparameter_dict.get('inactivity_timer', slap_configuration['configuration.default_nr_inactivity_timer']) }},
drb_config: [
{
qci: 1,
use_for_mr_dc_scg: false,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 100,
pdcp_SN_SizeUL: 12,
pdcp_SN_SizeDL: 12,
statusReportRequired: false,
outOfOrderDelivery: false,
t_Reordering: 0,
},
rlc_config: {
ul_um: {
sn_FieldLength: 6,
},
dl_um: {
sn_FieldLength: 6,
t_Reassembly: 50,
},
},
logical_channel_config: {
priority: 7,
prioritisedBitRate: 0,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
},
},
{
qci: 2,
use_for_mr_dc_scg: false,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 150,
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,
bucketSizeDuration: 100,
logicalChannelGroup: 1,
},
},
{
qci: 3,
pdcp_config: {
discardTimer: 100,
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,
bucketSizeDuration: 100,
logicalChannelGroup: 2,
},
},
{
qci: 4,
pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
},
rlc_config: {
ul_am: {
sn_FieldLength: 18,
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 4,
},
dl_am: {
sn_FieldLength: 18,
t_Reassembly: 80,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 9,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 3,
},
},
{
qci: 65,
use_for_mr_dc_scg: false,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 100,
pdcp_SN_SizeUL: 12,
pdcp_SN_SizeDL: 12,
statusReportRequired: false,
outOfOrderDelivery: false,
t_Reordering: 0,
},
rlc_config: {
ul_um: {
sn_FieldLength: 6,
},
dl_um: {
sn_FieldLength: 6,
t_Reassembly: 50,
},
},
logical_channel_config: {
priority: 5,
prioritisedBitRate: 0,
bucketSizeDuration: 100,
logicalChannelGroup: 4,
},
},
{
qci: 66,
use_for_mr_dc_scg: false,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 150,
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,
bucketSizeDuration: 100,
logicalChannelGroup: 4,
},
},
{
qci: 67,
use_for_mr_dc_scg: false,
ims_dedicated_bearer: true,
pdcp_config: {
discardTimer: 100,
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,
bucketSizeDuration: 100,
logicalChannelGroup: 5,
},
},
{
qci: 5,
use_for_mr_dc_scg: false,
pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
},
rlc_config: {
ul_am: {
sn_FieldLength: 18,
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 4,
},
dl_am: {
sn_FieldLength: 18,
t_Reassembly: 80,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 6,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 4,
},
},
{
qci: 6,
pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
},
rlc_config: {
ul_am: {
sn_FieldLength: 18,
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 4,
},
dl_am: {
sn_FieldLength: 18,
t_Reassembly: 80,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 10,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 5,
},
},
{
qci: 7,
pdcp_config: {
discardTimer: 100,
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,
bucketSizeDuration: 100,
logicalChannelGroup: 6,
},
},
{
qci: 8,
pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
},
rlc_config: {
ul_am: {
sn_FieldLength: 18,
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 4,
},
dl_am: {
sn_FieldLength: 18,
t_Reassembly: 80,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 12,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 7,
},
},
{
qci: 9,
pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
},
rlc_config: {
ul_am: {
sn_FieldLength: 18,
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 4,
},
dl_am: {
sn_FieldLength: 18,
t_Reassembly: 80,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 13,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 7,
},
},
{
qci: 69,
use_for_mr_dc_scg: false,
pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
},
rlc_config: {
ul_am: {
sn_FieldLength: 18,
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 4,
},
dl_am: {
sn_FieldLength: 18,
t_Reassembly: 80,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 4,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 4,
},
},
{
qci: 70,
pdcp_config: {
discardTimer: 0,
pdcp_SN_SizeUL: 18,
pdcp_SN_SizeDL: 18,
statusReportRequired: true,
outOfOrderDelivery: false,
},
rlc_config: {
ul_am: {
sn_FieldLength: 18,
t_PollRetransmit: 80,
pollPDU: 64,
pollByte: 125,
maxRetxThreshold: 4,
},
dl_am: {
sn_FieldLength: 18,
t_Reassembly: 80,
t_StatusProhibit: 10,
},
},
logical_channel_config: {
priority: 11,
prioritisedBitRate: 8,
bucketSizeDuration: 100,
logicalChannelGroup: 5,
},
},
],
meas_config_desc: {
a1_report_type: "rsrp",
a1_rsrp: -60,
a1_hysteresis: 10,
a1_time_to_trigger: 100,
a2_report_type: "rsrp",
a2_rsrp: -70,
a2_hysteresis: 0,
a2_time_to_trigger: 100,
a3_report_type: "rsrp",
a3_offset: {{ slapparameter_dict.get('nr_handover_a3_offset', 6) }},
a3_hysteresis: 0,
a3_time_to_trigger: {{ slapparameter_dict.get('nr_handover_time_to_trigger', 100) }},
ssb_rsrq_filter_coeff: 3,
ssb_sinr_filter_coeff: 5
},
meas_gap_config: {
pattern_id: 0
},
},
}
{
log_options: "all.level=debug,all.max_size=32",
log_filename: "{{ directory['log'] }}/ims.log",
sip_addr: [
{addr: "{{ slap_configuration['tun-ipv4-addr'] }}", bind_addr: "0.0.0.0", port_min: 10000, port_max: 20000},
{#" slap_configuration['tun-ipv6-addr'] ",#}
],
mms_server_bind_addr: "{{ netaddr.IPAddress(netaddr.IPNetwork(slap_configuration['tun-ipv4-network']).first) + 1 }}:1111",
sctp_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
cx_server_addr: "127.0.1.100",
cx_bind_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
rx_server_addr: "127.0.1.100",
rx_bind_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
domain: "{{ slap_configuration['configuration.domain'] }}",
include "{{ slap_configuration['ue_db_path'] }}",
{# Example of of s6a connection #}
{# s6: { #}
{# server_addr: "", #}
{# bind_addr: "", #}
{# origin_realm: "", #}
{# origin_host: "", #}
{# }, #}
echo: [
"tel:666",
"tel:+666",
{impu: "tel:404", code: 404},
{impu: "urn:service:sos", anonymous: true, authentication: false},
{impu: "urn:service:sos.police", anonymous: true, authentication: false},
],
precondition: "on",
"100rel": true,
ipsec_aalg_list: ["hmac-md5-96", "hmac-sha-1-96"],
ipsec_ealg_list: ["null", "aes-cbc", "des-cbc", "des-ede3-cbc"],
mt_call_sdp_file: "{{ directory['software'] }}/mme/config/mt_call.sdp",
ue_db_filename: "{{ directory['var'] }}/lte_ue_ims.db",
}
{
log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,s1ap.level=debug,s1ap.max_size=1,ngap.level=debug,ngap.max_size=1,file.rotate=1G,file.path=/dev/null",
log_filename: "{{ directory['log'] }}/mme.log",
{% if slapparameter_dict.get('external_enb_gnb', '') %}
{% if slapparameter_dict.get('use_ipv4', False) %}
gtp_addr: "{{ gtp_addr_v4 }}",
{% else %}
gtp_addr: "{{ gtp_addr_v6 }}",
{% endif %}
{% else %}
gtp_addr: "{{ slap_configuration['configuration.gtp_addr'] }}",
{% endif %}
plmn: "{{ slapparameter_dict.get('core_network_plmn', "00101") }}",
mme_group_id: 32769,
mme_code: 1,
ims_vops_eps: true,
ims_vops_5gs_3gpp: true,
ims_vops_5gs_n3gpp: true,
emergency_number_list: [
{ category: 0x1f, digits: "911" },
{ category: 0x1f, digits: "112" },
],
rx: {
qci: {audio: 1, video: 2},
},
network_name: "{{ slapparameter_dict.get('network_name', 'RAPIDSPACE') }}",
network_short_name: "{{ slapparameter_dict.get('network_short_name', 'RAPIDSPACE') }}",
cp_ciot_opt: true,
nr_support: true,
eps_5gs_interworking: "with_n26",
fifteen_bearers: false,
ims_list: [
{
ims_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
bind_addr: "{{ slap_configuration['configuration.ims_bind'] }}"
}
],
pdn_list: [
{
{% if slap_configuration.get('tun-ipv6-network', '') %}
pdn_type: "ipv4v6",
first_ipv6_prefix: "{{ netaddr.IPAddress(slap_configuration.get('tun-ipv6-addr', '')) + 1 }}",
last_ipv6_prefix: "{{ netaddr.IPAddress(netaddr.IPNetwork(slap_configuration.get('tun-ipv6-network', '')).last) - 1 }}",
{% if slapparameter_dict.get('local_domain', '') %}
dns_addr: ["{{ slap_configuration.get('tun-ipv4-addr', '') }}"],
{% else %}
dns_addr: ["8.8.8.8", "2001:4860:4860::8888"],
{% endif %}
{% else %}
pdn_type: "ipv4",
dns_addr: "8.8.8.8",
{% endif %}
tun_ifname: "{{ slap_configuration.get('tun-name', '') }}",
access_point_name: ["default", "internet", "ims", "sos"],
{% if slap_configuration.get('tun-name', '') %}
first_ip_addr: "{{ netaddr.IPAddress(netaddr.IPNetwork(slap_configuration.get('tun-ipv4-network', '')).first) + 2 }}",
last_ip_addr: "{{ netaddr.IPAddress(netaddr.IPNetwork(slap_configuration.get('tun-ipv4-network', '')).last) - 1 }}",
{% endif %}
ip_addr_shift: 2,
p_cscf_addr: ["{{ slap_configuration.get('tun-ipv4-addr', '') }}"],
erabs: [
{
qci: 9,
priority_level: 15,
pre_emption_capability: "shall_not_trigger_pre_emption",
pre_emption_vulnerability: "not_pre_emptable",
},
],
},
],
tun_setup_script: "{{ ifup_empty }}",
ue_to_ue_forwarding: false,
nas_cipher_algo_pref: [ ],
nas_integ_algo_pref: [ 2, 1 ],
include "{{ slap_configuration['ue_db_path'] }}",
ue_db_filename: "{{ directory['var'] }}/lte_ue.db"
}
{
message c1: systemInformation: {
criticalExtensions systemInformation-r8: {
sib-TypeAndInfo {
sib2: {
radioResourceConfigCommon {
rach-ConfigCommon {
preambleInfo {
numberOfRA-Preambles n52
},
powerRampingParameters {
powerRampingStep dB2,
preambleInitialReceivedTargetPower dBm-104
},
ra-SupervisionInfo {
preambleTransMax n10,
ra-ResponseWindowSize sf10,
mac-ContentionResolutionTimer sf40
},
maxHARQ-Msg3Tx 5
},
bcch-Config {
modificationPeriodCoeff n4
},
pcch-Config {
defaultPagingCycle rf128,
nB oneT
},
prach-Config {
rootSequenceIndex 0, /* patched by eNB */
prach-ConfigInfo {
prach-ConfigIndex 4, /* patched by eNB */
highSpeedFlag FALSE,
zeroCorrelationZoneConfig 11,
prach-FreqOffset 4 /* patched by eNB */
}
},
pdsch-ConfigCommon {
{% if bbu == "ors" %}
{%- if one_watt == "True" %}
referenceSignalPower {{ (tx_gain | int) - 54 }}, /* patched by eNB */
{%- else %}
referenceSignalPower {{ (tx_gain | int) - 35 }}, /* patched by eNB */
{%- endif %}
{% else %}
referenceSignalPower -8, /* patched by eNB */
{% endif %}
p-b 1 /* patched by eNB */
},
pusch-ConfigCommon {
pusch-ConfigBasic {
n-SB 1,
hoppingMode interSubFrame,
pusch-HoppingOffset 8, /* patched by eNB */
enable64QAM FALSE /* patched by eNB */
},
ul-ReferenceSignalsPUSCH {
groupHoppingEnabled FALSE,
groupAssignmentPUSCH 0,
sequenceHoppingEnabled FALSE,
cyclicShift 0
}
},
pucch-ConfigCommon {
deltaPUCCH-Shift ds2,
nRB-CQI 4, /* patched by eNB */
nCS-AN 0,
n1PUCCH-AN 12 /* patched by eNB */
},
soundingRS-UL-ConfigCommon setup: {
srs-BandwidthConfig bw2, /* patched by eNB */
srs-SubframeConfig sc3, /* patched by eNB */
ackNackSRS-SimultaneousTransmission TRUE
},
uplinkPowerControlCommon {
p0-NominalPUSCH -85,
alpha al1,
p0-NominalPUCCH -117,
deltaFList-PUCCH {
deltaF-PUCCH-Format1 deltaF0,
deltaF-PUCCH-Format1b deltaF3,
deltaF-PUCCH-Format2 deltaF1,
deltaF-PUCCH-Format2a deltaF2,
deltaF-PUCCH-Format2b deltaF2
},
deltaPreambleMsg3 4
},
ul-CyclicPrefixLength len1
},
ue-TimersAndConstants {
t300 ms200,
t301 ms200,
t310 ms200,
n310 n6,
t311 ms10000,
n311 n5
},
freqInfo {
additionalSpectrumEmission 1
},
timeAlignmentTimerCommon infinity
},
sib3: {
cellReselectionInfoCommon {
q-Hyst dB2
},
cellReselectionServingFreqInfo {
s-NonIntraSearch 3,
threshServingLow 2,
cellReselectionPriority 6
},
intraFreqCellReselectionInfo {
q-RxLevMin -61,
p-Max 23,
s-IntraSearch 5,
presenceAntennaPort1 TRUE,
neighCellConfig '01'B,
t-ReselectionEUTRA 1
}
}
}
}
}
}
{%- if slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '1.4 MHz' %}
#define N_RB_DL 6
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '3 MHz' %}
#define N_RB_DL 15
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '5 MHz' %}
#define N_RB_DL 25
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '10 MHz' %}
#define N_RB_DL 50
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '15 MHz' %}
#define N_RB_DL 75
{%- elif slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_lte_bandwidth']) == '20 MHz' %}
#define N_RB_DL 100
{%- endif %}
{
log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1,phy.level=info,file.rotate=1G,file.path=/dev/null",
log_filename: "{{ directory['log'] }}/ue.log",
rue_bind_addr: "{{ pub_info['rue_bind_addr'] }}",
com_addr: "{{ pub_info['com_addr'] }}",
rf_driver: {
name: "sdr",
args: "dev0=/dev/sdr0",
rx_antenna:"tx_rx",
},
tx_gain: {{ slapparameter_dict.get('tx_gain', 60) }},
rx_gain: {{ slapparameter_dict.get('rx_gain', 40) }},
cell_groups: [{
multi_ue: true,
cells: [
{
bandwidth: N_RB_DL,
dl_earfcn: {{ slapparameter_dict.get('dl_earfcn', 0) }},
n_antenna_dl: {{ slapparameter_dict.get('n_antenna_dl', slap_configuration['configuration.default_n_antenna_dl']) }},
n_antenna_ul: {{ slapparameter_dict.get('n_antenna_ul', slap_configuration['configuration.default_n_antenna_ul']) }},
global_timing_advance: -1,
}
],
pdcch_decode_opt: false,
pdcch_decode_opt_threshold: 0.1,
}],
ue_list: [
{
sim_algo: "{{ slapparameter_dict.get('sim_algo', 'milenage') }}",
opc: "{{ slapparameter_dict.get('opc', '') }}",
amf: {{ slapparameter_dict.get('amf', '0x9001') }},
sqn: "{{ slapparameter_dict.get('sqn', '000000000000') }}",
impu: "{{ slapparameter_dict.get('impu', '') }}",
impi: "{{ slapparameter_dict.get('impi', '') }}",
imsi: "{{ slapparameter_dict.get('imsi', slap_configuration['configuration.default_lte_imsi']) }}",
K: "{{ slapparameter_dict.get('k', slap_configuration['configuration.default_lte_k']) }}",
rue_addr: "{{ slapparameter_dict.get('rue_addr', '') }}",
ue_category: 12,
tun_setup_script: "ue-ifup",
apn: "internet",
}
],
}
{
log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1,phy.level=info,file.rotate=1G,file.path=/dev/null",
log_filename: "{{ directory['log'] }}/ue.log",
rue_bind_addr: "{{ pub_info['rue_bind_addr'] }}",
com_addr: "{{ pub_info['com_addr'] }}",
rf_driver: {
name: "sdr",
args: "dev0=/dev/sdr0",
rx_antenna:"tx_rx",
},
tx_gain: {{ slapparameter_dict.get('tx_gain', 60) }},
rx_gain: {{ slapparameter_dict.get('rx_gain', 40) }},
cell_groups: [{
group_type: "nr",
multi_ue: false,
cells: [{
rf_port: 0,
bandwidth: {{ slapparameter_dict.get('bandwidth', slap_configuration['configuration.default_nr_bandwidth']) }},
band: {{ slapparameter_dict.get('nr_band', 0) }},
dl_nr_arfcn: {{ slapparameter_dict.get('dl_nr_arfcn', 0) }},
ssb_nr_arfcn: {{ slapparameter_dict.get('ssb_nr_arfcn', 0) }},
subcarrier_spacing: 30,
n_antenna_dl: {{ slapparameter_dict.get('n_antenna_dl', slap_configuration['configuration.default_n_antenna_dl']) }},
n_antenna_ul: {{ slapparameter_dict.get('n_antenna_ul', slap_configuration['configuration.default_n_antenna_ul']) }},
}
],
}],
ue_list: [
{
sim_algo: "{{ slapparameter_dict.get('sim_algo', 'milenage') }}",
opc: "{{ slapparameter_dict.get('opc', '') }}",
amf: {{ slapparameter_dict.get('amf', '0x9001') }},
sqn: "{{ slapparameter_dict.get('sqn', '000000000000') }}",
impu: "{{ slapparameter_dict.get('impu', '') }}",
impi: "{{ slapparameter_dict.get('impi', '') }}",
imsi: "{{ slapparameter_dict.get('imsi', slap_configuration['configuration.default_nr_imsi']) }}",
K: "{{ slapparameter_dict.get('k', slap_configuration['configuration.default_nr_k']) }}",
rue_addr: "{{ slapparameter_dict.get('rue_addr', '') }}",
as_release: 15,
ue_category: "nr",
tun_setup_script: "ue-ifup",
apn: "internet",
}
]
}
{%- set filtered_slave_instance_list = [] %}
{%- for slave_instance in slave_instance_list %}
{%- if slave_instance.get('_', '') != '' %}
{%- set slave = json_module.loads(slave_instance.pop('_')) %}
{%- else %}
{%- set slave = slave_instance %}
{%- endif %}
{%- if slave.get('imsi', '') != '' %}
{%- do filtered_slave_instance_list.append(slave) %}
{%- endif %}
{%- endfor -%}
ue_db: [
{%- for i, slave in enumerate(filtered_slave_instance_list) %}
{%- if i == 0 -%}
{
{%- else -%}
, {
{%- endif %}
sim_algo: "{{ slave.get('sim_algo', 'milenage') }}",
imsi: "{{ slave.get('imsi', '') }}",
opc: "{{ slave.get('opc', '') }}",
amf: {{ slave.get('amf', '0x9001') }},
sqn: "{{ slave.get('sqn', '000000000000') }}",
K: "{{ slave.get('k', '') }}",
impu: "{{ slave.get('impu', '') }}",
impi: "{{ slave.get('impi', '') }}",
}
{%- endfor -%}
]
/*global window, rJS, RSVP, LineChart*/
/*jslint indent:2, maxlen:80, nomen:true */
(function () {
"use strict";
rJS(window)
.declareAcquiredMethod("getPromiseDocument", "getPromiseDocument")
.declareMethod("render", function () {
var gadget = this;
return gadget.getPromiseDocument(
"check-cpu-temperature",
"log/monitor/promise/check-cpu-temperature.json.log"
)
.push(function (result) {
//gadget.element.textContent = result;
result = result.replace(/\'/g, "\"");
var item = result.split("\n"),
tmp = "",
data_tmp = "",
data_list = [],
time = [],
data = [],
i = 0,
data_list_list,
canvas,
label,
tooltip,
line_chart;
item = JSON.parse(JSON.stringify(item));
for (i = 0; i < 30; i += 1) {
data_list.push(item[i]);
data_list_list = JSON.parse(data_list[i]);
if (data_list_list.hasOwnProperty("time")
&& data_list_list.hasOwnProperty("data")) {
tmp = data_list_list.time.split(" ")[1].split(",")[0];
data_tmp = data_list_list.data.cpu_temperature;
}
time.push(tmp);
data.push(data_tmp);
gadget.time = time;
gadget.data = data;
}
canvas = gadget.element.children.line;
data = gadget.data;
label = gadget.time;
tooltip = ['Twelve', 'Fifteen', 'Thirteen', 'Twenty-two',
'Eight', 'Twelve', 'Thirdy-one', 'Three', 'Five'];
line_chart = new LineChart(canvas, data, label, tooltip);
line_chart.draw();
line_chart.tooltipOn('mousemove');
});
});
}());
\ No newline at end of file
<html>
<head>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="g-chart.line.js"></script>
<script src="promise.gadget.js"></script>
<style type="text/css">
.tooltip-chart {
position: fixed;
z-index: 1000;
transform: translate(-50%, -120%);
padding: 10px;
background-color: white;
border-radius: 5px;
text-align: center;
min-width: 100px;
border: 1px solid #000;
box-shadow: 0 0 10px 5px #000;
}
</style>
</head>
<body>
<canvas id="line" width="1600" height="350"></canvas>
</body>
</html>
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Core Network Input Parameters",
"type": "object",
"properties": {
"core_network_plmn": {
"default": "00101",
"title": "Core Network PLMN",
"description": "Core Network Public Land Mobile Network",
"type": "string"
},
"external_enb_gnb": {
"default": false,
"title": "External eNB / gNB",
"description": "Set to true if external eNB / gNB will need to connect to this core network.",
"type": "boolean"
},
"iperf3": {
"default": false,
"title": "iperf3 UDP server",
"description": "Activate iperf3 UDP server",
"type": "boolean"
},
"local_domain": {
"default": "",
"title": "Local Domain",
"description": "Activates local DNS server serving the given domain name",
"type": "string"
},
"network_name": {
"title": "Network Name",
"description": "Network name displayed on UE",
"type": "string",
"default": "RAPIDSPACE"
},
"network_short_name": {
"title": "Network Short Name",
"description": "Network short name displayed on UE",
"type": "string",
"default": "RAPIDSPACE"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "SIM Card Parameters",
"required": [
"sim_algo",
"imsi",
"opc",
"amf",
"sqn",
"k",
"impu",
"impi"
],
"properties": {
"sim_algo": {
"title": "Sim Algorithm",
"description": "xor, milenage or tuak. Set the USIM authentication algorithm.",
"type": "string",
"default": "milenage"
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": ""
},
"opc": {
"title": "OPC",
"description": "Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, opc must be set.",
"type": "string",
"default": ""
},
"amf": {
"title": "AMF",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "SQN",
"description": "Optional String (6 byte hexadecimal string). Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": ""
},
"impu": {
"title": "IMPU",
"description": "sip URI or a telephone number. Note that sip URI must not include hostname. If IMPU does not start by a scheme, it is assumed to be a sip URI.",
"type": "string",
"default": ""
},
"impi": {
"title": "IMPI",
"description": "Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "{{ default_lte_bandwidth }}"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
{%- if bbu == 'ors' %}
"description": "1 or 2. Number of DL antennas.",
{%- else %}
"description": "1, 2, 4 or 8. Number of DL antennas.",
{%- endif %}
"type": "number",
"default": {{ default_n_antenna_dl }}
},
"n_antenna_ul": {
"title": "Number of UL antennas",
{%- if bbu == 'ors' %}
"description": "1 or 2. Number of UL antennas.",
{%- else %}
"description": "1, 2, 4 or 8. Number of UL antennas.",
{%- endif %}
"type": "number",
"default": {{ default_n_antenna_ul }}
},
{%- if rf_mode == 'tdd' %}
"tdd_ul_dl_config": {
"title": "TDD",
"description": "TDD",
"type": "string",
"enum": [
"[Configuration 2] 5ms 2UL 6DL (default)",
"[Configuration 6] 5ms 5UL 3DL (maximum uplink)"
],
"default": "5ms 2UL 7DL 4/6 (default)"
},
{%- endif %}
{%- if bbu != 'ors' %}
"sdr_number": {
"title": "SDR Number",
"description": "SDR Number",
"type": "number",
"default": 0
},
"cpri_port": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
{%- endif %}
{%- if trx == 'cpri' %}
"cpri_mult": {
"title": "CPRI Mult",
"description": "Select the CPRI line bit rate in terms of multiple of option 1 (614.4 Mbps). E.g set 4 for option 3, 8 for option 5 and 16 for option 7.",
"type": "number",
"default": 16,
"enum": [
4,
5,
8,
16
]
},
{%- endif %}
{%- if bbu == 'ors' %}
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 1
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tac": {
"title": "Tracking Area Code",
"description": "Tracking Area Code in hexadecimal representation (range 0x0000 to 0xffff)",
"default": "0x0001",
"type": "string"
},
"root_sequence_index": {
"title": "Root Sequence Index",
"description": "Range: 0 to 837. Set the PRACH root sequence index (SIB2.rootSequenceIndex field). It must be different for each neighbour cell operating on the same frequency and sharing the same PRACH configuration.",
"type": "number",
"default": 204
},
{%- else %}
"cell_list": {
"title": "Cell List",
"description": "Cell List",
"patternProperties": {
".*": {
"properties": {
{%- if trx == 'cpri' %}
"cpri_rx_delay": {
"title": "CPRI RX Delay",
"description": "Delays between TX and RX position in CPRI frame. This should be set to the value of (T2a + T3a - Toffset) provided by the RRH specification.",
"type": "number",
"default": 25.11
},
"cpri_tx_delay": {
"title": "CPRI TX Delay",
"description": "Advances Start of Frame relative to PPS to compensate for delays in transmit line and RRH. This should be set to T12 + T2a.",
"type": "number",
"default": 14.71
},
"cpri_tx_dbm": {
"title": "CPRI TX dBm",
"description": "Optional floating points value in dBm (default 0). Needed by ENB/GNB to have a notion of actual output power. Computed from maximum power output of the RRH for a 0dBFS input signal (full scale). ",
"type": "number",
"default": 63
},
"cpri_port_number": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
{%- endif %}
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell IDs",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Cell IDs",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
{%- endif %}
{%- if trx == 'sdr' %}
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
{%- endif %}
{%- if trx == 'cpri' %}
"dnsmasq": {
"default": false,
"title": "dnsmasq",
"description": "dnsmasq",
"type": "boolean"
},
"rrh_mac_addr": {
"default": "00:0a:00:00:10:20",
"title": "RRH MAC address",
"description": "RRH MAC address used for DNSMASQ",
"type": "string"
},
{%- endif %}
{%- if ru == 'lopcomm' %}
"txa0cc00_active": {
"title": "Lopcomm ORAN TX array carriers (TXA0CC00)",
"description": "Activate or inactivate Lopcomm ORAN TX array carriers (TXA0CC00)",
"type": "string",
"default": "INACTIVE",
"enum": [
"ACTIVE",
"INACTIVE"
]
},
"rxa0cc00_active": {
"title": "Lopcomm ORAN RX array carriers (RXA0CC00)",
"description": "Activate or inactivate Lopcomm ORAN RX array carriers (RXA0CC00)",
"type": "string",
"default": "INACTIVE",
"enum": [
"ACTIVE",
"INACTIVE"
]
},
"txa0cc00_center_frequency": {
"title": "Lopcomm ORAN DL Center Frequency in MHz (TXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in MHz (TXA0CC00)",
"type": "number",
"default": 2140
},
"rxa0cc00_center_frequency_earfcn": {
"title": "Lopcomm ORAN UL Center Frequency EARFCN (RXA0CC00)",
"description": "Lopcomm ORAN Center Frequency EARFCN (RXA0CC00)",
"type": "number",
"default": 18300
},
"rxa0cc00_center_frequency": {
"title": "Lopcomm ORAN UL Center Frequency in MHz (RXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in MHz (RXA0CC00)",
"type": "number",
"default": 1950
},
"txa0cc00_gain": {
"title": "ORAN Gain",
"description": "Lopcomm ORAN Gain (TXA0CC00)",
"type": "number",
"default": -20
},
"user-authorized-key": {
"title": "User Authorized Key",
"description": "SSH public key in order to connect to the SSH server of this instance.",
"textarea": true,
"type": "string"
},
"cron_schedule": {
"title": "Cron schedule for RRH reset",
"description": "Refer https://crontab.guru/ to make a reset schedule for RRH, for example, '0 1 * * *' means the RRH will reset every day at 1 am",
"type": "string"
},
{%- endif %}
"enb_id": {
"title": "eNB ID",
"description": "eNB ID",
"type": "string",
"default": "0x1A2D0"
},
"gtp_addr": {
"title": "GTP Address",
"description": "String. Set the IP address (and optional port) on which the GTP-U packets are received. The default port is 2152. It is normally the IP address of the network interface connected to the core network.",
"type": "string",
"default": "127.0.1.1"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"mme_addr": {
"title": "MME Address",
"description": "IP address (and optional port) of S1AP SCTP connection to the MME. The default port is 36412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the eNodeB, at most 6 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"attach_without_pdn": {
"default": false,
"title": "Attach Without PDN",
"description": "Optional boolean. Indicates if PLMN supports attach without PDN connectivity.",
"type": "boolean"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"lte_handover_a3_offset": {
"title": "A3 offset for LTE handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"lte_handover_time_to_trigger": {
"title": "Time to Trigger for LTE handover",
"description": "Time to triger after which LTE handover will be triggered if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 480
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Concatenation of enb_id and cell_id of the neighbour cell",
"type": "string"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": {{ default_lte_inactivity_timer }}
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"enb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics",
"type": "number",
"default": 60
},
"enb_drb_stats_enabled": {
"title": "Enable eNB drb statistics",
"description": "Enable eNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if minimum TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if average TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
[buildout]
parts =
directory
ltelogs
enb-config
enb-service
xamari-xlog-service
{% if slapparameter_dict.get('xlog_fluentbit_forward_host') %}
xlog-fluentbit-service
{% endif %}
amarisoft-stats-service
amarisoft-rf-info-service
{% if ru == "lopcomm" %}
lopcomm-firmware-dl
lopcomm-rrh-stats-service
lopcomm-rrh-supervision-service
lopcomm-rrh-reset-info-service
{% if slapparameter_dict.get("cron_schedule", None) %}
lopcomm-rrh-reset-cron
{% endif %}
lopcomm-rrh-config-template
lopcomm-rrh-software-template
netconf-connection-promise
firmware-update-promise
rrh-netconf-socket-promise
lopcomm-cu-config
sshd-service
sshd-add-authorized-key
sshd-promise
check-lopcomm-vswr.py
check-lopcomm-pa-current.py
check-lopcomm-pa-output-power.py
check-lopcomm-lof.py
check-lopcomm-rssi.py
check-lopcomm-sync.py
check-lopcomm-config-log.py
check-lopcomm-stats-log.py
check-cpri-lock.py
{% endif %}
{% if slapparameter_dict.get("dnsmasq", None) %}
dnsmasq-service
{% endif %}
check-sdr-busy.py
check-baseband-latency.py
check-amarisoft-stats-log.py
{% if not ru == "lopcomm" %}
check-rx-saturated.py
{% endif %}
monitor-base
publish-connection-information
extends = {{ monitor_template }}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[monitor-httpd-conf-parameter]
httpd-include-file = {{ buildout_directory }}/etc/httpd-include-file.conf
port = ${monitor-instance-parameter:monitor-httpd-port}
url = https://[${monitor-instance-parameter:monitor-httpd-ipv6}]:${:port}
[monitor-instance-parameter]
monitor-httpd-port = ${monitor-address:port}
[monitor-address]
recipe = slapos.cookbook:free_port
minimum = 8035
maximum = 8055
ip = ${monitor-instance-parameter:monitor-httpd-ipv6}
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised
computer = {{ slap_connection['computer-id'] }}
partition = {{ slap_connection['partition-id'] }}
url = {{ slap_connection['server-url'] }}
key = {{ slap_connection['key-file'] }}
cert = {{ slap_connection['cert-file'] }}
configuration.com_ws_port = 9001
configuration.com_addr = 127.0.1.2
configuration.mme_addr = 127.0.1.100
configuration.gtp_addr = 127.0.1.1
configuration.default_lte_bandwidth = {{ default_lte_bandwidth }}
configuration.default_lte_inactivity_timer = {{ default_lte_inactivity_timer }}
configuration.default_n_antenna_dl = {{ default_n_antenna_dl }}
configuration.default_n_antenna_ul = {{ default_n_antenna_ul }}
[directory]
recipe = slapos.cookbook:mkdirectory
software = {{ buildout_directory }}
home = ${buildout:directory}
var = ${:home}/var
etc = ${:home}/etc
bin = ${:home}/bin
tmp = ${:home}/tmp
run = ${:var}/run
script = ${:etc}/run
service = ${:etc}/service
promise = ${:etc}/promise
log = ${:var}/log
[ltelogs]
recipe = slapos.recipe.template:jinja2
url = {{ ltelogs_template }}
output = ${directory:home}/ltelogs.sh
extensions = jinja2.ext.do
context =
section directory directory
{% if slapparameter_dict.get("enb_config_link", None) %}
[enb-config-dl]
recipe = slapos.recipe.build:download
url = {{ slapparameter_dict.get("enb_config_link") }}
version = {{ slapparameter_dict.get("enb_config_version") }}
offline = false
{% endif %}
{% if slapparameter_dict.get("cu_config_link", None) %}
[cu-config-dl]
recipe = slapos.recipe.build:download
url = {{ slapparameter_dict.get("cu_config_link") }}
version = {{ slapparameter_dict.get("cu_config_version") }}
offline = false
{% endif %}
[enb-sh-wrapper]
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
enb-log = ${directory:log}/enb-output.log
inline =
#!/bin/sh
{% if not slapparameter_dict.get("testing", False) %}
sudo -n /opt/amarisoft/rm-tmp-lte;
sudo -n /opt/amarisoft/init-sdr;
sudo -n /opt/amarisoft/init-enb;
(echo && echo && date "+[%Y/%m/%d %T.%N %Z] Starting eNB software..." && echo) >> ${:enb-log};
tail -c 1M ${:enb-log} > ${:enb-log}.tmp;
mv ${:enb-log}.tmp ${:enb-log};
{{ enb }}/lteenb ${directory:etc}/enb.cfg >> ${:enb-log} 2>> ${:enb-log};
{% endif %}
[enb-service]
recipe = slapos.cookbook:wrapper
init = ${ltelogs:output} ${directory:log}/enb.log; sleep 2
command-line = ${enb-sh-wrapper:output}
wrapper-path = ${directory:service}/enb
mode = 0775
reserve-cpu = True
pidfile = ${directory:run}/enb.pid
hash-files =
${enb-config:output}
${enb-sh-wrapper:output}
environment =
LD_LIBRARY_PATH={{ openssl_location }}/lib
AMARISOFT_PATH=/opt/amarisoft/.amarisoft
{% if slapparameter_dict.get("dnsmasq", None) %}
[dnsmasq-service]
recipe = slapos.cookbook:wrapper
port = 5353
ip = ${slap-configuration:tun-ipv4-addr}
command-line = {{ dnsmasq_location }}/sbin/dnsmasq --conf-file={{ dnsmasq_config_path }} -x ${directory:run}/dnsmasq.pid --local-service --keep-in-foreground
wrapper-path = ${directory:service}/dnsmasq
mode = 0775
hash-files =
{{ dnsmasq_config_path }}
#[dnsmasq-listen-promise]
#<= monitor-promise-base
#promise = check_socket_listening
#name = dnsmasq-port-listening.py
#config-host = ${dnsmasq-service:ip}
#config-port = ${dnsmasq-service:port}
{% endif %}
[xamari-xlog-script]
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
stats_logspec = stats[samples,rf]/${:period}s
{%- if slapparameter_dict.get("enb_drb_stats_enabled", True) %}
drb_stats_logspec = x.drb_stats/${:period}s
{%- else %}
drb_stats_logspec =
{%- endif %}
rotatespec = 100MB.9
logspec = ${:stats_logspec} ${:drb_stats_logspec}
{%- if slapparameter_dict.get("websocket_password", "") %}
websock = ws://[${slap-configuration:ipv6-random}]:9001
{%- else %}
websock = ws://127.0.1.2:9001
{%- endif %}
xamari = {{ buildout_directory }}/bin/xamari
logfile = ${monitor-directory:public}/enb.xlog
inline =
#!/bin/sh
exec ${:xamari} xlog --rotate ${:rotatespec} ${:websock} ${:logfile} ${:logspec}
[xamari-xlog-service]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:service}/${:_buildout_section_name_}
command-line = ${xamari-xlog-script:output}
hash-files = ${:command-line}
{% if slapparameter_dict.get('xlog_fluentbit_forward_host') %}
[xlog-fluentbit-config]
recipe = slapos.recipe.template
output = ${directory:etc}/${:_buildout_section_name_}.cfg
logfile = ${xamari-xlog-script:logfile}
forward-host = {{ slapparameter_dict.get('xlog_fluentbit_forward_host', '') }}
forward-port = {{ slapparameter_dict.get('xlog_fluentbit_forward_port', '') }}
forward-shared-key = {{ slapparameter_dict.get('xlog_fluentbit_forward_shared_key', '') }}
forward-self-hostname = {{ ors_id['ors-id'] }}
inline =
[SERVICE]
flush 5
[INPUT]
name tail
path ${:logfile}
Read_from_Head True
[OUTPUT]
name forward
match *
Host ${:forward-host}
{%- if slapparameter_dict.get('xlog_fluentbit_forward_port') %}
Port ${:forward-port}
{%- endif %}
Shared_Key ${:forward-shared-key}
Self_Hostname ${:forward-self-hostname}
tls on
tls.verify off
[xlog-fluentbit-service]
recipe = slapos.cookbook:wrapper
fluentbit = {{ fluent_bit_location }}/bin/fluent-bit
fluentbit-config = ${xlog-fluentbit-config:output}
command-line = ${:fluentbit} -c ${:fluentbit-config}
wrapper-path = ${directory:service}/${:_buildout_section_name_}
hash-files = ${:fluentbit-config}
{% endif %}
[amarisoft-stats-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/amarisoft-stats.json.log
context =
section directory directory
key slapparameter_dict slap-configuration:configuration
key log_file :log-output
raw stats_period {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
mode = 0775
url = {{ amarisoft_stats_template }}
output = ${directory:bin}/amarisoft-stats.py
[amarisoft-rf-info-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/amarisoft-rf-info.json.log
context =
section directory directory
key slapparameter_dict slap-configuration:configuration
key log_file :log-output
raw stats_period {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
mode = 0775
url = {{ amarisoft_rf_info_template }}
output = ${directory:bin}/amarisoft-rf-info.py
[lopcomm-rrh-stats-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/lopcomm-rrh-stats.log
json-log-output = ${directory:var}/log/lopcomm-rrh-stats.json.log
cfg-json-log-output = ${directory:var}/log/lopcomm-rrh-config.json.log
supervision-json-log-output = ${directory:var}/log/lopcomm-rrh-supervision.json.log
ncsession-json-log-output = ${directory:var}/log/lopcomm-rrh-ncsession.json.log
software-json-log-output = ${directory:var}/log/lopcomm-rrh-software.json.log
context =
section directory directory
section slap_configuration slap-configuration
key slapparameter_dict slap-configuration:configuration
key log_file :log-output
key json_log_file :json-log-output
key cfg_json_log_file :cfg-json-log-output
key supervision_json_log_file :supervision-json-log-output
key ncsession_json_log_file :ncsession-json-log-output
key software_json_log_file :software-json-log-output
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
raw buildout_directory_path {{ buildout_directory }}
import netaddr netaddr
mode = 0775
url = {{ lopcomm_rrh_stats_template }}
output = ${directory:bin}/lopcomm-rrh-stats.py
[lopcomm-cu-config]
<= config-base
{% if slapparameter_dict.get("cu_config_link", None) %}
url = ${enb-config-dl:target}
{% else %}
url = {{ cu_config_template }}
{% endif %}
output = ${directory:etc}/cu_config.xml
[lopcomm-rrh-config-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/lopcomm-rrh-config.log
context =
section directory directory
section slap_configuration slap-configuration
key slapparameter_dict slap-configuration:configuration
key log_file :log-output
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
raw buildout_directory_path {{ buildout_directory }}
raw CreateProcessingEle_template {{ CreateProcessingEle_template }}
key cu_config_template lopcomm-cu-config:output
import netaddr netaddr
mode = 0775
url = {{ lopcomm_rrh_config_template }}
output = ${directory:script}/lopcomm-rrh-config.py
[lopcomm-rrh-software-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/lopcomm-rrh-software.log
software-reply-json-log-output = ${directory:var}/log/lopcomm-rrh-software-reply.json.log
remote-file-path = sftp://${user-info:pw-name}@[${slap-configuration:ipv6-random}]:${sshd-port:port}${lopcomm-firmware-dl:destination}
context =
section directory directory
section slap_configuration slap-configuration
key slapparameter_dict slap-configuration:configuration
key log_file :log-output
key software_reply_json_log_file :software-reply-json-log-output
key remote_file_path :remote-file-path
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
raw buildout_directory_path {{ buildout_directory }}
raw etc_path ${directory:etc}
raw firmware_name ${lopcomm-firmware-dl:filename}
import netaddr netaddr
mode = 0775
url = {{ lopcomm_rrh_software_template }}
output = ${directory:script}/lopcomm-rrh-software.py
[lopcomm-rrh-supervision-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/lopcomm-rrh-supervision.log
supervision-reply-json-log-output = ${directory:var}/log/lopcomm-rrh-supervision-reply.json.log
context =
section directory directory
section slap_configuration slap-configuration
key slapparameter_dict slap-configuration:configuration
key log_file :log-output
key supervision_reply_json_log_file :supervision-reply-json-log-output
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
raw buildout_directory_path {{ buildout_directory }}
raw etc_path ${directory:etc}
import netaddr netaddr
mode = 0775
url = {{ lopcomm_rrh_supervision_template }}
output = ${directory:bin}/lopcomm-rrh-supervision.py
[lopcomm-rrh-reset-info-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/lopcomm-rrh-reset-info.log
json-log-output = ${directory:var}/log/lopcomm-rrh-reset-info.json.log
context =
section slap_configuration slap-configuration
key log_file :log-output
key json_log_file :json-log-output
raw stats_period {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
import netaddr netaddr
mode = 0775
url = {{ lopcomm_rrh_reset_info_template }}
output = ${directory:bin}/lopcomm-rrh-reset-info.py
[lopcomm-rrh-reset-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/lopcomm-rrh-reset.log
json-log-output = ${directory:var}/log/lopcomm-rrh-reset.json.log
context =
section slap_configuration slap-configuration
key log_file :log-output
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
raw buildout_directory_path {{ buildout_directory }}
import netaddr netaddr
mode = 0775
url = {{ lopcomm_rrh_reset_template }}
output = ${directory:etc}/lopcomm-rrh-reset.py
[lopcomm-rrh-reset-cron]
recipe = slapos.cookbook:cron.d
cron-entries = ${cron:cron-entries}
name = rrh-resest
frequency = {{ slapparameter_dict.get("cron_schedule", "") }}
command = {{ buildout_directory}}/bin/pythonwitheggs ${lopcomm-rrh-reset-template:output}
[netconf-connection-promise]
<= monitor-promise-base
promise = check_command_execute
name = netconf-connection-promise.py
config-command = [ -f ${directory:etc}/is_netconf_connected ]
[firmware-update-promise]
<= monitor-promise-base
promise = check_command_execute
name = firmware-update-promise.py
config-command = [ -f ${directory:etc}/is_firmware_updated ]
[rrh-netconf-socket-promise]
<= monitor-promise-base
promise = check_socket_listening
name = rrh-netconf-socket-promise.py
config-host = ${slap-configuration:tap-ipv6-gateway}
config-port = 830
[amarisoft-stats-service]
recipe = slapos.cookbook:wrapper
command-line = ${amarisoft-stats-template:output}
wrapper-path = ${directory:service}/amarisoft-stats
mode = 0775
hash-files =
${amarisoft-stats-template:output}
[amarisoft-rf-info-service]
recipe = slapos.cookbook:wrapper
command-line = ${amarisoft-rf-info-template:output}
wrapper-path = ${directory:service}/amarisoft-rf-info
mode = 0775
hash-files =
${amarisoft-rf-info-template:output}
[lopcomm-rrh-stats-service]
recipe = slapos.cookbook:wrapper
command-line = ${lopcomm-rrh-stats-template:output}
wrapper-path = ${directory:service}/lopcomm-rrh-stats
mode = 0775
hash-files =
${lopcomm-rrh-stats-template:output}
[lopcomm-rrh-supervision-service]
recipe = slapos.cookbook:wrapper
command-line = ${lopcomm-rrh-supervision-template:output}
wrapper-path = ${directory:service}/lopcomm-rrh-supervision
mode = 0775
hash-files =
${lopcomm-rrh-supervision-template:output}
[lopcomm-rrh-reset-info-service]
recipe = slapos.cookbook:wrapper
command-line = ${lopcomm-rrh-reset-info-template:output}
wrapper-path = ${directory:service}/lopcomm-rrh-reset-info
mode = 0775
hash-files =
${lopcomm-rrh-reset-info-template:output}
[lopcomm-firmware-dl]
recipe = slapos.recipe.build:download
url = https://lab.nexedi.com/nexedi/ors-utils/raw/master/lopcomm-firmware/${:filename}
filename = PR.PRM61C70V1004.006.tar.gz
md5sum = 5139019aae77c2f3178a99915f1c57dc
destination = ${directory:etc}/${:filename}
offline = false
[user-info]
recipe = slapos.cookbook:userinfo
# Deploy openssh-server
[sshd-port]
recipe = slapos.cookbook:free_port
minimum = 22222
maximum = 22231
ip = ${slap-configuration:ipv6-random}
[sshd-config]
recipe = slapos.recipe.template:jinja2
output = ${directory:etc}/sshd.conf
path_pid = ${directory:run}/sshd.pid
inline =
PidFile ${:path_pid}
Port ${sshd-port:port}
ListenAddress ${slap-configuration:ipv6-random}
Protocol 2
HostKey ${sshd-ssh-host-rsa-key:output}
HostKey ${sshd-ssh-host-ecdsa-key:output}
PasswordAuthentication no
PubkeyAuthentication yes
HostKeyAlgorithms ssh-rsa,ssh-dss,rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp521
AuthorizedKeysFile ${buildout:directory}/.ssh/authorized_keys
Subsystem sftp {{ openssh_location }}/libexec/sftp-server
[sshd-service]
recipe = slapos.cookbook:wrapper
command-line = {{ openssh_location }}/sbin/sshd -D -e -f ${sshd-config:output}
wrapper-path = ${directory:service}/sshd
hash-files = ${sshd-config:output}
environment =
HOME=${directory:home}
[sshd-add-authorized-key]
recipe = slapos.cookbook:dropbear.add_authorized_key
home = ${buildout:directory}
key = {{ slapparameter_dict.get("user-authorized-key", '') }}
[sshd-ssh-keygen-base]
recipe = plone.recipe.command
output = ${directory:etc}/${:_buildout_section_name_}
command = {{ openssh_output_keygen }} -f ${:output} -N '' ${:extra-args}
[sshd-ssh-host-rsa-key]
<=sshd-ssh-keygen-base
extra-args=-t rsa
[sshd-ssh-host-ecdsa-key]
<=sshd-ssh-keygen-base
extra-args=-t ecdsa -b 521
[sshd-promise]
<= monitor-promise-base
promise = check_socket_listening
name = sshd.py
config-host = ${slap-configuration:ipv6-random}
config-port = ${sshd-port:port}
[config-base]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
extra-context =
context =
section directory directory
section slap_configuration slap-configuration
key slapparameter_dict slap-configuration:configuration
key gtp_addr_v6 slap-configuration:ipv6-random
raw gtp_addr_v4 {{ lan_ipv4 }}
raw one_watt {{ ors_version['one-watt'] }}
raw tx_gain {{ ors_version['current-tx-gain'] }}
raw rx_gain {{ ors_version['current-rx-gain'] }}
raw earfcn {{ ors_version['current-earfcn'] }}
raw software_name {{ software_name }}
raw rf_mode {{ rf_mode }}
raw trx {{ trx }}
raw bbu {{ bbu }}
raw ru {{ ru }}
import netaddr netaddr
${:extra-context}
[sib-config]
<= config-base
url = {{ sib23_template }}
output = ${directory:etc}/sib23.cfg
[enb-config]
<= config-base
{% if slapparameter_dict.get("enb_config_link", None) %}
url = ${enb-config-dl:target}
{% else %}
url = {{ enb_template }}
{% endif %}
output = ${directory:etc}/enb.cfg
extra-context =
key sib23_file sib-config:output
[publish-connection-information]
<= monitor-publish
recipe = slapos.cookbook:publish.serialised
{%- if slapparameter_dict.get("websocket_password", "") %}
websocket_url = ws://[${slap-configuration:ipv6-random}]:9001
{%- endif %}
enb-ipv6 = ${slap-configuration:ipv6-random}
enb-ipv4 = {{ lan_ipv4 }}
{% if bbu == "ors" %}
ors-version = {{ ors_version['ors-version'] }}
frequency-range-rating = {{ ors_version['range'] }}
current-tx-power-estimate = {{ ors_version['power-estimate'] }}
current-tx-gain = {{ ors_version['current-tx-gain'] }}
current-rx-gain = {{ ors_version['current-rx-gain'] }}
{% endif %}
current-earfcn = {{ ors_version['current-earfcn'] }}
amarisoft-version = {{ lte_version }}
license-expiration = {{ lte_expiration }}
monitor-gadget-url = ${:monitor-base-url}/gadget/software.cfg.html
{% if ru == "lopcomm" %}
ssh-command = ssh ${user-info:pw-name}@${slap-configuration:ipv6-random} -p ${sshd-port:port}
ssh-url = ssh://${user-info:pw-name}@[${slap-configuration:ipv6-random}]:${sshd-port:port}
ru-firmware = ${lopcomm-firmware-dl:filename}
ru-ipv6 = ${slap-configuration:tap-ipv6-gateway}
{% endif %}
[monitor-instance-parameter]
{% if slapparameter_dict.get("name", None) %}
monitor-title = {{ slapparameter_dict['name'] | string }}
{% endif %}
{% if slapparameter_dict.get("monitor-password", None) %}
password = {{ slapparameter_dict['monitor-password'] | string }}
{% endif %}
[macro.promise]
<= monitor-promise-base
name = ${:_buildout_section_name_}
[check-sdr-busy.py]
<= macro.promise
promise = check_sdr_busy
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-sdr = {{ sdr }}
[check-baseband-latency.py]
<= macro.promise
promise = check_baseband_latency
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
config-min-txrx-delay = {{ slapparameter_dict.get("min_txrx_delay", 5) }}
[check-amarisoft-stats-log.py]
<= macro.promise
promise = check_amarisoft_stats_log
output = ${directory:plugins}/check-amarisoft-stats-log.py
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-lopcomm-vswr.py]
<= macro.promise
promise = check_lopcomm_vswr
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-netconf-log = ${lopcomm-rrh-stats-template:json-log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-lopcomm-rssi.py]
<= macro.promise
promise = check_lopcomm_rssi
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-netconf-log = ${lopcomm-rrh-stats-template:json-log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-lopcomm-pa-current.py]
<= macro.promise
promise = check_lopcomm_pa_current
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-netconf-log = ${lopcomm-rrh-stats-template:json-log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-lopcomm-pa-output-power.py]
<= macro.promise
promise = check_lopcomm_pa_output_power
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-netconf-log = ${lopcomm-rrh-stats-template:json-log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-lopcomm-sync.py]
<= macro.promise
promise = check_lopcomm_sync
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-netconf-log = ${lopcomm-rrh-stats-template:json-log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-lopcomm-lof.py]
<= macro.promise
promise = check_lopcomm_lof
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-netconf-log = ${lopcomm-rrh-stats-template:json-log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-lopcomm-stats-log.py]
<= macro.promise
promise = check_lopcomm_stats_log
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-stats-log = ${lopcomm-rrh-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-lopcomm-config-log.py]
<= macro.promise
promise = check_lopcomm_config_log
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-config-log = ${lopcomm-rrh-config-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-cpri-lock.py]
<= macro.promise
promise = check_cpri_lock
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-rf-info-log = ${amarisoft-rf-info-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
[check-rx-saturated.py]
<= macro.promise
promise = check_rx_saturated
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
config-max-rx-sample-db = {{ slapparameter_dict.get("max_rx_sample_db", 0) }}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1, 2, 4 or 8. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1, 2, 4 or 8. Number of UL antennas.",
"type": "number",
"default": 2
},
"sdr_number": {
"title": "SDR Number",
"description": "SDR Number",
"type": "number",
"default": 0
},
"cpri_port": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
"cell_list": {
"title": "Cell List",
"description": "Cell List",
"patternProperties": {
".*": {
"properties": {
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell IDs",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Cell IDs",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"enb_id": {
"title": "eNB ID",
"description": "eNB ID",
"type": "string",
"default": "0x1A2D0"
},
"gtp_addr": {
"title": "GTP Address",
"description": "String. Set the IP address (and optional port) on which the GTP-U packets are received. The default port is 2152. It is normally the IP address of the network interface connected to the core network.",
"type": "string",
"default": "127.0.1.1"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"mme_addr": {
"title": "MME Address",
"description": "IP address (and optional port) of S1AP SCTP connection to the MME. The default port is 36412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the eNodeB, at most 6 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"attach_without_pdn": {
"default": false,
"title": "Attach Without PDN",
"description": "Optional boolean. Indicates if PLMN supports attach without PDN connectivity.",
"type": "boolean"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"lte_handover_a3_offset": {
"title": "A3 offset for LTE handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"lte_handover_time_to_trigger": {
"title": "Time to Trigger for LTE handover",
"description": "Time to triger after which LTE handover will be triggered if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 480
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Concatenation of enb_id and cell_id of the neighbour cell",
"type": "string"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"enb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics",
"type": "number",
"default": 60
},
"enb_drb_stats_enabled": {
"title": "Enable eNB drb statistics",
"description": "Enable eNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if minimum TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if average TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"nr_bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1, 2, 4 or 8. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1, 2, 4 or 8. Number of UL antennas.",
"type": "number",
"default": 2
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"ssb_pos_bitmap": {
"title": "SSB Position Bitmap",
"description": "SSB position bitmap in bits (4, 8 or 64 bits depending on the DL frequency).",
"type": "string",
"default": 10000000
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 500
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"gnb_id": {
"title": "gNB ID",
"description": "gNB ID",
"type": "string",
"default": "0x12345"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number",
"default": 28
},
"amf_list": {
"title": "AMF list",
"description": "Optionnal. List of AMF to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"amf_addr": {
"title": "AMF Address",
"description": "IP address (and optional port) of NGAP SCTP connection to the AMF. The default port is 38412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the gNodeB, at most 12 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"tac": {
"default": 100,
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
},
"ranac": {
"title": "Optional integer (range 0 to 255)",
"description": "RAN Area Code",
"type": "number"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nssai": {
"title": "AMF slices configuration",
"description": "AMF slices configuration.",
"patternProperties": {
".*": {
"properties": {
"sst": {
"default": 1,
"title": "Slice Service Type",
"description": "Integer (range 1 to 255).",
"type": "number"
},
"sd": {
"default": "0x000032",
"title": "Slice Differentiator",
"description": "Optional integer (range 0 to 0xFFFFFE)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nr_handover_a3_offset": {
"title": "A3 offset for NR handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"nr_handover_time_to_trigger": {
"title": "Time to Trigger for NR handover",
"description": "Time to triger after which NR handover will be triggerd if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 100
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"nr_cell_id": {
"title": "NR Cell ID",
"description": "Concatenation of gnb_id and cell_id of the neighbour cell",
"type": "string"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"xn_peers": {
"title": "XN Peers",
"description": "XN Peers",
"patternProperties": {
".*": {
"properties": {
"xn_addr": {
"title": "XN Address",
"description": "XN Address of the neighbour cell (gNB Address)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"gnb_stats_fetch_period": {
"title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number",
"default": 60
},
"gnb_drb_stats_enabled": {
"title": "Enable gNB drb statistics",
"description": "Enable gNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Minimum TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Average TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1, 2, 4 or 8. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1, 2, 4 or 8. Number of UL antennas.",
"type": "number",
"default": 2
},
"sdr_number": {
"title": "SDR Number",
"description": "SDR Number",
"type": "number",
"default": 0
},
"cpri_port": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
"cpri_mult": {
"title": "CPRI Mult",
"description": "Select the CPRI line bit rate in terms of multiple of option 1 (614.4 Mbps). E.g set 4 for option 3, 8 for option 5 and 16 for option 7.",
"type": "number",
"default": 16,
"enum": [
4,
5,
8,
16
]
},
"cell_list": {
"title": "Cell List",
"description": "Cell List",
"patternProperties": {
".*": {
"properties": {
"cpri_rx_delay": {
"title": "CPRI RX Delay",
"description": "Delays between TX and RX position in CPRI frame. This should be set to the value of (T2a + T3a - Toffset) provided by the RRH specification.",
"type": "number",
"default": 25.11
},
"cpri_tx_delay": {
"title": "CPRI TX Delay",
"description": "Advances Start of Frame relative to PPS to compensate for delays in transmit line and RRH. This should be set to T12 + T2a.",
"type": "number",
"default": 14.71
},
"cpri_tx_dbm": {
"title": "CPRI TX dBm",
"description": "Optional floating points value in dBm (default 0). Needed by ENB/GNB to have a notion of actual output power. Computed from maximum power output of the RRH for a 0dBFS input signal (full scale). ",
"type": "number",
"default": 63
},
"cpri_port_number": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell IDs",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Cell IDs",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"dnsmasq": {
"default": false,
"title": "dnsmasq",
"description": "dnsmasq",
"type": "boolean"
},
"rrh_mac_addr": {
"default": "00:0a:00:00:10:20",
"title": "RRH MAC address",
"description": "RRH MAC address used for DNSMASQ",
"type": "string"
},
"txa0cc00_active": {
"title": "Lopcomm ORAN TX array carriers (TXA0CC00)",
"description": "Activate or inactivate Lopcomm ORAN TX array carriers (TXA0CC00)",
"type": "string",
"default": "INACTIVE",
"enum": [
"ACTIVE",
"INACTIVE"
]
},
"rxa0cc00_active": {
"title": "Lopcomm ORAN RX array carriers (RXA0CC00)",
"description": "Activate or inactivate Lopcomm ORAN RX array carriers (RXA0CC00)",
"type": "string",
"default": "INACTIVE",
"enum": [
"ACTIVE",
"INACTIVE"
]
},
"txa0cc00_center_frequency": {
"title": "Lopcomm ORAN DL Center Frequency in MHz (TXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in MHz (TXA0CC00)",
"type": "number",
"default": 2140
},
"rxa0cc00_center_frequency_earfcn": {
"title": "Lopcomm ORAN UL Center Frequency EARFCN (RXA0CC00)",
"description": "Lopcomm ORAN Center Frequency EARFCN (RXA0CC00)",
"type": "number",
"default": 18300
},
"rxa0cc00_center_frequency": {
"title": "Lopcomm ORAN UL Center Frequency in MHz (RXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in MHz (RXA0CC00)",
"type": "number",
"default": 1950
},
"txa0cc00_gain": {
"title": "ORAN Gain",
"description": "Lopcomm ORAN Gain (TXA0CC00)",
"type": "number",
"default": -20
},
"user-authorized-key": {
"title": "User Authorized Key",
"description": "SSH public key in order to connect to the SSH server of this instance.",
"textarea": true,
"type": "string"
},
"cron_schedule": {
"title": "Cron schedule for RRH reset",
"description": "Refer https://crontab.guru/ to make a reset schedule for RRH, for example, '0 1 * * *' means the RRH will reset every day at 1 am",
"type": "string"
},
"enb_id": {
"title": "eNB ID",
"description": "eNB ID",
"type": "string",
"default": "0x1A2D0"
},
"gtp_addr": {
"title": "GTP Address",
"description": "String. Set the IP address (and optional port) on which the GTP-U packets are received. The default port is 2152. It is normally the IP address of the network interface connected to the core network.",
"type": "string",
"default": "127.0.1.1"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"mme_addr": {
"title": "MME Address",
"description": "IP address (and optional port) of S1AP SCTP connection to the MME. The default port is 36412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the eNodeB, at most 6 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"attach_without_pdn": {
"default": false,
"title": "Attach Without PDN",
"description": "Optional boolean. Indicates if PLMN supports attach without PDN connectivity.",
"type": "boolean"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"lte_handover_a3_offset": {
"title": "A3 offset for LTE handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"lte_handover_time_to_trigger": {
"title": "Time to Trigger for LTE handover",
"description": "Time to triger after which LTE handover will be triggered if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 480
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Concatenation of enb_id and cell_id of the neighbour cell",
"type": "string"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"enb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics",
"type": "number",
"default": 60
},
"enb_drb_stats_enabled": {
"title": "Enable eNB drb statistics",
"description": "Enable eNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if minimum TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if average TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"nr_bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1, 2, 4 or 8. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1, 2, 4 or 8. Number of UL antennas.",
"type": "number",
"default": 2
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"ssb_pos_bitmap": {
"title": "SSB Position Bitmap",
"description": "SSB position bitmap in bits (4, 8 or 64 bits depending on the DL frequency).",
"type": "string",
"default": 10000000
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 500
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"gnb_id": {
"title": "gNB ID",
"description": "gNB ID",
"type": "string",
"default": "0x12345"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number",
"default": 28
},
"amf_list": {
"title": "AMF list",
"description": "Optionnal. List of AMF to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"amf_addr": {
"title": "AMF Address",
"description": "IP address (and optional port) of NGAP SCTP connection to the AMF. The default port is 38412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the gNodeB, at most 12 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"tac": {
"default": 100,
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
},
"ranac": {
"title": "Optional integer (range 0 to 255)",
"description": "RAN Area Code",
"type": "number"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nssai": {
"title": "AMF slices configuration",
"description": "AMF slices configuration.",
"patternProperties": {
".*": {
"properties": {
"sst": {
"default": 1,
"title": "Slice Service Type",
"description": "Integer (range 1 to 255).",
"type": "number"
},
"sd": {
"default": "0x000032",
"title": "Slice Differentiator",
"description": "Optional integer (range 0 to 0xFFFFFE)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nr_handover_a3_offset": {
"title": "A3 offset for NR handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"nr_handover_time_to_trigger": {
"title": "Time to Trigger for NR handover",
"description": "Time to triger after which NR handover will be triggerd if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 100
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"nr_cell_id": {
"title": "NR Cell ID",
"description": "Concatenation of gnb_id and cell_id of the neighbour cell",
"type": "string"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"xn_peers": {
"title": "XN Peers",
"description": "XN Peers",
"patternProperties": {
".*": {
"properties": {
"xn_addr": {
"title": "XN Address",
"description": "XN Address of the neighbour cell (gNB Address)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"gnb_stats_fetch_period": {
"title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number",
"default": 60
},
"gnb_drb_stats_enabled": {
"title": "Enable gNB drb statistics",
"description": "Enable gNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Minimum TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Average TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR ARFCN, you can retrieve from ENB/GNB side",
"type": "number"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1 or 2. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1 or 2. Number of UL antennas.",
"type": "number",
"default": 2
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 1
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tac": {
"title": "Tracking Area Code",
"description": "Tracking Area Code in hexadecimal representation (range 0x0000 to 0xffff)",
"default": "0x0001",
"type": "string"
},
"root_sequence_index": {
"title": "Root Sequence Index",
"description": "Range: 0 to 837. Set the PRACH root sequence index (SIB2.rootSequenceIndex field). It must be different for each neighbour cell operating on the same frequency and sharing the same PRACH configuration.",
"type": "number",
"default": 204
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"enb_id": {
"title": "eNB ID",
"description": "eNB ID",
"type": "string",
"default": "0x1A2D0"
},
"gtp_addr": {
"title": "GTP Address",
"description": "String. Set the IP address (and optional port) on which the GTP-U packets are received. The default port is 2152. It is normally the IP address of the network interface connected to the core network.",
"type": "string",
"default": "127.0.1.1"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"mme_addr": {
"title": "MME Address",
"description": "IP address (and optional port) of S1AP SCTP connection to the MME. The default port is 36412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the eNodeB, at most 6 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"attach_without_pdn": {
"default": false,
"title": "Attach Without PDN",
"description": "Optional boolean. Indicates if PLMN supports attach without PDN connectivity.",
"type": "boolean"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"lte_handover_a3_offset": {
"title": "A3 offset for LTE handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"lte_handover_time_to_trigger": {
"title": "Time to Trigger for LTE handover",
"description": "Time to triger after which LTE handover will be triggered if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 480
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Concatenation of enb_id and cell_id of the neighbour cell",
"type": "string"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"enb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics",
"type": "number",
"default": 60
},
"enb_drb_stats_enabled": {
"title": "Enable eNB drb statistics",
"description": "Enable eNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if minimum TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if average TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"nr_bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1 or 2. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1 or 2. Number of UL antennas.",
"type": "number",
"default": 2
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"ssb_pos_bitmap": {
"title": "SSB Position Bitmap",
"description": "SSB position bitmap in bits (4, 8 or 64 bits depending on the DL frequency).",
"type": "string",
"default": 10000000
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 500
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"gnb_id": {
"title": "gNB ID",
"description": "gNB ID",
"type": "string",
"default": "0x12345"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number",
"default": 28
},
"amf_list": {
"title": "AMF list",
"description": "Optionnal. List of AMF to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"amf_addr": {
"title": "AMF Address",
"description": "IP address (and optional port) of NGAP SCTP connection to the AMF. The default port is 38412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the gNodeB, at most 12 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"tac": {
"default": 100,
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
},
"ranac": {
"title": "Optional integer (range 0 to 255)",
"description": "RAN Area Code",
"type": "number"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nssai": {
"title": "AMF slices configuration",
"description": "AMF slices configuration.",
"patternProperties": {
".*": {
"properties": {
"sst": {
"default": 1,
"title": "Slice Service Type",
"description": "Integer (range 1 to 255).",
"type": "number"
},
"sd": {
"default": "0x000032",
"title": "Slice Differentiator",
"description": "Optional integer (range 0 to 0xFFFFFE)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nr_handover_a3_offset": {
"title": "A3 offset for NR handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"nr_handover_time_to_trigger": {
"title": "Time to Trigger for NR handover",
"description": "Time to triger after which NR handover will be triggerd if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 100
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"nr_cell_id": {
"title": "NR Cell ID",
"description": "Concatenation of gnb_id and cell_id of the neighbour cell",
"type": "string"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"xn_peers": {
"title": "XN Peers",
"description": "XN Peers",
"patternProperties": {
".*": {
"properties": {
"xn_addr": {
"title": "XN Address",
"description": "XN Address of the neighbour cell (gNB Address)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"gnb_stats_fetch_period": {
"title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number",
"default": 60
},
"gnb_drb_stats_enabled": {
"title": "Enable gNB drb statistics",
"description": "Enable gNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Minimum TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Average TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR ARFCN, you can retrieve from ENB/GNB side",
"type": "number"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR ARFCN, you can retrieve from ENB/GNB side",
"type": "number"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"nr_bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": {{ default_nr_bandwidth }}
},
"n_antenna_dl": {
"title": "Number of DL antennas",
{%- if bbu == 'ors' %}
"description": "1 or 2. Number of DL antennas.",
{%- else %}
"description": "1, 2, 4 or 8. Number of DL antennas.",
{%- endif %}
"type": "number",
"default": {{ default_n_antenna_dl }}
},
"n_antenna_ul": {
"title": "Number of UL antennas",
{%- if bbu == 'ors' %}
"description": "1 or 2. Number of UL antennas.",
{%- else %}
"description": "1, 2, 4 or 8. Number of UL antennas.",
{%- endif %}
"type": "number",
"default": {{ default_n_antenna_ul }}
},
{%- if rf_mode == 'tdd' %}
"tdd_ul_dl_config": {
"title": "TDD",
"description": "TDD",
"type": "string",
"enum": [
"5ms 2UL 7DL 4/6 (default)",
"2.5ms 1UL 3DL 2/10",
"5ms 8UL 1DL 2/10 (maximum uplink)"
],
"default": "5ms 2UL 7DL 4/6 (default)"
},
{%- endif %}
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"ssb_pos_bitmap": {
"title": "SSB Position Bitmap",
"description": "SSB position bitmap in bits (4, 8 or 64 bits depending on the DL frequency).",
"type": "string",
"default": {{ default_nr_ssb_pos_bitmap }}
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 500
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"gnb_id": {
"title": "gNB ID",
"description": "gNB ID",
"type": "string",
"default": "0x12345"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number",
"default": 28
},
"amf_list": {
"title": "AMF list",
"description": "Optionnal. List of AMF to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"amf_addr": {
"title": "AMF Address",
"description": "IP address (and optional port) of NGAP SCTP connection to the AMF. The default port is 38412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the gNodeB, at most 12 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"tac": {
"default": 100,
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
},
"ranac": {
"title": "Optional integer (range 0 to 255)",
"description": "RAN Area Code",
"type": "number"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nssai": {
"title": "AMF slices configuration",
"description": "AMF slices configuration.",
"patternProperties": {
".*": {
"properties": {
"sst": {
"default": 1,
"title": "Slice Service Type",
"description": "Integer (range 1 to 255).",
"type": "number"
},
"sd": {
"default": "0x000032",
"title": "Slice Differentiator",
"description": "Optional integer (range 0 to 0xFFFFFE)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nr_handover_a3_offset": {
"title": "A3 offset for NR handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"nr_handover_time_to_trigger": {
"title": "Time to Trigger for NR handover",
"description": "Time to triger after which NR handover will be triggerd if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 100
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"nr_cell_id": {
"title": "NR Cell ID",
"description": "Concatenation of gnb_id and cell_id of the neighbour cell",
"type": "string"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"xn_peers": {
"title": "XN Peers",
"description": "XN Peers",
"patternProperties": {
".*": {
"properties": {
"xn_addr": {
"title": "XN Address",
"description": "XN Address of the neighbour cell (gNB Address)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": {{ default_nr_inactivity_timer }}
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"gnb_stats_fetch_period": {
"title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number",
"default": 60
},
"gnb_drb_stats_enabled": {
"title": "Enable gNB drb statistics",
"description": "Enable gNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Minimum TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Average TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
[buildout]
parts =
directory
ltelogs
gnb-config
enb-service
xamari-xlog-service
{% if slapparameter_dict.get('xlog_fluentbit_forward_host') %}
xlog-fluentbit-service
{% endif %}
amarisoft-stats-service
amarisoft-rf-info-service
check-sdr-busy.py
check-baseband-latency.py
check-amarisoft-stats-log.py
check-rx-saturated.py
monitor-base
publish-connection-information
extends = {{ monitor_template }}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[monitor-httpd-conf-parameter]
httpd-include-file = {{ buildout_directory }}/etc/httpd-include-file.conf
port = ${monitor-instance-parameter:monitor-httpd-port}
url = https://[${monitor-instance-parameter:monitor-httpd-ipv6}]:${:port}
[monitor-instance-parameter]
monitor-httpd-port = ${monitor-address:port}
[monitor-address]
recipe = slapos.cookbook:free_port
minimum = 8035
maximum = 8055
ip = ${monitor-instance-parameter:monitor-httpd-ipv6}
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised
computer = {{ slap_connection['computer-id'] }}
partition = {{ slap_connection['partition-id'] }}
url = {{ slap_connection['server-url'] }}
key = {{ slap_connection['key-file'] }}
cert = {{ slap_connection['cert-file'] }}
configuration.com_ws_port = 9001
configuration.com_addr = 127.0.1.2
configuration.amf_addr = 127.0.1.100
configuration.gtp_addr = 127.0.1.1
configuration.default_nr_bandwidth = {{ default_nr_bandwidth }}
configuration.default_nr_inactivity_timer = {{ default_nr_inactivity_timer }}
configuration.default_nr_ssb_pos_bitmap = {{ default_nr_ssb_pos_bitmap }}
configuration.default_n_antenna_dl = {{ default_n_antenna_dl }}
configuration.default_n_antenna_ul = {{ default_n_antenna_ul }}
[directory]
recipe = slapos.cookbook:mkdirectory
software = {{ buildout_directory }}
home = ${buildout:directory}
etc = ${:home}/etc
var = ${:home}/var
etc = ${:home}/etc
bin = ${:home}/bin
tmp = ${:home}/tmp
run = ${:var}/run
script = ${:etc}/run
service = ${:etc}/service
promise = ${:etc}/promise
log = ${:var}/log
[ltelogs]
recipe = slapos.recipe.template:jinja2
url = {{ ltelogs_template }}
output = ${directory:home}/ltelogs.sh
extensions = jinja2.ext.do
context =
section directory directory
{% if slapparameter_dict.get("gnb_config_link", None) %}
[gnb-config-dl]
recipe = slapos.recipe.build:download
url = {{ slapparameter_dict.get("gnb_config_link") }}
version = {{ slapparameter_dict.get("gnb_config_version") }}
offline = false
{% endif %}
[enb-sh-wrapper]
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
gnb-log = ${directory:log}/gnb-output.log
inline =
#!/bin/sh
{% if not slapparameter_dict.get("testing", False) %}
sudo -n /opt/amarisoft/rm-tmp-lte;
sudo -n /opt/amarisoft/init-sdr;
sudo -n /opt/amarisoft/init-enb;
(echo && echo && date "+[%Y/%m/%d %T.%N %Z] Starting gNB software..." && echo) >> ${:gnb-log};
tail -c 1M ${:gnb-log} > ${:gnb-log}.tmp;
mv ${:gnb-log}.tmp ${:gnb-log};
{{ enb }}/lteenb ${directory:etc}/gnb.cfg >> ${:gnb-log} 2>> ${:gnb-log};
{% endif %}
### eNodeB (enb)
[enb-service]
recipe = slapos.cookbook:wrapper
init = ${ltelogs:output} ${directory:log}/enb.log; sleep 2
command-line = ${enb-sh-wrapper:output}
wrapper-path = ${directory:service}/enb
mode = 0775
reserve-cpu = True
pidfile = ${directory:run}/enb.pid
hash-files =
${gnb-config:output}
${enb-sh-wrapper:output}
environment =
LD_LIBRARY_PATH={{ openssl_location }}/lib
AMARISOFT_PATH=/opt/amarisoft/.amarisoft
[xamari-xlog-script]
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
period = {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
stats_logspec = stats[samples,rf]/${:period}s
{%- if slapparameter_dict.get("gnb_drb_stats_enabled", True) %}
drb_stats_logspec = x.drb_stats/${:period}s
{%- else %}
drb_stats_logspec =
{%- endif %}
rotatespec = 100MB.9
logspec = ${:stats_logspec} ${:drb_stats_logspec}
logspec = ${:stats_logspec} ${:drb_stats_logspec}
{% if slapparameter_dict.get("websocket_password", "") %}
websock = ws://[${slap-configuration:ipv6-random}]:9001
{% else %}
websock = ws://127.0.1.2:9001
{% endif %}
xamari = {{ buildout_directory }}/bin/xamari
logfile = ${monitor-directory:public}/gnb.xlog
inline =
#!/bin/sh
exec ${:xamari} xlog --rotate ${:rotatespec} ${:websock} ${:logfile} ${:logspec}
[xamari-xlog-service]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:service}/${:_buildout_section_name_}
command-line = ${xamari-xlog-script:output}
hash-files = ${:command-line}
{% if slapparameter_dict.get('xlog_fluentbit_forward_host') %}
[xlog-fluentbit-config]
recipe = slapos.recipe.template
output = ${directory:etc}/${:_buildout_section_name_}.cfg
logfile = ${xamari-xlog-script:logfile}
forward-host = {{ slapparameter_dict.get('xlog_fluentbit_forward_host', '') }}
forward-port = {{ slapparameter_dict.get('xlog_fluentbit_forward_port', '') }}
forward-shared-key = {{ slapparameter_dict.get('xlog_fluentbit_forward_shared_key', '') }}
forward-self-hostname = {{ ors_id['ors-id'] }}
inline =
[SERVICE]
flush 5
[INPUT]
name tail
path ${:logfile}
Read_from_Head True
[OUTPUT]
name forward
match *
Host ${:forward-host}
{%- if slapparameter_dict.get('xlog_fluentbit_forward_port') %}
Port ${:forward-port}
{%- endif %}
Shared_Key ${:forward-shared-key}
Self_Hostname ${:forward-self-hostname}
tls on
tls.verify off
[xlog-fluentbit-service]
recipe = slapos.cookbook:wrapper
fluentbit = {{ fluent_bit_location }}/bin/fluent-bit
fluentbit-config = ${xlog-fluentbit-config:output}
command-line = ${:fluentbit} -c ${:fluentbit-config}
wrapper-path = ${directory:service}/${:_buildout_section_name_}
hash-files = ${:fluentbit-config}
{% endif %}
[amarisoft-stats-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/amarisoft-stats.json.log
context =
section directory directory
key slapparameter_dict slap-configuration:configuration
key log_file :log-output
raw stats_period {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
mode = 0775
url = {{ amarisoft_stats_template }}
output = ${directory:bin}/amarisoft-stats.py
[amarisoft-rf-info-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
log-output = ${directory:var}/log/amarisoft-rf-info.json.log
context =
section directory directory
key slapparameter_dict slap-configuration:configuration
key log_file :log-output
raw stats_period {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
mode = 0775
url = {{ amarisoft_rf_info_template }}
output = ${directory:bin}/amarisoft-rf-info.py
[amarisoft-stats-service]
recipe = slapos.cookbook:wrapper
command-line = ${amarisoft-stats-template:output}
wrapper-path = ${directory:service}/amarisoft-stats
mode = 0775
hash-files =
${amarisoft-stats-template:output}
[amarisoft-rf-info-service]
recipe = slapos.cookbook:wrapper
command-line = ${amarisoft-rf-info-template:output}
wrapper-path = ${directory:service}/amarisoft-rf-info
mode = 0775
hash-files =
${amarisoft-rf-info-template:output}
[config-base]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
context =
section directory directory
section slap_configuration slap-configuration
key slapparameter_dict slap-configuration:configuration
key gtp_addr_v6 slap-configuration:ipv6-random
raw gtp_addr_v4 {{ lan_ipv4 }}
raw one_watt {{ ors_version['one-watt'] }}
raw tx_gain {{ ors_version['current-tx-gain'] }}
raw rx_gain {{ ors_version['current-rx-gain'] }}
raw nr_arfcn {{ ors_version['current-nr-arfcn'] }}
raw nr_band {{ ors_version['current-nr-band'] }}
raw software_name {{ software_name }}
raw rf_mode {{ rf_mode }}
raw trx {{ trx }}
raw bbu {{ bbu }}
raw ru {{ ru }}
import netaddr netaddr
[gnb-config]
<= config-base
{% if slapparameter_dict.get("gnb_config_link", None) %}
url = ${gnb-config-dl:target}
{% else %}
url = {{ gnb_template }}
{% endif %}
output = ${directory:etc}/gnb.cfg
[publish-connection-information]
<= monitor-publish
recipe = slapos.cookbook:publish.serialised
{%- if slapparameter_dict.get("websocket_password", "") %}
websocket_url = ws://[${slap-configuration:ipv6-random}]:9001
{%- endif %}
gnb-ipv6 = ${slap-configuration:ipv6-random}
gnb-ipv4 = {{ lan_ipv4 }}
ors-version = {{ ors_version['ors-version'] }}
frequency-range-rating = {{ ors_version['range'] }}
current-tx-power-estimate = {{ ors_version['power-estimate'] }}
current-tx-gain = {{ ors_version['current-tx-gain'] }}
current-rx-gain = {{ ors_version['current-rx-gain'] }}
current-nr-arfcn = {{ ors_version['current-nr-arfcn'] }}
current-nr-band = {{ ors_version['current-nr-band'] }}
amarisoft-version = {{ lte_version }}
license-expiration = {{ lte_expiration }}
monitor-gadget-url = ${:monitor-base-url}/gadget/software.cfg.html
[monitor-instance-parameter]
{% if slapparameter_dict.get("name", None) %}
monitor-title = {{ slapparameter_dict['name'] | string }}
{% endif %}
{% if slapparameter_dict.get("monitor-password", None) %}
password = {{ slapparameter_dict['monitor-password'] | string }}
{% endif %}
[macro.promise]
<= monitor-promise-base
name = ${:_buildout_section_name_}
[check-sdr-busy.py]
<= macro.promise
promise = check_sdr_busy
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-sdr = {{ sdr }}
[check-baseband-latency.py]
<= macro.promise
promise = check_baseband_latency
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
config-min-txrx-delay = {{ slapparameter_dict.get("min_txrx_delay", 5) }}
[check-amarisoft-stats-log.py]
<= macro.promise
promise = check_amarisoft_stats_log
output = ${directory:plugins}/check-amarisoft-stats-log.py
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
[check-rx-saturated.py]
<= macro.promise
promise = check_rx_saturated
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
config-max-rx-sample-db = {{ slapparameter_dict.get("max_rx_sample_db", 0) }}
{% set obsolete_message = "This software type doesn't exist anymore. Please ask Rapid.Space team to switch your services to the correct software types (gNB, eNB and Core Network)" -%}
{% set part_list = [] -%}
{%- for i, slave in enumerate(slave_instance_list) %}
{% set slave_reference = slave.get('slave_reference', '') %}
{% set publish_section_title = 'publish-%s' % slave_reference %}
{% do part_list.append(publish_section_title) %}
[{{ publish_section_title }}]
recipe = slapos.cookbook:publish.serialised
-slave-reference = {{ slave_reference }}
info = {{ obsolete_message }}
{%- endfor %}
[buildout]
parts =
publish-connection-information
{% for part in part_list -%}
{{ ' %s' % part }}
{% endfor %}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[publish-connection-information]
recipe = slapos.cookbook:publish.serialised
message = {{ obsolete_message }}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1, 2, 4 or 8. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1, 2, 4 or 8. Number of UL antennas.",
"type": "number",
"default": 2
},
"tdd_ul_dl_config": {
"title": "TDD",
"description": "TDD",
"type": "string",
"enum": [
"[Configuration 2] 5ms 2UL 6DL (default)",
"[Configuration 6] 5ms 5UL 3DL (maximum uplink)"
],
"default": "5ms 2UL 7DL 4/6 (default)"
},
"sdr_number": {
"title": "SDR Number",
"description": "SDR Number",
"type": "number",
"default": 0
},
"cpri_port": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
"cell_list": {
"title": "Cell List",
"description": "Cell List",
"patternProperties": {
".*": {
"properties": {
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell IDs",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Cell IDs",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"enb_id": {
"title": "eNB ID",
"description": "eNB ID",
"type": "string",
"default": "0x1A2D0"
},
"gtp_addr": {
"title": "GTP Address",
"description": "String. Set the IP address (and optional port) on which the GTP-U packets are received. The default port is 2152. It is normally the IP address of the network interface connected to the core network.",
"type": "string",
"default": "127.0.1.1"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"mme_addr": {
"title": "MME Address",
"description": "IP address (and optional port) of S1AP SCTP connection to the MME. The default port is 36412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the eNodeB, at most 6 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"attach_without_pdn": {
"default": false,
"title": "Attach Without PDN",
"description": "Optional boolean. Indicates if PLMN supports attach without PDN connectivity.",
"type": "boolean"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"lte_handover_a3_offset": {
"title": "A3 offset for LTE handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"lte_handover_time_to_trigger": {
"title": "Time to Trigger for LTE handover",
"description": "Time to triger after which LTE handover will be triggered if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 480
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Concatenation of enb_id and cell_id of the neighbour cell",
"type": "string"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"enb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics",
"type": "number",
"default": 60
},
"enb_drb_stats_enabled": {
"title": "Enable eNB drb statistics",
"description": "Enable eNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if minimum TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if average TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"nr_bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1, 2, 4 or 8. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1, 2, 4 or 8. Number of UL antennas.",
"type": "number",
"default": 2
},
"tdd_ul_dl_config": {
"title": "TDD",
"description": "TDD",
"type": "string",
"enum": [
"5ms 2UL 7DL 4/6 (default)",
"2.5ms 1UL 3DL 2/10",
"5ms 8UL 1DL 2/10 (maximum uplink)"
],
"default": "5ms 2UL 7DL 4/6 (default)"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"ssb_pos_bitmap": {
"title": "SSB Position Bitmap",
"description": "SSB position bitmap in bits (4, 8 or 64 bits depending on the DL frequency).",
"type": "string",
"default": 10000000
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 500
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"gnb_id": {
"title": "gNB ID",
"description": "gNB ID",
"type": "string",
"default": "0x12345"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number",
"default": 28
},
"amf_list": {
"title": "AMF list",
"description": "Optionnal. List of AMF to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"amf_addr": {
"title": "AMF Address",
"description": "IP address (and optional port) of NGAP SCTP connection to the AMF. The default port is 38412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the gNodeB, at most 12 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"tac": {
"default": 100,
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
},
"ranac": {
"title": "Optional integer (range 0 to 255)",
"description": "RAN Area Code",
"type": "number"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nssai": {
"title": "AMF slices configuration",
"description": "AMF slices configuration.",
"patternProperties": {
".*": {
"properties": {
"sst": {
"default": 1,
"title": "Slice Service Type",
"description": "Integer (range 1 to 255).",
"type": "number"
},
"sd": {
"default": "0x000032",
"title": "Slice Differentiator",
"description": "Optional integer (range 0 to 0xFFFFFE)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nr_handover_a3_offset": {
"title": "A3 offset for NR handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"nr_handover_time_to_trigger": {
"title": "Time to Trigger for NR handover",
"description": "Time to triger after which NR handover will be triggerd if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 100
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"nr_cell_id": {
"title": "NR Cell ID",
"description": "Concatenation of gnb_id and cell_id of the neighbour cell",
"type": "string"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"xn_peers": {
"title": "XN Peers",
"description": "XN Peers",
"patternProperties": {
".*": {
"properties": {
"xn_addr": {
"title": "XN Address",
"description": "XN Address of the neighbour cell (gNB Address)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"gnb_stats_fetch_period": {
"title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number",
"default": 60
},
"gnb_drb_stats_enabled": {
"title": "Enable gNB drb statistics",
"description": "Enable gNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Minimum TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Average TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1, 2, 4 or 8. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1, 2, 4 or 8. Number of UL antennas.",
"type": "number",
"default": 2
},
"tdd_ul_dl_config": {
"title": "TDD",
"description": "TDD",
"type": "string",
"enum": [
"[Configuration 2] 5ms 2UL 6DL (default)",
"[Configuration 6] 5ms 5UL 3DL (maximum uplink)"
],
"default": "5ms 2UL 7DL 4/6 (default)"
},
"sdr_number": {
"title": "SDR Number",
"description": "SDR Number",
"type": "number",
"default": 0
},
"cpri_port": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
"cpri_mult": {
"title": "CPRI Mult",
"description": "Select the CPRI line bit rate in terms of multiple of option 1 (614.4 Mbps). E.g set 4 for option 3, 8 for option 5 and 16 for option 7.",
"type": "number",
"default": 16,
"enum": [
4,
5,
8,
16
]
},
"cell_list": {
"title": "Cell List",
"description": "Cell List",
"patternProperties": {
".*": {
"properties": {
"cpri_rx_delay": {
"title": "CPRI RX Delay",
"description": "Delays between TX and RX position in CPRI frame. This should be set to the value of (T2a + T3a - Toffset) provided by the RRH specification.",
"type": "number",
"default": 25.11
},
"cpri_tx_delay": {
"title": "CPRI TX Delay",
"description": "Advances Start of Frame relative to PPS to compensate for delays in transmit line and RRH. This should be set to T12 + T2a.",
"type": "number",
"default": 14.71
},
"cpri_tx_dbm": {
"title": "CPRI TX dBm",
"description": "Optional floating points value in dBm (default 0). Needed by ENB/GNB to have a notion of actual output power. Computed from maximum power output of the RRH for a 0dBFS input signal (full scale). ",
"type": "number",
"default": 63
},
"cpri_port_number": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell IDs",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Cell IDs",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"dnsmasq": {
"default": false,
"title": "dnsmasq",
"description": "dnsmasq",
"type": "boolean"
},
"rrh_mac_addr": {
"default": "00:0a:00:00:10:20",
"title": "RRH MAC address",
"description": "RRH MAC address used for DNSMASQ",
"type": "string"
},
"enb_id": {
"title": "eNB ID",
"description": "eNB ID",
"type": "string",
"default": "0x1A2D0"
},
"gtp_addr": {
"title": "GTP Address",
"description": "String. Set the IP address (and optional port) on which the GTP-U packets are received. The default port is 2152. It is normally the IP address of the network interface connected to the core network.",
"type": "string",
"default": "127.0.1.1"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"mme_addr": {
"title": "MME Address",
"description": "IP address (and optional port) of S1AP SCTP connection to the MME. The default port is 36412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the eNodeB, at most 6 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"attach_without_pdn": {
"default": false,
"title": "Attach Without PDN",
"description": "Optional boolean. Indicates if PLMN supports attach without PDN connectivity.",
"type": "boolean"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"lte_handover_a3_offset": {
"title": "A3 offset for LTE handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"lte_handover_time_to_trigger": {
"title": "Time to Trigger for LTE handover",
"description": "Time to triger after which LTE handover will be triggered if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 480
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Concatenation of enb_id and cell_id of the neighbour cell",
"type": "string"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"enb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics",
"type": "number",
"default": 60
},
"enb_drb_stats_enabled": {
"title": "Enable eNB drb statistics",
"description": "Enable eNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if minimum TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if average TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"nr_bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1, 2, 4 or 8. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1, 2, 4 or 8. Number of UL antennas.",
"type": "number",
"default": 2
},
"tdd_ul_dl_config": {
"title": "TDD",
"description": "TDD",
"type": "string",
"enum": [
"5ms 2UL 7DL 4/6 (default)",
"2.5ms 1UL 3DL 2/10",
"5ms 8UL 1DL 2/10 (maximum uplink)"
],
"default": "5ms 2UL 7DL 4/6 (default)"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"ssb_pos_bitmap": {
"title": "SSB Position Bitmap",
"description": "SSB position bitmap in bits (4, 8 or 64 bits depending on the DL frequency).",
"type": "string",
"default": 10000000
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 500
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"gnb_id": {
"title": "gNB ID",
"description": "gNB ID",
"type": "string",
"default": "0x12345"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number",
"default": 28
},
"amf_list": {
"title": "AMF list",
"description": "Optionnal. List of AMF to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"amf_addr": {
"title": "AMF Address",
"description": "IP address (and optional port) of NGAP SCTP connection to the AMF. The default port is 38412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the gNodeB, at most 12 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"tac": {
"default": 100,
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
},
"ranac": {
"title": "Optional integer (range 0 to 255)",
"description": "RAN Area Code",
"type": "number"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nssai": {
"title": "AMF slices configuration",
"description": "AMF slices configuration.",
"patternProperties": {
".*": {
"properties": {
"sst": {
"default": 1,
"title": "Slice Service Type",
"description": "Integer (range 1 to 255).",
"type": "number"
},
"sd": {
"default": "0x000032",
"title": "Slice Differentiator",
"description": "Optional integer (range 0 to 0xFFFFFE)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nr_handover_a3_offset": {
"title": "A3 offset for NR handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"nr_handover_time_to_trigger": {
"title": "Time to Trigger for NR handover",
"description": "Time to triger after which NR handover will be triggerd if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 100
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"nr_cell_id": {
"title": "NR Cell ID",
"description": "Concatenation of gnb_id and cell_id of the neighbour cell",
"type": "string"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"xn_peers": {
"title": "XN Peers",
"description": "XN Peers",
"patternProperties": {
".*": {
"properties": {
"xn_addr": {
"title": "XN Address",
"description": "XN Address of the neighbour cell (gNB Address)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"gnb_stats_fetch_period": {
"title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number",
"default": 60
},
"gnb_drb_stats_enabled": {
"title": "Enable gNB drb statistics",
"description": "Enable gNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Minimum TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Average TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR ARFCN, you can retrieve from ENB/GNB side",
"type": "number"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1 or 2. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1 or 2. Number of UL antennas.",
"type": "number",
"default": 2
},
"tdd_ul_dl_config": {
"title": "TDD",
"description": "TDD",
"type": "string",
"enum": [
"[Configuration 2] 5ms 2UL 6DL (default)",
"[Configuration 6] 5ms 5UL 3DL (maximum uplink)"
],
"default": "5ms 2UL 7DL 4/6 (default)"
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 1
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tac": {
"title": "Tracking Area Code",
"description": "Tracking Area Code in hexadecimal representation (range 0x0000 to 0xffff)",
"default": "0x0001",
"type": "string"
},
"root_sequence_index": {
"title": "Root Sequence Index",
"description": "Range: 0 to 837. Set the PRACH root sequence index (SIB2.rootSequenceIndex field). It must be different for each neighbour cell operating on the same frequency and sharing the same PRACH configuration.",
"type": "number",
"default": 204
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"enb_id": {
"title": "eNB ID",
"description": "eNB ID",
"type": "string",
"default": "0x1A2D0"
},
"gtp_addr": {
"title": "GTP Address",
"description": "String. Set the IP address (and optional port) on which the GTP-U packets are received. The default port is 2152. It is normally the IP address of the network interface connected to the core network.",
"type": "string",
"default": "127.0.1.1"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"mme_addr": {
"title": "MME Address",
"description": "IP address (and optional port) of S1AP SCTP connection to the MME. The default port is 36412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the eNodeB, at most 6 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"attach_without_pdn": {
"default": false,
"title": "Attach Without PDN",
"description": "Optional boolean. Indicates if PLMN supports attach without PDN connectivity.",
"type": "boolean"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"lte_handover_a3_offset": {
"title": "A3 offset for LTE handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"lte_handover_time_to_trigger": {
"title": "Time to Trigger for LTE handover",
"description": "Time to triger after which LTE handover will be triggered if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 480
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"cell_id": {
"title": "Cell ID",
"description": "Concatenation of enb_id and cell_id of the neighbour cell",
"type": "string"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"enb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics",
"type": "number",
"default": 60
},
"enb_drb_stats_enabled": {
"title": "Enable eNB drb statistics",
"description": "Enable eNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if minimum TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Baseband latency promise will fail if average TX/RX diff reaches threshold (higher than this value)",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"nr_bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "1 or 2. Number of DL antennas.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "1 or 2. Number of UL antennas.",
"type": "number",
"default": 2
},
"tdd_ul_dl_config": {
"title": "TDD",
"description": "TDD",
"type": "string",
"enum": [
"5ms 2UL 7DL 4/6 (default)",
"2.5ms 1UL 3DL 2/10",
"5ms 8UL 1DL 2/10 (maximum uplink)"
],
"default": "5ms 2UL 7DL 4/6 (default)"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"ssb_pos_bitmap": {
"title": "SSB Position Bitmap",
"description": "SSB position bitmap in bits (4, 8 or 64 bits depending on the DL frequency).",
"type": "string",
"default": 10000000
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID",
"type": "number",
"default": 500
},
"cell_id": {
"title": "Cell ID",
"description": "Cell ID",
"type": "string",
"default": "0x01"
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"gnb_id": {
"title": "gNB ID",
"description": "gNB ID",
"type": "string",
"default": "0x12345"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number",
"default": 28
},
"amf_list": {
"title": "AMF list",
"description": "Optionnal. List of AMF to which the gNodeB is connected",
"patternProperties": {
".*": {
"properties": {
"amf_addr": {
"title": "AMF Address",
"description": "IP address (and optional port) of NGAP SCTP connection to the AMF. The default port is 38412.",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"plmn_list": {
"title": "PLMN list",
"description": "List of PLMNs broadcasted by the gNodeB, at most 12 (default: 00101)",
"patternProperties": {
".*": {
"properties": {
"plmn": {
"default": "00101",
"title": "Public Land Mobile Network",
"description": "Public Land Mobile Network",
"type": "string"
},
"tac": {
"default": 100,
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
},
"ranac": {
"title": "Optional integer (range 0 to 255)",
"description": "RAN Area Code",
"type": "number"
},
"reserved": {
"default": false,
"title": "Reserved",
"description": "True if the cell is reserved for operator use.",
"type": "boolean"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nssai": {
"title": "AMF slices configuration",
"description": "AMF slices configuration.",
"patternProperties": {
".*": {
"properties": {
"sst": {
"default": 1,
"title": "Slice Service Type",
"description": "Integer (range 1 to 255).",
"type": "number"
},
"sd": {
"default": "0x000032",
"title": "Slice Differentiator",
"description": "Optional integer (range 0 to 0xFFFFFE)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"nr_handover_a3_offset": {
"title": "A3 offset for NR handover",
"description": "RSRP gain offset between gNBs which will trigger handover",
"type": "number",
"default": 6
},
"nr_handover_time_to_trigger": {
"title": "Time to Trigger for NR handover",
"description": "Time to triger after which NR handover will be triggerd if A3 offset is reached",
"type": "number",
"enum": [
0,
40,
64,
80,
100,
128,
160,
256,
320,
480,
512,
640,
1024,
1280,
2560,
5120
],
"default": 100
},
"ncell_list": {
"title": "Neighbour Cell Info",
"description": "Neighbour Cell Info",
"patternProperties": {
".*": {
"properties": {
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR Absolute Radio Frequency Channel Number of the neighbour cell",
"type": "number"
},
"pci": {
"title": "Physical Cell ID",
"description": "Physical Cell ID of the neighbour cell",
"type": "number"
},
"nr_cell_id": {
"title": "NR Cell ID",
"description": "Concatenation of gnb_id and cell_id of the neighbour cell",
"type": "string"
},
"gnb_id_bits": {
"title": "gNB ID bits",
"description": "Number of bits for the gNodeB global identifier. (range 22 to 32)",
"type": "number"
},
"nr_band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"tac": {
"title": "Tracking Area Code",
"description": "Integer (range 0 to 16777215)",
"type": "number"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"xn_peers": {
"title": "XN Peers",
"description": "XN Peers",
"patternProperties": {
".*": {
"properties": {
"xn_addr": {
"title": "XN Address",
"description": "XN Address of the neighbour cell (gNB Address)",
"type": "string"
}
},
"type": "object"
}
},
"type": "object",
"default": {}
},
"websocket_password": {
"title": "Websocket password",
"description": "Activates websocket for remote control and sets password",
"type": "string"
},
"inactivity_timer": {
"title": "Inactivity Timer",
"description": "Send RRC connection release after this time (in ms) of network inactivity.",
"type": "number",
"default": 10000
},
"log_phy_debug": {
"title": "Physical layer log debug",
"description": "Enable debug mode for physical layer logs",
"type": "boolean",
"default": false
},
"gps_sync": {
"default": false,
"title": "GPS synchronisation",
"description": "True if GPS should be used for synchronisation",
"type": "boolean"
},
"disable_sdr": {
"default": false,
"title": "Disable SDR",
"description": "Disables radio",
"type": "boolean"
},
"use_ipv4": {
"default": false,
"title": "Use IPv4",
"description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean"
},
"gnb_stats_fetch_period": {
"title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number",
"default": 60
},
"gnb_drb_stats_enabled": {
"title": "Enable gNB drb statistics",
"description": "Enable gNB drb statistics through 100Hz polling, needed for E-UTRAN IP Throughput KPI",
"type": "boolean",
"default": true
},
"max_rx_sample_db": {
"title": "Maximum RX sample value (dB)",
"description": "Maximum RX sample threshold above which RX saturated promise will fail",
"type": "number",
"default": 0
},
"min_txrx_delay": {
"title": "Minimum available time for radio front end processing (ms)",
"description": "Minimum TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 5
},
"avg_txrx_delay": {
"title": "Average available time for radio front end processing (ms)",
"description": "Average TX/RX diff threshold above which baseband latency promise will fail",
"type": "number",
"default": 7
},
"xlog_fluentbit_forward_host": {
"title": "Address to Forward Xlog by Fluenbit",
"description": "Address of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_port": {
"title": "Port to Forward Xlog by Fluentbit",
"description": "Optional Port of Remote Fluentd or Fluentbit Server to Forward Xlog",
"type": "string"
},
"xlog_fluentbit_forward_shared_key": {
"title": "Shared Key to Forward Xlog by Fluentbit",
"description": "Secret Key Shared with Remote Fluentd or Fluentbit Server for Authentication when Forwarding Xlog",
"type": "string"
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR ARFCN, you can retrieve from ENB/GNB side",
"type": "number"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "20 MHz"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": 40
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR ARFCN, you can retrieve from ENB/GNB side",
"type": "number"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": 2
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "001010123456789"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "00112233445566778899aabbccddeeff"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_earfcn": {
"title": "DL EARFCN",
"description": "Downlink E-UTRA Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth",
"type": "string",
"enum": [
"1.4 MHz",
"3 MHz",
"5 MHz",
"10 MHz",
"15 MHz",
"20 MHz"
],
"default": "{{ default_lte_bandwidth }}"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": {{ default_n_antenna_dl }}
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": {{ default_n_antenna_ul }}
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "{{ default_lte_imsi }}"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "{{ default_lte_k }}"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
[buildout]
parts =
directory
ltelogs
lte-ue-lte-config
lte-ue-service
check-sdr-busy.py
monitor-base
publish-connection-information
extends = {{ monitor_template }}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[monitor-httpd-conf-parameter]
httpd-include-file = {{ buildout_directory }}/etc/httpd-include-file.conf
port = ${monitor-instance-parameter:monitor-httpd-port}
url = https://[${monitor-instance-parameter:monitor-httpd-ipv6}]:${:port}
[monitor-instance-parameter]
monitor-httpd-port = ${monitor-address:port}
[monitor-address]
recipe = slapos.cookbook:free_port
minimum = 8035
maximum = 8055
ip = ${monitor-instance-parameter:monitor-httpd-ipv6}
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised
computer = {{ slap_connection['computer-id'] }}
partition = {{ slap_connection['partition-id'] }}
url = {{ slap_connection['server-url'] }}
key = {{ slap_connection['key-file'] }}
cert = {{ slap_connection['cert-file'] }}
configuration.default_lte_bandwidth = {{ default_lte_bandwidth }}
configuration.default_n_antenna_dl = {{ default_n_antenna_dl }}
configuration.default_n_antenna_ul = {{ default_n_antenna_ul }}
configuration.default_lte_imsi = {{ default_lte_imsi }}
configuration.default_lte_k = {{default_lte_k}}
[directory]
recipe = slapos.cookbook:mkdirectory
software = {{ buildout_directory }}
home = ${buildout:directory}
etc = ${:home}/etc
var = ${:home}/var
etc = ${:home}/etc
bin = ${:home}/bin
tmp = ${:home}/tmp
run = ${:var}/run
script = ${:etc}/run
service = ${:etc}/service
promise = ${:etc}/promise
log = ${:var}/log
[ltelogs]
recipe = slapos.recipe.template:jinja2
url = {{ ltelogs_template }}
output = ${directory:home}/ltelogs.sh
extensions = jinja2.ext.do
context =
section directory directory
{% if slapparameter_dict.get("ue_lte_config_link", None) %}
[ue-lte-config-dl]
recipe = slapos.recipe.build:download
url = {{ slapparameter_dict.get("ue_lte_config_link") }}
version = {{ slapparameter_dict.get("ue_lte_config_version") }}
offline = false
{% endif %}
[lte-ue-sh-wrapper]
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
ue-log = ${directory:log}/ue-output.log
inline =
#!/bin/sh
{% if not slapparameter_dict.get("testing", False) %}
sudo /opt/amarisoft/rm-tmp-lte | true;
(echo && echo && date "+[%Y/%m/%d %T.%N %Z] Starting UE software..." && echo) >> ${:ue-log};
tail -c 1M ${:ue-log} > ${:ue-log}.tmp;
mv ${:ue-log}.tmp ${:ue-log};
{{ ue }}/lteue ${directory:etc}/ue.cfg >> ${:ue-log} 2>> ${:ue-log};
{% endif %}
### User Equipment (UE)
[lte-ue-service]
recipe = slapos.cookbook:wrapper
init = ${ltelogs:output} ${directory:log}/ue.log; sleep 2
command-line = ${lte-ue-sh-wrapper:output}
wrapper-path = ${directory:service}/lte-ue
mode = 0775
reserve-cpu = True
pidfile = ${directory:run}/ue.pid
hash-files =
${lte-ue-lte-config:output}
${lte-ue-sh-wrapper:output}
environment =
LD_LIBRARY_PATH={{ openssl_location }}/lib
AMARISOFT_PATH=/opt/amarisoft/.amarisoft
[config-base]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
context =
section directory directory
section slap_configuration slap-configuration
section pub_info publish-connection-information
key slapparameter_dict slap-configuration:configuration
[lte-ue-lte-config]
<= config-base
{% if slapparameter_dict.get("ue_lte_config_link", None) %}
url = ${ue-lte-config-dl:target}
{% else %}
url = {{ ue_lte_template }}
{% endif %}
output = ${directory:etc}/ue.cfg
[publish-connection-information]
<= monitor-publish
recipe = slapos.cookbook:publish.serialised
rue_bind_addr = ${slap-configuration:ipv6-random}
com_addr = [${slap-configuration:ipv6-random}]:9002
monitor-gadget-url = ${:monitor-base-url}/gadget/software.cfg.html
[monitor-instance-parameter]
{% if slapparameter_dict.get("name", None) %}
monitor-title = {{ slapparameter_dict['name'] | string }}
{% endif %}
{% if slapparameter_dict.get("monitor-password", None) %}
password = {{ slapparameter_dict['monitor-password'] | string }}
{% endif %}
[macro.promise]
<= monitor-promise-base
name = ${:_buildout_section_name_}
[check-sdr-busy.py]
<= macro.promise
promise = check_sdr_busy
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-sdr = {{ sdr }}
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"rue_addr": {
"title": "[Required] Remote UE address",
"description": "[Required] Address of remote UE server. Default port is 2152.",
"type": "string",
"default": ""
},
"tx_gain": {
"title": "Tx gain",
"description": "Tx gain (in dB)",
"type": "number"
},
"rx_gain": {
"title": "Rx gain",
"description": "Rx gain (in dB)",
"type": "number"
},
"dl_nr_arfcn": {
"title": "DL NR ARFCN",
"description": "Downlink NR Absolute Radio Frequency Channel Number of the cell",
"type": "number"
},
"band": {
"title": "NR band",
"description": "NR band number",
"type": "number"
},
"bandwidth": {
"title": "Bandwidth",
"description": "Downlink Bandwidth (in MHz)",
"type": "number",
"default": {{ default_nr_bandwidth }}
},
"ssb_nr_arfcn": {
"title": "SSB NR ARFCN",
"description": "SSB NR ARFCN, you can retrieve from ENB/GNB side",
"type": "number"
},
"n_antenna_dl": {
"title": "Number of DL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of DL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": {{ default_n_antenna_dl }}
},
"n_antenna_ul": {
"title": "Number of UL antennas",
"description": "Enumeration: 1, 2, 4 or 8. Number of UL antennas. It must be the same for all NB-IoT and LTE cells sharing the same RF port.",
"type": "number",
"default": {{ default_n_antenna_ul }}
},
"imsi": {
"title": "IMSI",
"description": "IMSI",
"type": "string",
"default": "{{ default_nr_imsi }}"
},
"k": {
"title": "K",
"description": "Set the user secret key (as a 16 bytes hexadecimal string, or eventually 32 bytes hexadecimal string for TUAK).",
"type": "string",
"default": "{{ default_nr_k }}"
},
"sim_algo": {
"title": "sim_algo",
"description": "Optional enumeration. xor, milenage or tuak (default = milenage). Set the USIM authentication algorithm. Note: test USIM cards use the XOR algorithm.",
"type": "string",
"default": "milenage"
},
"opc": {
"title": "opc",
"description": "Optional string. Operator key preprocessed with the user secret key (as a 16 byte hexadecimal string). When the Milenage authentication algorithm is used, either op or opc must be set.",
"type": "string",
"default": "milenage"
},
"amf": {
"title": "amf",
"description": "Range: 0 to 65535. Set the Authentication Management Field.",
"type": "string",
"default": "0x9001"
},
"sqn": {
"title": "sqn",
"description": "Optional String (6 byte hexadecimal string). Default = '000000000000'. Set the initial sequence number. For the XOR algorithm, the actual value does not matter. For the Milenage or TUAK algorithm, a sequence number resynchronization is initiated if the sequence number does not match the one stored in the USIM.",
"type": "string",
"default": "000000000000"
},
"impu": {
"title": "impu",
"description": "Array of string or object. Each string represent an IMPU and can be a sip URI or a telephone number.",
"type": "string",
"default": ""
},
"impi": {
"title": "impi",
"description": "String. Defines user IMPI. Must be fully filled with hostname if necessary.",
"type": "string",
"default": ""
}
}
}
[buildout]
parts =
directory
ltelogs
lte-ue-nr-config
lte-ue-service
check-sdr-busy.py
monitor-base
publish-connection-information
extends = {{ monitor_template }}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[monitor-httpd-conf-parameter]
httpd-include-file = {{ buildout_directory }}/etc/httpd-include-file.conf
port = ${monitor-instance-parameter:monitor-httpd-port}
url = https://[${monitor-instance-parameter:monitor-httpd-ipv6}]:${:port}
[monitor-instance-parameter]
monitor-httpd-port = ${monitor-address:port}
[monitor-address]
recipe = slapos.cookbook:free_port
minimum = 8035
maximum = 8055
ip = ${monitor-instance-parameter:monitor-httpd-ipv6}
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised
computer = {{ slap_connection['computer-id'] }}
partition = {{ slap_connection['partition-id'] }}
url = {{ slap_connection['server-url'] }}
key = {{ slap_connection['key-file'] }}
cert = {{ slap_connection['cert-file'] }}
configuration.default_nr_bandwidth = {{ default_nr_bandwidth }}
configuration.default_n_antenna_dl = {{ default_n_antenna_dl }}
configuration.default_n_antenna_ul = {{ default_n_antenna_ul }}
configuration.default_nr_imsi = {{ default_nr_imsi }}
configuration.default_nr_k = {{ default_nr_k }}
[directory]
recipe = slapos.cookbook:mkdirectory
software = {{ buildout_directory }}
home = ${buildout:directory}
etc = ${:home}/etc
var = ${:home}/var
etc = ${:home}/etc
bin = ${:home}/bin
tmp = ${:home}/tmp
run = ${:var}/run
script = ${:etc}/run
service = ${:etc}/service
promise = ${:etc}/promise
log = ${:var}/log
[ltelogs]
recipe = slapos.recipe.template:jinja2
url = {{ ltelogs_template }}
output = ${directory:home}/ltelogs.sh
extensions = jinja2.ext.do
context =
section directory directory
{% if slapparameter_dict.get("ue_nr_config_link", None) %}
[ue-nr-config-dl]
recipe = slapos.recipe.build:download
url = {{ slapparameter_dict.get("ue_nr_config_link") }}
version = {{ slapparameter_dict.get("ue_nr_config_version") }}
offline = false
{% endif %}
[lte-ue-sh-wrapper]
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
ue-log = ${directory:log}/ue-output.log
inline =
#!/bin/sh
{% if not slapparameter_dict.get("testing", False) %}
sudo /opt/amarisoft/rm-tmp-lte | true;
(echo && echo && date "+[%Y/%m/%d %T.%N %Z] Starting UE software..." && echo) >> ${:ue-log};
tail -c 1M ${:ue-log} > ${:ue-log}.tmp;
mv ${:ue-log}.tmp ${:ue-log};
{{ ue }}/lteue ${directory:etc}/ue.cfg >> ${:ue-log} 2>> ${:ue-log};
{% endif %}
### User Equipment (UE)
[lte-ue-service]
recipe = slapos.cookbook:wrapper
init = ${ltelogs:output} ${directory:log}/ue.log; sleep 2
command-line = ${lte-ue-sh-wrapper:output}
wrapper-path = ${directory:service}/lte-ue
mode = 0775
reserve-cpu = True
pidfile = ${directory:run}/ue.pid
hash-files =
${lte-ue-nr-config:output}
${lte-ue-sh-wrapper:output}
environment =
LD_LIBRARY_PATH={{ openssl_location }}/lib
AMARISOFT_PATH=/opt/amarisoft/.amarisoft
[config-base]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
context =
section directory directory
section slap_configuration slap-configuration
section pub_info publish-connection-information
key slapparameter_dict slap-configuration:configuration
[lte-ue-nr-config]
<= config-base
{% if slapparameter_dict.get("ue_nr_config_link", None) %}
url = ${ue-nr-config-dl:target}
{% else %}
url = {{ ue_nr_template }}
{% endif %}
output = ${directory:etc}/ue.cfg
[publish-connection-information]
<= monitor-publish
recipe = slapos.cookbook:publish.serialised
rue_bind_addr = ${slap-configuration:ipv6-random}
com_addr = [${slap-configuration:ipv6-random}]:9002
monitor-gadget-url = ${:monitor-base-url}/gadget/software.cfg.html
[monitor-instance-parameter]
{% if slapparameter_dict.get("name", None) %}
monitor-title = {{ slapparameter_dict['name'] | string }}
{% endif %}
{% if slapparameter_dict.get("monitor-password", None) %}
password = {{ slapparameter_dict['monitor-password'] | string }}
{% endif %}
[macro.promise]
<= monitor-promise-base
name = ${:_buildout_section_name_}
[check-sdr-busy.py]
<= macro.promise
promise = check_sdr_busy
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-sdr = {{ sdr }}
#!{{ python_path }}
import time
import sys
sys.path.append({{ repr(buildout_directory_path) }})
from ncclient_common import LopcommNetconfClient
if __name__ == '__main__':
nc = LopcommNetconfClient(log_file="{{ log_file }}")
while True:
try:
nc.connect("{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) }}", 830, "oranuser", "oranpassword")
nc.edit_config(["{{ CreateProcessingEle_template }}", "{{ cu_config_template }}"])
break
except Exception as e:
nc.logger.debug('Got exception, waiting 10 seconds before reconnecting...')
nc.logger.debug(e)
time.sleep(10)
finally:
nc.close()
#!{{ python_path }}
import paramiko
import logging
from logging.handlers import RotatingFileHandler
def get_uptime(hostname, username, password):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname, username=username, password=password)
stdin, stdout, stderr = client.exec_command('uptime')
uptime_output = stdout.read().decode()
return uptime_output
except Exception as e:
logger.info(f"Error: {e}")
finally:
client.close()
# Usage
hostname = "{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) }}"
username = "oranuser"
password = "oranpassword"
# Initialize logger
log_file = "{{ log_file }}"
logger = logging.getLogger('logger')
logger.setLevel(logging.INFO)
handler = RotatingFileHandler(log_file, maxBytes=30000, backupCount=2)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
if {{ testing }}:
pass
else:
rrh_uptime = get_uptime(hostname, username, password)
logger.info(f"Uptime from RRH: {rrh_uptime}")
#!{{ python_path }}
import time
import sys
sys.path.append({{ repr(buildout_directory_path) }})
from ncclient_common import LopcommNetconfClient
if __name__ == '__main__':
nc = LopcommNetconfClient(log_file="{{ log_file }}")
try:
nc.connect("{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) }}", 830, "oranuser", "oranpassword")
nc.reset_device()
nc.logger.info("Device reset successful.")
except Exception as e:
nc.logger.debug('Got exception while resetting...')
nc.logger.debug(e)
finally:
nc.close()
#!{{ python_path }}
import time
import json
import xmltodict
import sys
import re
import os
sys.path.append({{ repr(buildout_directory_path) }})
from ncclient_common import LopcommNetconfClient
if __name__ == '__main__':
nc = LopcommNetconfClient(
log_file="{{ log_file }}",
software_reply_json_log_file="{{ software_reply_json_log_file }}"
)
while True:
try:
firmware_check_file= os.path.join('{{etc_path}}','is_firmware_updated')
nc.connect("{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) }}", 830, "oranuser", "oranpassword")
# Fetch software inventory
inventory_vars = nc.get_inventory()
nonrunning_slot_name = inventory_vars["nonrunning_slot_name"]
running_slot_name = inventory_vars["running_slot_name"]
active_nonrunning_slot_name = inventory_vars["active_nonrunning_slot_name"]
nonrunning_slot_name_build_version = inventory_vars["nonrunning_slot_name_build_version"]
running_slot_name_build_version = inventory_vars["running_slot_name_build_version"]
if running_slot_name and nonrunning_slot_name:
if running_slot_name:
nc.logger.info("One slot is running and one is non-running. Proceeding...")
if running_slot_name_build_version in "{{firmware_name}}":
if not os.path.exists(firmware_check_file):
open(firmware_check_file, "w").write('True')
nc.logger.info("Running slot's build-version %s is already updated. Skipping install." % running_slot_name_build_version)
else:
if os.path.exists(firmware_check_file):
os.remove(firmware_check_file)
nc.logger.info("Current build version: %s" % running_slot_name_build_version)
user_authorized_key ="""{{ slapparameter_dict.get('user-authorized-key', '') }}"""
match = re.match(r'ssh-rsa ([^\s]+)', user_authorized_key)
if match:
extracted_key = match.group(1)
else:
nc.logger.info("No valid key found in user authorized key.")
download_rpc_xml = f"""
<software-download xmlns="urn:o-ran:software-management:1.0">
<remote-file-path>{{remote_file_path}}</remote-file-path>
<server>
<keys>
<algorithm xmlns:ct="urn:ietf:params:xml:ns:yang:ietf-crypto-types">1024</algorithm>
<public-key>{extracted_key}</public-key>
</keys>
</server>
</software-download>
"""
download_reply_xml = nc.custom_rpc_request(download_rpc_xml)
nc.logger.info("Downloading software...")
time.sleep(60)
if download_reply_xml:
nc.logger.info("Download proceed.")
download_data = xmltodict.parse(download_reply_xml)
nc.software_reply_json_logger.info('', extra={'data': json.dumps(download_data)})
install_rpc_xml = f"""
<software-install xmlns="urn:o-ran:software-management:1.0">
<slot-name>{nonrunning_slot_name}</slot-name>
<file-names>{{firmware_name}}</file-names>
</software-install>
"""
install_reply_xml = nc.custom_rpc_request(install_rpc_xml)
nc.logger.info("Installing software...")
time.sleep(60)
if install_reply_xml:
nc.logger.info("Installation proceed.")
install_data = xmltodict.parse(install_reply_xml)
nc.software_reply_json_logger.info('', extra={'data': json.dumps(install_data)})
if nonrunning_slot_name_build_version in "{{firmware_name}}":
activate_rpc_xml = f"""
<software-activate xmlns="urn:o-ran:software-management:1.0">
<slot-name>{nonrunning_slot_name}</slot-name>
</software-activate>
"""
activate_reply_xml = nc.custom_rpc_request(activate_rpc_xml)
nc.logger.info("Activating software...")
time.sleep(60)
if activate_reply_xml:
nc.logger.info("Activation proceed.")
activate_data = xmltodict.parse(activate_reply_xml)
nc.software_reply_json_logger.info('', extra={'data': json.dumps(activate_data)})
nc.get_inventory()
if nonrunning_slot_name_build_version in "{{firmware_name}}" and active_nonrunning_slot_name:
nc.logger.info("Active non-running slot has the updated build version. Resetting device.")
nc.reset_device()
break
except Exception as e:
nc.logger.debug('Got exception, waiting 10 seconds before reconnecting...')
nc.logger.debug(str(e))
time.sleep(10)
finally:
nc.close()
#!{{ python_path }}
import time
import sys
sys.path.append({{ repr(buildout_directory_path) }})
from ncclient_common import LopcommNetconfClient
if __name__ == '__main__':
nc = LopcommNetconfClient(
log_file="{{ log_file }}",
json_log_file="{{ json_log_file }}",
cfg_json_log_file="{{ cfg_json_log_file }}",
supervision_json_log_file="{{ supervision_json_log_file }}",
ncsession_json_log_file="{{ ncsession_json_log_file }}",
software_json_log_file="{{ software_json_log_file }}"
)
while True:
try:
nc.connect("{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) }}", 830, "oranuser", "oranpassword")
nc.subscribe()
while True:
nc.get_notification()
except Exception as e:
nc.logger.debug('Got exception, waiting 10 seconds before reconnecting...')
nc.logger.debug(e)
time.sleep(10)
finally:
nc.close()
#!{{ python_path }}
import time
import json
import xmltodict
import sys
import re
import os
sys.path.append({{ repr(buildout_directory_path) }})
from ncclient_common import LopcommNetconfClient
if __name__ == '__main__':
nc = LopcommNetconfClient(
log_file="{{ log_file }}",
supervision_reply_json_log_file="{{ supervision_reply_json_log_file }}"
)
try:
netconf_check_file = os.path.join('{{etc_path}}', 'is_netconf_connected')
nc.connect("{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) }}", 830, "oranuser", "oranpassword")
supervision_subscription_rpc_xml = """
<create-subscription xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
<stream>o-ran-supervision</stream>
</create-subscription>
"""
nc.logger.info("Subscription creating...")
supervision_subscription_reply_xml = nc.custom_rpc_request(supervision_subscription_rpc_xml)
if supervision_subscription_reply_xml:
nc.logger.info("Subscription created")
supervision_subscription_data = xmltodict.parse(supervision_subscription_reply_xml)
nc.supervision_reply_json_logger.info('', extra={'data': json.dumps(supervision_subscription_data)})
while True:
supervision_watchdog_rpc_xml = """
<supervision-watchdog-reset xmlns="urn:o-ran:supervision:1.0">
<supervision-notification-interval>60</supervision-notification-interval>
<guard-timer-overhead>10</guard-timer-overhead>
</supervision-watchdog-reset>
"""
nc.logger.info("NETCONF server replying...")
supervision_watchdog_reply_xml = nc.custom_rpc_request(supervision_watchdog_rpc_xml)
if supervision_watchdog_reply_xml:
if not os.path.exists(netconf_check_file):
open(netconf_check_file, "w").write('True')
nc.logger.info("NETCONF server replied")
supervision_watchdog_data = xmltodict.parse(supervision_watchdog_reply_xml)
nc.supervision_reply_json_logger.info('', extra={'data': json.dumps(supervision_watchdog_data)})
# It must be the same interval as <supervision-notification-interval>
time.sleep(60)
else:
if os.path.exists(netconf_check_file):
os.remove(netconf_check_file)
else:
nc.logger.debug("Subscription failed.")
except Exception as e:
nc.logger.debug('Got exception, waiting 10 seconds before reconnecting...')
nc.logger.debug(str(e))
time.sleep(10)
finally:
nc.close()
\ No newline at end of file
#!/bin/bash
# Copyright (C) 2012-2015 Amarisoft
# LTE system logger version 2016-10-13
# Path for multi environment support
export PATH="$PATH:/bin/:/usr/bin/:/usr/local/bin"
while [ "$1" != "" ] ; do
if [ -e "$1" ] ; then
# Avoid storing logs with comments only
HAS_LOG=$(grep -v -l "#" $1)
if [ "$HAS_LOG" != "" ] ; then
DATE=$(date -u +%Y%m%d.%H:%M:%S | sed -e "s/ /-/g")
FILE=$(basename $1)
mv $1 "{{ directory['log'] }}/${FILE}.${DATE}"
else
rm -f $1
fi
fi
shift
done
import time
import logging
import json
import xmltodict
from logging.handlers import RotatingFileHandler
from ncclient import manager
from ncclient.operations import RPCError
from ncclient.xml_ import *
from ncclient.devices.default import DefaultDeviceHandler
class LopcommNetconfClient:
def __init__(self, log_file, json_log_file=None, cfg_json_log_file=None, supervision_json_log_file=None, ncsession_json_log_file=None, software_json_log_file=None, software_reply_json_log_file=None, supervision_reply_json_log_file=None, testing=False):
self.logger = logging.getLogger('logger')
self.logger.setLevel(logging.DEBUG)
handler = RotatingFileHandler(log_file, maxBytes=100000, backupCount=5)
self.logger.addHandler(handler)
formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(message)s")
handler.setFormatter(formatter)
if json_log_file:
self.json_logger = logging.getLogger('json_logger')
self.json_logger.setLevel(logging.DEBUG)
json_handler = RotatingFileHandler(json_log_file, maxBytes=100000, backupCount=5)
json_formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
json_handler.setFormatter(json_formatter)
self.json_logger.addHandler(json_handler)
self.cfg_json_logger = logging.getLogger('cfg_json_logger')
self.cfg_json_logger.setLevel(logging.DEBUG)
cfg_json_handler = RotatingFileHandler(cfg_json_log_file, maxBytes=100000, backupCount=5)
cfg_json_formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
cfg_json_handler.setFormatter(cfg_json_formatter)
self.cfg_json_logger.addHandler(cfg_json_handler)
self.supervision_json_logger = logging.getLogger('supervision_json_logger')
self.supervision_json_logger.setLevel(logging.DEBUG)
supervision_json_handler = RotatingFileHandler(supervision_json_log_file, maxBytes=100000, backupCount=5)
supervision_json_formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
supervision_json_handler.setFormatter(supervision_json_formatter)
self.supervision_json_logger.addHandler(supervision_json_handler)
self.ncsession_json_logger = logging.getLogger('ncsession_json_logger')
self.ncsession_json_logger.setLevel(logging.DEBUG)
ncsession_json_handler = RotatingFileHandler(ncsession_json_log_file, maxBytes=100000, backupCount=5)
ncsession_json_formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
ncsession_json_handler.setFormatter(ncsession_json_formatter)
self.ncsession_json_logger.addHandler(ncsession_json_handler)
self.software_json_logger = logging.getLogger('software_json_logger')
self.software_json_logger.setLevel(logging.DEBUG)
software_json_handler = RotatingFileHandler(software_json_log_file, maxBytes=100000, backupCount=5)
software_json_formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
software_json_handler.setFormatter(software_json_formatter)
self.software_json_logger.addHandler(software_json_handler)
else:
self.json_logger = None
self.cfg_json_logger = None
self.supervision_json_logger = None
self.ncsession_json_logger = None
self.software_json_logger = None
if supervision_reply_json_log_file:
self.supervision_reply_json_logger = logging.getLogger('supervision_reply_json_logger')
self.supervision_reply_json_logger.setLevel(logging.DEBUG)
supervision_reply_json_handler = RotatingFileHandler(supervision_reply_json_log_file, maxBytes=100000, backupCount=5)
supervision_reply_json_formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
supervision_reply_json_handler.setFormatter(supervision_reply_json_formatter)
self.supervision_reply_json_logger.addHandler(supervision_reply_json_handler)
else:
self.supervision_reply_json_logger = None
if software_reply_json_log_file:
self.software_reply_json_logger = logging.getLogger('software_reply_json_logger')
self.software_reply_json_logger.setLevel(logging.DEBUG)
software_reply_json_handler = RotatingFileHandler(software_reply_json_log_file, maxBytes=100000, backupCount=5)
software_reply_json_formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
software_reply_json_handler.setFormatter(software_reply_json_formatter)
self.software_reply_json_logger.addHandler(software_reply_json_handler)
else:
self.software_reply_json_logger = None
if testing:
return
def connect(self, host, port, user, password):
self.address = (host, port)
self.logger.info('Connecting to %s, user %s...' % (self.address, user))
self.conn = manager.connect(host=host,
port=port,
username=user,
password=password,
timeout=1800,
device_params={
'name': 'default'
},
hostkey_verify=False)
self.logger.info('Connection to %s successful' % (self.address,))
def subscribe(self):
sub = self.conn.create_subscription()
self.logger.info('Subscription to %s successful' % (self.address,))
def get_notification(self):
result = None
while result == None:
self.logger.debug('Waiting for notification from %s...' % (self.address,))
result = self.conn.take_notification(block=True)
if result:
self.logger.debug('Got new notification from %s...' % (self.address,))
result_in_xml = result._raw
data_dict = xmltodict.parse(result_in_xml)
if 'alarm-notif' in data_dict['notification']:
self.json_logger.info('', extra={'data': json.dumps(data_dict)})
elif 'supervision-notification' in data_dict['notification']:
self.supervision_json_logger.info('', extra={'data': json.dumps(data_dict)})
elif 'netconf-session-start' in data_dict['notification'] or 'netconf-session-end' in data_dict['notification']:
self.ncsession_json_logger.info('', extra={'data': json.dumps(data_dict)})
elif any(event in data_dict['notification'] for event in ['install-event', 'activation-event', 'download-event']):
self.software_json_logger.info('', extra={'data': json.dumps(data_dict)})
else:
self.cfg_json_logger.info('', extra={'data': json.dumps(data_dict)})
def edit_config(self, config_files):
for config_file in config_files:
with open(config_file) as f:
config_xml = f.read()
try:
self.logger.info('Sending edit-config RPC request...')
self.conn.edit_config(target='running', config=config_xml)
self.logger.info('Edit-config RPC request sent successfully')
except RPCError as e:
self.logger.error('Error sending edit-config RPC request: %s' % e)
def custom_rpc_request(self, rpc_xml):
try:
self.logger.info('Sending custom RPC request...')
response = self.conn.dispatch(to_ele(rpc_xml))
if response.ok:
self.logger.info('Custom RPC request sent successfully')
return response.xml
else:
self.logger.error('Error sending custom RPC request: %s' % response.error)
except RPCError as e:
self.logger.error('Error sending custom RPC request: %s' % e)
def reset_device(self):
self.logger.info('Resetting...')
reset_rpc_xml = """
<reset xmlns="urn:o-ran:operations:1.0">
</reset>
"""
reset_reply_xml = self.custom_rpc_request(reset_rpc_xml)
if reset_reply_xml:
reset_data = xmltodict.parse(reset_reply_xml)
if self.software_reply_json_logger:
self.software_reply_json_logger.info('', extra={'data': json.dumps(reset_data)})
self.logger.info('Wait 60 second then reboot!')
time.sleep(60)
def get_inventory(self):
self.logger.info('Fetching software inventory...')
inventory_rpc_xml = """
<get xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<filter type="subtree">
<software-inventory xmlns="urn:o-ran:software-management:1.0" />
</filter>
</get>
"""
inventory_reply_xml = self.custom_rpc_request(inventory_rpc_xml)
if inventory_reply_xml:
self.logger.info('Finish fetching software inventory.')
inventory_data = xmltodict.parse(inventory_reply_xml)
self.software_reply_json_logger.info('', extra={'data': json.dumps(inventory_data)})
nonrunning_slot_name = None
running_slot_name = None
active_nonrunning_slot_name = None
nonrunning_slot_name_build_version = None
running_slot_name_build_version = None
software_slots = inventory_data['nc:rpc-reply']['data']['software-inventory']['software-slot']
for slot in software_slots:
if slot['running'] == 'false':
nonrunning_slot_name = slot['name']
nonrunning_slot_name_build_version = slot['build-version']
if slot['running'] == 'true':
running_slot_name = slot['name']
running_slot_name_build_version = slot['build-version']
elif slot['active'] == 'true' and slot['running'] == 'false':
active_nonrunning_slot_name = slot['name']
return {
"nonrunning_slot_name": nonrunning_slot_name,
"running_slot_name": running_slot_name,
"active_nonrunning_slot_name": active_nonrunning_slot_name,
"nonrunning_slot_name_build_version": nonrunning_slot_name_build_version,
"running_slot_name_build_version": running_slot_name_build_version
}
def close(self):
# Close not compatible between ncclient and netconf server
#self.conn.close()
pass
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<processing-elements xmlns="urn:o-ran:processing-element:1.0">
<transport-session-type>CPRI-INTERFACE</transport-session-type>
<ru-elements>
<name>PE0</name>
<transport-flow>
<interface-name>eth1</interface-name>
</transport-flow>
</ru-elements>
</processing-elements>
</config>
\ No newline at end of file
<xc:config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
<user-plane-configuration xc:operation="replace" xmlns="urn:o-ran:uplane-conf-option8:1.0">
<!-- low-level-t[r]x-links -->
<tx-links>
<name>TXA0P00C00</name>
<processing-element>PE0</processing-element>
<tx-array-carrier>TXA0CC00</tx-array-carrier>
<tx-endpoint>TXA0P00C00</tx-endpoint>
</tx-links>
{% if slapparameter_dict.get('n_antenna_dl') == 4 %}
<tx-links>
<name>TXA0P01C00</name>
<processing-element>PE0</processing-element>
<tx-array-carrier>TXA0CC00</tx-array-carrier>
<tx-endpoint>TXA0P01C00</tx-endpoint>
</tx-links>
{% endif %}
<tx-links>
<name>TXA0P00C01</name>
<processing-element>PE0</processing-element>
<tx-array-carrier>TXA0CC00</tx-array-carrier>
<tx-endpoint>TXA0P00C01</tx-endpoint>
</tx-links>
{% if slapparameter_dict.get('n_antenna_dl') == 4 %}
<tx-links>
<name>TXA0P01C01</name>
<processing-element>PE0</processing-element>
<tx-array-carrier>TXA0CC00</tx-array-carrier>
<tx-endpoint>TXA0P01C01</tx-endpoint>
</tx-links>
{% endif %}
<rx-links>
<name>RXA0P00C00</name>
<processing-element>PE0</processing-element>
<rx-array-carrier>RXA0CC00</rx-array-carrier>
<rx-endpoint>RXA0P00C00</rx-endpoint>
</rx-links>
<rx-links>
<name>PRACH0P00C00</name>
<processing-element>PE0</processing-element>
<rx-array-carrier>RXA0CC00</rx-array-carrier>
<rx-endpoint>PRACH0P00C00</rx-endpoint>
</rx-links>
{% if slapparameter_dict.get('n_antenna_dl') == 4 %}
<rx-links>
<name>RXA0P01C00</name>
<processing-element>PE0</processing-element>
<rx-array-carrier>RXA0CC00</rx-array-carrier>
<rx-endpoint>RXA0P01C00</rx-endpoint>
</rx-links>
<rx-links>
<name>PRACH0P01C00</name>
<processing-element>PE0</processing-element>
<rx-array-carrier>RXA0CC00</rx-array-carrier>
<rx-endpoint>PRACH0P01C00</rx-endpoint>
</rx-links>
{% endif %}
<rx-links>
<name>RXA0P00C01</name>
<processing-element>PE0</processing-element>
<rx-array-carrier>RXA0CC00</rx-array-carrier>
<rx-endpoint>RXA0P00C01</rx-endpoint>
</rx-links>
<rx-links>
<name>PRACH0P00C01</name>
<processing-element>PE0</processing-element>
<rx-array-carrier>RXA0CC00</rx-array-carrier>
<rx-endpoint>PRACH0P00C01</rx-endpoint>
</rx-links>
{% if slapparameter_dict.get('n_antenna_dl') == 4 %}
<rx-links>
<name>RXA0P01C01</name>
<processing-element>PE0</processing-element>
<rx-array-carrier>RXA0CC00</rx-array-carrier>
<rx-endpoint>RXA0P01C01</rx-endpoint>
</rx-links>
<rx-links>
<name>PRACH0P01C01</name>
<processing-element>PE0</processing-element>
<rx-array-carrier>RXA0CC00</rx-array-carrier>
<rx-endpoint>PRACH0P01C01</rx-endpoint>
</rx-links>
{% endif %}
<tx-endpoints>
<name>TXA0P00C00</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>0</eaxc-id>
</e-axcid>
</tx-endpoints>
{% if slapparameter_dict.get('n_antenna_dl') == 4 %}
<tx-endpoints>
<name>TXA0P01C00</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>2</eaxc-id>
</e-axcid>
</tx-endpoints>
{% endif %}
<tx-endpoints>
<name>TXA0P00C01</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>1</eaxc-id>
</e-axcid>
</tx-endpoints>
{% if slapparameter_dict.get('n_antenna_dl') == 4 %}
<tx-endpoints>
<name>TXA0P01C01</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>3</eaxc-id>
</e-axcid>
</tx-endpoints>
{% endif %}
<rx-endpoints>
<name>RXA0P00C00</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>0</eaxc-id>
</e-axcid>
</rx-endpoints>
<rx-endpoints>
<name>PRACH0P00C00</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>8</eaxc-id>
</e-axcid>
</rx-endpoints>
{% if slapparameter_dict.get('n_antenna_dl') == 4 %}
<rx-endpoints>
<name>RXA0P01C00</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>2</eaxc-id>
</e-axcid>
</rx-endpoints>
<rx-endpoints>
<name>PRACH0P01C00</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>9</eaxc-id>
</e-axcid>
</rx-endpoints>
{% endif %}
<rx-endpoints>
<name>RXA0P00C01</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>1</eaxc-id>
</e-axcid>
</rx-endpoints>
<rx-endpoints>
<name>PRACH0P00C01</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>24</eaxc-id>
</e-axcid>
</rx-endpoints>
{% if slapparameter_dict.get('n_antenna_dl') == 4 %}
<rx-endpoints>
<name>RXA0P01C01</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>3</eaxc-id>
</e-axcid>
</rx-endpoints>
<rx-endpoints>
<name>PRACH0P01C01</name>
<e-axcid>
<o-du-port-bitmask>61440</o-du-port-bitmask>
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>25</eaxc-id>
</e-axcid>
</rx-endpoints>
{% endif %}
<tx-array-carriers>
<name>TXA0CC00</name>
<absolute-frequency-center>{{ slapparameter_dict.get('dl_earfcn', 300) }}</absolute-frequency-center>
<center-of-channel-bandwidth>{{ 1000000*slapparameter_dict.get('txa0cc00_center_frequency', 2140) }}</center-of-channel-bandwidth>
<channel-bandwidth>{{ {'1.4 MHz': 1400000, '3 MHz': 3000000, '5 MHz': 5000000, '10 MHz': 10000000, '15 MHz': 15000000, '20 MHz': 20000000}.get(slapparameter_dict.get('bandwidth'), '20 MHz') }}</channel-bandwidth>
<active>{{ slapparameter_dict.get('txa0cc00_active', 'INACTIVE') }}</active>
<rw-type>LTE</rw-type>
<rw-duplex-scheme>FDD</rw-duplex-scheme>
<gain>{{ slapparameter_dict.get('txa0cc00_gain', '-20') }}</gain>
<downlink-radio-frame-offset>0</downlink-radio-frame-offset>
<downlink-sfn-offset>0</downlink-sfn-offset>
</tx-array-carriers>
<rx-array-carriers>
<name>RXA0CC00</name>
<absolute-frequency-center>{{ slapparameter_dict.get('rxa0cc00_center_frequency_earfcn', 18300) }}</absolute-frequency-center>
<center-of-channel-bandwidth>{{ 1000000*slapparameter_dict.get('rxa0cc00_center_frequency', 1950) }}</center-of-channel-bandwidth>
<channel-bandwidth>{{ {'1.4 MHz': 1400000, '3 MHz': 3000000, '5 MHz': 5000000, '10 MHz': 10000000, '15 MHz': 15000000, '20 MHz': 20000000}.get(slapparameter_dict.get('bandwidth'), '20 MHz') }}</channel-bandwidth>
<active>{{ slapparameter_dict.get('rxa0cc00_active', 'INACTIVE') }}</active>
<downlink-radio-frame-offset>0</downlink-radio-frame-offset>
<downlink-sfn-offset>0</downlink-sfn-offset>
<gain-correction>0.0</gain-correction>
<n-ta-offset>0</n-ta-offset>
</rx-array-carriers>
</user-plane-configuration>
</xc:config>
#!/usr/bin/env python3
from jinja2 import Template
import argparse
import os
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--delete', action='store_true')
args = parser.parse_args()
if args.delete:
directory = os.path.dirname(os.path.realpath(__file__))
test_directory = os.path.join(directory, 'test')
for f in os.listdir(directory):
if 'tdd' in f:
os.remove(os.path.join(directory, f))
for f in os.listdir(test_directory):
if 'testTDD' in f:
os.remove(os.path.join(test_directory, f))
exit()
global_context = {
'generated_file_message': "This file was generated using a jinja2 template and the render-templates script, don't modify directly."
}
software_list = [
{
'software_name' : 'tdd-ors',
'rf_mode' : 'tdd',
'trx' : 'sdr',
'bbu' : 'ors',
'ru' : 'ors',
}, {
'software_name' : 'fdd-ors',
'rf_mode' : 'fdd',
'trx' : 'sdr',
'bbu' : 'ors',
'ru' : 'ors',
}, {
'software_name' : 'tdd-m2ru',
'rf_mode' : 'tdd',
'trx' : 'cpri',
'bbu' : 'server',
'ru' : 'm2ru',
}, {
'software_name' : 'fdd-lopcomm',
'rf_mode' : 'fdd',
'trx' : 'cpri',
'bbu' : 'server',
'ru' : 'lopcomm',
}, {
'software_name' : 'fdd',
'rf_mode' : 'fdd',
'trx' : 'sdr',
'bbu' : 'server',
'ru' : 'any',
}, {
'software_name' : 'tdd',
'rf_mode' : 'tdd',
'trx' : 'sdr',
'bbu' : 'server',
'ru' : 'any',
}
]
for i in range (len(software_list)):
software_list[i].update({
'default_lte_bandwidth' : "20 MHz",
'default_lte_imsi' : "001010123456789",
'default_lte_k' : "00112233445566778899aabbccddeeff",
'default_lte_inactivity_timer' : 10000,
'default_nr_bandwidth' : 40,
'default_nr_imsi' : "001010123456789",
'default_nr_k' : "00112233445566778899aabbccddeeff",
'default_nr_ssb_pos_bitmap' : "10000000",
'default_n_antenna_dl' : 2,
'default_n_antenna_ul' : 2,
'default_nr_inactivity_timer' : 10000,
})
with open('software.cfg.json.jinja2', 'r') as f:
software_json_template = Template(f.read())
instance_json_template_map = {}
for software_type in ['enb', 'gnb', 'ue-lte', 'ue-nr']:
with open('instance-{}-input-schema.json.jinja2'.format(software_type), 'r') as f:
instance_json_template_map[software_type] = Template(f.read())
with open('software.jinja2.cfg', 'r') as f:
software_template = Template(f.read())
with open('test/test.jinja2.py', 'r') as f:
test_template = Template(f.read())
for software in software_list:
with open('software-{}.cfg.json'.format(software['software_name']),
'w+') as f:
f.write(software_json_template.render(**software, **global_context) + '\n')
with open('test/test{}.py'.format(software['software_name'].upper()),
'w+') as f:
f.write(test_template.render(**software, **global_context) + '\n')
with open('software-{}.cfg'.format(software['software_name']),
'w+') as f:
f.write(software_template.render(**software, **global_context) + '\n')
for software_type in ['enb', 'gnb', 'ue-lte', 'ue-nr']:
with open('instance-{}-{}-input-schema.json'.format(
software['software_name'],
software_type),
'w+') as f:
f.write(instance_json_template_map[software_type].render(**software, **global_context) + '\n')
config = "gnb"
json_params_empty = """{
"rf_mode": 'fdd',
"slap_configuration": {
},
"directory": {
},
"slapparameter_dict": {
}
}"""
json_params = """{
"rf_mode": "tdd",
"trx": "sdr",
"bbu": "ors",
"ru": "ors",
"one_watt": "True",
"earfcn": 646666,
"nr_arfcn": 646666,
"nr_band": 43,
"tx_gain": 62,
"rx_gain": 43,
"sib23_file": "sib",
"slap_configuration": {
"tap-name": "slaptap9",
"configuration.default_lte_bandwidth": "10 MHz",
"configuration.default_lte_imsi": "001010123456789",
"configuration.default_lte_k": "00112233445566778899aabbccddeeff",
"configuration.default_lte_inactivity_timer": 10000,
"configuration.default_nr_bandwidth": 40,
"configuration.default_nr_imsi": "001010123456789",
"configuration.default_nr_k": "00112233445566778899aabbccddeeff",
"configuration.default_nr_ssb_pos_bitmap": "10000000",
"configuration.default_n_antenna_dl": 2,
"configuration.default_n_antenna_ul": 2,
"configuration.default_nr_inactivity_timer": 10000
},
"directory": {
"log": "log",
"etc": "etc",
"var": "var"
},
"slapparameter_dict": {
"tdd_ul_dl_config": "5ms 8UL 1DL 2/10 (maximum uplink)"
}
}"""
import os
import json
from jinja2 import Environment, StrictUndefined, \
BaseLoader, TemplateNotFound, PrefixLoader
import six
DEFAULT_CONTEXT = {x.__name__: x for x in (
abs, all, any, bin, bool, bytes, callable, chr, complex, dict, divmod,
enumerate, filter, float, format, frozenset, hex, int,
isinstance, iter, len, list, map, max, min, next, oct, ord, pow,
range, repr, reversed, round, set, six, sorted, str, sum, tuple, zip)}
if six.PY2:
import itertools
DEFAULT_CONTEXT.update(
filter=itertools.ifilter,
map=itertools.imap,
range=xrange,
zip=itertools.izip,
)
def _assert(x, *args):
if x:
return ""
raise AssertionError(*args)
DEFAULT_CONTEXT['assert'] = _assert
DUMPS_KEY = 'dumps'
DEFAULT_IMPORT_DELIMITER = '/'
def getKey(expression, buildout, _, options):
section, entry = expression.split(':')
if section:
return buildout[section][entry]
else:
return options[entry]
def getJsonKey(expression, buildout, _, __):
return json.loads(getKey(expression, buildout, _, __))
EXPRESSION_HANDLER = {
'raw': (lambda expression, _, __, ___: expression),
'key': getKey,
'json': (lambda expression, _, __, ___: json.loads(expression)),
'jsonkey': getJsonKey,
'import': (lambda expression, _, __, ___:
__import__(expression, fromlist=['*'], level=0)),
'section': (lambda expression, buildout, _, __: dict(
buildout[expression])),
}
class RelaxedPrefixLoader(PrefixLoader):
"""
Same as PrefixLoader, but accepts imports lacking separator.
"""
def get_loader(self, template):
if self.delimiter not in template:
template += self.delimiter
return super(RelaxedPrefixLoader, self).get_loader(template)
class RecipeBaseLoader(BaseLoader):
"""
Base class for import classes altering import path.
"""
def __init__(self, path, delimiter, encoding):
self.base = os.path.normpath(path)
self.delimiter = delimiter
self.encoding = encoding
def get_source(self, environment, template):
path = self._getPath(template)
# Code adapted from jinja2's doc on BaseLoader.
if path is None or not os.path.exists(path):
raise TemplateNotFound(template)
mtime = os.path.getmtime(path)
with open(path, 'rb') as f:
source = f.read().decode(self.encoding)
return source, path, lambda: mtime == os.path.getmtime(path)
def _getPath(self, template):
raise NotImplementedError
class FileLoader(RecipeBaseLoader):
"""
Single-path loader.
"""
def _getPath(self, template):
if template:
return None
return self.base
class FolderLoader(RecipeBaseLoader):
"""
Multi-path loader (to allow importing a folder's content).
"""
def _getPath(self, template):
path = os.path.normpath(os.path.join(
self.base,
*template.split(self.delimiter)
))
if path.startswith(self.base):
return path
return None
LOADER_TYPE_DICT = {
'rawfile': (FileLoader, EXPRESSION_HANDLER['raw']),
'file': (FileLoader, getKey),
'rawfolder': (FolderLoader, EXPRESSION_HANDLER['raw']),
'folder': (FolderLoader, getKey),
}
compiled_source_cache = {}
class Recipe():
def _init(self, name, options):
self.once = options.get('once')
self.encoding = options.get('encoding', 'utf-8')
self._update = True
import_delimiter = options.get('import-delimiter',
DEFAULT_IMPORT_DELIMITER)
import_dict = {}
for line in options.get('import-list', '').splitlines(False):
if not line:
continue
expression_type, alias, expression = line.split(None, 2)
if alias in import_dict:
raise ValueError('Duplicate import-list entry %r' % alias)
loader_type, expression_handler = LOADER_TYPE_DICT[
expression_type]
import_dict[alias] = loader_type(
expression_handler(expression, *args),
import_delimiter, self.encoding,
)
if import_dict:
loader = RelaxedPrefixLoader(import_dict,
delimiter=import_delimiter)
else:
loader = None
self.template = options['url']
extension_list = [x for x in (y.strip()
for y in options.get('extensions', '').split()) if x]
self.context = options['context']
self.context.update(DEFAULT_CONTEXT.copy())
self.env = Environment(
extensions=extension_list,
undefined=StrictUndefined,
loader=loader)
def _render(self):
env = self.env
template = self.template
with open(template, 'rb') as f:
source = f.read().decode(self.encoding)
compiled_source_cache[template] = compiled_source = \
env.compile(source, filename=template)
template_object = env.template_class.from_code(env,
compiled_source,
env.make_globals(None), None)
print(self.context)
return template_object.render(**self.context).encode(self.encoding)
def install(self):
once = self.once
if once and os.path.exists(once):
return
installed = super(Recipe, self).install()
if once:
open(once, 'ab').close()
return
return installed
def update(self):
if self._update:
self.install()
else:
super(Recipe, self).update()
r = Recipe()
r._init("recipe", {
'extensions': 'jinja2.ext.do',
'url': 'config/{}.jinja2.cfg'.format(config),
'output': 'config/{}.cfg'.format(config),
'context': json.loads(json_params),
})
with open('config/{}.cfg'.format(config), 'w+') as f:
f.write(r._render().decode())
[buildout]
extends =
buildout.hash.cfg
../../stack/slapos.cfg
../../stack/monitor/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/nghttp2/buildout.cfg
../../component/iperf3/buildout.cfg
../../component/python3/buildout.cfg
../../component/python-pynacl/buildout.cfg
../../component/bcrypt/buildout.cfg
../../component/numpy/buildout.cfg
../../component/pygolang/buildout.cfg
../../component/git/buildout.cfg
../../component/dnsmasq/buildout.cfg
../../component/fluent-bit/buildout.cfg
../../component/openssh/buildout.cfg
parts +=
template
slapos-cookbook
ltelogs.jinja2.sh
ncclient_common
# copy all configs by default
mme.jinja2.cfg
dnsmasq.jinja2.cfg
ims.jinja2.cfg
enb.jinja2.cfg
gnb.jinja2.cfg
ue_db.jinja2.cfg
ue-lte.jinja2.cfg
ue-nr.jinja2.cfg
CreateProcessingEle.jinja2.xml
cu_config.jinja2.xml
sib23.jinja2.asn
monitor-httpd-extra-conf
# copy all gadget file
gadget
g-chart.line.js
promise.gadget.js
software.cfg.html
rsvp.js
iperf3
dnsmasq
eggs
xamari
setcap
# unimplemented parts - the http monitor and better log handling using logrotate
# apache-php
# logrotate
[template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/template.cfg
[download-base]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_update_hash_filename_}
[ncclient_common]
<= download-base
destination = ${buildout:directory}/ncclient_common.py
[amarisoft-stats.jinja2.py]
<= download-base
[amarisoft-rf-info.jinja2.py]
<= download-base
[lopcomm-rrh-stats.jinja2.py]
<= download-base
[lopcomm-rrh-config.jinja2.py]
<= download-base
[lopcomm-rrh-software.jinja2.py]
<= download-base
[lopcomm-rrh-supervision.jinja2.py]
<= download-base
[lopcomm-rrh-reset-info.jinja2.py]
<= download-base
[lopcomm-rrh-reset.jinja2.py]
<= download-base
[template-enb]
<= download-base
[template-gnb]
<= download-base
[template-core-network]
<= download-base
[template-ue-lte]
<= download-base
[template-ue-nr]
<= download-base
[template-obsolete]
<= download-base
[copy-to-instance]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_buildout_section_name_}
[copy-config-to-instance]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/config/${:_buildout_section_name_}
[copy-netconf-to-instance]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/netconf/${:_buildout_section_name_}
[gadget]
recipe = slapos.recipe.template
output = ${buildout:directory}/${:_buildout_section_name_}/renderjs.js
url = https://lab.nexedi.com/nexedi/renderjs/raw/b715d066bfddc30bedfc8356fb720dcbb391378e/dist/renderjs-0.28.0.js
md5sum = 7e074a29b07e0045d2ba8a8e63bd499e
[monitor-httpd-extra-conf]
recipe = slapos.recipe.template
output = ${buildout:directory}/etc/httpd-include-file.conf
inline =
Alias /gadget ${buildout:directory}/gadget
<Directory ${buildout:directory}/gadget>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
Satisfy Any
Allow from all
</Directory>
[copy-gadget-to-software]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/gadget/${:_buildout_section_name_}
destination = ${buildout:directory}/gadget/${:_buildout_section_name_}
[enb.jinja2.cfg]
<= copy-config-to-instance
filename = enb.jinja2.cfg
[sib23.jinja2.asn]
<= copy-config-to-instance
filename = sib23.jinja2.asn
[gnb.jinja2.cfg]
<= copy-config-to-instance
filename = gnb.jinja2.cfg
[ltelogs.jinja2.sh]
<= copy-to-instance
filename = ltelogs.jinja2.sh
[ue_db.jinja2.cfg]
<= copy-config-to-instance
filename = ue_db.jinja2.cfg
[mme.jinja2.cfg]
<= copy-config-to-instance
filename = mme.jinja2.cfg
[dnsmasq.jinja2.cfg]
<= copy-config-to-instance
filename = dnsmasq.jinja2.cfg
[ims.jinja2.cfg]
<= copy-config-to-instance
filename = ims.jinja2.cfg
[ue-lte.jinja2.cfg]
<= copy-config-to-instance
filename = ue-lte.jinja2.cfg
[ue-nr.jinja2.cfg]
<= copy-config-to-instance
filename = ue-nr.jinja2.cfg
[CreateProcessingEle.jinja2.xml]
<= copy-netconf-to-instance
filename = CreateProcessingEle.jinja2.xml
[cu_config.jinja2.xml]
<= copy-netconf-to-instance
filename = cu_config.jinja2.xml
# Download gadget files
[software.cfg.html]
<= copy-gadget-to-software
[promise.gadget.js]
<= copy-gadget-to-software
[rsvp.js]
<= copy-gadget-to-software
url = https://lab.nexedi.com/nexedi/rsvp.js/raw/b0c4596df6a52d75705a59262bc992a166ff11a1/dist/rsvp-2.0.4.js
md5sum = 2b0f2d52857b17fdfb8a5c2ea451a5ad
[g-chart.line.js]
<= copy-gadget-to-software
url = https://raw.githubusercontent.com/guschnwg/g-chart/cbcc7bc40f88fcce4854b55d0902b6273004ba3e/g-chart.line.js
md5sum = 57c50b46c9492c6ab78dc44deac3c0ce
[eggs]
recipe = zc.recipe.egg
eggs =
websocket-client
${python-pynacl:egg}
${bcrypt:egg}
xmltodict
ncclient
interpreter = pythonwitheggs
[xlte-repository]
recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/kirr/xlte.git
revision = e716ab51
git-executable = ${git:location}/bin/git
[xlte]
recipe = zc.recipe.egg:develop
setup = ${xlte-repository:location}
egg = xlte
depends =
${numpy:egg}
${pygolang:egg}
[xamari]
recipe = zc.recipe.egg
eggs = ${xlte:egg}
scripts = xamari
[setcap]
recipe = plone.recipe.command
command = sudo -n /opt/amarisoft/setcap ${dnsmasq:location}/sbin/dnsmasq || true
update-command = ${:command}
[versions]
websocket-client = 1.4.2
ncclient = 0.6.13
xmltodict = 0.13.0
# This file was generated using a jinja2 template and the render-templates script, don't modify directly.
[buildout]
extends =
software-base.cfg
[default-params]
default-lte-bandwidth = 20 MHz
default-lte-inactivity-timer = 10000
default-lte-imsi = 001010123456789
default-lte-k = 00112233445566778899aabbccddeeff
default-nr-bandwidth = 40
default-nr-ssb-pos-bitmap = 10000000
default-nr-inactivity-timer = 10000
default-nr-imsi = 001010123456789
default-nr-k = 00112233445566778899aabbccddeeff
default-n-antenna-dl = 2
default-n-antenna-ul = 2
[rf-mode]
software-name = fdd-lopcomm
rf-mode = fdd
trx = cpri
bbu = server
ru = lopcomm
{
"name": "ORS Amarisoft",
"description": "4G and 5G amarisoft stack for ORS",
"serialisation": "json-in-xml",
"software-type": {
"ue-lte": {
"title": "UE-LTE",
"description": "UE LTE Configuration",
"software-type": "ue-lte",
"request": "instance-fdd-lopcomm-ue-lte-input-schema.json",
"response": "instance-fdd-lopcomm-ue-lte-schema.json",
"index": 4
},
"ue-nr": {
"title": "UE-NR",
"description": "UE NR Configuration",
"software-type": "ue-nr",
"request": "instance-fdd-lopcomm-ue-nr-input-schema.json",
"response": "instance-fdd-lopcomm-ue-nr-schema.json",
"index": 5
},
"enb": {
"title": "eNB",
"software-type": "enb",
"description": "eNodeB Configuration",
"request": "instance-fdd-lopcomm-enb-input-schema.json",
"response": "instance-fdd-lopcomm-enb-schema.json",
"index": 0
},
"gnb": {
"title": "gNB",
"software-type": "gnb",
"description": "gNodeB Configuration",
"request": "instance-fdd-lopcomm-gnb-input-schema.json",
"response": "instance-fdd-lopcomm-gnb-schema.json",
"index": 1
},
"core-network": {
"title": "Core Network",
"software-type": "core-network",
"description": "Core Network Configuration",
"request": "instance-core-network-input-schema.json",
"response": "instance-core-network-schema.json",
"index": 2
},
"core-network-slave": {
"title": "Core Network Sim Card",
"description": "Core Network Sim Card Configuration",
"software-type": "core-network",
"request": "instance-core-network-slave-input-schema.json",
"response": "instance-core-network-slave-schema.json",
"shared": true,
"index": 3
}
}
}
# This file was generated using a jinja2 template and the render-templates script, don't modify directly.
[buildout]
extends =
software-base.cfg
[default-params]
default-lte-bandwidth = 20 MHz
default-lte-inactivity-timer = 10000
default-lte-imsi = 001010123456789
default-lte-k = 00112233445566778899aabbccddeeff
default-nr-bandwidth = 40
default-nr-ssb-pos-bitmap = 10000000
default-nr-inactivity-timer = 10000
default-nr-imsi = 001010123456789
default-nr-k = 00112233445566778899aabbccddeeff
default-n-antenna-dl = 2
default-n-antenna-ul = 2
[rf-mode]
software-name = fdd-ors
rf-mode = fdd
trx = sdr
bbu = ors
ru = ors
{
"name": "ORS Amarisoft",
"description": "4G and 5G amarisoft stack for ORS",
"serialisation": "json-in-xml",
"software-type": {
"enb": {
"title": "eNB",
"software-type": "enb",
"description": "eNodeB Configuration",
"request": "instance-fdd-ors-enb-input-schema.json",
"response": "instance-fdd-ors-enb-schema.json",
"index": 0
},
"gnb": {
"title": "gNB",
"software-type": "gnb",
"description": "gNodeB Configuration",
"request": "instance-fdd-ors-gnb-input-schema.json",
"response": "instance-fdd-ors-gnb-schema.json",
"index": 1
},
"core-network": {
"title": "Core Network",
"software-type": "core-network",
"description": "Core Network Configuration",
"request": "instance-core-network-input-schema.json",
"response": "instance-core-network-schema.json",
"index": 2
},
"core-network-slave": {
"title": "Core Network Sim Card",
"description": "Core Network Sim Card Configuration",
"software-type": "core-network",
"request": "instance-core-network-slave-input-schema.json",
"response": "instance-core-network-slave-schema.json",
"shared": true,
"index": 3
}
}
}
# This file was generated using a jinja2 template and the render-templates script, don't modify directly.
[buildout]
extends =
software-base.cfg
[default-params]
default-lte-bandwidth = 20 MHz
default-lte-inactivity-timer = 10000
default-lte-imsi = 001010123456789
default-lte-k = 00112233445566778899aabbccddeeff
default-nr-bandwidth = 40
default-nr-ssb-pos-bitmap = 10000000
default-nr-inactivity-timer = 10000
default-nr-imsi = 001010123456789
default-nr-k = 00112233445566778899aabbccddeeff
default-n-antenna-dl = 2
default-n-antenna-ul = 2
[rf-mode]
software-name = fdd
rf-mode = fdd
trx = sdr
bbu = server
ru = any
{
"name": "ORS Amarisoft",
"description": "4G and 5G amarisoft stack for ORS",
"serialisation": "json-in-xml",
"software-type": {
"ue-lte": {
"title": "UE-LTE",
"description": "UE LTE Configuration",
"software-type": "ue-lte",
"request": "instance-fdd-ue-lte-input-schema.json",
"response": "instance-fdd-ue-lte-schema.json",
"index": 4
},
"ue-nr": {
"title": "UE-NR",
"description": "UE NR Configuration",
"software-type": "ue-nr",
"request": "instance-fdd-ue-nr-input-schema.json",
"response": "instance-fdd-ue-nr-schema.json",
"index": 5
},
"enb": {
"title": "eNB",
"software-type": "enb",
"description": "eNodeB Configuration",
"request": "instance-fdd-enb-input-schema.json",
"response": "instance-fdd-enb-schema.json",
"index": 0
},
"gnb": {
"title": "gNB",
"software-type": "gnb",
"description": "gNodeB Configuration",
"request": "instance-fdd-gnb-input-schema.json",
"response": "instance-fdd-gnb-schema.json",
"index": 1
},
"core-network": {
"title": "Core Network",
"software-type": "core-network",
"description": "Core Network Configuration",
"request": "instance-core-network-input-schema.json",
"response": "instance-core-network-schema.json",
"index": 2
},
"core-network-slave": {
"title": "Core Network Sim Card",
"description": "Core Network Sim Card Configuration",
"software-type": "core-network",
"request": "instance-core-network-slave-input-schema.json",
"response": "instance-core-network-slave-schema.json",
"shared": true,
"index": 3
}
}
}
# This file was generated using a jinja2 template and the render-templates script, don't modify directly.
[buildout]
extends =
software-base.cfg
[default-params]
default-lte-bandwidth = 20 MHz
default-lte-inactivity-timer = 10000
default-lte-imsi = 001010123456789
default-lte-k = 00112233445566778899aabbccddeeff
default-nr-bandwidth = 40
default-nr-ssb-pos-bitmap = 10000000
default-nr-inactivity-timer = 10000
default-nr-imsi = 001010123456789
default-nr-k = 00112233445566778899aabbccddeeff
default-n-antenna-dl = 2
default-n-antenna-ul = 2
[rf-mode]
software-name = tdd-m2ru
rf-mode = tdd
trx = cpri
bbu = server
ru = m2ru
{
"name": "ORS Amarisoft",
"description": "4G and 5G amarisoft stack for ORS",
"serialisation": "json-in-xml",
"software-type": {
"ue-lte": {
"title": "UE-LTE",
"description": "UE LTE Configuration",
"software-type": "ue-lte",
"request": "instance-tdd-m2ru-ue-lte-input-schema.json",
"response": "instance-tdd-m2ru-ue-lte-schema.json",
"index": 4
},
"ue-nr": {
"title": "UE-NR",
"description": "UE NR Configuration",
"software-type": "ue-nr",
"request": "instance-tdd-m2ru-ue-nr-input-schema.json",
"response": "instance-tdd-m2ru-ue-nr-schema.json",
"index": 5
},
"enb": {
"title": "eNB",
"software-type": "enb",
"description": "eNodeB Configuration",
"request": "instance-tdd-m2ru-enb-input-schema.json",
"response": "instance-tdd-m2ru-enb-schema.json",
"index": 0
},
"gnb": {
"title": "gNB",
"software-type": "gnb",
"description": "gNodeB Configuration",
"request": "instance-tdd-m2ru-gnb-input-schema.json",
"response": "instance-tdd-m2ru-gnb-schema.json",
"index": 1
},
"core-network": {
"title": "Core Network",
"software-type": "core-network",
"description": "Core Network Configuration",
"request": "instance-core-network-input-schema.json",
"response": "instance-core-network-schema.json",
"index": 2
},
"core-network-slave": {
"title": "Core Network Sim Card",
"description": "Core Network Sim Card Configuration",
"software-type": "core-network",
"request": "instance-core-network-slave-input-schema.json",
"response": "instance-core-network-slave-schema.json",
"shared": true,
"index": 3
}
}
}
# This file was generated using a jinja2 template and the render-templates script, don't modify directly.
[buildout]
extends =
software-base.cfg
[default-params]
default-lte-bandwidth = 20 MHz
default-lte-inactivity-timer = 10000
default-lte-imsi = 001010123456789
default-lte-k = 00112233445566778899aabbccddeeff
default-nr-bandwidth = 40
default-nr-ssb-pos-bitmap = 10000000
default-nr-inactivity-timer = 10000
default-nr-imsi = 001010123456789
default-nr-k = 00112233445566778899aabbccddeeff
default-n-antenna-dl = 2
default-n-antenna-ul = 2
[rf-mode]
software-name = tdd-ors
rf-mode = tdd
trx = sdr
bbu = ors
ru = ors
{
"name": "ORS Amarisoft",
"description": "4G and 5G amarisoft stack for ORS",
"serialisation": "json-in-xml",
"software-type": {
"enb": {
"title": "eNB",
"software-type": "enb",
"description": "eNodeB Configuration",
"request": "instance-tdd-ors-enb-input-schema.json",
"response": "instance-tdd-ors-enb-schema.json",
"index": 0
},
"gnb": {
"title": "gNB",
"software-type": "gnb",
"description": "gNodeB Configuration",
"request": "instance-tdd-ors-gnb-input-schema.json",
"response": "instance-tdd-ors-gnb-schema.json",
"index": 1
},
"core-network": {
"title": "Core Network",
"software-type": "core-network",
"description": "Core Network Configuration",
"request": "instance-core-network-input-schema.json",
"response": "instance-core-network-schema.json",
"index": 2
},
"core-network-slave": {
"title": "Core Network Sim Card",
"description": "Core Network Sim Card Configuration",
"software-type": "core-network",
"request": "instance-core-network-slave-input-schema.json",
"response": "instance-core-network-slave-schema.json",
"shared": true,
"index": 3
}
}
}
# This file was generated using a jinja2 template and the render-templates script, don't modify directly.
[buildout]
extends =
software-base.cfg
[default-params]
default-lte-bandwidth = 20 MHz
default-lte-inactivity-timer = 10000
default-lte-imsi = 001010123456789
default-lte-k = 00112233445566778899aabbccddeeff
default-nr-bandwidth = 40
default-nr-ssb-pos-bitmap = 10000000
default-nr-inactivity-timer = 10000
default-nr-imsi = 001010123456789
default-nr-k = 00112233445566778899aabbccddeeff
default-n-antenna-dl = 2
default-n-antenna-ul = 2
[rf-mode]
software-name = tdd
rf-mode = tdd
trx = sdr
bbu = server
ru = any
{
"name": "ORS Amarisoft",
"description": "4G and 5G amarisoft stack for ORS",
"serialisation": "json-in-xml",
"software-type": {
"ue-lte": {
"title": "UE-LTE",
"description": "UE LTE Configuration",
"software-type": "ue-lte",
"request": "instance-tdd-ue-lte-input-schema.json",
"response": "instance-tdd-ue-lte-schema.json",
"index": 4
},
"ue-nr": {
"title": "UE-NR",
"description": "UE NR Configuration",
"software-type": "ue-nr",
"request": "instance-tdd-ue-nr-input-schema.json",
"response": "instance-tdd-ue-nr-schema.json",
"index": 5
},
"enb": {
"title": "eNB",
"software-type": "enb",
"description": "eNodeB Configuration",
"request": "instance-tdd-enb-input-schema.json",
"response": "instance-tdd-enb-schema.json",
"index": 0
},
"gnb": {
"title": "gNB",
"software-type": "gnb",
"description": "gNodeB Configuration",
"request": "instance-tdd-gnb-input-schema.json",
"response": "instance-tdd-gnb-schema.json",
"index": 1
},
"core-network": {
"title": "Core Network",
"software-type": "core-network",
"description": "Core Network Configuration",
"request": "instance-core-network-input-schema.json",
"response": "instance-core-network-schema.json",
"index": 2
},
"core-network-slave": {
"title": "Core Network Sim Card",
"description": "Core Network Sim Card Configuration",
"software-type": "core-network",
"request": "instance-core-network-slave-input-schema.json",
"response": "instance-core-network-slave-schema.json",
"shared": true,
"index": 3
}
}
}
{
"name": "ORS Amarisoft",
"description": "4G and 5G amarisoft stack for ORS",
"serialisation": "json-in-xml",
"software-type": {
{% if bbu != 'ors' %}
"ue-lte": {
"title": "UE-LTE",
"description": "UE LTE Configuration",
"software-type": "ue-lte",
"request": "instance-{{ software_name }}-ue-lte-input-schema.json",
"response": "instance-{{ software_name }}-ue-lte-schema.json",
"index": 4
},
"ue-nr": {
"title": "UE-NR",
"description": "UE NR Configuration",
"software-type": "ue-nr",
"request": "instance-{{ software_name }}-ue-nr-input-schema.json",
"response": "instance-{{ software_name }}-ue-nr-schema.json",
"index": 5
},
{% endif %}
"enb": {
"title": "eNB",
"software-type": "enb",
"description": "eNodeB Configuration",
"request": "instance-{{ software_name }}-enb-input-schema.json",
"response": "instance-{{ software_name }}-enb-schema.json",
"index": 0
},
"gnb": {
"title": "gNB",
"software-type": "gnb",
"description": "gNodeB Configuration",
"request": "instance-{{ software_name }}-gnb-input-schema.json",
"response": "instance-{{ software_name }}-gnb-schema.json",
"index": 1
},
"core-network": {
"title": "Core Network",
"software-type": "core-network",
"description": "Core Network Configuration",
"request": "instance-core-network-input-schema.json",
"response": "instance-core-network-schema.json",
"index": 2
},
"core-network-slave": {
"title": "Core Network Sim Card",
"description": "Core Network Sim Card Configuration",
"software-type": "core-network",
"request": "instance-core-network-slave-input-schema.json",
"response": "instance-core-network-slave-schema.json",
"shared": true,
"index": 3
}
}
}
# {{ generated_file_message }}
[buildout]
extends =
software-base.cfg
[default-params]
default-lte-bandwidth = {{ default_lte_bandwidth }}
default-lte-inactivity-timer = {{ default_lte_inactivity_timer }}
default-lte-imsi = {{ default_lte_imsi }}
default-lte-k = {{ default_lte_k }}
default-nr-bandwidth = {{ default_nr_bandwidth }}
default-nr-ssb-pos-bitmap = {{ default_nr_ssb_pos_bitmap }}
default-nr-inactivity-timer = {{ default_nr_inactivity_timer }}
default-nr-imsi = {{ default_nr_imsi }}
default-nr-k = {{ default_nr_k }}
default-n-antenna-dl = {{ default_n_antenna_dl }}
default-n-antenna-ul = {{ default_n_antenna_ul }}
[rf-mode]
software-name = {{ software_name }}
rf-mode = {{ rf_mode }}
trx = {{ trx }}
bbu = {{ bbu }}
ru = {{ ru }}
Tests for ors-amarisoft software release
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from setuptools import setup, find_packages
version = '0.0.1.dev0'
name = 'slapos.test.ors_amarisoft'
with open("README.md") as f:
long_description = f.read()
setup(
name=name,
version=version,
description="Test for SlapOS' ors-amarisoft",
long_description=long_description,
long_description_content_type='text/markdown',
maintainer="Nexedi",
maintainer_email="info@nexedi.com",
url="https://lab.nexedi.com/nexedi/slapos",
packages=find_packages(),
install_requires=[
'slapos.core',
'slapos.libnetworkcache',
'slapos.cookbook',
],
zip_safe=True,
test_suite='test',
)
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import yaml
import json
import glob
import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, ORSTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software-{{ software_name }}.cfg')))
param_dict = {
'testing': True,
'sim_algo': 'milenage',
'imsi': '001010000000331',
'opc': '000102030405060708090A0B0C0D0E0F',
'amf': '0x9001',
'sqn': '000000000000',
'k': '00112233445566778899AABBCCDDEEFF',
'impu': 'impu331',
'impi': 'impi331@amarisoft.com',
'tx_gain': 17,
'rx_gain': 17,
'dl_earfcn': 325320,
'bandwidth': "10 MHz",
'enb_id': '0x17',
'pci': 250,
'tac': '0x1717',
'root_sequence_index': '1',
'mme_list': {
'10.0.0.1': {'mme_addr': '10.0.0.1'},
'2001:db8::1': {'mme_addr': '2001:db8::1'},
},
'core_network_plmn': '00102',
'dl_nr_arfcn': 325320,
'nr_band': 99,
'nr_bandwidth': 50,
'ssb_nr_arfcn': 377790,
'rue_addr': '192.168.99.88',
'n_antenna_dl': 2,
'n_antenna_ul': 2,
'inactivity_timer': 17,
'gnb_id': '0x17',
'gnb_id_bits': 30,
'ssb_pos_bitmap': '10',
'amf_list': {
'10.0.0.1': {'amf_addr': '10.0.0.1'},
'2001:db8::1': {'amf_addr': '2001:db8::1'},
},
'nr_handover_time_to_trigger': 40,
'nr_handover_a3_offset': 10,
'ncell_list': {
'ORS1': {
'dl_earfcn': 100000,
'dl_nr_arfcn': 100000,
'ssb_nr_arfcn': 100000,
'pci': 1,
'nr_cell_id': '0x0000001',
'cell_id': '0x0000001',
'gnb_id_bits': 28,
'nr_band': 1,
'tac': 1
},
'ORS2': {
'dl_earfcn': 200000,
'dl_nr_arfcn': 200000,
'ssb_nr_arfcn': 200000,
'pci': 2,
'nr_cell_id': '0x0000002',
'cell_id': '0x0000001',
'gnb_id_bits': 30,
'nr_band': 2,
'tac': 2
},
},
'xn_peers': {
'2001:db8::1': {
'xn_addr': '2001:db8::1',
},
'2001:db8::2': {
'xn_addr': '2001:db8::2',
},
},
}
enb_param_dict = {
'plmn_list': {
'00101': {'attach_without_pdn': True, 'plmn': '00101', 'reserved': True},
'00102': {'attach_without_pdn': False, 'plmn': '00102', 'reserved': False},
},
'tdd_ul_dl_config': '[Configuration 6] 5ms 5UL 3DL (maximum uplink)',
}
gnb_param_dict1 = {
'plmn_list': {
'00101': {'plmn': '00101', 'ranac': 1, 'reserved': True, 'tac': 1},
'00102': {'plmn': '00102', 'ranac': 2, 'reserved': False, 'tac': 2},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
gnb_param_dict2 = {
'nssai': {
'0x171717': {'sd': '0x171717', 'sst': 10},
'0x181818': {'sd': '0x181818', 'sst': 20},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
enb_param_dict.update(param_dict)
gnb_param_dict1.update(param_dict)
gnb_param_dict2.update(param_dict)
def test_enb_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'enb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
if 'tx_gain' in conf and 'rx_gain' in conf:
self.assertEqual(conf['tx_gain'], enb_param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], enb_param_dict['rx_gain'])
self.assertEqual(conf['cell_default']['inactivity_timer'], enb_param_dict['inactivity_timer'])
self.assertEqual(conf['cell_default']['uldl_config'], 6)
self.assertEqual(conf['cell_list'][0]['dl_earfcn'], enb_param_dict['dl_earfcn'])
self.assertEqual(conf['enb_id'], int(enb_param_dict['enb_id'], 16))
self.assertEqual(conf['cell_list'][0]['n_id_cell'], enb_param_dict['pci'])
self.assertEqual(conf['cell_list'][0]['tac'], int(enb_param_dict['tac'], 16))
self.assertEqual(conf['cell_list'][0]['root_sequence_index'], int(enb_param_dict['root_sequence_index']))
self.assertEqual(conf['cell_list'][0]['cell_id'], 0)
for p in conf['cell_default']['plmn_list']:
for n in "plmn attach_without_pdn reserved".split():
self.assertEqual(p[n], enb_param_dict['plmn_list'][p['plmn']][n])
for p in conf['mme_list']:
self.assertEqual(p['mme_addr'], enb_param_dict['mme_list'][p['mme_addr']]['mme_addr'])
for p in conf['cell_list'][0]['ncell_list']:
for k in enb_param_dict['ncell_list']:
if p['dl_earfcn'] == gnb_param_dict1['ncell_list'][k]['dl_earfcn']:
break
conf_ncell = enb_param_dict['ncell_list'][k]
self.assertEqual(p['dl_earfcn'], conf_ncell['dl_earfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
self.assertEqual(p['cell_id'], int(conf_ncell['cell_id'], 16))
self.assertEqual(p['tac'], conf_ncell['tac'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
def test_gnb_conf1(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['tx_gain'], gnb_param_dict1['tx_gain'])
self.assertEqual(conf['rx_gain'], gnb_param_dict1['rx_gain'])
self.assertEqual(conf['nr_cell_default']['inactivity_timer'], gnb_param_dict1['inactivity_timer'])
self.assertEqual(conf['nr_cell_list'][0]['dl_nr_arfcn'], gnb_param_dict1['dl_nr_arfcn'])
self.assertEqual(conf['nr_cell_list'][0]['band'], gnb_param_dict1['nr_band'])
self.assertEqual(conf['nr_cell_list'][0]['ssb_pos_bitmap'], gnb_param_dict1['ssb_pos_bitmap'])
self.assertEqual(conf['nr_cell_default']['n_id_cell'], gnb_param_dict1['pci'])
self.assertEqual(conf['gnb_id'], int(gnb_param_dict1['gnb_id'], 16))
self.assertEqual(conf['gnb_id_bits'], gnb_param_dict1['gnb_id_bits'])
for p in conf['nr_cell_default']['plmn_list']:
for n in "plmn ranac reserved tac".split():
self.assertEqual(p[n], gnb_param_dict1['plmn_list'][p['plmn']][n])
for p in conf['amf_list']:
self.assertEqual(p['amf_addr'], gnb_param_dict1['amf_list'][p['amf_addr']]['amf_addr'])
for p in conf['xn_peers']:
self.assertEqual(p, gnb_param_dict1['xn_peers'][p]['xn_addr'])
for p in conf['nr_cell_list'][0]['ncell_list']:
for k in gnb_param_dict1['ncell_list']:
if p['dl_nr_arfcn'] == gnb_param_dict1['ncell_list'][k]['dl_nr_arfcn']:
break
conf_ncell = gnb_param_dict1['ncell_list'][k]
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['ul_nr_arfcn'], conf_ncell['dl_nr_arfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
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['tac'], conf_ncell['tac'])
self.assertEqual(p['band'], conf_ncell['nr_band'])
tdd_config = conf['nr_cell_default']['tdd_ul_dl_config']['pattern1']
self.assertEqual(float(tdd_config['period']), 2.5)
self.assertEqual(int(tdd_config['dl_slots']), 3)
self.assertEqual(int(tdd_config['dl_symbols']), 10)
self.assertEqual(int(tdd_config['ul_slots']), 1)
self.assertEqual(int(tdd_config['ul_symbols']), 2)
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define NR_BANDWIDTH'):
self.assertIn(str(gnb_param_dict1['nr_bandwidth']), l)
def test_gnb_conf2(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for p in conf['nr_cell_default']['plmn_list'][0]['nssai']:
sd = hex(p['sd'])
self.assertEqual(sd, gnb_param_dict2['nssai'][sd]['sd'], 16)
self.assertEqual(p['sst'], gnb_param_dict2['nssai'][sd]['sst'])
def test_mme_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'mme.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['plmn'], param_dict['core_network_plmn'])
def test_sim_card(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue_db.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for n in "sim_algo imsi opc sqn impu impi".split():
self.assertEqual(conf['ue_db'][0][n], param_dict[n])
self.assertEqual(conf['ue_db'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_db'][0]['amf'], int(param_dict['amf'], 16))
p = self.requestSlaveInstance().getConnectionParameterDict()
p = p['_'] if '_' in p else p
self.assertIn('info', p)
def test_monitor_gadget_url(self):
parameters = json.loads(self.computer_partition.getConnectionParameterDict()['_'])
self.assertIn('monitor-gadget-url', parameters)
monitor_setup_url = parameters['monitor-setup-url']
monitor_gadget_url = parameters['monitor-gadget-url']
monitor_base_url = parameters['monitor-base-url']
public_url = monitor_base_url + '/public'
response = requests.get(public_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('software.cfg.html', monitor_gadget_url)
response = requests.get(monitor_gadget_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('<script src="rsvp.js"></script>', response.text)
self.assertIn('<script src="renderjs.js"></script>', response.text)
self.assertIn('<script src="g-chart.line.js"></script>', response.text)
self.assertIn('<script src="promise.gadget.js"></script>', response.text)
class TestENBParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_enb_conf(self):
test_enb_conf(self)
class TestGNBParameters1(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf1(self)
class TestGNBParameters2(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict2)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf2(self)
class TestCoreNetworkParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_mme_conf(self):
test_mme_conf(self)
def requestSlaveInstance(cls):
software_url = cls.getSoftwareURL()
return cls.slap.request(
software_release=software_url,
partition_reference="SIM-CARD",
partition_parameter_kw={'_': json.dumps(param_dict)},
shared=True,
software_type='core-network',
)
class TestENBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestGNBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestCoreNetworkMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True, 'slave-list': []})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUELTEMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUENRMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestSimCard(ORSTestCase):
@classmethod
def requestDefaultInstance(cls, state='started'):
default_instance = super(
ORSTestCase, cls).requestDefaultInstance(state=state)
cls.requestSlaveInstance()
return default_instance
@classmethod
def requestSlaveInstance(cls):
return requestSlaveInstance(cls)
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_sim_card(self):
test_sim_card(self)
class TestUELTEParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_ue_lte_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_earfcn'], param_dict['dl_earfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
class TestUENRParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_ue_nr_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['ssb_nr_arfcn'], param_dict['ssb_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_nr_arfcn'], param_dict['dl_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['bandwidth'], '10 MHz')
self.assertEqual(conf['cell_groups'][0]['cells'][0]['band'], param_dict['nr_band'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import yaml
import json
import glob
import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, ORSTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software-fdd-lopcomm.cfg')))
param_dict = {
'testing': True,
'sim_algo': 'milenage',
'imsi': '001010000000331',
'opc': '000102030405060708090A0B0C0D0E0F',
'amf': '0x9001',
'sqn': '000000000000',
'k': '00112233445566778899AABBCCDDEEFF',
'impu': 'impu331',
'impi': 'impi331@amarisoft.com',
'tx_gain': 17,
'rx_gain': 17,
'dl_earfcn': 325320,
'bandwidth': "10 MHz",
'enb_id': '0x17',
'pci': 250,
'tac': '0x1717',
'root_sequence_index': '1',
'mme_list': {
'10.0.0.1': {'mme_addr': '10.0.0.1'},
'2001:db8::1': {'mme_addr': '2001:db8::1'},
},
'core_network_plmn': '00102',
'dl_nr_arfcn': 325320,
'nr_band': 99,
'nr_bandwidth': 50,
'ssb_nr_arfcn': 377790,
'rue_addr': '192.168.99.88',
'n_antenna_dl': 2,
'n_antenna_ul': 2,
'inactivity_timer': 17,
'gnb_id': '0x17',
'gnb_id_bits': 30,
'ssb_pos_bitmap': '10',
'amf_list': {
'10.0.0.1': {'amf_addr': '10.0.0.1'},
'2001:db8::1': {'amf_addr': '2001:db8::1'},
},
'nr_handover_time_to_trigger': 40,
'nr_handover_a3_offset': 10,
'ncell_list': {
'ORS1': {
'dl_earfcn': 100000,
'dl_nr_arfcn': 100000,
'ssb_nr_arfcn': 100000,
'pci': 1,
'nr_cell_id': '0x0000001',
'cell_id': '0x0000001',
'gnb_id_bits': 28,
'nr_band': 1,
'tac': 1
},
'ORS2': {
'dl_earfcn': 200000,
'dl_nr_arfcn': 200000,
'ssb_nr_arfcn': 200000,
'pci': 2,
'nr_cell_id': '0x0000002',
'cell_id': '0x0000001',
'gnb_id_bits': 30,
'nr_band': 2,
'tac': 2
},
},
'xn_peers': {
'2001:db8::1': {
'xn_addr': '2001:db8::1',
},
'2001:db8::2': {
'xn_addr': '2001:db8::2',
},
},
}
enb_param_dict = {
'plmn_list': {
'00101': {'attach_without_pdn': True, 'plmn': '00101', 'reserved': True},
'00102': {'attach_without_pdn': False, 'plmn': '00102', 'reserved': False},
},
'tdd_ul_dl_config': '[Configuration 6] 5ms 5UL 3DL (maximum uplink)',
}
gnb_param_dict1 = {
'plmn_list': {
'00101': {'plmn': '00101', 'ranac': 1, 'reserved': True, 'tac': 1},
'00102': {'plmn': '00102', 'ranac': 2, 'reserved': False, 'tac': 2},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
gnb_param_dict2 = {
'nssai': {
'0x171717': {'sd': '0x171717', 'sst': 10},
'0x181818': {'sd': '0x181818', 'sst': 20},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
enb_param_dict.update(param_dict)
gnb_param_dict1.update(param_dict)
gnb_param_dict2.update(param_dict)
def test_enb_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'enb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
if 'tx_gain' in conf and 'rx_gain' in conf:
self.assertEqual(conf['tx_gain'], enb_param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], enb_param_dict['rx_gain'])
self.assertEqual(conf['cell_default']['inactivity_timer'], enb_param_dict['inactivity_timer'])
self.assertEqual(conf['cell_default']['uldl_config'], 6)
self.assertEqual(conf['cell_list'][0]['dl_earfcn'], enb_param_dict['dl_earfcn'])
self.assertEqual(conf['enb_id'], int(enb_param_dict['enb_id'], 16))
self.assertEqual(conf['cell_list'][0]['n_id_cell'], enb_param_dict['pci'])
self.assertEqual(conf['cell_list'][0]['tac'], int(enb_param_dict['tac'], 16))
self.assertEqual(conf['cell_list'][0]['root_sequence_index'], int(enb_param_dict['root_sequence_index']))
self.assertEqual(conf['cell_list'][0]['cell_id'], 0)
for p in conf['cell_default']['plmn_list']:
for n in "plmn attach_without_pdn reserved".split():
self.assertEqual(p[n], enb_param_dict['plmn_list'][p['plmn']][n])
for p in conf['mme_list']:
self.assertEqual(p['mme_addr'], enb_param_dict['mme_list'][p['mme_addr']]['mme_addr'])
for p in conf['cell_list'][0]['ncell_list']:
for k in enb_param_dict['ncell_list']:
if p['dl_earfcn'] == gnb_param_dict1['ncell_list'][k]['dl_earfcn']:
break
conf_ncell = enb_param_dict['ncell_list'][k]
self.assertEqual(p['dl_earfcn'], conf_ncell['dl_earfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
self.assertEqual(p['cell_id'], int(conf_ncell['cell_id'], 16))
self.assertEqual(p['tac'], conf_ncell['tac'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
def test_gnb_conf1(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['tx_gain'], gnb_param_dict1['tx_gain'])
self.assertEqual(conf['rx_gain'], gnb_param_dict1['rx_gain'])
self.assertEqual(conf['nr_cell_default']['inactivity_timer'], gnb_param_dict1['inactivity_timer'])
self.assertEqual(conf['nr_cell_list'][0]['dl_nr_arfcn'], gnb_param_dict1['dl_nr_arfcn'])
self.assertEqual(conf['nr_cell_list'][0]['band'], gnb_param_dict1['nr_band'])
self.assertEqual(conf['nr_cell_list'][0]['ssb_pos_bitmap'], gnb_param_dict1['ssb_pos_bitmap'])
self.assertEqual(conf['nr_cell_default']['n_id_cell'], gnb_param_dict1['pci'])
self.assertEqual(conf['gnb_id'], int(gnb_param_dict1['gnb_id'], 16))
self.assertEqual(conf['gnb_id_bits'], gnb_param_dict1['gnb_id_bits'])
for p in conf['nr_cell_default']['plmn_list']:
for n in "plmn ranac reserved tac".split():
self.assertEqual(p[n], gnb_param_dict1['plmn_list'][p['plmn']][n])
for p in conf['amf_list']:
self.assertEqual(p['amf_addr'], gnb_param_dict1['amf_list'][p['amf_addr']]['amf_addr'])
for p in conf['xn_peers']:
self.assertEqual(p, gnb_param_dict1['xn_peers'][p]['xn_addr'])
for p in conf['nr_cell_list'][0]['ncell_list']:
for k in gnb_param_dict1['ncell_list']:
if p['dl_nr_arfcn'] == gnb_param_dict1['ncell_list'][k]['dl_nr_arfcn']:
break
conf_ncell = gnb_param_dict1['ncell_list'][k]
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['ul_nr_arfcn'], conf_ncell['dl_nr_arfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
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['tac'], conf_ncell['tac'])
self.assertEqual(p['band'], conf_ncell['nr_band'])
tdd_config = conf['nr_cell_default']['tdd_ul_dl_config']['pattern1']
self.assertEqual(float(tdd_config['period']), 2.5)
self.assertEqual(int(tdd_config['dl_slots']), 3)
self.assertEqual(int(tdd_config['dl_symbols']), 10)
self.assertEqual(int(tdd_config['ul_slots']), 1)
self.assertEqual(int(tdd_config['ul_symbols']), 2)
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define NR_BANDWIDTH'):
self.assertIn(str(gnb_param_dict1['nr_bandwidth']), l)
def test_gnb_conf2(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for p in conf['nr_cell_default']['plmn_list'][0]['nssai']:
sd = hex(p['sd'])
self.assertEqual(sd, gnb_param_dict2['nssai'][sd]['sd'], 16)
self.assertEqual(p['sst'], gnb_param_dict2['nssai'][sd]['sst'])
def test_mme_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'mme.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['plmn'], param_dict['core_network_plmn'])
def test_sim_card(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue_db.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for n in "sim_algo imsi opc sqn impu impi".split():
self.assertEqual(conf['ue_db'][0][n], param_dict[n])
self.assertEqual(conf['ue_db'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_db'][0]['amf'], int(param_dict['amf'], 16))
p = self.requestSlaveInstance().getConnectionParameterDict()
p = p['_'] if '_' in p else p
self.assertIn('info', p)
def test_monitor_gadget_url(self):
parameters = json.loads(self.computer_partition.getConnectionParameterDict()['_'])
self.assertIn('monitor-gadget-url', parameters)
monitor_setup_url = parameters['monitor-setup-url']
monitor_gadget_url = parameters['monitor-gadget-url']
monitor_base_url = parameters['monitor-base-url']
public_url = monitor_base_url + '/public'
response = requests.get(public_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('software.cfg.html', monitor_gadget_url)
response = requests.get(monitor_gadget_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('<script src="rsvp.js"></script>', response.text)
self.assertIn('<script src="renderjs.js"></script>', response.text)
self.assertIn('<script src="g-chart.line.js"></script>', response.text)
self.assertIn('<script src="promise.gadget.js"></script>', response.text)
class TestENBParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_enb_conf(self):
test_enb_conf(self)
class TestGNBParameters1(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf1(self)
class TestGNBParameters2(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict2)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf2(self)
class TestCoreNetworkParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_mme_conf(self):
test_mme_conf(self)
def requestSlaveInstance(cls):
software_url = cls.getSoftwareURL()
return cls.slap.request(
software_release=software_url,
partition_reference="SIM-CARD",
partition_parameter_kw={'_': json.dumps(param_dict)},
shared=True,
software_type='core-network',
)
class TestENBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestGNBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestCoreNetworkMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True, 'slave-list': []})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUELTEMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUENRMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestSimCard(ORSTestCase):
@classmethod
def requestDefaultInstance(cls, state='started'):
default_instance = super(
ORSTestCase, cls).requestDefaultInstance(state=state)
cls.requestSlaveInstance()
return default_instance
@classmethod
def requestSlaveInstance(cls):
return requestSlaveInstance(cls)
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_sim_card(self):
test_sim_card(self)
class TestUELTEParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_ue_lte_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_earfcn'], param_dict['dl_earfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
class TestUENRParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_ue_nr_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['ssb_nr_arfcn'], param_dict['ssb_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_nr_arfcn'], param_dict['dl_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['bandwidth'], '10 MHz')
self.assertEqual(conf['cell_groups'][0]['cells'][0]['band'], param_dict['nr_band'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import yaml
import json
import glob
import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, ORSTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software-fdd-ors.cfg')))
param_dict = {
'testing': True,
'sim_algo': 'milenage',
'imsi': '001010000000331',
'opc': '000102030405060708090A0B0C0D0E0F',
'amf': '0x9001',
'sqn': '000000000000',
'k': '00112233445566778899AABBCCDDEEFF',
'impu': 'impu331',
'impi': 'impi331@amarisoft.com',
'tx_gain': 17,
'rx_gain': 17,
'dl_earfcn': 325320,
'bandwidth': "10 MHz",
'enb_id': '0x17',
'pci': 250,
'tac': '0x1717',
'root_sequence_index': '1',
'mme_list': {
'10.0.0.1': {'mme_addr': '10.0.0.1'},
'2001:db8::1': {'mme_addr': '2001:db8::1'},
},
'core_network_plmn': '00102',
'dl_nr_arfcn': 325320,
'nr_band': 99,
'nr_bandwidth': 50,
'ssb_nr_arfcn': 377790,
'rue_addr': '192.168.99.88',
'n_antenna_dl': 2,
'n_antenna_ul': 2,
'inactivity_timer': 17,
'gnb_id': '0x17',
'gnb_id_bits': 30,
'ssb_pos_bitmap': '10',
'amf_list': {
'10.0.0.1': {'amf_addr': '10.0.0.1'},
'2001:db8::1': {'amf_addr': '2001:db8::1'},
},
'nr_handover_time_to_trigger': 40,
'nr_handover_a3_offset': 10,
'ncell_list': {
'ORS1': {
'dl_earfcn': 100000,
'dl_nr_arfcn': 100000,
'ssb_nr_arfcn': 100000,
'pci': 1,
'nr_cell_id': '0x0000001',
'cell_id': '0x0000001',
'gnb_id_bits': 28,
'nr_band': 1,
'tac': 1
},
'ORS2': {
'dl_earfcn': 200000,
'dl_nr_arfcn': 200000,
'ssb_nr_arfcn': 200000,
'pci': 2,
'nr_cell_id': '0x0000002',
'cell_id': '0x0000001',
'gnb_id_bits': 30,
'nr_band': 2,
'tac': 2
},
},
'xn_peers': {
'2001:db8::1': {
'xn_addr': '2001:db8::1',
},
'2001:db8::2': {
'xn_addr': '2001:db8::2',
},
},
}
enb_param_dict = {
'plmn_list': {
'00101': {'attach_without_pdn': True, 'plmn': '00101', 'reserved': True},
'00102': {'attach_without_pdn': False, 'plmn': '00102', 'reserved': False},
},
'tdd_ul_dl_config': '[Configuration 6] 5ms 5UL 3DL (maximum uplink)',
}
gnb_param_dict1 = {
'plmn_list': {
'00101': {'plmn': '00101', 'ranac': 1, 'reserved': True, 'tac': 1},
'00102': {'plmn': '00102', 'ranac': 2, 'reserved': False, 'tac': 2},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
gnb_param_dict2 = {
'nssai': {
'0x171717': {'sd': '0x171717', 'sst': 10},
'0x181818': {'sd': '0x181818', 'sst': 20},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
enb_param_dict.update(param_dict)
gnb_param_dict1.update(param_dict)
gnb_param_dict2.update(param_dict)
def test_enb_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'enb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
if 'tx_gain' in conf and 'rx_gain' in conf:
self.assertEqual(conf['tx_gain'], enb_param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], enb_param_dict['rx_gain'])
self.assertEqual(conf['cell_default']['inactivity_timer'], enb_param_dict['inactivity_timer'])
self.assertEqual(conf['cell_default']['uldl_config'], 6)
self.assertEqual(conf['cell_list'][0]['dl_earfcn'], enb_param_dict['dl_earfcn'])
self.assertEqual(conf['enb_id'], int(enb_param_dict['enb_id'], 16))
self.assertEqual(conf['cell_list'][0]['n_id_cell'], enb_param_dict['pci'])
self.assertEqual(conf['cell_list'][0]['tac'], int(enb_param_dict['tac'], 16))
self.assertEqual(conf['cell_list'][0]['root_sequence_index'], int(enb_param_dict['root_sequence_index']))
self.assertEqual(conf['cell_list'][0]['cell_id'], 0)
for p in conf['cell_default']['plmn_list']:
for n in "plmn attach_without_pdn reserved".split():
self.assertEqual(p[n], enb_param_dict['plmn_list'][p['plmn']][n])
for p in conf['mme_list']:
self.assertEqual(p['mme_addr'], enb_param_dict['mme_list'][p['mme_addr']]['mme_addr'])
for p in conf['cell_list'][0]['ncell_list']:
for k in enb_param_dict['ncell_list']:
if p['dl_earfcn'] == gnb_param_dict1['ncell_list'][k]['dl_earfcn']:
break
conf_ncell = enb_param_dict['ncell_list'][k]
self.assertEqual(p['dl_earfcn'], conf_ncell['dl_earfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
self.assertEqual(p['cell_id'], int(conf_ncell['cell_id'], 16))
self.assertEqual(p['tac'], conf_ncell['tac'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
def test_gnb_conf1(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['tx_gain'], gnb_param_dict1['tx_gain'])
self.assertEqual(conf['rx_gain'], gnb_param_dict1['rx_gain'])
self.assertEqual(conf['nr_cell_default']['inactivity_timer'], gnb_param_dict1['inactivity_timer'])
self.assertEqual(conf['nr_cell_list'][0]['dl_nr_arfcn'], gnb_param_dict1['dl_nr_arfcn'])
self.assertEqual(conf['nr_cell_list'][0]['band'], gnb_param_dict1['nr_band'])
self.assertEqual(conf['nr_cell_list'][0]['ssb_pos_bitmap'], gnb_param_dict1['ssb_pos_bitmap'])
self.assertEqual(conf['nr_cell_default']['n_id_cell'], gnb_param_dict1['pci'])
self.assertEqual(conf['gnb_id'], int(gnb_param_dict1['gnb_id'], 16))
self.assertEqual(conf['gnb_id_bits'], gnb_param_dict1['gnb_id_bits'])
for p in conf['nr_cell_default']['plmn_list']:
for n in "plmn ranac reserved tac".split():
self.assertEqual(p[n], gnb_param_dict1['plmn_list'][p['plmn']][n])
for p in conf['amf_list']:
self.assertEqual(p['amf_addr'], gnb_param_dict1['amf_list'][p['amf_addr']]['amf_addr'])
for p in conf['xn_peers']:
self.assertEqual(p, gnb_param_dict1['xn_peers'][p]['xn_addr'])
for p in conf['nr_cell_list'][0]['ncell_list']:
for k in gnb_param_dict1['ncell_list']:
if p['dl_nr_arfcn'] == gnb_param_dict1['ncell_list'][k]['dl_nr_arfcn']:
break
conf_ncell = gnb_param_dict1['ncell_list'][k]
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['ul_nr_arfcn'], conf_ncell['dl_nr_arfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
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['tac'], conf_ncell['tac'])
self.assertEqual(p['band'], conf_ncell['nr_band'])
tdd_config = conf['nr_cell_default']['tdd_ul_dl_config']['pattern1']
self.assertEqual(float(tdd_config['period']), 2.5)
self.assertEqual(int(tdd_config['dl_slots']), 3)
self.assertEqual(int(tdd_config['dl_symbols']), 10)
self.assertEqual(int(tdd_config['ul_slots']), 1)
self.assertEqual(int(tdd_config['ul_symbols']), 2)
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define NR_BANDWIDTH'):
self.assertIn(str(gnb_param_dict1['nr_bandwidth']), l)
def test_gnb_conf2(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for p in conf['nr_cell_default']['plmn_list'][0]['nssai']:
sd = hex(p['sd'])
self.assertEqual(sd, gnb_param_dict2['nssai'][sd]['sd'], 16)
self.assertEqual(p['sst'], gnb_param_dict2['nssai'][sd]['sst'])
def test_mme_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'mme.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['plmn'], param_dict['core_network_plmn'])
def test_sim_card(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue_db.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for n in "sim_algo imsi opc sqn impu impi".split():
self.assertEqual(conf['ue_db'][0][n], param_dict[n])
self.assertEqual(conf['ue_db'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_db'][0]['amf'], int(param_dict['amf'], 16))
p = self.requestSlaveInstance().getConnectionParameterDict()
p = p['_'] if '_' in p else p
self.assertIn('info', p)
def test_monitor_gadget_url(self):
parameters = json.loads(self.computer_partition.getConnectionParameterDict()['_'])
self.assertIn('monitor-gadget-url', parameters)
monitor_setup_url = parameters['monitor-setup-url']
monitor_gadget_url = parameters['monitor-gadget-url']
monitor_base_url = parameters['monitor-base-url']
public_url = monitor_base_url + '/public'
response = requests.get(public_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('software.cfg.html', monitor_gadget_url)
response = requests.get(monitor_gadget_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('<script src="rsvp.js"></script>', response.text)
self.assertIn('<script src="renderjs.js"></script>', response.text)
self.assertIn('<script src="g-chart.line.js"></script>', response.text)
self.assertIn('<script src="promise.gadget.js"></script>', response.text)
class TestENBParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_enb_conf(self):
test_enb_conf(self)
class TestGNBParameters1(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf1(self)
class TestGNBParameters2(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict2)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf2(self)
class TestCoreNetworkParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_mme_conf(self):
test_mme_conf(self)
def requestSlaveInstance(cls):
software_url = cls.getSoftwareURL()
return cls.slap.request(
software_release=software_url,
partition_reference="SIM-CARD",
partition_parameter_kw={'_': json.dumps(param_dict)},
shared=True,
software_type='core-network',
)
class TestENBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestGNBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestCoreNetworkMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True, 'slave-list': []})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUELTEMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUENRMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestSimCard(ORSTestCase):
@classmethod
def requestDefaultInstance(cls, state='started'):
default_instance = super(
ORSTestCase, cls).requestDefaultInstance(state=state)
cls.requestSlaveInstance()
return default_instance
@classmethod
def requestSlaveInstance(cls):
return requestSlaveInstance(cls)
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_sim_card(self):
test_sim_card(self)
class TestUELTEParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_ue_lte_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_earfcn'], param_dict['dl_earfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
class TestUENRParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_ue_nr_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['ssb_nr_arfcn'], param_dict['ssb_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_nr_arfcn'], param_dict['dl_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['bandwidth'], '10 MHz')
self.assertEqual(conf['cell_groups'][0]['cells'][0]['band'], param_dict['nr_band'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import yaml
import json
import glob
import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, ORSTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software-fdd.cfg')))
param_dict = {
'testing': True,
'sim_algo': 'milenage',
'imsi': '001010000000331',
'opc': '000102030405060708090A0B0C0D0E0F',
'amf': '0x9001',
'sqn': '000000000000',
'k': '00112233445566778899AABBCCDDEEFF',
'impu': 'impu331',
'impi': 'impi331@amarisoft.com',
'tx_gain': 17,
'rx_gain': 17,
'dl_earfcn': 325320,
'bandwidth': "10 MHz",
'enb_id': '0x17',
'pci': 250,
'tac': '0x1717',
'root_sequence_index': '1',
'mme_list': {
'10.0.0.1': {'mme_addr': '10.0.0.1'},
'2001:db8::1': {'mme_addr': '2001:db8::1'},
},
'core_network_plmn': '00102',
'dl_nr_arfcn': 325320,
'nr_band': 99,
'nr_bandwidth': 50,
'ssb_nr_arfcn': 377790,
'rue_addr': '192.168.99.88',
'n_antenna_dl': 2,
'n_antenna_ul': 2,
'inactivity_timer': 17,
'gnb_id': '0x17',
'gnb_id_bits': 30,
'ssb_pos_bitmap': '10',
'amf_list': {
'10.0.0.1': {'amf_addr': '10.0.0.1'},
'2001:db8::1': {'amf_addr': '2001:db8::1'},
},
'nr_handover_time_to_trigger': 40,
'nr_handover_a3_offset': 10,
'ncell_list': {
'ORS1': {
'dl_earfcn': 100000,
'dl_nr_arfcn': 100000,
'ssb_nr_arfcn': 100000,
'pci': 1,
'nr_cell_id': '0x0000001',
'cell_id': '0x0000001',
'gnb_id_bits': 28,
'nr_band': 1,
'tac': 1
},
'ORS2': {
'dl_earfcn': 200000,
'dl_nr_arfcn': 200000,
'ssb_nr_arfcn': 200000,
'pci': 2,
'nr_cell_id': '0x0000002',
'cell_id': '0x0000001',
'gnb_id_bits': 30,
'nr_band': 2,
'tac': 2
},
},
'xn_peers': {
'2001:db8::1': {
'xn_addr': '2001:db8::1',
},
'2001:db8::2': {
'xn_addr': '2001:db8::2',
},
},
}
enb_param_dict = {
'plmn_list': {
'00101': {'attach_without_pdn': True, 'plmn': '00101', 'reserved': True},
'00102': {'attach_without_pdn': False, 'plmn': '00102', 'reserved': False},
},
'tdd_ul_dl_config': '[Configuration 6] 5ms 5UL 3DL (maximum uplink)',
}
gnb_param_dict1 = {
'plmn_list': {
'00101': {'plmn': '00101', 'ranac': 1, 'reserved': True, 'tac': 1},
'00102': {'plmn': '00102', 'ranac': 2, 'reserved': False, 'tac': 2},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
gnb_param_dict2 = {
'nssai': {
'0x171717': {'sd': '0x171717', 'sst': 10},
'0x181818': {'sd': '0x181818', 'sst': 20},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
enb_param_dict.update(param_dict)
gnb_param_dict1.update(param_dict)
gnb_param_dict2.update(param_dict)
def test_enb_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'enb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
if 'tx_gain' in conf and 'rx_gain' in conf:
self.assertEqual(conf['tx_gain'], enb_param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], enb_param_dict['rx_gain'])
self.assertEqual(conf['cell_default']['inactivity_timer'], enb_param_dict['inactivity_timer'])
self.assertEqual(conf['cell_default']['uldl_config'], 6)
self.assertEqual(conf['cell_list'][0]['dl_earfcn'], enb_param_dict['dl_earfcn'])
self.assertEqual(conf['enb_id'], int(enb_param_dict['enb_id'], 16))
self.assertEqual(conf['cell_list'][0]['n_id_cell'], enb_param_dict['pci'])
self.assertEqual(conf['cell_list'][0]['tac'], int(enb_param_dict['tac'], 16))
self.assertEqual(conf['cell_list'][0]['root_sequence_index'], int(enb_param_dict['root_sequence_index']))
self.assertEqual(conf['cell_list'][0]['cell_id'], 0)
for p in conf['cell_default']['plmn_list']:
for n in "plmn attach_without_pdn reserved".split():
self.assertEqual(p[n], enb_param_dict['plmn_list'][p['plmn']][n])
for p in conf['mme_list']:
self.assertEqual(p['mme_addr'], enb_param_dict['mme_list'][p['mme_addr']]['mme_addr'])
for p in conf['cell_list'][0]['ncell_list']:
for k in enb_param_dict['ncell_list']:
if p['dl_earfcn'] == gnb_param_dict1['ncell_list'][k]['dl_earfcn']:
break
conf_ncell = enb_param_dict['ncell_list'][k]
self.assertEqual(p['dl_earfcn'], conf_ncell['dl_earfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
self.assertEqual(p['cell_id'], int(conf_ncell['cell_id'], 16))
self.assertEqual(p['tac'], conf_ncell['tac'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
def test_gnb_conf1(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['tx_gain'], gnb_param_dict1['tx_gain'])
self.assertEqual(conf['rx_gain'], gnb_param_dict1['rx_gain'])
self.assertEqual(conf['nr_cell_default']['inactivity_timer'], gnb_param_dict1['inactivity_timer'])
self.assertEqual(conf['nr_cell_list'][0]['dl_nr_arfcn'], gnb_param_dict1['dl_nr_arfcn'])
self.assertEqual(conf['nr_cell_list'][0]['band'], gnb_param_dict1['nr_band'])
self.assertEqual(conf['nr_cell_list'][0]['ssb_pos_bitmap'], gnb_param_dict1['ssb_pos_bitmap'])
self.assertEqual(conf['nr_cell_default']['n_id_cell'], gnb_param_dict1['pci'])
self.assertEqual(conf['gnb_id'], int(gnb_param_dict1['gnb_id'], 16))
self.assertEqual(conf['gnb_id_bits'], gnb_param_dict1['gnb_id_bits'])
for p in conf['nr_cell_default']['plmn_list']:
for n in "plmn ranac reserved tac".split():
self.assertEqual(p[n], gnb_param_dict1['plmn_list'][p['plmn']][n])
for p in conf['amf_list']:
self.assertEqual(p['amf_addr'], gnb_param_dict1['amf_list'][p['amf_addr']]['amf_addr'])
for p in conf['xn_peers']:
self.assertEqual(p, gnb_param_dict1['xn_peers'][p]['xn_addr'])
for p in conf['nr_cell_list'][0]['ncell_list']:
for k in gnb_param_dict1['ncell_list']:
if p['dl_nr_arfcn'] == gnb_param_dict1['ncell_list'][k]['dl_nr_arfcn']:
break
conf_ncell = gnb_param_dict1['ncell_list'][k]
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['ul_nr_arfcn'], conf_ncell['dl_nr_arfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
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['tac'], conf_ncell['tac'])
self.assertEqual(p['band'], conf_ncell['nr_band'])
tdd_config = conf['nr_cell_default']['tdd_ul_dl_config']['pattern1']
self.assertEqual(float(tdd_config['period']), 2.5)
self.assertEqual(int(tdd_config['dl_slots']), 3)
self.assertEqual(int(tdd_config['dl_symbols']), 10)
self.assertEqual(int(tdd_config['ul_slots']), 1)
self.assertEqual(int(tdd_config['ul_symbols']), 2)
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define NR_BANDWIDTH'):
self.assertIn(str(gnb_param_dict1['nr_bandwidth']), l)
def test_gnb_conf2(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for p in conf['nr_cell_default']['plmn_list'][0]['nssai']:
sd = hex(p['sd'])
self.assertEqual(sd, gnb_param_dict2['nssai'][sd]['sd'], 16)
self.assertEqual(p['sst'], gnb_param_dict2['nssai'][sd]['sst'])
def test_mme_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'mme.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['plmn'], param_dict['core_network_plmn'])
def test_sim_card(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue_db.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for n in "sim_algo imsi opc sqn impu impi".split():
self.assertEqual(conf['ue_db'][0][n], param_dict[n])
self.assertEqual(conf['ue_db'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_db'][0]['amf'], int(param_dict['amf'], 16))
p = self.requestSlaveInstance().getConnectionParameterDict()
p = p['_'] if '_' in p else p
self.assertIn('info', p)
def test_monitor_gadget_url(self):
parameters = json.loads(self.computer_partition.getConnectionParameterDict()['_'])
self.assertIn('monitor-gadget-url', parameters)
monitor_setup_url = parameters['monitor-setup-url']
monitor_gadget_url = parameters['monitor-gadget-url']
monitor_base_url = parameters['monitor-base-url']
public_url = monitor_base_url + '/public'
response = requests.get(public_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('software.cfg.html', monitor_gadget_url)
response = requests.get(monitor_gadget_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('<script src="rsvp.js"></script>', response.text)
self.assertIn('<script src="renderjs.js"></script>', response.text)
self.assertIn('<script src="g-chart.line.js"></script>', response.text)
self.assertIn('<script src="promise.gadget.js"></script>', response.text)
class TestENBParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_enb_conf(self):
test_enb_conf(self)
class TestGNBParameters1(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf1(self)
class TestGNBParameters2(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict2)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf2(self)
class TestCoreNetworkParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_mme_conf(self):
test_mme_conf(self)
def requestSlaveInstance(cls):
software_url = cls.getSoftwareURL()
return cls.slap.request(
software_release=software_url,
partition_reference="SIM-CARD",
partition_parameter_kw={'_': json.dumps(param_dict)},
shared=True,
software_type='core-network',
)
class TestENBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestGNBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestCoreNetworkMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True, 'slave-list': []})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUELTEMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUENRMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestSimCard(ORSTestCase):
@classmethod
def requestDefaultInstance(cls, state='started'):
default_instance = super(
ORSTestCase, cls).requestDefaultInstance(state=state)
cls.requestSlaveInstance()
return default_instance
@classmethod
def requestSlaveInstance(cls):
return requestSlaveInstance(cls)
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_sim_card(self):
test_sim_card(self)
class TestUELTEParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_ue_lte_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_earfcn'], param_dict['dl_earfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
class TestUENRParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_ue_nr_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['ssb_nr_arfcn'], param_dict['ssb_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_nr_arfcn'], param_dict['dl_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['bandwidth'], '10 MHz')
self.assertEqual(conf['cell_groups'][0]['cells'][0]['band'], param_dict['nr_band'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import yaml
import json
import glob
import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, ORSTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software-tdd-m2ru.cfg')))
param_dict = {
'testing': True,
'sim_algo': 'milenage',
'imsi': '001010000000331',
'opc': '000102030405060708090A0B0C0D0E0F',
'amf': '0x9001',
'sqn': '000000000000',
'k': '00112233445566778899AABBCCDDEEFF',
'impu': 'impu331',
'impi': 'impi331@amarisoft.com',
'tx_gain': 17,
'rx_gain': 17,
'dl_earfcn': 325320,
'bandwidth': "10 MHz",
'enb_id': '0x17',
'pci': 250,
'tac': '0x1717',
'root_sequence_index': '1',
'mme_list': {
'10.0.0.1': {'mme_addr': '10.0.0.1'},
'2001:db8::1': {'mme_addr': '2001:db8::1'},
},
'core_network_plmn': '00102',
'dl_nr_arfcn': 325320,
'nr_band': 99,
'nr_bandwidth': 50,
'ssb_nr_arfcn': 377790,
'rue_addr': '192.168.99.88',
'n_antenna_dl': 2,
'n_antenna_ul': 2,
'inactivity_timer': 17,
'gnb_id': '0x17',
'gnb_id_bits': 30,
'ssb_pos_bitmap': '10',
'amf_list': {
'10.0.0.1': {'amf_addr': '10.0.0.1'},
'2001:db8::1': {'amf_addr': '2001:db8::1'},
},
'nr_handover_time_to_trigger': 40,
'nr_handover_a3_offset': 10,
'ncell_list': {
'ORS1': {
'dl_earfcn': 100000,
'dl_nr_arfcn': 100000,
'ssb_nr_arfcn': 100000,
'pci': 1,
'nr_cell_id': '0x0000001',
'cell_id': '0x0000001',
'gnb_id_bits': 28,
'nr_band': 1,
'tac': 1
},
'ORS2': {
'dl_earfcn': 200000,
'dl_nr_arfcn': 200000,
'ssb_nr_arfcn': 200000,
'pci': 2,
'nr_cell_id': '0x0000002',
'cell_id': '0x0000001',
'gnb_id_bits': 30,
'nr_band': 2,
'tac': 2
},
},
'xn_peers': {
'2001:db8::1': {
'xn_addr': '2001:db8::1',
},
'2001:db8::2': {
'xn_addr': '2001:db8::2',
},
},
}
enb_param_dict = {
'plmn_list': {
'00101': {'attach_without_pdn': True, 'plmn': '00101', 'reserved': True},
'00102': {'attach_without_pdn': False, 'plmn': '00102', 'reserved': False},
},
'tdd_ul_dl_config': '[Configuration 6] 5ms 5UL 3DL (maximum uplink)',
}
gnb_param_dict1 = {
'plmn_list': {
'00101': {'plmn': '00101', 'ranac': 1, 'reserved': True, 'tac': 1},
'00102': {'plmn': '00102', 'ranac': 2, 'reserved': False, 'tac': 2},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
gnb_param_dict2 = {
'nssai': {
'0x171717': {'sd': '0x171717', 'sst': 10},
'0x181818': {'sd': '0x181818', 'sst': 20},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
enb_param_dict.update(param_dict)
gnb_param_dict1.update(param_dict)
gnb_param_dict2.update(param_dict)
def test_enb_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'enb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
if 'tx_gain' in conf and 'rx_gain' in conf:
self.assertEqual(conf['tx_gain'], enb_param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], enb_param_dict['rx_gain'])
self.assertEqual(conf['cell_default']['inactivity_timer'], enb_param_dict['inactivity_timer'])
self.assertEqual(conf['cell_default']['uldl_config'], 6)
self.assertEqual(conf['cell_list'][0]['dl_earfcn'], enb_param_dict['dl_earfcn'])
self.assertEqual(conf['enb_id'], int(enb_param_dict['enb_id'], 16))
self.assertEqual(conf['cell_list'][0]['n_id_cell'], enb_param_dict['pci'])
self.assertEqual(conf['cell_list'][0]['tac'], int(enb_param_dict['tac'], 16))
self.assertEqual(conf['cell_list'][0]['root_sequence_index'], int(enb_param_dict['root_sequence_index']))
self.assertEqual(conf['cell_list'][0]['cell_id'], 0)
for p in conf['cell_default']['plmn_list']:
for n in "plmn attach_without_pdn reserved".split():
self.assertEqual(p[n], enb_param_dict['plmn_list'][p['plmn']][n])
for p in conf['mme_list']:
self.assertEqual(p['mme_addr'], enb_param_dict['mme_list'][p['mme_addr']]['mme_addr'])
for p in conf['cell_list'][0]['ncell_list']:
for k in enb_param_dict['ncell_list']:
if p['dl_earfcn'] == gnb_param_dict1['ncell_list'][k]['dl_earfcn']:
break
conf_ncell = enb_param_dict['ncell_list'][k]
self.assertEqual(p['dl_earfcn'], conf_ncell['dl_earfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
self.assertEqual(p['cell_id'], int(conf_ncell['cell_id'], 16))
self.assertEqual(p['tac'], conf_ncell['tac'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
def test_gnb_conf1(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['tx_gain'], gnb_param_dict1['tx_gain'])
self.assertEqual(conf['rx_gain'], gnb_param_dict1['rx_gain'])
self.assertEqual(conf['nr_cell_default']['inactivity_timer'], gnb_param_dict1['inactivity_timer'])
self.assertEqual(conf['nr_cell_list'][0]['dl_nr_arfcn'], gnb_param_dict1['dl_nr_arfcn'])
self.assertEqual(conf['nr_cell_list'][0]['band'], gnb_param_dict1['nr_band'])
self.assertEqual(conf['nr_cell_list'][0]['ssb_pos_bitmap'], gnb_param_dict1['ssb_pos_bitmap'])
self.assertEqual(conf['nr_cell_default']['n_id_cell'], gnb_param_dict1['pci'])
self.assertEqual(conf['gnb_id'], int(gnb_param_dict1['gnb_id'], 16))
self.assertEqual(conf['gnb_id_bits'], gnb_param_dict1['gnb_id_bits'])
for p in conf['nr_cell_default']['plmn_list']:
for n in "plmn ranac reserved tac".split():
self.assertEqual(p[n], gnb_param_dict1['plmn_list'][p['plmn']][n])
for p in conf['amf_list']:
self.assertEqual(p['amf_addr'], gnb_param_dict1['amf_list'][p['amf_addr']]['amf_addr'])
for p in conf['xn_peers']:
self.assertEqual(p, gnb_param_dict1['xn_peers'][p]['xn_addr'])
for p in conf['nr_cell_list'][0]['ncell_list']:
for k in gnb_param_dict1['ncell_list']:
if p['dl_nr_arfcn'] == gnb_param_dict1['ncell_list'][k]['dl_nr_arfcn']:
break
conf_ncell = gnb_param_dict1['ncell_list'][k]
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['ul_nr_arfcn'], conf_ncell['dl_nr_arfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
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['tac'], conf_ncell['tac'])
self.assertEqual(p['band'], conf_ncell['nr_band'])
tdd_config = conf['nr_cell_default']['tdd_ul_dl_config']['pattern1']
self.assertEqual(float(tdd_config['period']), 2.5)
self.assertEqual(int(tdd_config['dl_slots']), 3)
self.assertEqual(int(tdd_config['dl_symbols']), 10)
self.assertEqual(int(tdd_config['ul_slots']), 1)
self.assertEqual(int(tdd_config['ul_symbols']), 2)
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define NR_BANDWIDTH'):
self.assertIn(str(gnb_param_dict1['nr_bandwidth']), l)
def test_gnb_conf2(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for p in conf['nr_cell_default']['plmn_list'][0]['nssai']:
sd = hex(p['sd'])
self.assertEqual(sd, gnb_param_dict2['nssai'][sd]['sd'], 16)
self.assertEqual(p['sst'], gnb_param_dict2['nssai'][sd]['sst'])
def test_mme_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'mme.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['plmn'], param_dict['core_network_plmn'])
def test_sim_card(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue_db.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for n in "sim_algo imsi opc sqn impu impi".split():
self.assertEqual(conf['ue_db'][0][n], param_dict[n])
self.assertEqual(conf['ue_db'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_db'][0]['amf'], int(param_dict['amf'], 16))
p = self.requestSlaveInstance().getConnectionParameterDict()
p = p['_'] if '_' in p else p
self.assertIn('info', p)
def test_monitor_gadget_url(self):
parameters = json.loads(self.computer_partition.getConnectionParameterDict()['_'])
self.assertIn('monitor-gadget-url', parameters)
monitor_setup_url = parameters['monitor-setup-url']
monitor_gadget_url = parameters['monitor-gadget-url']
monitor_base_url = parameters['monitor-base-url']
public_url = monitor_base_url + '/public'
response = requests.get(public_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('software.cfg.html', monitor_gadget_url)
response = requests.get(monitor_gadget_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('<script src="rsvp.js"></script>', response.text)
self.assertIn('<script src="renderjs.js"></script>', response.text)
self.assertIn('<script src="g-chart.line.js"></script>', response.text)
self.assertIn('<script src="promise.gadget.js"></script>', response.text)
class TestENBParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_enb_conf(self):
test_enb_conf(self)
class TestGNBParameters1(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf1(self)
class TestGNBParameters2(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict2)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf2(self)
class TestCoreNetworkParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_mme_conf(self):
test_mme_conf(self)
def requestSlaveInstance(cls):
software_url = cls.getSoftwareURL()
return cls.slap.request(
software_release=software_url,
partition_reference="SIM-CARD",
partition_parameter_kw={'_': json.dumps(param_dict)},
shared=True,
software_type='core-network',
)
class TestENBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestGNBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestCoreNetworkMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True, 'slave-list': []})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUELTEMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUENRMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestSimCard(ORSTestCase):
@classmethod
def requestDefaultInstance(cls, state='started'):
default_instance = super(
ORSTestCase, cls).requestDefaultInstance(state=state)
cls.requestSlaveInstance()
return default_instance
@classmethod
def requestSlaveInstance(cls):
return requestSlaveInstance(cls)
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_sim_card(self):
test_sim_card(self)
class TestUELTEParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_ue_lte_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_earfcn'], param_dict['dl_earfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
class TestUENRParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_ue_nr_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['ssb_nr_arfcn'], param_dict['ssb_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_nr_arfcn'], param_dict['dl_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['bandwidth'], '10 MHz')
self.assertEqual(conf['cell_groups'][0]['cells'][0]['band'], param_dict['nr_band'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import yaml
import json
import glob
import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, ORSTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software-tdd-ors.cfg')))
param_dict = {
'testing': True,
'sim_algo': 'milenage',
'imsi': '001010000000331',
'opc': '000102030405060708090A0B0C0D0E0F',
'amf': '0x9001',
'sqn': '000000000000',
'k': '00112233445566778899AABBCCDDEEFF',
'impu': 'impu331',
'impi': 'impi331@amarisoft.com',
'tx_gain': 17,
'rx_gain': 17,
'dl_earfcn': 325320,
'bandwidth': "10 MHz",
'enb_id': '0x17',
'pci': 250,
'tac': '0x1717',
'root_sequence_index': '1',
'mme_list': {
'10.0.0.1': {'mme_addr': '10.0.0.1'},
'2001:db8::1': {'mme_addr': '2001:db8::1'},
},
'core_network_plmn': '00102',
'dl_nr_arfcn': 325320,
'nr_band': 99,
'nr_bandwidth': 50,
'ssb_nr_arfcn': 377790,
'rue_addr': '192.168.99.88',
'n_antenna_dl': 2,
'n_antenna_ul': 2,
'inactivity_timer': 17,
'gnb_id': '0x17',
'gnb_id_bits': 30,
'ssb_pos_bitmap': '10',
'amf_list': {
'10.0.0.1': {'amf_addr': '10.0.0.1'},
'2001:db8::1': {'amf_addr': '2001:db8::1'},
},
'nr_handover_time_to_trigger': 40,
'nr_handover_a3_offset': 10,
'ncell_list': {
'ORS1': {
'dl_earfcn': 100000,
'dl_nr_arfcn': 100000,
'ssb_nr_arfcn': 100000,
'pci': 1,
'nr_cell_id': '0x0000001',
'cell_id': '0x0000001',
'gnb_id_bits': 28,
'nr_band': 1,
'tac': 1
},
'ORS2': {
'dl_earfcn': 200000,
'dl_nr_arfcn': 200000,
'ssb_nr_arfcn': 200000,
'pci': 2,
'nr_cell_id': '0x0000002',
'cell_id': '0x0000001',
'gnb_id_bits': 30,
'nr_band': 2,
'tac': 2
},
},
'xn_peers': {
'2001:db8::1': {
'xn_addr': '2001:db8::1',
},
'2001:db8::2': {
'xn_addr': '2001:db8::2',
},
},
}
enb_param_dict = {
'plmn_list': {
'00101': {'attach_without_pdn': True, 'plmn': '00101', 'reserved': True},
'00102': {'attach_without_pdn': False, 'plmn': '00102', 'reserved': False},
},
'tdd_ul_dl_config': '[Configuration 6] 5ms 5UL 3DL (maximum uplink)',
}
gnb_param_dict1 = {
'plmn_list': {
'00101': {'plmn': '00101', 'ranac': 1, 'reserved': True, 'tac': 1},
'00102': {'plmn': '00102', 'ranac': 2, 'reserved': False, 'tac': 2},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
gnb_param_dict2 = {
'nssai': {
'0x171717': {'sd': '0x171717', 'sst': 10},
'0x181818': {'sd': '0x181818', 'sst': 20},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
enb_param_dict.update(param_dict)
gnb_param_dict1.update(param_dict)
gnb_param_dict2.update(param_dict)
def test_enb_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'enb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
if 'tx_gain' in conf and 'rx_gain' in conf:
self.assertEqual(conf['tx_gain'], enb_param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], enb_param_dict['rx_gain'])
self.assertEqual(conf['cell_default']['inactivity_timer'], enb_param_dict['inactivity_timer'])
self.assertEqual(conf['cell_default']['uldl_config'], 6)
self.assertEqual(conf['cell_list'][0]['dl_earfcn'], enb_param_dict['dl_earfcn'])
self.assertEqual(conf['enb_id'], int(enb_param_dict['enb_id'], 16))
self.assertEqual(conf['cell_list'][0]['n_id_cell'], enb_param_dict['pci'])
self.assertEqual(conf['cell_list'][0]['tac'], int(enb_param_dict['tac'], 16))
self.assertEqual(conf['cell_list'][0]['root_sequence_index'], int(enb_param_dict['root_sequence_index']))
self.assertEqual(conf['cell_list'][0]['cell_id'], 0)
for p in conf['cell_default']['plmn_list']:
for n in "plmn attach_without_pdn reserved".split():
self.assertEqual(p[n], enb_param_dict['plmn_list'][p['plmn']][n])
for p in conf['mme_list']:
self.assertEqual(p['mme_addr'], enb_param_dict['mme_list'][p['mme_addr']]['mme_addr'])
for p in conf['cell_list'][0]['ncell_list']:
for k in enb_param_dict['ncell_list']:
if p['dl_earfcn'] == gnb_param_dict1['ncell_list'][k]['dl_earfcn']:
break
conf_ncell = enb_param_dict['ncell_list'][k]
self.assertEqual(p['dl_earfcn'], conf_ncell['dl_earfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
self.assertEqual(p['cell_id'], int(conf_ncell['cell_id'], 16))
self.assertEqual(p['tac'], conf_ncell['tac'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
def test_gnb_conf1(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['tx_gain'], gnb_param_dict1['tx_gain'])
self.assertEqual(conf['rx_gain'], gnb_param_dict1['rx_gain'])
self.assertEqual(conf['nr_cell_default']['inactivity_timer'], gnb_param_dict1['inactivity_timer'])
self.assertEqual(conf['nr_cell_list'][0]['dl_nr_arfcn'], gnb_param_dict1['dl_nr_arfcn'])
self.assertEqual(conf['nr_cell_list'][0]['band'], gnb_param_dict1['nr_band'])
self.assertEqual(conf['nr_cell_list'][0]['ssb_pos_bitmap'], gnb_param_dict1['ssb_pos_bitmap'])
self.assertEqual(conf['nr_cell_default']['n_id_cell'], gnb_param_dict1['pci'])
self.assertEqual(conf['gnb_id'], int(gnb_param_dict1['gnb_id'], 16))
self.assertEqual(conf['gnb_id_bits'], gnb_param_dict1['gnb_id_bits'])
for p in conf['nr_cell_default']['plmn_list']:
for n in "plmn ranac reserved tac".split():
self.assertEqual(p[n], gnb_param_dict1['plmn_list'][p['plmn']][n])
for p in conf['amf_list']:
self.assertEqual(p['amf_addr'], gnb_param_dict1['amf_list'][p['amf_addr']]['amf_addr'])
for p in conf['xn_peers']:
self.assertEqual(p, gnb_param_dict1['xn_peers'][p]['xn_addr'])
for p in conf['nr_cell_list'][0]['ncell_list']:
for k in gnb_param_dict1['ncell_list']:
if p['dl_nr_arfcn'] == gnb_param_dict1['ncell_list'][k]['dl_nr_arfcn']:
break
conf_ncell = gnb_param_dict1['ncell_list'][k]
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['ul_nr_arfcn'], conf_ncell['dl_nr_arfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
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['tac'], conf_ncell['tac'])
self.assertEqual(p['band'], conf_ncell['nr_band'])
tdd_config = conf['nr_cell_default']['tdd_ul_dl_config']['pattern1']
self.assertEqual(float(tdd_config['period']), 2.5)
self.assertEqual(int(tdd_config['dl_slots']), 3)
self.assertEqual(int(tdd_config['dl_symbols']), 10)
self.assertEqual(int(tdd_config['ul_slots']), 1)
self.assertEqual(int(tdd_config['ul_symbols']), 2)
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define NR_BANDWIDTH'):
self.assertIn(str(gnb_param_dict1['nr_bandwidth']), l)
def test_gnb_conf2(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for p in conf['nr_cell_default']['plmn_list'][0]['nssai']:
sd = hex(p['sd'])
self.assertEqual(sd, gnb_param_dict2['nssai'][sd]['sd'], 16)
self.assertEqual(p['sst'], gnb_param_dict2['nssai'][sd]['sst'])
def test_mme_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'mme.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['plmn'], param_dict['core_network_plmn'])
def test_sim_card(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue_db.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for n in "sim_algo imsi opc sqn impu impi".split():
self.assertEqual(conf['ue_db'][0][n], param_dict[n])
self.assertEqual(conf['ue_db'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_db'][0]['amf'], int(param_dict['amf'], 16))
p = self.requestSlaveInstance().getConnectionParameterDict()
p = p['_'] if '_' in p else p
self.assertIn('info', p)
def test_monitor_gadget_url(self):
parameters = json.loads(self.computer_partition.getConnectionParameterDict()['_'])
self.assertIn('monitor-gadget-url', parameters)
monitor_setup_url = parameters['monitor-setup-url']
monitor_gadget_url = parameters['monitor-gadget-url']
monitor_base_url = parameters['monitor-base-url']
public_url = monitor_base_url + '/public'
response = requests.get(public_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('software.cfg.html', monitor_gadget_url)
response = requests.get(monitor_gadget_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('<script src="rsvp.js"></script>', response.text)
self.assertIn('<script src="renderjs.js"></script>', response.text)
self.assertIn('<script src="g-chart.line.js"></script>', response.text)
self.assertIn('<script src="promise.gadget.js"></script>', response.text)
class TestENBParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_enb_conf(self):
test_enb_conf(self)
class TestGNBParameters1(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf1(self)
class TestGNBParameters2(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict2)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf2(self)
class TestCoreNetworkParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_mme_conf(self):
test_mme_conf(self)
def requestSlaveInstance(cls):
software_url = cls.getSoftwareURL()
return cls.slap.request(
software_release=software_url,
partition_reference="SIM-CARD",
partition_parameter_kw={'_': json.dumps(param_dict)},
shared=True,
software_type='core-network',
)
class TestENBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestGNBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestCoreNetworkMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True, 'slave-list': []})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUELTEMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUENRMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestSimCard(ORSTestCase):
@classmethod
def requestDefaultInstance(cls, state='started'):
default_instance = super(
ORSTestCase, cls).requestDefaultInstance(state=state)
cls.requestSlaveInstance()
return default_instance
@classmethod
def requestSlaveInstance(cls):
return requestSlaveInstance(cls)
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_sim_card(self):
test_sim_card(self)
class TestUELTEParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_ue_lte_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_earfcn'], param_dict['dl_earfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
class TestUENRParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_ue_nr_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['ssb_nr_arfcn'], param_dict['ssb_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_nr_arfcn'], param_dict['dl_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['bandwidth'], '10 MHz')
self.assertEqual(conf['cell_groups'][0]['cells'][0]['band'], param_dict['nr_band'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import yaml
import json
import glob
import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, ORSTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software-tdd.cfg')))
param_dict = {
'testing': True,
'sim_algo': 'milenage',
'imsi': '001010000000331',
'opc': '000102030405060708090A0B0C0D0E0F',
'amf': '0x9001',
'sqn': '000000000000',
'k': '00112233445566778899AABBCCDDEEFF',
'impu': 'impu331',
'impi': 'impi331@amarisoft.com',
'tx_gain': 17,
'rx_gain': 17,
'dl_earfcn': 325320,
'bandwidth': "10 MHz",
'enb_id': '0x17',
'pci': 250,
'tac': '0x1717',
'root_sequence_index': '1',
'mme_list': {
'10.0.0.1': {'mme_addr': '10.0.0.1'},
'2001:db8::1': {'mme_addr': '2001:db8::1'},
},
'core_network_plmn': '00102',
'dl_nr_arfcn': 325320,
'nr_band': 99,
'nr_bandwidth': 50,
'ssb_nr_arfcn': 377790,
'rue_addr': '192.168.99.88',
'n_antenna_dl': 2,
'n_antenna_ul': 2,
'inactivity_timer': 17,
'gnb_id': '0x17',
'gnb_id_bits': 30,
'ssb_pos_bitmap': '10',
'amf_list': {
'10.0.0.1': {'amf_addr': '10.0.0.1'},
'2001:db8::1': {'amf_addr': '2001:db8::1'},
},
'nr_handover_time_to_trigger': 40,
'nr_handover_a3_offset': 10,
'ncell_list': {
'ORS1': {
'dl_earfcn': 100000,
'dl_nr_arfcn': 100000,
'ssb_nr_arfcn': 100000,
'pci': 1,
'nr_cell_id': '0x0000001',
'cell_id': '0x0000001',
'gnb_id_bits': 28,
'nr_band': 1,
'tac': 1
},
'ORS2': {
'dl_earfcn': 200000,
'dl_nr_arfcn': 200000,
'ssb_nr_arfcn': 200000,
'pci': 2,
'nr_cell_id': '0x0000002',
'cell_id': '0x0000001',
'gnb_id_bits': 30,
'nr_band': 2,
'tac': 2
},
},
'xn_peers': {
'2001:db8::1': {
'xn_addr': '2001:db8::1',
},
'2001:db8::2': {
'xn_addr': '2001:db8::2',
},
},
}
enb_param_dict = {
'plmn_list': {
'00101': {'attach_without_pdn': True, 'plmn': '00101', 'reserved': True},
'00102': {'attach_without_pdn': False, 'plmn': '00102', 'reserved': False},
},
'tdd_ul_dl_config': '[Configuration 6] 5ms 5UL 3DL (maximum uplink)',
}
gnb_param_dict1 = {
'plmn_list': {
'00101': {'plmn': '00101', 'ranac': 1, 'reserved': True, 'tac': 1},
'00102': {'plmn': '00102', 'ranac': 2, 'reserved': False, 'tac': 2},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
gnb_param_dict2 = {
'nssai': {
'0x171717': {'sd': '0x171717', 'sst': 10},
'0x181818': {'sd': '0x181818', 'sst': 20},
},
'tdd_ul_dl_config': '2.5ms 1UL 3DL 2/10',
}
enb_param_dict.update(param_dict)
gnb_param_dict1.update(param_dict)
gnb_param_dict2.update(param_dict)
def test_enb_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'enb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
if 'tx_gain' in conf and 'rx_gain' in conf:
self.assertEqual(conf['tx_gain'], enb_param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], enb_param_dict['rx_gain'])
self.assertEqual(conf['cell_default']['inactivity_timer'], enb_param_dict['inactivity_timer'])
self.assertEqual(conf['cell_default']['uldl_config'], 6)
self.assertEqual(conf['cell_list'][0]['dl_earfcn'], enb_param_dict['dl_earfcn'])
self.assertEqual(conf['enb_id'], int(enb_param_dict['enb_id'], 16))
self.assertEqual(conf['cell_list'][0]['n_id_cell'], enb_param_dict['pci'])
self.assertEqual(conf['cell_list'][0]['tac'], int(enb_param_dict['tac'], 16))
self.assertEqual(conf['cell_list'][0]['root_sequence_index'], int(enb_param_dict['root_sequence_index']))
self.assertEqual(conf['cell_list'][0]['cell_id'], 0)
for p in conf['cell_default']['plmn_list']:
for n in "plmn attach_without_pdn reserved".split():
self.assertEqual(p[n], enb_param_dict['plmn_list'][p['plmn']][n])
for p in conf['mme_list']:
self.assertEqual(p['mme_addr'], enb_param_dict['mme_list'][p['mme_addr']]['mme_addr'])
for p in conf['cell_list'][0]['ncell_list']:
for k in enb_param_dict['ncell_list']:
if p['dl_earfcn'] == gnb_param_dict1['ncell_list'][k]['dl_earfcn']:
break
conf_ncell = enb_param_dict['ncell_list'][k]
self.assertEqual(p['dl_earfcn'], conf_ncell['dl_earfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
self.assertEqual(p['cell_id'], int(conf_ncell['cell_id'], 16))
self.assertEqual(p['tac'], conf_ncell['tac'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
def test_gnb_conf1(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['tx_gain'], gnb_param_dict1['tx_gain'])
self.assertEqual(conf['rx_gain'], gnb_param_dict1['rx_gain'])
self.assertEqual(conf['nr_cell_default']['inactivity_timer'], gnb_param_dict1['inactivity_timer'])
self.assertEqual(conf['nr_cell_list'][0]['dl_nr_arfcn'], gnb_param_dict1['dl_nr_arfcn'])
self.assertEqual(conf['nr_cell_list'][0]['band'], gnb_param_dict1['nr_band'])
self.assertEqual(conf['nr_cell_list'][0]['ssb_pos_bitmap'], gnb_param_dict1['ssb_pos_bitmap'])
self.assertEqual(conf['nr_cell_default']['n_id_cell'], gnb_param_dict1['pci'])
self.assertEqual(conf['gnb_id'], int(gnb_param_dict1['gnb_id'], 16))
self.assertEqual(conf['gnb_id_bits'], gnb_param_dict1['gnb_id_bits'])
for p in conf['nr_cell_default']['plmn_list']:
for n in "plmn ranac reserved tac".split():
self.assertEqual(p[n], gnb_param_dict1['plmn_list'][p['plmn']][n])
for p in conf['amf_list']:
self.assertEqual(p['amf_addr'], gnb_param_dict1['amf_list'][p['amf_addr']]['amf_addr'])
for p in conf['xn_peers']:
self.assertEqual(p, gnb_param_dict1['xn_peers'][p]['xn_addr'])
for p in conf['nr_cell_list'][0]['ncell_list']:
for k in gnb_param_dict1['ncell_list']:
if p['dl_nr_arfcn'] == gnb_param_dict1['ncell_list'][k]['dl_nr_arfcn']:
break
conf_ncell = gnb_param_dict1['ncell_list'][k]
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['ul_nr_arfcn'], conf_ncell['dl_nr_arfcn'])
self.assertEqual(p['n_id_cell'], conf_ncell['pci'])
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['tac'], conf_ncell['tac'])
self.assertEqual(p['band'], conf_ncell['nr_band'])
tdd_config = conf['nr_cell_default']['tdd_ul_dl_config']['pattern1']
self.assertEqual(float(tdd_config['period']), 2.5)
self.assertEqual(int(tdd_config['dl_slots']), 3)
self.assertEqual(int(tdd_config['dl_symbols']), 10)
self.assertEqual(int(tdd_config['ul_slots']), 1)
self.assertEqual(int(tdd_config['ul_symbols']), 2)
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define NR_BANDWIDTH'):
self.assertIn(str(gnb_param_dict1['nr_bandwidth']), l)
def test_gnb_conf2(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'gnb.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for p in conf['nr_cell_default']['plmn_list'][0]['nssai']:
sd = hex(p['sd'])
self.assertEqual(sd, gnb_param_dict2['nssai'][sd]['sd'], 16)
self.assertEqual(p['sst'], gnb_param_dict2['nssai'][sd]['sst'])
def test_mme_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'mme.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['plmn'], param_dict['core_network_plmn'])
def test_sim_card(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue_db.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
for n in "sim_algo imsi opc sqn impu impi".split():
self.assertEqual(conf['ue_db'][0][n], param_dict[n])
self.assertEqual(conf['ue_db'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_db'][0]['amf'], int(param_dict['amf'], 16))
p = self.requestSlaveInstance().getConnectionParameterDict()
p = p['_'] if '_' in p else p
self.assertIn('info', p)
def test_monitor_gadget_url(self):
parameters = json.loads(self.computer_partition.getConnectionParameterDict()['_'])
self.assertIn('monitor-gadget-url', parameters)
monitor_setup_url = parameters['monitor-setup-url']
monitor_gadget_url = parameters['monitor-gadget-url']
monitor_base_url = parameters['monitor-base-url']
public_url = monitor_base_url + '/public'
response = requests.get(public_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('software.cfg.html', monitor_gadget_url)
response = requests.get(monitor_gadget_url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('<script src="rsvp.js"></script>', response.text)
self.assertIn('<script src="renderjs.js"></script>', response.text)
self.assertIn('<script src="g-chart.line.js"></script>', response.text)
self.assertIn('<script src="promise.gadget.js"></script>', response.text)
class TestENBParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_enb_conf(self):
test_enb_conf(self)
class TestGNBParameters1(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf1(self)
class TestGNBParameters2(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict2)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_gnb_conf(self):
test_gnb_conf2(self)
class TestCoreNetworkParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_mme_conf(self):
test_mme_conf(self)
def requestSlaveInstance(cls):
software_url = cls.getSoftwareURL()
return cls.slap.request(
software_release=software_url,
partition_reference="SIM-CARD",
partition_parameter_kw={'_': json.dumps(param_dict)},
shared=True,
software_type='core-network',
)
class TestENBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(enb_param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "enb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestGNBMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(gnb_param_dict1)}
@classmethod
def getInstanceSoftwareType(cls):
return "gnb"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestCoreNetworkMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True, 'slave-list': []})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUELTEMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestUENRMonitorGadgetUrl(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_monitor_gadget_url(self):
test_monitor_gadget_url(self)
class TestSimCard(ORSTestCase):
@classmethod
def requestDefaultInstance(cls, state='started'):
default_instance = super(
ORSTestCase, cls).requestDefaultInstance(state=state)
cls.requestSlaveInstance()
return default_instance
@classmethod
def requestSlaveInstance(cls):
return requestSlaveInstance(cls)
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'testing': True})}
@classmethod
def getInstanceSoftwareType(cls):
return "core-network"
def test_sim_card(self):
test_sim_card(self)
class TestUELTEParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-lte"
def test_ue_lte_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_earfcn'], param_dict['dl_earfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
with open(conf_file, 'r') as f:
for l in f:
if l.startswith('#define N_RB_DL'):
self.assertIn('50', l)
class TestUENRParameters(ORSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps(param_dict)}
@classmethod
def getInstanceSoftwareType(cls):
return "ue-nr"
def test_ue_nr_conf(self):
conf_file = glob.glob(os.path.join(
self.slap.instance_directory, '*', 'etc', 'ue.cfg'))[0]
with open(conf_file, 'r') as f:
conf = yaml.load(f)
self.assertEqual(conf['cell_groups'][0]['cells'][0]['ssb_nr_arfcn'], param_dict['ssb_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['dl_nr_arfcn'], param_dict['dl_nr_arfcn'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['bandwidth'], '10 MHz')
self.assertEqual(conf['cell_groups'][0]['cells'][0]['band'], param_dict['nr_band'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_dl'], param_dict['n_antenna_dl'])
self.assertEqual(conf['cell_groups'][0]['cells'][0]['n_antenna_ul'], param_dict['n_antenna_ul'])
self.assertEqual(conf['ue_list'][0]['rue_addr'], param_dict['rue_addr'])
self.assertEqual(conf['ue_list'][0]['imsi'], param_dict['imsi'])
self.assertEqual(conf['ue_list'][0]['K'], param_dict['k'])
self.assertEqual(conf['ue_list'][0]['sim_algo'], param_dict['sim_algo'])
self.assertEqual(conf['ue_list'][0]['opc'], param_dict['opc'])
self.assertEqual(conf['ue_list'][0]['amf'], int(param_dict['amf'], 16))
self.assertEqual(conf['ue_list'][0]['sqn'], param_dict['sqn'])
self.assertEqual(conf['ue_list'][0]['impu'], param_dict['impu'])
self.assertEqual(conf['ue_list'][0]['impi'], param_dict['impi'])
self.assertEqual(conf['tx_gain'], param_dict['tx_gain'])
self.assertEqual(conf['rx_gain'], param_dict['rx_gain'])
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