[buildout]
extends =
  ${template:output}

[switch-softwaretype]
enb = dynamic-template-ors-enb:output
gnb = dynamic-template-ors-enb:output
obsolete = dynamic-template-obsolete:output
enb-epc = $${:obsolete}
gnb-epc = $${:obsolete}
epc = $${:obsolete}
mme = $${:obsolete}
ue = dynamic-template-ors-ue:output

[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

# ORS-specific enb and gnb
# both are served by instance-ors-enb, which translates
# ORS enb/gnb schemas to generic enb with only one RU and one LTE or NR CELL
[dynamic-template-ors-enb]
< = dynamic-template-enb
url = ${template-ors-enb:target}
filename = instance-enb.cfg
extra-context +=
    section ors ors-version
    section ors_version ors-version
import-list +=
    rawfile instance-enb-base.jinja2.cfg ${template-enb:target}

[dynamic-template-ors-ue]
< = dynamic-template-ue
url = ${template-ors-ue:target}
filename = instance-ue.cfg
extra-context +=
    section ors ors-version
    section ors_version ors-version
    raw ue_ifup ${ue-ifup:output}
import-list +=
    rawfile instance-ue-base.jinja2.cfg ${template-ue:target}

[ors-version]
recipe = slapos.recipe.build
configuration = $${slap-configuration:configuration}
sdr-dir = $${sdr:dir}
init =
  import subprocess
  default_map = {
      "B28": {
          "range": "758MHz - 803MHz",
          "dl_earfcn": 9550,
          "dl_nr_arfcn": 158400,
          "nr_band": 28,
          "tx_gain": [60, 62],
          "rx_gain": [25, 25],
          "rf_mode": "fdd",
          "power_estimation": (
            lambda x: "UNKNOWN",
            lambda x: (-0.004711416231164319) * x**2 + (1.5976906979683085) * x + (-67.71316951508676),
          ),
      },
      "B38": {
          "range": "2570MHz - 2620MHz",
          "dl_earfcn": 38050,
          "dl_nr_arfcn": 519000,
          "nr_band": 41,
          "tx_gain": [59, 65],
          "rx_gain": [25, 25],
          "rf_mode": "tdd",
          "power_estimation": (
            lambda x: (-0.008712931375092506) * x**2 + (2.1973585140044642) * x + (-94.29420762479742),
            lambda x: (-0.004472751640641793) * x**2 + (1.6308290630103919) * x + (-81.84549245154561),
          ),
      },
      "B39": {
          "range": "1880MHz - 1920MHz",
          "dl_earfcn": 38350,
          "dl_nr_arfcn": 378000,
          "nr_band": 39,
          "tx_gain": [59, 64],
          "rx_gain": [25, 25],
          "rf_mode": "tdd",
          "power_estimation": (
            lambda x: (-0.008712931375092506) * x**2 + (2.1973585140044642) * x + (-94.29420762479742),
            lambda x: (-0.0022523817802900985) * x**2 + (1.2674016231310092) * x + (-66.57165215468584),
          ),
      },
      "B40": {
          "range": "2300MHz - 2400MHz",
          "dl_earfcn": 39150,
          "dl_nr_arfcn": 470000,
          "nr_band": 40,
          "tx_gain": [59, 64],
          "rx_gain": [25, 25],
          "rf_mode": "tdd",
          "power_estimation": (
            lambda x: "UNKNOWN",
            lambda x: (-0.0016475305254340404) * x**2 + (1.1580162105112186) * x + (-62.10679297527826),
          ),
      },
      "B41": {
          "range": "2496MHz - 2690MHz",
          "dl_earfcn": 40620,
          "dl_nr_arfcn": 518600,
          "nr_band": 41,
          "tx_gain": [59, 64],
          "rx_gain": [25, 25],
          "rf_mode": "tdd",
          "power_estimation": (
            lambda x: "UNKNOWN",
            lambda x: "UNKNOWN",
          ),
      },
      "B42": {
          "range": "3400MHz - 3600MHz",
          "dl_earfcn": 42590,
          "dl_nr_arfcn": 632628,
          "nr_band": 78,
          "tx_gain": [63, 62],
          "rx_gain": [25, 25],
          "rf_mode": "tdd",
          "power_estimation": (
            lambda x: (-0.014198126839751619) * x**2 + (2.980758813262773) * x + (-125.25800492285738),
            lambda x: (0.003977721774394756) * x**2 + (0.527208191717173) * x + (-42.761142655285376),
          ),
      },
      "B43": {
          "range": "3600MHz - 3800MHz",
          "dl_earfcn": 44590,
          "dl_nr_arfcn": 646666,
          "nr_band": 78,
          "tx_gain": [63, 62],
          "rx_gain": [25, 25],
          "rf_mode": "tdd",
          "power_estimation": (
            lambda x: (-0.014198126839751619) * x**2 + (2.980758813262773) * x + (-125.25800492285738),
            lambda x: (-0.0036530114002551943) * x**2 + (1.510856844601873) * x + (-74.58790185136355),
          ),
      },
      "N77": {
          "range": "3800MHz - 4000MHz",
          "dl_earfcn": 0,
          "dl_nr_arfcn": 660000,
          "nr_band": 77,
          "tx_gain": [60, 62],
          "rx_gain": [25, 25],
          "rf_mode": "tdd",
          "power_estimation": (
            lambda x: "UNKNOWN",
            lambda x: (-0.003358281211508112) * x**2 + (1.4533760798172672) * x + (-70.18774498873421),
          ),
      },
      "N79": {
          "range": "4600MHz - 5000MHz",
          "dl_earfcn": 0,
          "dl_nr_arfcn": 720000,
          "nr_band": 79,
          "tx_gain": [60, 62],
          "rx_gain": [25, 25],
          "rf_mode": "tdd",
          "power_estimation": (
            lambda x: "UNKNOWN",
            lambda x: (-0.004745509248998074) * x**2 + (1.659474968728413) * x + (-76.46937551110834),
          ),
      },
      "UNKNOWN": {
          "range": "Information not available for this band",
          "dl_earfcn": 0,
          "dl_nr_arfcn": 0,
          "nr_band": 0,
          "tx_gain": [60, 62],
          "rx_gain": [25, 25],
          "rf_mode": "tdd",
          "power_estimation": (
            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]
    return subprocess.check_output(
      ["sudo", "-n", options['sdr-dir'] + "/get-sdr-info", "-" + cmd]
    ).decode()
  version = get_sdr_info('v')
  options['version'] = float(version) if version != 'UNKNOWN' else 0
  options['band'] = get_sdr_info('b')
  options['tdd'] = get_sdr_info('t')
  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_map[options['band']]['tx_gain'    ][int(options['one-watt'])]
  default_rx_gain  = default_map[options['band']]['rx_gain'    ][int(options['one-watt'])]
  default_earfcn   = default_map[options['band']]['dl_earfcn'  ]
  default_nr_arfcn = default_map[options['band']]['dl_nr_arfcn']
  default_nr_band  = default_map[options['band']]['nr_band'    ]
  default_rf_mode  = default_map[options['band']]['rf_mode'    ]
  options['range']            = default_map[options['band']]['range']
  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 )
  options['current-rf-mode']  = options['configuration'].get('rf_mode'    , default_rf_mode )
  power_estimate_dbm = default_map[options['band']]['power_estimation'][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
