[buildout]
parts =
  switch-softwaretype

eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true

[directory]
recipe = slapos.cookbook:mkdirectory
software = ${buildout:directory}
home = $${buildout:directory}
etc = $${:home}/etc

[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}

[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
output = $${buildout:directory}/$${:filename}
extra-context =
context =
    import json_module json
    key eggs_directory buildout:eggs-directory
    key develop_eggs_directory buildout:develop-eggs-directory
    raw buildout_directory ${buildout:directory}
    section slap_connection slap-connection
    key slapparameter_dict slap-configuration:configuration
    key lan_ipv4 lan-ip:ipv4
    $${:extra-context}

[amarisoft]
recipe = slapos.recipe.build
init =
  import os, re
  try:
    lte_version = sorted(filter(lambda x: re.match(r"v[0-9]{4}-[0-9]{2}-[0-9]{2}", x), os.listdir('/opt/amarisoft')))[-1][1:]
  except FileNotFoundError:
    lte_version = 'LTEVERSION'
  path = "/opt/amarisoft/v" + lte_version
  options['lte-version'] = lte_version
  options['path'] = path
  options['sdr'] = path + "/trx_sdr"
  options['enb'] = path + "/enb"
  options['mme'] = path + "/mme"
  options['ims'] = path + "/ims"
  options['ue'] = path + "/ue"

[ors-version]
recipe = slapos.recipe.build
configuration = $${slap-configuration:configuration}
init =
  import subprocess
  range_map = {
    "B38": "2570MHz - 2620MHz",
    "B39": "1880MHz - 1920MHz",
    "B42": "3400MHz - 3600MHz",
    "B43": "3600MHz - 3800MHz",
    "Unknown": "Information not available for this band",
  }
  default_tx_gain_map = {
    "B38": (59, 65),
    "B39": (59, 64),
    "B42": (63, 62),
    "B43": (63, 62),
    "Unknown": (60, 62),
  }
  default_rx_gain_map = {
    "B38": (43, 43),
    "B39": (43, 43),
    "B42": (43, 43),
    "B43": (43, 43),
    "Unknown": (43, 43),
  }
  default_earfcn_map = {
    "B38": 38050,
    "B39": 38350,
    "B42": 42590,
    "B43": 44590,
    "Unknown": 0,
  }
  default_nr_arfcn_map = {
    "B38": 519000,
    "B39": 378000,
    "B42": 632628,
    "B43": 646666,
    "Unknown": 0,
  }
  default_nr_band_map = {
    "B38": 41,
    "B39": 39,
    "B42": 78,
    "B43": 78,
    "Unknown": 0,
  }
  power_map = {
    "B38": (
      lambda x: (-0.008712931375092506) * x**2 + (2.1973585140044642) * x + (-94.29420762479742),
      lambda x: (-0.004472751640641793) * x**2 + (1.6308290630103919) * x + (-81.84549245154561),
    ),
    "B39": (
      lambda x: (-0.008712931375092506) * x**2 + (2.1973585140044642) * x + (-94.29420762479742),
      lambda x: (-0.0022523817802900985) * x**2 + (1.2674016231310092) * x + (-66.57165215468584),
    ),
    "B42": (
      lambda x: (-0.014198126839751619) * x**2 + (2.980758813262773) * x + (-125.25800492285738),
      lambda x: (0.003977721774394756) * x**2 + (0.527208191717173) * x + (-42.761142655285376),
    ),
    "B43": (
      lambda x: (-0.014198126839751619) * x**2 + (2.980758813262773) * x + (-125.25800492285738),
      lambda x: (-0.0036530114002551943) * x**2 + (1.510856844601873) * x + (-74.58790185136355),
    ),
    "Unknown": (
      lambda x: "UNKNOWN",
      lambda x: "UNKNOWN",
    ),
  }
  def get_sdr_info(cmd):
    if options['configuration'].get('testing', False):
      return {'t': 'TDD', 'b': 'B39', 'v': '4.2', 's': 'B53'}[cmd].encode()
    return subprocess.check_output(
      ["sudo", "-n", "/opt/amarisoft/get-sdr-info", "-" + cmd]
    )
  options['version'] = float(get_sdr_info('v').decode())
  options['band'] = get_sdr_info('b').decode()
  options['tdd'] = get_sdr_info('t').decode()
  options['one-watt'] = bool(options['version'] >= 4)
  options['ors-version'] = "{} {} {}".format(
    options['tdd'], 
    options['band'],
    "2x1W" if options['one-watt'] else "2x0.5W",
  )
  default_tx_gain  = default_tx_gain_map [options['band']][int(options['one-watt'])]
  default_rx_gain  = default_rx_gain_map [options['band']][int(options['one-watt'])]
  default_earfcn   = default_earfcn_map  [options['band']]
  default_nr_arfcn = default_nr_arfcn_map[options['band']]
  default_nr_band  = default_nr_band_map [options['band']]
  options['range']            = range_map           [options['band']]
  options['current-tx-gain']  = options['configuration'].get('tx_gain'    , default_tx_gain )
  options['current-rx-gain']  = options['configuration'].get('rx_gain'    , default_rx_gain )
  options['current-earfcn']   = options['configuration'].get('dl_earfcn'  , default_earfcn  )
  options['current-nr-arfcn'] = options['configuration'].get('dl_nr_arfcn', default_nr_arfcn)
  options['current-nr-band']  = options['configuration'].get('nr_band'    , default_nr_band )
  power_estimate_dbm = power_map[options['band']][int(options['one-watt'])](float(options['current-tx-gain']))
  if power_estimate_dbm == "UNKNOWN":
    power_estimate = "Information not available for this band"
  else:
    power_estimate_mw = 10 ** ( power_estimate_dbm / 10 )
    if power_estimate_mw < 0.01:
      power_estimate_s = "{:0.2f} µW".format(power_estimate_mw * 1000)
    else:
      power_estimate_s = "{:0.2f} mW".format(power_estimate_mw)
    power_estimate = "{:0.2f} dBm ({})".format(power_estimate_dbm, power_estimate_s)
  options['power-estimate'] = power_estimate

[lan-ip]
recipe = slapos.recipe.build
init =
  import netifaces
  for i in netifaces.interfaces():
      if not (i.startswith("slaptun") or i.startswith("slaptap") or i.startswith("re6stnet") or i == "lo"):
          a = netifaces.ifaddresses(i)
          if netifaces.AF_INET in a:
              try:
                  options['ipv4'] = a[netifaces.AF_INET][0]['addr']
              except:
                  options['ipv4'] = "0.0.0.0"

[ors-id]
recipe = slapos.recipe.build
computer = $${slap-connection:computer-id}
title = $${slap-configuration:root-instance-title}
init =
  import socket
  options['hostname'] = socket.gethostname()
  ors_id = '__'.join(options[x] for x in ('hostname', 'computer', 'title'))
  options['ors-id'] = ors_id

[switch-softwaretype]
recipe = slapos.cookbook:switch-softwaretype
enb = dynamic-template-enb:output
gnb = dynamic-template-gnb:output
core-network = dynamic-template-core-network:output
ue-lte = dynamic-template-ue-lte:output
ue-nr = dynamic-template-ue-nr:output
RootSoftwareInstance = $${:core-network}
obsolete = dynamic-template-obsolete:output
enb-epc = $${:obsolete}
gnb-epc = $${:obsolete}
epc = $${:obsolete}
mme = $${:obsolete}

[dynamic-template-obsolete]
< = jinja2-template-base
url = ${template-obsolete:target}
filename = instance-obsolete.cfg
extensions = jinja2.ext.do
extra-context =
    key slave_instance_list slap-configuration:slave-instance-list

[dynamic-template-enb]
< = jinja2-template-base
url = ${template-enb:target}
filename = instance-enb.cfg
extensions = jinja2.ext.do
extra-context =
    raw monitor_template ${monitor2-template:output}
    section ors_version ors-version
    section ors_id ors-id
    key enb amarisoft:enb
    key sdr amarisoft:sdr
    raw enb_template   ${enb.jinja2.cfg:target}
    raw sib23_template   ${sib23.jinja2.asn:target}
    raw ltelogs_template   ${ltelogs.jinja2.sh:target}
    raw amarisoft_stats_template   ${amarisoft-stats.jinja2.py:target}
    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 CreateProcessingEle_template   ${CreateProcessingEle.jinja2.xml:target}
    raw cu_config_template   ${cu_config.jinja2.xml:target}
    raw openssl_location ${openssl:location}
    raw default_lte_n_rb_dl ${default-params:default-lte-n-rb-dl}
    raw default_lte_inactivity_timer ${default-params:default-lte-inactivity-timer}
    raw default_n_antenna_dl ${default-params:default-n-antenna-dl}
    raw default_n_antenna_ul ${default-params:default-n-antenna-ul}
    raw rf_mode ${rf-mode:rf-mode}
    raw dnsmasq_template   ${dnsmasq.jinja2.cfg:target}
    raw dnsmasq_location ${dnsmasq:location}
    key dnsmasq_config_path dnsmasq-config:output
    raw fluent_bit_location ${fluent-bit:location}

[dynamic-template-gnb]
< = jinja2-template-base
url = ${template-gnb:target}
filename = instance-gnb.cfg
extensions = jinja2.ext.do
extra-context =
    raw monitor_template ${monitor2-template:output}
    section ors_version ors-version
    section ors_id ors-id
    key enb amarisoft:enb
    key sdr amarisoft:sdr
    raw gnb_template   ${gnb.jinja2.cfg:target}
    raw ltelogs_template   ${ltelogs.jinja2.sh:target}
    raw amarisoft_stats_template   ${amarisoft-stats.jinja2.py:target}
    raw amarisoft_rf_info_template   ${amarisoft-rf-info.jinja2.py:target}
    raw openssl_location ${openssl:location}
    raw default_nr_bandwidth ${default-params:default-nr-bandwidth}
    raw default_nr_ssb_pos_bitmap ${default-params:default-nr-ssb-pos-bitmap}
    raw default_nr_inactivity_timer ${default-params:default-nr-inactivity-timer}
    raw default_n_antenna_dl ${default-params:default-n-antenna-dl}
    raw default_n_antenna_ul ${default-params:default-n-antenna-ul}
    raw rf_mode ${rf-mode:rf-mode}
    raw python_path ${python3:location}
    raw fluent_bit_location ${fluent-bit:location}

[dynamic-template-core-network]
< = jinja2-template-base
url = ${template-core-network:target}
filename = instance-core-network.cfg
extensions = jinja2.ext.do
extra-context =
    raw monitor_template ${monitor2-template:output}
    key mme amarisoft:mme
    raw mme_template   ${mme.jinja2.cfg:target}
    raw dnsmasq_template   ${dnsmasq.jinja2.cfg:target}
    raw ims_template   ${ims.jinja2.cfg:target}
    raw ltelogs_template   ${ltelogs.jinja2.sh:target}
    raw openssl_location ${openssl:location}
    raw nghttp2_location ${nghttp2:location}
    raw iperf3_location ${iperf3:location}
    raw dnsmasq_location ${dnsmasq:location}
    key ue_db_path ue-db-config:output
    key dnsmasq_config_path dnsmasq-config:output
    key slave_instance_list slap-configuration:slave-instance-list

[dynamic-template-ue-lte]
< = jinja2-template-base
url = ${template-ue-lte:target}
filename = instance-ue-lte.cfg
extensions = jinja2.ext.do
extra-context =
    raw monitor_template ${monitor2-template:output}
    key ue amarisoft:ue
    key sdr amarisoft:sdr
    raw ue_lte_template   ${ue-lte.jinja2.cfg:target}
    raw ltelogs_template   ${ltelogs.jinja2.sh:target}
    raw openssl_location ${openssl:location}
    raw default_lte_n_rb_dl ${default-params:default-lte-n-rb-dl}
    raw default_n_antenna_dl ${default-params:default-n-antenna-dl}
    raw default_n_antenna_ul ${default-params:default-n-antenna-ul}
    raw default_lte_imsi ${default-params:default-lte-imsi}
    raw default_lte_k ${default-params:default-lte-k}

[dynamic-template-ue-nr]
< = jinja2-template-base
url = ${template-ue-nr:target}
filename = instance-ue-nr.cfg
extensions = jinja2.ext.do
extra-context =
    raw monitor_template ${monitor2-template:output}
    key ue amarisoft:ue
    key sdr amarisoft:sdr
    raw ue_nr_template   ${ue-nr.jinja2.cfg:target}
    raw ltelogs_template   ${ltelogs.jinja2.sh:target}
    raw openssl_location ${openssl:location}
    raw default_nr_bandwidth ${default-params:default-nr-bandwidth}
    raw default_n_antenna_dl ${default-params:default-n-antenna-dl}
    raw default_n_antenna_ul ${default-params:default-n-antenna-ul}
    raw default_nr_imsi ${default-params:default-nr-imsi}
    raw default_nr_k ${default-params:default-nr-k}

[ue-db-config]
recipe = slapos.recipe.template:jinja2
url = ${ue_db.jinja2.cfg:target}
filename = ue_db.cfg
extensions = jinja2.ext.do
output = $${directory:etc}/$${:filename}
context =
    import json_module json
    key slave_instance_list slap-configuration:slave-instance-list

[dnsmasq-config]
recipe = slapos.recipe.template:jinja2
url = ${dnsmasq.jinja2.cfg:target}
filename = dnsmasq.cfg
extensions = jinja2.ext.do
output = $${directory:etc}/$${:filename}
context =
    import json_module json
    import netaddr netaddr
    section directory directory
    section slap_configuration slap-configuration
    key slapparameter_dict slap-configuration:configuration

