Commit 97ad2a51 authored by Joanne Hugé's avatar Joanne Hugé

Update Release Candidate

parents 7e4eb099 94bf8492
......@@ -16,39 +16,47 @@
[template]
filename = instance.cfg
md5sum = 9d5f4fc9ed3664140d33dd7c447dbd63
md5sum = 06331958afaaeb200e4d7f48b417cde8
[template-lte-enb-epc]
_update_hash_filename_ = instance-enb-epc.jinja2.cfg
md5sum = 2dce6e5aa97ffb331bae8fc95b9f8cf0
md5sum = 946c70155a691e508e934a7ef2e442ba
[template-lte-enb]
_update_hash_filename_ = instance-enb.jinja2.cfg
md5sum = 79f3c30ab08efbb22b0cbcbbc45a66cb
md5sum = 2b0ba32fb176fead6fb32779fa4d88be
[template-lte-gnb-epc]
_update_hash_filename_ = instance-gnb-epc.jinja2.cfg
md5sum = c43e4233ec44abdc87aa3068ebb8640b
md5sum = 4a258326fe571790e07a0e903d94fde0
[template-lte-epc]
_update_hash_filename_ = instance-epc.jinja2.cfg
md5sum = 1039c60e2dcb8ef144a8c56e34acce9b
[template-lte-gnb]
_update_hash_filename_ = instance-gnb.jinja2.cfg
md5sum = 7d25976008c3aa588527db2b461ad72c
[template-lte-epc]
_update_hash_filename_ = instance-epc.jinja2.cfg
md5sum = 5e7a832ca1be147948ae562f3b45c88b
[template-lte-mme]
_update_hash_filename_ = instance-mme.jinja2.cfg
md5sum = e95761b8670ec8b90694e119a818e684
[ue_db.jinja2.cfg]
filename = config/ue_db.jinja2.cfg
md5sum = d33163012d6c98efc59161974c649557
md5sum = dcaac06553a3222b14c0013a13f4a149
[enb.jinja2.cfg]
filename = config/enb.jinja2.cfg
md5sum = b78082a9c5d6af79f11a1c79d6d25a86
md5sum = 18a8f16240881dbb87ecb5183d9872e0
[sib23.asn]
filename = config/sib23.asn
md5sum = b377dac7f1fcf94fb9ce9ebed617f36a
[gnb.jinja2.cfg]
filename = config/gnb.jinja2.cfg
md5sum = 944e342d426d5a7c4c16bdcb01398ba3
md5sum = c0d3d042960f5704dd2e3fa7714a4a5f
[ltelogs.jinja2.sh]
filename = ltelogs.jinja2.sh
......@@ -56,11 +64,11 @@ md5sum = 1ba2e065bdf14a6411e95e80db17dcfd
[mme.jinja2.cfg]
filename = config/mme.jinja2.cfg
md5sum = 13ce0230f06e1089c10924b17f80e49b
md5sum = fc073eb6450da95955009a127a333396
[ims.jinja2.cfg]
filename = config/ims.jinja2.cfg
md5sum = e561ec26a70943c61557def1781cf65f
md5sum = 36281b03597252cf75169417d02fc28c
[sdr-busy-promise]
_update_hash_filename_ = promise/check_sdr_busy.py
......
/* lteims configuration file
* version 2021-09-18
* Copyright (C) 2015-2021 Amarisoft
*/
{
log_options: "all.level=debug,all.max_size=32",
log_filename: "{{ directory['log'] }}/ims.log",
/* SIP bind address */
//sip_addr: [
// {addr: "192.168.4.1", bind_addr: "192.168.4.1", port_min: 10000, port_max: 20000},
// "2001:468:3000:1::",
// {addr: "192.168.5.1", bind_addr: "192.168.5.1", port_min: 10000, port_max: 20000},
// "2001:468:4000:1::"
//],
/* SIP bind address */
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",
/* MME connection for SMS over SG */
sctp_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
/* Cx connection */
cx_server_addr: "127.0.1.100",
cx_bind_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
/* Rx connection */
rx_server_addr: "127.0.1.100",
rx_bind_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
/* Remote API */
com_addr: "[{{ slap_configuration['ipv6-random'] }}]:{{ slap_configuration['configuration.ims_ws_port'] }}",
/* Global domain name (May be overriden for each user) */
domain: "{{ slap_configuration['configuration.domain'] }}",
include "{{ slap_configuration['ue_db_path'] }}",
......@@ -48,27 +30,17 @@
{# origin_host: "", #}
{# }, #}
/* Echo phone number */
echo: [
"tel:666",
"tel:+666",
{impu: "tel:404", code: 404}, /* 404 test */
{impu: "urn:service:sos", anonymous: true, authentication: false}, /* Emergency call */
{impu: "urn:service:sos.police", anonymous: true, authentication: false}, /* Emergency call */
{impu: "tel:404", code: 404},
{impu: "urn:service:sos", anonymous: true, authentication: false},
{impu: "urn:service:sos.police", anonymous: true, authentication: false},
],
/* Delay */
//sms_expires: 86400,
//binding_expires: 3600,
/* on: 3GPP mode allowed
* silent: 3GPP mode forced
* off: IETF mode
*/
precondition: "on",
"100rel": true,
/* IPsec */
ipsec_aalg_list: ["hmac-md5-96", "hmac-sha-1-96"],
ipsec_ealg_list: ["null", "aes-cbc", "des-cbc", "des-ede3-cbc"],
......
/* ltemme configuration file for ims
* version 2021-09-18
* Copyright (C) 2015-2021 Amarisoft
*/
{
/* Log filter: syntax: layer.field=value[,...]
Possible layers are nas, ip, s1ap, gtpu and all. The 'all' layer
is used to address all the layers at the same time.
field values:
- 'level': the log level of each layer can be set to 'none',
'error', 'info' or 'debug'. Use 'debug' to log all the messages.
- 'max_size': set the maximum size of the hex dump. 0 means no
hex dump. -1 means no limit.
*/
log_options: "all.level=debug,all.max_size=32",
log_options: "all.level=debug,all.max_size=32,file.rotate=1G,file.path={{ directory['tmp'] }}",
log_filename: "{{ directory['log'] }}/mme.log",
/* bind address for GTP-U. Normally = address of the PC, here bound
on local interface to be able to run ltemme on the same PC as
lteenb. By default, the S1AP SCTP connection is bound on the same
address. */
{% if slapparameter_dict.get('external_enb_gnb', '') %}
gtp_addr: "{{ gtp_addr }}",
{% else %}
......@@ -33,20 +12,11 @@
mme_group_id: 32769,
mme_code: 1,
ims_vops_eps: true, /* IMS supported */
ims_vops_5gs_3gpp: true, /* IMS supported */
ims_vops_5gs_n3gpp: true, /* IMS supported */
//emc_bs: true, /* emergency calls supported */
//emc: 3, /* NR/E-UTRA connected to 5GCN emergency calls supported */
//emc_n3gpp: true, /* non-3GPP emergency calls supported */
ims_vops_eps: true,
ims_vops_5gs_3gpp: true,
ims_vops_5gs_n3gpp: true,
emergency_number_list: [
/* Category bits: (Table 10.5.135d/3GPP TS 24.008)
Bit 1 Police
Bit 2 Ambulance
Bit 3 Fire Brigade
Bit 4 Marine Guard
Bit 5 Mountain Rescue
*/
{ category: 0x1f, digits: "911" },
{ category: 0x1f, digits: "112" },
],
......@@ -55,21 +25,16 @@
qci: {audio: 1, video: 2},
},
/* network name and network short name sent in the EMM information
message to the UE */
network_name: "{{ slap_configuration['configuration.network_name'] }}",
network_short_name: "{{ slap_configuration['configuration.network_name'] }}",
/* Control Plane Cellular IoT EPS optimization support */
cp_ciot_opt: true,
/* DCNR support */
nr_support: true,
eps_5gs_interworking: "with_n26",
/* 15 bearers support */
fifteen_bearers: false,
ims_list: [
......@@ -78,31 +43,7 @@
bind_addr: "{{ slap_configuration['configuration.ims_bind'] }}"
}
],
/* AMF slices configuration */
/*nssai: [
{
sst: 1,
},
{
sst: 2,
},
{
sst: 3,
sd: 50,
}
],*/
/* ePDG configuration */
//epdg: {
// bind_addr: "127.0.1.100:500",
// esp_duration: 900,
// certificate: "epdg.pem",
// /* required for some buggy Mediatek phones */
// //omit_auth_in_first_auth_rsp: true
//},
/* Public Data Networks. The first one is the default. */
pdn_list: [
{
pdn_type: "ipv4",
......@@ -110,8 +51,8 @@
access_point_name: ["default", "internet", "ims", "sos"],
first_ip_addr: "{{ netaddr.IPAddress(netaddr.IPNetwork(slap_configuration['tun-ipv4-network']).first) + 2 }}",
last_ip_addr: "{{ netaddr.IPAddress(netaddr.IPNetwork(slap_configuration['tun-ipv4-network']).last) - 1 }}",
ip_addr_shift: 2, /* difference between allocated IP addresses is 4 */
dns_addr: "8.8.8.8", /* Google DNS address */
ip_addr_shift: 2,
dns_addr: "8.8.8.8",
// TODO: enable this instead of Google's DNS above
// dns_addr: "{{ slap_configuration['tun-ipv4-addr'] }}",
p_cscf_addr: ["{{ slap_configuration['tun-ipv4-addr'] }}"],
......@@ -127,34 +68,10 @@
},
],
/* Setup script for the network interface.
If no script is given, no network interface is created.
Script is called for each PDN with following parameters:
1) Interface name
2) PDN index
3) Access Point Name
4) IP version: 'ipv4' or 'ipv6'
5) IP address: first IP address for ipv4 and link local address for IPv6
6) First IP address
7) Last IP address
SlapOS: We suplement the script by preparing the TUN interface in slapos format phase.
Gotcha: The script has to be presented
*/
tun_setup_script: "{{ ifup_empty }}",
/* If true, inter-UE routing is done inside the MME (hence no IP
packet is output to the virtual network interface in case of
inter-UE communication). Otherwise, it is done by the Linux IP
layer. */
ue_to_ue_forwarding: false,
/* NAS ciphering algorithm preference. EEA0 is always the last. */
nas_cipher_algo_pref: [ ],
/* NAS integrity algorithm preference. EIA0 is always the last. */
nas_integ_algo_pref: [ 2, 1 ],
include "{{ slap_configuration['ue_db_path'] }}",
/* persistent user database */
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 {
referenceSignalPower -8, /* patched by eNB */
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
}
}
}
}
}
}
{%- set filtered_slave_instance_list = [] %}
{%- for slave_instance in slave_instance_list %}
{%- if slave_instance.get('imsi', '') != '' %}
{%- do filtered_slave_instance_list.append(slave_instance) %}
{%- 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_instance in enumerate(filtered_slave_instance_list) %}
{%- for i, slave in enumerate(filtered_slave_instance_list) %}
{%- if i == 0 -%}
{
{%- else -%}
, {
{%- endif %}
sim_algo: "{{ slave_instance.get('sim_algo', 'milenage') }}",
imsi: "{{ slave_instance.get('imsi', '') }}",
opc: "{{ slave_instance.get('opc', '') }}",
amf: {{ slave_instance.get('amf', '0x9001') }},
sqn: "{{ slave_instance.get('sqn', '000000000000') }}",
K: "{{ slave_instance.get('k', '') }}",
impu: "{{ slave_instance.get('impu', '') }}",
impi: "{{ slave_instance.get('impi', '') }}",
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 -%}
]
......
{
"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": ""
}
}
}
......@@ -2,7 +2,7 @@
parts =
directory
lte-enb-request
lte-epc-request
lte-mme-request
publish-connection-information
extends = {{ monitor_template }}
......@@ -45,16 +45,17 @@ cert-file = {{ slap_connection['cert-file'] }}
sla-computer_guid = {{ slap_connection['computer-id'] }}
config-monitor-password = ${monitor-htpasswd:passwd}
return = monitor-base-url
[lte-epc-request]
[lte-mme-request]
<= request-common-base
name = EPC
software-type = epc
config-name = epc
name = MME
software-type = mme
config-name = mme
{%- for key, value in slapparameter_dict.iteritems() %}
config-{{ key }} = {{ dumps(value) }}
{% endfor -%}
config-slave-list = {{ dumps(slave_instance_list) }}
return = monitor-base-url epc-ip
[lte-enb-request]
<= request-common-base
......@@ -64,11 +65,13 @@ config-name = enb
{%- for key, value in slapparameter_dict.iteritems() %}
config-{{ key }} = {{ dumps(value) }}
{% endfor -%}
return = monitor-base-url
[monitor-base-url-dict]
lte-epc-request = ${lte-epc-request:connection-monitor-base-url}
lte-mme-request = ${lte-mme-request:connection-monitor-base-url}
lte-enb-request = ${lte-enb-request:connection-monitor-base-url}
[publish-connection-information]
recipe = slapos.cookbook:publish.serialised
<= monitor-publish
epc-ip = ${lte-mme-request:connection-epc-ip}
......@@ -41,12 +41,6 @@
"type": "number",
"default": {{ default_lte_n_rb_dl }}
},
"mme_addr": {
"title": "MME Address",
"description": "IPv4 of the core network",
"type": "string",
"default": "127.0.0.100"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
......
......@@ -106,6 +106,7 @@ context =
section slap_configuration slap-configuration
key slapparameter_dict slap-configuration:configuration
key gtp_addr slap-configuration:ipv6-random
raw sib23 {{ sib23 }}
import netaddr netaddr
[lte-enb-config]
......
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "EPC SIM Card Parameters",
"title": "SIM Card Parameters",
"required": [
"sim_algo",
"imsi",
......
[buildout]
parts =
directory
ltelogs
lte-mme-config
lte-mme-service
tun-up-promise
monitor-base
lte-mme-request
publish-connection-information
extends = {{ monitor_template }}
......@@ -22,19 +18,6 @@ url = {{ slap_connection['server-url'] }}
key = {{ slap_connection['key-file'] }}
cert = {{ slap_connection['cert-file'] }}
configuration.network_name = RAPIDSPACE
configuration.domain = rapid.space
configuration.log_size = 50M
configuration.mme_ws_port = 9000
configuration.enb_ws_port = 9002
configuration.ims_ws_port = 9003
configuration.mme_addr = 127.0.1.100
configuration.ims_addr = 127.0.0.1
configuration.ims_bind = 127.0.0.2
configuration.enb_addr = 127.0.1.1
ue_db_path = {{ ue_db_path }}
[directory]
recipe = slapos.cookbook:mkdirectory
software = {{ buildout_directory }}
......@@ -49,110 +32,34 @@ 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("mme_config_link", None) %}
[mme-config-dl]
recipe = slapos.recipe.build:download
url = {{ slapparameter_dict.get("mme_config_link") }}
version = {{ slapparameter_dict.get("mme_config_version") }}
offline = false
{% endif %}
### IMS
[lte-ims-service]
recipe = slapos.cookbook:wrapper
init = ${ltelogs:output} ${directory:log}/ims.log; sleep 1
command-line = {{ mme }}/lteims ${directory:etc}/ims.cfg
wrapper-path = ${directory:service}/lte-ims
mode = 0775
pidfile = ${directory:run}/ims.pid
hash-files =
${lte-ims-config:output}
{{ ue_db_path }}
environment = AMARISOFT_PATH=/opt/amarisoft/.amarisoft
[lte-mme-sh-wrapper]
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
inline =
#!/bin/sh
rm -f ${directory:var}/lte_ue.db;
{{ mme }}/ltemme ${directory:etc}/mme.cfg >> ${directory:log}/mme-output.log 2>> ${directory:log}/mme-output.log
### MME
[lte-mme-service]
recipe = slapos.cookbook:wrapper
# When the machine shutdowns abruptly, lte_ue is not cleaned up which causes
# amarisoft ltemme to fail. TODO: find a cleaner way to handle this
init = ${ltelogs:output} ${directory:log}/mme.log
command-line = ${lte-mme-sh-wrapper:output}
wrapper-path = ${directory:service}/lte-mme
mode = 0775
pidfile = ${directory:run}/mme.pid
hash-files =
${lte-mme-config:output}
{{ ue_db_path }}
${lte-mme-sh-wrapper:output}
environment =
LD_LIBRARY_PATH={{ openssl_location }}/lib:{{ nghttp2_location }}/lib
AMARISOFT_PATH=/opt/amarisoft/.amarisoft
### EMPTY mme-ifup script
[lte-mme-ifup-empty]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:bin}/mme-ifup-empty
command-line = echo Using interface
mode = 775
[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 slap-configuration:ipv6-random
import netaddr netaddr
key ifup_empty lte-mme-ifup-empty:wrapper-path
[lte-ims-config]
<= config-base
url = {{ ims_template }}
output = ${directory:etc}/ims.cfg
[lte-mme-config]
<= config-base
{% if slapparameter_dict.get("mme_config_link", None) %}
url = ${mme-config-dl:target}
{% else %}
url = {{ mme_template }}
{% endif %}
output = ${directory:etc}/mme.cfg
[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 %}
[request-common-base]
recipe = slapos.cookbook:request.serialised
software-url = {{ slap_connection['software-release-url'] }}
server-url = {{ slap_connection['server-url'] }}
computer-id = {{ slap_connection['computer-id'] }}
partition-id = {{ slap_connection['partition-id'] }}
key-file = {{ slap_connection['key-file'] }}
cert-file = {{ slap_connection['cert-file'] }}
sla-computer_guid = {{ slap_connection['computer-id'] }}
config-monitor-password = ${monitor-htpasswd:passwd}
return = monitor-base-url epc-ip
[lte-mme-request]
<= request-common-base
name = MME
software-type = mme
config-name = mme
{%- for key, value in slapparameter_dict.iteritems() %}
config-{{ key }} = {{ dumps(value) }}
{% endfor -%}
config-slave-list = {{ dumps(slave_instance_list) }}
[monitor-base-url-dict]
lte-mme-request = ${lte-mme-request:connection-monitor-base-url}
[publish-connection-information]
<= monitor-publish
recipe = slapos.cookbook:publish.serialised
epc-ip = ${slap-configuration:ipv6-random}
# Add custom promise to check if /dev/sdr0 is busy
[tun-up-promise]
recipe = slapos.cookbook:promise.plugin
eggs = slapos.core
file = {{ interface_up_promise }}
output = ${directory:plugins}/check-tun-up.py
config-ifname = ${slap-configuration:tun-name}
<= monitor-publish
epc-ip = ${lte-mme-request:connection-epc-ip}
{
"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": ""
}
}
}
......@@ -2,7 +2,7 @@
parts =
directory
lte-gnb-request
lte-epc-request
lte-mme-request
publish-connection-information
extends = {{ monitor_template }}
......@@ -45,16 +45,17 @@ cert-file = {{ slap_connection['cert-file'] }}
sla-computer_guid = {{ slap_connection['computer-id'] }}
config-monitor-password = ${monitor-htpasswd:passwd}
return = monitor-base-url
[lte-epc-request]
[lte-mme-request]
<= request-common-base
name = EPC
software-type = epc
config-name = epc
name = MME
software-type = mme
config-name = mme
{%- for key, value in slapparameter_dict.iteritems() %}
config-{{ key }} = {{ dumps(value) }}
{% endfor -%}
config-slave-list = {{ dumps(slave_instance_list) }}
return = monitor-base-url epc-ip
[lte-gnb-request]
<= request-common-base
......@@ -64,11 +65,13 @@ config-name = gnb
{%- for key, value in slapparameter_dict.iteritems() %}
config-{{ key }} = {{ dumps(value) }}
{% endfor -%}
return = monitor-base-url
[monitor-base-url-dict]
lte-epc-request = ${lte-epc-request:connection-monitor-base-url}
lte-mme-request = ${lte-mme-request:connection-monitor-base-url}
lte-gnb-request = ${lte-gnb-request:connection-monitor-base-url}
[publish-connection-information]
recipe = slapos.cookbook:publish.serialised
<= monitor-publish
epc-ip = ${lte-mme-request:connection-epc-ip}
[buildout]
parts =
directory
ltelogs
lte-mme-config
lte-mme-service
tun-up-promise
monitor-base
publish-connection-information
extends = {{ monitor_template }}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[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.network_name = RAPIDSPACE
configuration.domain = rapid.space
configuration.log_size = 50M
configuration.mme_ws_port = 9000
configuration.enb_ws_port = 9002
configuration.ims_ws_port = 9003
configuration.mme_addr = 127.0.1.100
configuration.ims_addr = 127.0.0.1
configuration.ims_bind = 127.0.0.2
configuration.enb_addr = 127.0.1.1
ue_db_path = {{ ue_db_path }}
[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("mme_config_link", None) %}
[mme-config-dl]
recipe = slapos.recipe.build:download
url = {{ slapparameter_dict.get("mme_config_link") }}
version = {{ slapparameter_dict.get("mme_config_version") }}
offline = false
{% endif %}
### IMS
[lte-ims-service]
recipe = slapos.cookbook:wrapper
init = ${ltelogs:output} ${directory:log}/ims.log; sleep 1
command-line = {{ mme }}/lteims ${directory:etc}/ims.cfg
wrapper-path = ${directory:service}/lte-ims
mode = 0775
pidfile = ${directory:run}/ims.pid
hash-files =
${lte-ims-config:output}
{{ ue_db_path }}
environment = AMARISOFT_PATH=/opt/amarisoft/.amarisoft
[lte-mme-sh-wrapper]
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
inline =
#!/bin/sh
rm -f ${directory:var}/lte_ue.db;
{{ mme }}/ltemme ${directory:etc}/mme.cfg >> ${directory:log}/mme-output.log 2>> ${directory:log}/mme-output.log
### MME
[lte-mme-service]
recipe = slapos.cookbook:wrapper
# When the machine shutdowns abruptly, lte_ue is not cleaned up which causes
# amarisoft ltemme to fail. TODO: find a cleaner way to handle this
init = ${ltelogs:output} ${directory:log}/mme.log
command-line = ${lte-mme-sh-wrapper:output}
wrapper-path = ${directory:service}/lte-mme
mode = 0775
pidfile = ${directory:run}/mme.pid
hash-files =
${lte-mme-config:output}
{{ ue_db_path }}
${lte-mme-sh-wrapper:output}
environment =
LD_LIBRARY_PATH={{ openssl_location }}/lib:{{ nghttp2_location }}/lib
AMARISOFT_PATH=/opt/amarisoft/.amarisoft
### EMPTY mme-ifup script
[lte-mme-ifup-empty]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:bin}/mme-ifup-empty
command-line = echo Using interface
mode = 775
[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 slap-configuration:ipv6-random
import netaddr netaddr
key ifup_empty lte-mme-ifup-empty:wrapper-path
[lte-ims-config]
<= config-base
url = {{ ims_template }}
output = ${directory:etc}/ims.cfg
[lte-mme-config]
<= config-base
{% if slapparameter_dict.get("mme_config_link", None) %}
url = ${mme-config-dl:target}
{% else %}
url = {{ mme_template }}
{% endif %}
output = ${directory:etc}/mme.cfg
[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 %}
[publish-connection-information]
<= monitor-publish
recipe = slapos.cookbook:publish.serialised
epc-ip = ${slap-configuration:ipv6-random}
# Add custom promise to check if /dev/sdr0 is busy
[tun-up-promise]
recipe = slapos.cookbook:promise.plugin
eggs = slapos.core
file = {{ interface_up_promise }}
output = ${directory:plugins}/check-tun-up.py
config-ifname = ${slap-configuration:tun-name}
......@@ -39,12 +39,6 @@
"type": "number",
"default": 100
},
"mme_addr": {
"title": "MME Address",
"description": "IPv4 of the core network",
"type": "string",
"default": "127.0.0.100"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
......
......@@ -27,12 +27,6 @@
"type": "number",
"default": 100
},
"mme_addr": {
"title": "MME Address",
"description": "IPv4 of the core network",
"type": "string",
"default": "127.0.0.100"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
......
......@@ -39,12 +39,6 @@
"type": "number",
"default": 100
},
"mme_addr": {
"title": "MME Address",
"description": "IPv4 of the core network",
"type": "string",
"default": "127.0.0.100"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
......
......@@ -27,12 +27,6 @@
"type": "number",
"default": 100
},
"mme_addr": {
"title": "MME Address",
"description": "IPv4 of the core network",
"type": "string",
"default": "127.0.0.100"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
......
......@@ -39,12 +39,6 @@
"type": "number",
"default": 100
},
"mme_addr": {
"title": "MME Address",
"description": "IPv4 of the core network",
"type": "string",
"default": "127.0.0.100"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
......
......@@ -27,12 +27,6 @@
"type": "number",
"default": 100
},
"mme_addr": {
"title": "MME Address",
"description": "IPv4 of the core network",
"type": "string",
"default": "127.0.0.100"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
......
......@@ -39,12 +39,6 @@
"type": "number",
"default": 100
},
"mme_addr": {
"title": "MME Address",
"description": "IPv4 of the core network",
"type": "string",
"default": "127.0.0.100"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
......
......@@ -27,12 +27,6 @@
"type": "number",
"default": 100
},
"mme_addr": {
"title": "MME Address",
"description": "IPv4 of the core network",
"type": "string",
"default": "127.0.0.100"
},
"mme_list": {
"title": "MME list",
"description": "Optionnal. List of MME to which the gNodeB is connected",
......
......@@ -27,13 +27,26 @@ context =
key slapparameter_dict slap-configuration:configuration
$${:extra-context}
[amarisoft]
recipe = slapos.recipe.build
init =
import os
lte_version = "2021-09-18"
path = "/opt/amarisoft/v" + lte_version
options['lte-version'] = lte_version
options['path'] = path
options['enb'] = path + "/enb"
options['mme'] = path + "/mme"
options['ims'] = path + "/ims"
[switch-softwaretype]
recipe = slapos.cookbook:switch-softwaretype
enb-epc = dynamic-template-lte-enb-epc:output
gnb-epc = dynamic-template-lte-gnb-epc:output
epc = dynamic-template-lte-epc:output
enb = dynamic-template-lte-enb:output
gnb = dynamic-template-lte-gnb:output
epc = dynamic-template-lte-epc:output
mme = dynamic-template-lte-mme:output
RootSoftwareInstance = $${:enb-epc}
[dynamic-template-lte-enb-epc]
......@@ -43,6 +56,7 @@ filename = instance-lte-enb-epc.cfg
extensions = jinja2.ext.do
extra-context =
raw monitor_template ${monitor2-template:output}
key slave_instance_list slap-configuration:slave-instance-list
[dynamic-template-lte-gnb-epc]
< = jinja2-template-base
......@@ -51,6 +65,16 @@ filename = instance-lte-gnb-epc.cfg
extensions = jinja2.ext.do
extra-context =
raw monitor_template ${monitor2-template:output}
key slave_instance_list slap-configuration:slave-instance-list
[dynamic-template-lte-epc]
< = jinja2-template-base
url = ${template-lte-epc:target}
filename = instance-lte-epc.cfg
extensions = jinja2.ext.do
extra-context =
raw monitor_template ${monitor2-template:output}
key slave_instance_list slap-configuration:slave-instance-list
[dynamic-template-lte-enb]
< = jinja2-template-base
......@@ -59,8 +83,9 @@ filename = instance-lte-enb.cfg
extensions = jinja2.ext.do
extra-context =
raw monitor_template ${monitor2-template:output}
raw enb ${enb:destination}
key enb amarisoft:enb
raw enb_template ${enb.jinja2.cfg:target}
raw sib23 ${sib23.asn:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
raw openssl_location ${openssl:location}
......@@ -80,7 +105,7 @@ filename = instance-lte-gnb.cfg
extensions = jinja2.ext.do
extra-context =
raw monitor_template ${monitor2-template:output}
raw enb ${enb:destination}
key enb amarisoft:enb
raw gnb_template ${gnb.jinja2.cfg:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
......@@ -95,15 +120,15 @@ extra-context =
raw min_frequency ${enb:min-frequency}
raw max_frequency ${enb:max-frequency}
[dynamic-template-lte-epc]
[dynamic-template-lte-mme]
< = jinja2-template-base
url = ${template-lte-epc:target}
filename = instance-lte-epc.cfg
url = ${template-lte-mme:target}
filename = instance-lte-mme.cfg
extensions = jinja2.ext.do
extra-context =
raw monitor_template ${monitor2-template:output}
raw interface_up_promise ${interface-up-promise:target}
raw mme ${mme:destination}
key mme amarisoft:mme
raw mme_template ${mme.jinja2.cfg:target}
raw ims_template ${ims.jinja2.cfg:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target}
......@@ -118,4 +143,5 @@ filename = ue_db.cfg
extensions = jinja2.ext.do
output = $${buildout:directory}/$${:filename}
context =
key slave_instance_list slap-configuration:slave-instance-list
import json_module json
key slave_instance_list slap-configuration:configuration.slave-list
......@@ -43,14 +43,32 @@
"response": "instance-epc-schema.json",
"index": 4
},
"gnb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "gnb-epc",
"request": "instance-gnb-epc-slave-input-schema.json",
"response": "instance-gnb-epc-slave-schema.json",
"shared": true,
"index": 5
},
"enb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "enb-epc",
"request": "instance-enb-epc-slave-input-schema.json",
"response": "instance-enb-epc-slave-schema.json",
"shared": true,
"index": 6
},
"epc-slave": {
"title": "Sim Card",
"description": "EPC Configuration",
"description": "Sim Card Configuration",
"software-type": "epc",
"request": "instance-epc-slave-input-schema.json",
"response": "instance-epc-slave-schema.json",
"shared": true,
"index": 5
"index": 7
}
}
}
}
\ No newline at end of file
......@@ -43,14 +43,32 @@
"response": "instance-epc-schema.json",
"index": 4
},
"gnb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "gnb-epc",
"request": "instance-gnb-epc-slave-input-schema.json",
"response": "instance-gnb-epc-slave-schema.json",
"shared": true,
"index": 5
},
"enb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "enb-epc",
"request": "instance-enb-epc-slave-input-schema.json",
"response": "instance-enb-epc-slave-schema.json",
"shared": true,
"index": 6
},
"epc-slave": {
"title": "Sim Card",
"description": "EPC Configuration",
"description": "Sim Card Configuration",
"software-type": "epc",
"request": "instance-epc-slave-input-schema.json",
"response": "instance-epc-slave-schema.json",
"shared": true,
"index": 5
"index": 7
}
}
}
}
\ No newline at end of file
......@@ -43,14 +43,32 @@
"response": "instance-epc-schema.json",
"index": 4
},
"gnb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "gnb-epc",
"request": "instance-gnb-epc-slave-input-schema.json",
"response": "instance-gnb-epc-slave-schema.json",
"shared": true,
"index": 5
},
"enb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "enb-epc",
"request": "instance-enb-epc-slave-input-schema.json",
"response": "instance-enb-epc-slave-schema.json",
"shared": true,
"index": 6
},
"epc-slave": {
"title": "Sim Card",
"description": "EPC Configuration",
"description": "Sim Card Configuration",
"software-type": "epc",
"request": "instance-epc-slave-input-schema.json",
"response": "instance-epc-slave-schema.json",
"shared": true,
"index": 5
"index": 7
}
}
}
}
\ No newline at end of file
......@@ -43,14 +43,32 @@
"response": "instance-epc-schema.json",
"index": 4
},
"gnb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "gnb-epc",
"request": "instance-gnb-epc-slave-input-schema.json",
"response": "instance-gnb-epc-slave-schema.json",
"shared": true,
"index": 5
},
"enb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "enb-epc",
"request": "instance-enb-epc-slave-input-schema.json",
"response": "instance-enb-epc-slave-schema.json",
"shared": true,
"index": 6
},
"epc-slave": {
"title": "Sim Card",
"description": "EPC Configuration",
"description": "Sim Card Configuration",
"software-type": "epc",
"request": "instance-epc-slave-input-schema.json",
"response": "instance-epc-slave-schema.json",
"shared": true,
"index": 5
"index": 7
}
}
}
}
\ No newline at end of file
......@@ -16,10 +16,7 @@ parts +=
enb.jinja2.cfg
gnb.jinja2.cfg
ue_db.jinja2.cfg
# sdr driver is dependent on ENB thus should be added explicitely by software.cfg
sdr-driver
lteenb-cap-sys-nice
lteenb-avx2-cap-sys-nice
sib23.asn
# unimplemented parts - the http monitor and better log handling using logrotate
# apache-php
# logrotate
......@@ -39,13 +36,16 @@ url = ${:_profile_base_location_}/${:_update_hash_filename_}
[template-lte-gnb-epc]
<= download-base
[template-lte-epc]
<= download-base
[template-lte-enb]
<= download-base
[template-lte-gnb]
<= download-base
[template-lte-epc]
[template-lte-mme]
<= download-base
[sdr-busy-promise]
......@@ -54,13 +54,6 @@ url = ${:_profile_base_location_}/${:_update_hash_filename_}
[interface-up-promise]
<= download-base
[amarisoft]
recipe = slapos.recipe.build
path = /opt/amarisoft/lte
init =
import os
options['lte-version'] = os.readlink(options["path"])[:-1]
[copy-to-instance]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_buildout_section_name_}
......@@ -69,15 +62,12 @@ url = ${:_profile_base_location_}/${:_buildout_section_name_}
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/config/${:_buildout_section_name_}
[unpack-to-instance]
recipe = slapos.recipe.build:download-unpacked
url = ${amarisoft:path}/lte${:_buildout_section_name_}-linux-${amarisoft:lte-version}.tar.gz
destination = ${buildout:directory}/${:_buildout_section_name_}
strip-top-level-dir = true
[enb.jinja2.cfg]
<= copy-config-to-instance
filename = enb.jinja2.cfg
[sib23.asn]
<= copy-config-to-instance
filename = sib23.asn
[gnb.jinja2.cfg]
<= copy-config-to-instance
filename = gnb.jinja2.cfg
......@@ -93,55 +83,3 @@ filename = mme.jinja2.cfg
[ims.jinja2.cfg]
<= copy-config-to-instance
filename = ims.jinja2.cfg
[sdr]
<= unpack-to-instance
url = ${amarisoft:path}/trx_${:_buildout_section_name_}-linux-${amarisoft:lte-version}.tar.gz
destination = ${enb:destination}/x86_64
md5sum = ${trx_sdr-linux:md5sum}
[sdr-driver]
# move trx_sdr.so next to lteenb binary
recipe = plone.recipe.command
command = cp -p ${sdr:destination}/trx_sdr.so ${enb:destination}
[enb]
<= unpack-to-instance
md5sum = ${lteenb-linux:md5sum}
[mme]
<= unpack-to-instance
md5sum = ${ltemme-linux:md5sum}
[lteenb-linux]
filename = ${amarisoft:lte-version}/lteenb-linux-${amarisoft:lte-version}.tar.gz
md5sum = 842b1526073472a30cb0b286d3b1528c
[ltemme-linux]
filename = ${amarisoft:lte-version}/ltemme-linux-${amarisoft:lte-version}.tar.gz
md5sum = 9d7917f90c7c7b2a8ba624d874595351
[ltewww-linux]
filename = ${amarisoft:lte-version}/ltewww-linux-${amarisoft:lte-version}.tar.gz
md5sum = 416b6167f70b12910fbbb9293038554c
[trx_sdr-linux]
filename = ${amarisoft:lte-version}/trx_sdr-linux-${amarisoft:lte-version}.tar.gz
md5sum = e6960e3460f1a32c2436f36b2082995d
[base-lteenb-cap-sys-nice]
recipe = plone.recipe.command
command =
getcap ${amarisoft:path}/${:binary} | grep cap_sys_nice+ep && exit 0;
# Make a copy or restore the copy, as patchelf will irreversibly change the md5sum
stat ${enb:destination}/${:binary}-unpriviledged ||
cp ${enb:destination}/${:binary} ${enb:destination}/${:binary}-unpriviledged &&
cp ${enb:destination}/${:binary}-unpriviledged ${enb:destination}/${:binary}
# ORS are pre-configured to have sudo allow slapsoft to run give-cap-sys-nice-lteenb script
# with root permissions
sudo -n ${amarisoft:path}/../give-cap-sys-nice-lteenb ${enb:destination}/${:binary} || true;
update-command = ${:command}
[lteenb-avx2-cap-sys-nice]
<= base-lteenb-cap-sys-nice
binary=lteenb
[lteenb-cap-sys-nice]
<= base-lteenb-cap-sys-nice
binary=lteenb-avx2
......@@ -43,14 +43,32 @@
"response": "instance-epc-schema.json",
"index": 4
},
"gnb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "gnb-epc",
"request": "instance-gnb-epc-slave-input-schema.json",
"response": "instance-gnb-epc-slave-schema.json",
"shared": true,
"index": 5
},
"enb-epc-slave": {
"title": "Sim Card",
"description": "Sim Card Configuration",
"software-type": "enb-epc",
"request": "instance-enb-epc-slave-input-schema.json",
"response": "instance-enb-epc-slave-schema.json",
"shared": true,
"index": 6
},
"epc-slave": {
"title": "Sim Card",
"description": "EPC Configuration",
"description": "Sim Card Configuration",
"software-type": "epc",
"request": "instance-epc-slave-input-schema.json",
"response": "instance-epc-slave-schema.json",
"shared": true,
"index": 5
"index": 7
}
}
}
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