Commit b9ce538e authored by Lu Xu's avatar Lu Xu 👀

Implement ors-amarisoft for lopcomm RU

See merge request nexedi/slapos!1428
parents 9b80bf6c 8baf732e
Pipeline #30050 failed with stage
in 0 seconds
......@@ -54,7 +54,7 @@ class enbWebSocket:
"rf": True
})
r = self.recv('stats')
self.logger.info('Samples stats', extra={'data': r})
self.logger.info('Samples stats', extra={'data': json.dumps(r)})
if __name__ == '__main__':
ws = enbWebSocket()
......
......@@ -16,31 +16,43 @@
[template]
filename = instance.cfg
md5sum = 50e83105328c6434ba94f77c5753cbf8
md5sum = bc60058a9407fc481b1a652b2f3b5498
[amarisoft-stats.jinja2.py]
_update_hash_filename_ = amarisoft-stats.jinja2.py
md5sum = 6e0a052bd0ca08cc0c7b4880d3deffcc
md5sum = c4d5e9fcf460d88bc2b4bcfbdfe554f7
[amarisoft-rf-info.jinja2.py]
_update_hash_filename_ = amarisoft-rf-info.jinja2.py
md5sum = c930c28365c685a6066f382c9b5d8893
[ncclient_common]
_update_hash_filename_ = ncclient_common.py
md5sum = f34a196e947fa58b141431a00cc744df
[lopcomm-rrh-stats.jinja2.py]
_update_hash_filename_ = lopcomm-rrh-stats.jinja2.py
md5sum = f0451b3c2494f103042bda04433c943d
md5sum = b861ef43beba4a0a2904e8c2aee04723
[lopcomm-rrh-config.jinja2.py]
_update_hash_filename_ = lopcomm-rrh-config.jinja2.py
md5sum = b34fe47a73890097fbc6ea6374aeb38d
md5sum = f2f550b68c8ab243ce1a4bb73a9abc1c
[lopcomm-rrh-software.jinja2.py]
_update_hash_filename_ = lopcomm-rrh-software.jinja2.py
md5sum = 860fa5e5bab65f414535c7e25f622a6c
[lopcomm-rrh-supervision.jinja2.py]
_update_hash_filename_ = lopcomm-rrh-supervision.jinja2.py
md5sum = a2ba0343ddb7f9cf2904a4c5c751f68a
[template-enb]
_update_hash_filename_ = instance-enb.jinja2.cfg
md5sum = 62252527eb4998de5bb23058dbbdbd75
md5sum = 8a47df7cfefa3876afea38ced2c5005f
[template-gnb]
_update_hash_filename_ = instance-gnb.jinja2.cfg
md5sum = b4d7406d9d7df7fafbbf0ddbc792f5fb
md5sum = e758c9358c49360ef0b3db946ab0f493
[template-core-network]
_update_hash_filename_ = instance-core-network.jinja2.cfg
......@@ -64,15 +76,15 @@ md5sum = dcaac06553a3222b14c0013a13f4a149
[enb.jinja2.cfg]
filename = config/enb.jinja2.cfg
md5sum = 1680fde9d6d5f8c1678fb11d7a891191
md5sum = e33bf40dfdb32d91d3a1b3f3a10ede34
[sib23.jinja2.asn]
filename = config/sib23.jinja2.asn
md5sum = 0af07bba51f8d4e773f9bfef4f2ca535
md5sum = a1973ba6e43d40e510d61d461c2d13ac
[gnb.jinja2.cfg]
filename = config/gnb.jinja2.cfg
md5sum = f1e7f37a9c0866c08237b03cecdcd2c7
md5sum = 2f7b70b6225ca94feaf1ba512643b0d1
[ltelogs.jinja2.sh]
filename = ltelogs.jinja2.sh
......@@ -84,7 +96,7 @@ md5sum = 48b577daa5b53c2cf7fe2d30ea9c0235
[dnsmasq.jinja2.cfg]
filename = config/dnsmasq.jinja2.cfg
md5sum = 5f67c7f750e7c7bd9b9839c527a06853
md5sum = ecf6081d1fc76a60ba57f042446bc161
[ims.jinja2.cfg]
filename = config/ims.jinja2.cfg
......@@ -104,7 +116,7 @@ md5sum = e435990eb0a0d4be41efa9bd16dce09b
[cu_config.jinja2.xml]
filename = netconf/cu_config.jinja2.xml
md5sum = 39ef850c68ea6cb1282176e718819c4a
md5sum = d10b063ad4edc760e154f7a8d63bea47
[software.cfg.html]
_update_hash_filename_ = gadget/software.cfg.html
......
Changelog
=========
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)
-------------
......
{% if slapparameter_dict.get('rrh', '') == "Lopcomm ORAN" %}
{% if ru == "lopcomm" %}
dhcp-leasefile={{ directory['etc'] }}/dnsmasq.leases
port=5354
dhcp-range=::1,::1,constructor:{{ slap_configuration.get('tap-name', '') }},ra-names,64,12h
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
......
......@@ -35,7 +35,7 @@
{% endif %}
log_filename: "{{ directory['log'] }}/enb.log",
{% if slapparameter_dict.get('rrh', 'ORS') == "Lopcomm ORAN" %}
{% if ru == "lopcomm" %}
rf_driver: {
{%- if slapparameter_dict.get('disable_sdr', False) %}
name: "dummy",
......@@ -92,7 +92,7 @@
},
tx_gain: 0,
rx_gain: 0,
{% elif slapparameter_dict.get('rrh', 'ORS') == "ORS" %}
{% elif bbu == "ors" %}
rf_driver: {
{%- if slapparameter_dict.get('disable_sdr', False) %}
name: "dummy",
......@@ -136,11 +136,15 @@
{% endif %}
],
{% if slapparameter_dict.get('mme_list', '') %}
{% if slapparameter_dict.get('use_ipv4', False) %}
gtp_addr: "{{ gtp_addr_v4 }}",
{% else %}
{% 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 }}",
{% endif %}
{% else %}
gtp_addr: "{{ gtp_addr_v4 }}",
{% endif %}
{% endif %}
{% else %}
gtp_addr: "127.0.1.1",
{% endif %}
......@@ -218,7 +222,7 @@
],
n_antenna_dl: N_ANTENNA_DL,
n_antenna_ul: N_ANTENNA_UL,
{% if slapparameter_dict.get('rrh', 'ORS') == "ORS" %}
{% if bbu == "ors" %}
manual_ref_signal_power: true,
{% endif %}
#if TDD == 1
......
......@@ -7,7 +7,7 @@
{%- endif %}
#define N_ANTENNA_DL {{ slapparameter_dict.get('n_antenna_dl', slap_configuration['configuration.default_n_antenna_dl']) }}
{% if slapparameter_dict.get('rrh', 'ORS') == "M2RU Sunwave" %}
{% 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']) }}
......@@ -19,7 +19,7 @@
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 slapparameter_dict.get('rrh', 'ORS') == "M2RU Sunwave" %}
{% if ru == "m2ru" %}
rf_driver: {
{%- if slapparameter_dict.get('disable_sdr', False) %}
name: "dummy",
......@@ -140,7 +140,7 @@
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 slapparameter_dict.get('rrh', 'ORS') == "ORS" %}
{%- if bbu == "ors" %}
manual_ref_signal_power: true,
{%- if one_watt == "True" %}
ss_pbch_block_power: {{ (tx_gain | int) - 54 }},
......@@ -257,7 +257,7 @@
prach_config_index: 160,
msg1_subcarrier_spacing: 30,
msg1_fdm: 1,
{% if slapparameter_dict.get('rrh', 'ORS') == "M2RU Sunwave" %}
{% if ru == "m2ru" %}
msg1_frequency_start: 0,
{% else %}
msg1_frequency_start: -1,
......@@ -273,7 +273,7 @@
cb_preambles_per_ssb: 8,
},
pdcch: {
{% if slapparameter_dict.get('rrh', 'ORS') == "M2RU Sunwave" %}
{% if ru == "m2ru" %}
n_rb_coreset0: 48,
n_symb_coreset0: 1,
{% endif %}
......@@ -281,7 +281,7 @@
dedicated_coreset: {
rb_start: -1,
l_crb: -1,
{% if slapparameter_dict.get('rrh', 'ORS') == "M2RU Sunwave" %}
{% if ru == "m2ru" %}
duration: 1,
{% else %}
duration: 0,
......@@ -311,7 +311,7 @@
dmrs_add_pos: 1,
dmrs_type: 1,
dmrs_max_len: 1,
{% if slapparameter_dict.get('rrh', 'ORS') == "M2RU Sunwave" %}
{% if ru == "m2ru" %}
k0: 0,
k1: [ 8, 7, 7, 6, 5, 4, 12, 11 ],
{% elif tdd_config == 3 %}
......@@ -553,7 +553,7 @@
mcs_table: "qam256",
mcs_table_tp: "qam256",
ldpc_max_its: 5,
{% if slapparameter_dict.get('rrh', 'ORS') == "M2RU Sunwave" %}
{% if ru == "m2ru" %}
k2: 4,
msg3_k2: 7,
{% elif tdd_config == 3 %}
......
......@@ -36,7 +36,7 @@
}
},
pdsch-ConfigCommon {
{% if slapparameter_dict.get('rrh', 'ORS') == "ORS" %}
{% if bbu == "ors" %}
{%- if one_watt == "True" %}
referenceSignalPower {{ (tx_gain | int) - 54 }}, /* patched by eNB */
{%- else %}
......
......@@ -56,10 +56,16 @@
"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",
"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,
......@@ -113,19 +119,19 @@
"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": 0
"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": 0
"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": 0
"default": 63
},
"cpri_port_number": {
"title": "CPRI Port Number",
......@@ -204,41 +210,35 @@
"INACTIVE"
]
},
"txa0cc00_center_frequency_earfcn": {
"title": "Lopcomm ORAN Center Frequency EARFCN (TXA0CC00)",
"description": "Lopcomm ORAN Center Frequency EARFCN (TXA0CC00)",
"type": "number",
"default": 300
},
"txa0cc00_center_frequency": {
"title": "Lopcomm ORAN Center Frequency in Hz (TXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in Hz (TXA0CC00)",
"type": "number",
"default": 2140000000
},
"txa0cc00_bandwidth": {
"title": "Lopcomm ORAN bandwidth in Hz (TXA0CC00)",
"description": "Lopcomm ORAN bandwidth in Hz (TXA0CC00)",
"title": "Lopcomm ORAN DL Center Frequency in MHz (TXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in MHz (TXA0CC00)",
"type": "number",
"default": 20000000
"default": 2140
},
"rxa0cc00_center_frequency_earfcn": {
"title": "Lopcomm ORAN Center Frequency EARFCN (RXA0CC00)",
"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 Center Frequency in Hz (RXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in Hz (RXA0CC00)",
"title": "Lopcomm ORAN UL Center Frequency in MHz (RXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in MHz (RXA0CC00)",
"type": "number",
"default": 1950000000
"default": 1950
},
"rxa0cc00_bandwidth": {
"title": "Lopcomm ORAN bandwidth in Hz (RXA0CC00)",
"description": "Lopcomm ORAN bandwidth in Hz (RXA0CC00)",
"txa0cc00_gain": {
"title": "ORAN Gain",
"description": "Lopcomm ORAN Gain (TXA0CC00)",
"type": "number",
"default": 20000000
"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"
},
{%- endif %}
"enb_id": {
......@@ -247,6 +247,12 @@
"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",
......
......@@ -10,12 +10,22 @@ parts =
{% endif %}
amarisoft-stats-service
amarisoft-rf-info-service
{% if slapparameter_dict.get('rrh', '') == "Lopcomm ORAN" %}
{% if ru == "lopcomm" %}
lopcomm-firmware-dl
lopcomm-rrh-stats-service
lopcomm-rrh-supervision-service
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
......@@ -29,7 +39,9 @@ parts =
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
......@@ -267,6 +279,7 @@ 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
......@@ -276,8 +289,10 @@ context =
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 }}
......@@ -303,6 +318,7 @@ context =
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
......@@ -310,6 +326,68 @@ 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
[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}
......@@ -334,6 +412,81 @@ 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-firmware-dl]
recipe = slapos.recipe.build:download
url = https://lab.nexedi.com/nexedi/ors-utils/raw/master/lopcomm-firmware/${:filename}
filename = PR.PRM61C70V1004.002.tar.gz
md5sum = 4e06fd62968f9f53fd819ef8d880a8f4
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
......@@ -380,13 +533,19 @@ 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'] }}
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}
{% endif %}
[monitor-instance-parameter]
{% if slapparameter_dict.get("name", None) %}
......@@ -443,6 +602,13 @@ 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
......
......@@ -35,6 +35,12 @@
"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",
......@@ -79,6 +85,12 @@
"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",
......
......@@ -35,8 +35,14 @@
"type": "number",
"default": 0
},
"cpri_port": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
"cpri_mult": {
"title": "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,
......@@ -57,19 +63,19 @@
"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": 0
"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": 0
"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": 0
"default": 63
},
"cpri_port_number": {
"title": "CPRI Port Number",
......@@ -131,41 +137,35 @@
"INACTIVE"
]
},
"txa0cc00_center_frequency_earfcn": {
"title": "Lopcomm ORAN Center Frequency EARFCN (TXA0CC00)",
"description": "Lopcomm ORAN Center Frequency EARFCN (TXA0CC00)",
"type": "number",
"default": 300
},
"txa0cc00_center_frequency": {
"title": "Lopcomm ORAN Center Frequency in Hz (TXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in Hz (TXA0CC00)",
"type": "number",
"default": 2140000000
},
"txa0cc00_bandwidth": {
"title": "Lopcomm ORAN bandwidth in Hz (TXA0CC00)",
"description": "Lopcomm ORAN bandwidth in Hz (TXA0CC00)",
"title": "Lopcomm ORAN DL Center Frequency in MHz (TXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in MHz (TXA0CC00)",
"type": "number",
"default": 20000000
"default": 2140
},
"rxa0cc00_center_frequency_earfcn": {
"title": "Lopcomm ORAN Center Frequency EARFCN (RXA0CC00)",
"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 Center Frequency in Hz (RXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in Hz (RXA0CC00)",
"title": "Lopcomm ORAN UL Center Frequency in MHz (RXA0CC00)",
"description": "Lopcomm ORAN Center Frequency in MHz (RXA0CC00)",
"type": "number",
"default": 1950000000
"default": 1950
},
"rxa0cc00_bandwidth": {
"title": "Lopcomm ORAN bandwidth in Hz (RXA0CC00)",
"description": "Lopcomm ORAN bandwidth in Hz (RXA0CC00)",
"txa0cc00_gain": {
"title": "ORAN Gain",
"description": "Lopcomm ORAN Gain (TXA0CC00)",
"type": "number",
"default": 20000000
"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"
},
"enb_id": {
"title": "eNB ID",
......@@ -173,6 +173,12 @@
"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",
......
......@@ -74,6 +74,12 @@
"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",
......
......@@ -10,13 +10,6 @@ parts =
{% endif %}
amarisoft-stats-service
amarisoft-rf-info-service
{% if slapparameter_dict.get('rrh', '') == "Lopcomm ORAN" %}
lopcomm-rrh-stats-service
check-lopcomm-vswr.py
check-lopcomm-lof.py
check-lopcomm-rssi.py
check-cpri-lock.py
{% endif %}
check-sdr-busy.py
check-baseband-latency.py
check-amarisoft-stats-log.py
......@@ -324,34 +317,6 @@ 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-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("gnb_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-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-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
......
......@@ -45,6 +45,12 @@
"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",
......@@ -89,6 +95,12 @@
"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",
......
......@@ -45,8 +45,14 @@
"type": "number",
"default": 0
},
"cpri_port": {
"title": "CPRI Port Number",
"description": "CPRI Port Number",
"type": "number",
"default": 0
},
"cpri_mult": {
"title": "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,
......@@ -67,19 +73,19 @@
"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": 0
"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": 0
"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": 0
"default": 63
},
"cpri_port_number": {
"title": "CPRI Port Number",
......@@ -127,6 +133,12 @@
"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",
......
......@@ -84,6 +84,12 @@
"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",
......
......@@ -256,6 +256,8 @@ extra-context =
raw amarisoft_rf_info_template ${amarisoft-rf-info.jinja2.py:target}
raw lopcomm_rrh_stats_template ${lopcomm-rrh-stats.jinja2.py:target}
raw lopcomm_rrh_config_template ${lopcomm-rrh-config.jinja2.py:target}
raw lopcomm_rrh_software_template ${lopcomm-rrh-software.jinja2.py:target}
raw lopcomm_rrh_supervision_template ${lopcomm-rrh-supervision.jinja2.py:target}
raw CreateProcessingEle_template ${CreateProcessingEle.jinja2.xml:target}
raw cu_config_template ${cu_config.jinja2.xml:target}
raw openssl_location ${openssl:location}
......@@ -267,6 +269,8 @@ extra-context =
raw dnsmasq_location ${dnsmasq:location}
key dnsmasq_config_path dnsmasq-config:output
raw fluent_bit_location ${fluent-bit:location}
raw openssh_location ${openssh:location}
raw openssh_output_keygen ${openssh-output:keygen}
[dynamic-template-gnb]
< = jinja2-template-base
......@@ -370,4 +374,4 @@ context =
section directory directory
section slap_configuration slap-configuration
key slapparameter_dict slap-configuration:configuration
raw ru ${rf-mode:ru}
#!{{ python_path }}
import logging
import time
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 = "{{ log_file }}"
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 {{ testing }}:
return
def connect(self, host, port, user, password):
if {{ testing }}:
return
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 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 close(self):
# Close not compatible between ncclient and netconf server
#self.conn.close()
pass
import sys
sys.path.append({{ repr(buildout_directory_path) }})
from ncclient_common import LopcommNetconfClient
if __name__ == '__main__':
nc = LopcommNetconfClient()
nc = LopcommNetconfClient(log_file="{{ log_file }}")
while True:
try:
nc.connect("{{ netaddr.IPAddress(slap_configuration.get('tap-ipv6-gateway', '')) }}", 830, "oranuser", "oranpassword")
......
#!{{ 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.nc.reset_device()
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 time
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': 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': 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': 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 json
import logging
import time
import xmltodict
from logging.handlers import RotatingFileHandler
from ncclient import manager
from ncclient.xml_ import *
from ncclient.devices.default import DefaultDeviceHandler
class LopcommNetconfClient:
def __init__(self):
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 }}"
self.logger = logging.getLogger('logger')
self.json_logger = logging.getLogger('json_logger')
self.cfg_json_logger = logging.getLogger('cfg_json_logger')
self.supervision_json_logger = logging.getLogger('supervision_json_logger')
self.ncsession_json_logger = logging.getLogger('ncsession_json_logger')
self.logger.setLevel(logging.DEBUG)
self.json_logger.setLevel(logging.DEBUG)
self.cfg_json_logger.setLevel(logging.DEBUG)
self.supervision_json_logger.setLevel(logging.DEBUG)
self.ncsession_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)
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)
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)
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)
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 {{ testing }}:
return
def connect(self, host, port, user, password):
if {{ testing }}:
return
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):
# Filter not compatible between ncclient and netconf server
#result = self.conn.create_subscription(filter=('xpath', '/o-ran-fm:*'))
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': data_dict})
elif 'supervision-notification' in data_dict['notification']:
self.supervision_json_logger.info('', extra={'data': data_dict})
elif 'netconf-session-start' or 'netconf-session-end' in data_dict['notification']:
self.ncsession_json_logger.info('', extra={'data': data_dict})
else:
self.cfg_json_logger.info('', extra={'data': data_dict})
def close(self):
# Close not compatible between ncclient and netconf server
#self.conn.close()
pass
import sys
sys.path.append({{ repr(buildout_directory_path) }})
from ncclient_common import LopcommNetconfClient
if __name__ == '__main__':
nc = LopcommNetconfClient()
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")
......
#!{{ python_path }}
import time
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': 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': 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
import time
import logging
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': data_dict})
elif 'supervision-notification' in data_dict['notification']:
self.supervision_json_logger.info('', extra={'data': 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': 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': data_dict})
else:
self.cfg_json_logger.info('', extra={'data': 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)
self.software_reply_json_logger.info('', extra={'data': 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': 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">
<user-plane-configuration xmlns="urn:o-ran:uplane-conf-option8:1.0">
<!-- t[r]x-links -->
<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>
......@@ -25,6 +41,7 @@
<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>
......@@ -37,7 +54,33 @@
<rx-array-carrier>RXA0CC00</rx-array-carrier>
<rx-endpoint>PRACH0P01C00</rx-endpoint>
</rx-links>
<!-- t[r]x-endpoints -->
{% 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>
......@@ -48,8 +91,20 @@
<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>
......@@ -58,6 +113,18 @@
<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>
......@@ -67,7 +134,6 @@
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>0</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>false</non-time-managed-delay-enabled>
</rx-endpoints>
<rx-endpoints>
<name>PRACH0P00C00</name>
......@@ -78,8 +144,8 @@
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>8</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>false</non-time-managed-delay-enabled>
</rx-endpoints>
{% if slapparameter_dict.get('n_antenna_dl') == 4 %}
<rx-endpoints>
<name>RXA0P01C00</name>
<e-axcid>
......@@ -87,9 +153,8 @@
<band-sector-bitmask>3968</band-sector-bitmask>
<ccid-bitmask>112</ccid-bitmask>
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>1</eaxc-id>
<eaxc-id>2</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>false</non-time-managed-delay-enabled>
</rx-endpoints>
<rx-endpoints>
<name>PRACH0P01C00</name>
......@@ -100,26 +165,67 @@
<ru-port-bitmask>15</ru-port-bitmask>
<eaxc-id>9</eaxc-id>
</e-axcid>
<non-time-managed-delay-enabled>false</non-time-managed-delay-enabled>
</rx-endpoints>
<!-- t[r]x-array-carriers -->
{% 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('txa0cc00_center_frequency_earfcn', 300) }}</absolute-frequency-center>
<center-of-channel-bandwidth>{{ slapparameter_dict.get('txa0cc00_center_frequency', 2140000000) }}</center-of-channel-bandwidth>
<channel-bandwidth>{{ slapparameter_dict.get('txa0cc00_bandwidth', 20000000) }}</channel-bandwidth>
<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>0</gain>
<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>{{ slapparameter_dict.get('rxa0cc00_center_frequency', 1950000000) }}</center-of-channel-bandwidth>
<channel-bandwidth>{{ slapparameter_dict.get('rxa0cc00_bandwidth', 20000000) }}</channel-bandwidth>
<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>
......@@ -127,4 +233,4 @@
<n-ta-offset>0</n-ta-offset>
</rx-array-carriers>
</user-plane-configuration>
</config>
\ No newline at end of file
</xc:config>
......@@ -14,11 +14,13 @@ extends =
../../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
......@@ -56,6 +58,10 @@ output = ${buildout:directory}/template.cfg
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
......@@ -68,6 +74,12 @@ url = ${:_profile_base_location_}/${:_update_hash_filename_}
[lopcomm-rrh-config.jinja2.py]
<= download-base
[lopcomm-rrh-software.jinja2.py]
<= download-base
[lopcomm-rrh-supervision.jinja2.py]
<= download-base
[template-enb]
<= download-base
......
......@@ -142,6 +142,7 @@ def test_enb_conf(self):
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'])
......@@ -151,6 +152,7 @@ def test_enb_conf(self):
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])
......
......@@ -142,6 +142,7 @@ def test_enb_conf(self):
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'])
......@@ -151,6 +152,7 @@ def test_enb_conf(self):
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])
......
......@@ -142,6 +142,7 @@ def test_enb_conf(self):
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'])
......@@ -151,6 +152,7 @@ def test_enb_conf(self):
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])
......
......@@ -142,6 +142,7 @@ def test_enb_conf(self):
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'])
......@@ -151,6 +152,7 @@ def test_enb_conf(self):
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])
......
......@@ -142,6 +142,7 @@ def test_enb_conf(self):
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'])
......@@ -151,6 +152,7 @@ def test_enb_conf(self):
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])
......
......@@ -142,6 +142,7 @@ def test_enb_conf(self):
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'])
......@@ -151,6 +152,7 @@ def test_enb_conf(self):
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])
......
......@@ -142,6 +142,7 @@ def test_enb_conf(self):
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'])
......@@ -151,6 +152,7 @@ def test_enb_conf(self):
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])
......
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