Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Łukasz Nowak
slapos
Commits
8752dd76
Commit
8752dd76
authored
Jul 05, 2022
by
Joanne Hugé
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ors-amarisoft: remove binaries from SR
parent
e3829420
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1089 additions
and
507 deletions
+1089
-507
software/ors-amarisoft/buildout.hash.cfg
software/ors-amarisoft/buildout.hash.cfg
+5
-5
software/ors-amarisoft/config/enb.jinja2.cfg
software/ors-amarisoft/config/enb.jinja2.cfg
+540
-121
software/ors-amarisoft/config/gnb.jinja2.cfg
software/ors-amarisoft/config/gnb.jinja2.cfg
+509
-178
software/ors-amarisoft/config/ims.jinja2.cfg
software/ors-amarisoft/config/ims.jinja2.cfg
+7
-35
software/ors-amarisoft/config/mme.jinja2.cfg
software/ors-amarisoft/config/mme.jinja2.cfg
+13
-96
software/ors-amarisoft/instance.cfg
software/ors-amarisoft/instance.cfg
+15
-3
software/ors-amarisoft/software.cfg
software/ors-amarisoft/software.cfg
+0
-69
No files found.
software/ors-amarisoft/buildout.hash.cfg
View file @
8752dd76
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
[template]
[template]
filename = instance.cfg
filename = instance.cfg
md5sum =
9d5f4fc9ed3664140d33dd7c447dbd63
md5sum =
676e9d59bf7f6ce67dbf982abfa6a56e
[template-lte-enb-epc]
[template-lte-enb-epc]
_update_hash_filename_ = instance-enb-epc.jinja2.cfg
_update_hash_filename_ = instance-enb-epc.jinja2.cfg
...
@@ -44,11 +44,11 @@ md5sum = d33163012d6c98efc59161974c649557
...
@@ -44,11 +44,11 @@ md5sum = d33163012d6c98efc59161974c649557
[enb.jinja2.cfg]
[enb.jinja2.cfg]
filename = config/enb.jinja2.cfg
filename = config/enb.jinja2.cfg
md5sum =
b78082a9c5d6af79f11a1c79d6d25a86
md5sum =
04105bfaede4254c3f95637898a3361f
[gnb.jinja2.cfg]
[gnb.jinja2.cfg]
filename = config/gnb.jinja2.cfg
filename = config/gnb.jinja2.cfg
md5sum =
944e342d426d5a7c4c16bdcb01398ba3
md5sum =
c0d3d042960f5704dd2e3fa7714a4a5f
[ltelogs.jinja2.sh]
[ltelogs.jinja2.sh]
filename = ltelogs.jinja2.sh
filename = ltelogs.jinja2.sh
...
@@ -56,11 +56,11 @@ md5sum = 1ba2e065bdf14a6411e95e80db17dcfd
...
@@ -56,11 +56,11 @@ md5sum = 1ba2e065bdf14a6411e95e80db17dcfd
[mme.jinja2.cfg]
[mme.jinja2.cfg]
filename = config/mme.jinja2.cfg
filename = config/mme.jinja2.cfg
md5sum =
13ce0230f06e1089c10924b17f80e49b
md5sum =
fc073eb6450da95955009a127a333396
[ims.jinja2.cfg]
[ims.jinja2.cfg]
filename = config/ims.jinja2.cfg
filename = config/ims.jinja2.cfg
md5sum =
e561ec26a70943c61557def1781cf65f
md5sum =
36281b03597252cf75169417d02fc28c
[sdr-busy-promise]
[sdr-busy-promise]
_update_hash_filename_ = promise/check_sdr_busy.py
_update_hash_filename_ = promise/check_sdr_busy.py
...
...
software/ors-amarisoft/config/enb.jinja2.cfg
View file @
8752dd76
This diff is collapsed.
Click to expand it.
software/ors-amarisoft/config/gnb.jinja2.cfg
View file @
8752dd76
This diff is collapsed.
Click to expand it.
software/ors-amarisoft/config/ims.jinja2.cfg
View file @
8752dd76
/* lteims configuration file
* version 2021-09-18
* Copyright (C) 2015-2021 Amarisoft
*/
{
{
log_options: "all.level=debug,all.max_size=32",
log_options: "all.level=debug,all.max_size=32",
log_filename: "{{ directory['log'] }}/ims.log",
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: [
sip_addr: [
{addr: "{{ slap_configuration['tun-ipv4-addr'] }}", bind_addr: "0.0.0.0", port_min: 10000, port_max: 20000},
{addr: "{{ slap_configuration['tun-ipv4-addr'] }}", bind_addr: "0.0.0.0", port_min: 10000, port_max: 20000},
{#" slap_configuration['tun-ipv6-addr'] ",#}
{#" slap_configuration['tun-ipv6-addr'] ",#}
],
],
mms_server_bind_addr: "{{ netaddr.IPAddress(netaddr.IPNetwork(slap_configuration['tun-ipv4-network']).first) + 1 }}:1111",
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'] }}",
sctp_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
/* Cx connection */
cx_server_addr: "127.0.1.100",
cx_server_addr: "127.0.1.100",
cx_bind_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
cx_bind_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
/* Rx connection */
rx_server_addr: "127.0.1.100",
rx_server_addr: "127.0.1.100",
rx_bind_addr: "{{ slap_configuration['configuration.ims_addr'] }}",
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'] }}",
domain: "{{ slap_configuration['configuration.domain'] }}",
include "{{ slap_configuration['ue_db_path'] }}",
include "{{ slap_configuration['ue_db_path'] }}",
...
@@ -48,27 +30,17 @@
...
@@ -48,27 +30,17 @@
{# origin_host: "", #}
{# origin_host: "", #}
{# }, #}
{# }, #}
/* Echo phone number */
echo: [
echo: [
"tel:666",
"tel:666",
"tel:+666",
"tel:+666",
{impu: "tel:404", code: 404},
/* 404 test */
{impu: "tel:404", code: 404},
{impu: "urn:service:sos", anonymous: true, authentication: false},
/* Emergency call */
{impu: "urn:service:sos", anonymous: true, authentication: false},
{impu: "urn:service:sos.police", anonymous: true, authentication: false},
/* Emergency call */
{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",
precondition: "on",
"100rel": true,
"100rel": true,
/* IPsec */
ipsec_aalg_list: ["hmac-md5-96", "hmac-sha-1-96"],
ipsec_aalg_list: ["hmac-md5-96", "hmac-sha-1-96"],
ipsec_ealg_list: ["null", "aes-cbc", "des-cbc", "des-ede3-cbc"],
ipsec_ealg_list: ["null", "aes-cbc", "des-cbc", "des-ede3-cbc"],
...
...
software/ors-amarisoft/config/mme.jinja2.cfg
View file @
8752dd76
/* ltemme configuration file for ims
* version 2021-09-18
* Copyright (C) 2015-2021 Amarisoft
*/
{
{
/* Log filter: syntax: layer.field=value[,...]
log_options: "all.level=debug,all.max_size=32,file.rotate=1G,file.path={{ directory['tmp'] }}",
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_filename: "{{ directory['log'] }}/mme.log",
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', '') %}
{% if slapparameter_dict.get('external_enb_gnb', '') %}
gtp_addr: "{{ gtp_addr }}",
gtp_addr: "{{ gtp_addr }}",
{% else %}
{% else %}
...
@@ -33,20 +12,11 @@
...
@@ -33,20 +12,11 @@
mme_group_id: 32769,
mme_group_id: 32769,
mme_code: 1,
mme_code: 1,
ims_vops_eps: true, /* IMS supported */
ims_vops_eps: true,
ims_vops_5gs_3gpp: true, /* IMS supported */
ims_vops_5gs_3gpp: true,
ims_vops_5gs_n3gpp: true, /* IMS supported */
ims_vops_5gs_n3gpp: true,
//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 */
emergency_number_list: [
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: "911" },
{ category: 0x1f, digits: "112" },
{ category: 0x1f, digits: "112" },
],
],
...
@@ -55,21 +25,16 @@
...
@@ -55,21 +25,16 @@
qci: {audio: 1, video: 2},
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_name: "{{ slap_configuration['configuration.network_name'] }}",
network_short_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,
cp_ciot_opt: true,
/* DCNR support */
nr_support: true,
nr_support: true,
eps_5gs_interworking: "with_n26",
eps_5gs_interworking: "with_n26",
/* 15 bearers support */
fifteen_bearers: false,
fifteen_bearers: false,
ims_list: [
ims_list: [
...
@@ -78,31 +43,7 @@
...
@@ -78,31 +43,7 @@
bind_addr: "{{ slap_configuration['configuration.ims_bind'] }}"
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_list: [
{
{
pdn_type: "ipv4",
pdn_type: "ipv4",
...
@@ -110,8 +51,8 @@
...
@@ -110,8 +51,8 @@
access_point_name: ["default", "internet", "ims", "sos"],
access_point_name: ["default", "internet", "ims", "sos"],
first_ip_addr: "{{ netaddr.IPAddress(netaddr.IPNetwork(slap_configuration['tun-ipv4-network']).first) + 2 }}",
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 }}",
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 */
ip_addr_shift: 2,
dns_addr: "8.8.8.8",
/* Google DNS address */
dns_addr: "8.8.8.8",
// TODO: enable this instead of Google's DNS above
// TODO: enable this instead of Google's DNS above
// dns_addr: "{{ slap_configuration['tun-ipv4-addr'] }}",
// dns_addr: "{{ slap_configuration['tun-ipv4-addr'] }}",
p_cscf_addr: ["{{ slap_configuration['tun-ipv4-addr'] }}"],
p_cscf_addr: ["{{ slap_configuration['tun-ipv4-addr'] }}"],
...
@@ -127,34 +68,10 @@
...
@@ -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 }}",
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,
ue_to_ue_forwarding: false,
/* NAS ciphering algorithm preference. EEA0 is always the last. */
nas_cipher_algo_pref: [ ],
nas_cipher_algo_pref: [ ],
/* NAS integrity algorithm preference. EIA0 is always the last. */
nas_integ_algo_pref: [ 2, 1 ],
nas_integ_algo_pref: [ 2, 1 ],
include "{{ slap_configuration['ue_db_path'] }}",
include "{{ slap_configuration['ue_db_path'] }}",
/* persistent user database */
ue_db_filename: "{{ directory['var'] }}/lte_ue.db"
ue_db_filename: "{{ directory['var'] }}/lte_ue.db"
}
}
software/ors-amarisoft/instance.cfg
View file @
8752dd76
...
@@ -27,6 +27,18 @@ context =
...
@@ -27,6 +27,18 @@ context =
key slapparameter_dict slap-configuration:configuration
key slapparameter_dict slap-configuration:configuration
$${:extra-context}
$${: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]
[switch-softwaretype]
recipe = slapos.cookbook:switch-softwaretype
recipe = slapos.cookbook:switch-softwaretype
enb-epc = dynamic-template-lte-enb-epc:output
enb-epc = dynamic-template-lte-enb-epc:output
...
@@ -59,7 +71,7 @@ filename = instance-lte-enb.cfg
...
@@ -59,7 +71,7 @@ filename = instance-lte-enb.cfg
extensions = jinja2.ext.do
extensions = jinja2.ext.do
extra-context =
extra-context =
raw monitor_template ${monitor2-template:output}
raw monitor_template ${monitor2-template:output}
raw enb ${enb:destination}
key enb amarisoft:enb
raw enb_template ${enb.jinja2.cfg:target}
raw enb_template ${enb.jinja2.cfg:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
...
@@ -80,7 +92,7 @@ filename = instance-lte-gnb.cfg
...
@@ -80,7 +92,7 @@ filename = instance-lte-gnb.cfg
extensions = jinja2.ext.do
extensions = jinja2.ext.do
extra-context =
extra-context =
raw monitor_template ${monitor2-template:output}
raw monitor_template ${monitor2-template:output}
raw enb ${enb:destination}
key enb amarisoft:enb
raw gnb_template ${gnb.jinja2.cfg:target}
raw gnb_template ${gnb.jinja2.cfg:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
...
@@ -103,7 +115,7 @@ extensions = jinja2.ext.do
...
@@ -103,7 +115,7 @@ extensions = jinja2.ext.do
extra-context =
extra-context =
raw monitor_template ${monitor2-template:output}
raw monitor_template ${monitor2-template:output}
raw interface_up_promise ${interface-up-promise:target}
raw interface_up_promise ${interface-up-promise:target}
raw mme ${mme:destination}
key mme amarisoft:mme
raw mme_template ${mme.jinja2.cfg:target}
raw mme_template ${mme.jinja2.cfg:target}
raw ims_template ${ims.jinja2.cfg:target}
raw ims_template ${ims.jinja2.cfg:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target}
...
...
software/ors-amarisoft/software.cfg
View file @
8752dd76
...
@@ -16,10 +16,6 @@ parts +=
...
@@ -16,10 +16,6 @@ parts +=
enb.jinja2.cfg
enb.jinja2.cfg
gnb.jinja2.cfg
gnb.jinja2.cfg
ue_db.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
# unimplemented parts - the http monitor and better log handling using logrotate
# unimplemented parts - the http monitor and better log handling using logrotate
# apache-php
# apache-php
# logrotate
# logrotate
...
@@ -54,13 +50,6 @@ url = ${:_profile_base_location_}/${:_update_hash_filename_}
...
@@ -54,13 +50,6 @@ url = ${:_profile_base_location_}/${:_update_hash_filename_}
[interface-up-promise]
[interface-up-promise]
<= download-base
<= 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]
[copy-to-instance]
recipe = slapos.recipe.build:download
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_buildout_section_name_}
url = ${:_profile_base_location_}/${:_buildout_section_name_}
...
@@ -69,12 +58,6 @@ url = ${:_profile_base_location_}/${:_buildout_section_name_}
...
@@ -69,12 +58,6 @@ url = ${:_profile_base_location_}/${:_buildout_section_name_}
recipe = slapos.recipe.build:download
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/config/${:_buildout_section_name_}
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]
[enb.jinja2.cfg]
<= copy-config-to-instance
<= copy-config-to-instance
filename = enb.jinja2.cfg
filename = enb.jinja2.cfg
...
@@ -93,55 +76,3 @@ filename = mme.jinja2.cfg
...
@@ -93,55 +76,3 @@ filename = mme.jinja2.cfg
[ims.jinja2.cfg]
[ims.jinja2.cfg]
<= copy-config-to-instance
<= copy-config-to-instance
filename = ims.jinja2.cfg
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment