# Understanding NMS Software Release

This document aims to explain how the Amarisoft LTE software release is implemented, and the components related to it.

The entire source source of the Amarisoft LTE Software release contains:

- Software profile with the list of dependencies to deploy the stack
- Binaries of Amarisoft LTE stack (source code is not available - to use Amarisoft LTE software, please purchase the respective license from Amarisoft)
- Instance profiles to define types of instantiation you want to deploy
- JSON schemas parameter form rendering
- Templates of configuration files for amarisoft stack

The entire software release profile is present on:

    $MASTER_URL/raw/master/

# Table of Content

- NMS Software Release

# NMS Software Release

This section will introduce the Amarifsoft stack profile, templates and software profiles as well as input parameters.

# Amarisoft Stack Profile

The buildout profile can be found at:

    $MASTER_URL/blob/master/slapos/stack/amarisoft/buildout.cfg

and contains the entire definition of dependencies, downloads of the configuration files and as well downloads of the basic templates to be used on the Amarisoft stack.

The dependencies for the Software Release are:

    extends =
      buildout.hash.cfg
      https://lab.nexedi.com/nexedi/slapos/raw/07021e01b6ba9b3aee1eb7e1b4c1b68f44272
    193/stack/slapos.cfg
      https://lab.nexedi.com/nexedi/slapos/raw/07021e01b6ba9b3aee1eb7e1b4c1b68f44272
    193/stack/monitor/buildout.cfg
      https://lab.nexedi.com/nexedi/slapos/raw/07021e01b6ba9b3aee1eb7e1b4c1b68f44272
    193/component/logrotate/buildout.cfg
      https://lab.nexedi.com/nexedi/slapos/raw/07021e01b6ba9b3aee1eb7e1b4c1b68f44272
    193/component/gzip/buildout.cfg
      https://lab.nexedi.com/nexedi/slapos/raw/07021e01b6ba9b3aee1eb7e1b4c1b68f44272
    193/component/lxml-python/buildout.cfg
      https://lab.nexedi.com/nexedi/slapos/raw/07021e01b6ba9b3aee1eb7e1b4c1b68f44272
    193/component/msgpack-python/buildout.cfg
      https://lab.nexedi.com/nexedi/slapos/raw/07021e01b6ba9b3aee1eb7e1b4c1b68f44272
    193/component/cython-zstd/buildout.cfg
      https://lab.nexedi.com/nexedi/slapos/raw/07021e01b6ba9b3aee1eb7e1b4c1b68f44272
    193/component/python-mysqlclient/buildout.cfg
      https://lab.nexedi.com/nexedi/slapos/raw/07021e01b6ba9b3aee1eb7e1b4c1b68f44272
    193/component/python-mysqlclient/buildout.cfg

Here is the definition version of the Amarisoft Stack to use:

    [unpack-to-instance]
    recipe = slapos.recipe.build:download-unpacked
    lte-version = 2017-10-13
    url = ${:_profile_base_location_}/${:lte-version}/ \
    lte${:_buildout_section_name_}-linux-${:lte-version}.tar.gz
    destination = ${buildout:directory}/${:_buildout_section_name_}
    strip-top-level-dir = true
    ignore-existing = true
    on-update = true

Here is an example of additional action taken by the buildout to configure the software environment, which means copying the trx_sdr.so into enb folder:

    [sdr-driver]
    # move trx_sdr.so next to lteenb binary
    recipe  = slapos.recipe.build:download
    url = ${sdr:destination}/trx_sdr.so
    destination = ${enb:destination}/trx_sdr.so

# Configuration Templates

The following folder contains the configuration files that will be used by Buildout to render the final configuration files:

    $MASTER_URL/tree/master/slapos/stack/amarisoft/config

For example `enb.jinja.cfg` which uses Jinja2 templating to render the final configuration file includes:

    {% set cell_default = slapparameter_dict.get("cell_default", {}) %}

    [..]

      cell_default: {
        n_antenna_dl: {{ cell_default.get("n_antenna_dl", 2) }},
        /* antennas for downlink */
        n_antenna_ul: {{ cell_default.get("n_antenna_ul", 1) }},
        /* antennas for uplink */

which allows to use the Jinja2 templating language to define variables and load values from user input parameters. In the example, the number of antennas for download and uploade are defined by the user, or if not provided, a default value is set.

In this next example, you can notice that among other values the `cell_list` parameter can also be defined by the user:

    /* list of cells */
      cell_list: [
    {% for cell in cell_list %}
      {
        /* Broadcasted PLMN identities */
        plmn_list: [
          "00101",
        ],

        dl_earfcn: {{ cell.get("dl_earfcn") }},
        n_id_cell: {{ cell.get("n_id_cell") }},
        cell_id: {{ "0x%02x" % cell.get("n_id_cell") }},
        tac: {{ "0x%04x" % cell.get("n_id_cell") }},
        root_sequence_index: 204, /* PRACH root sequence index */
      },
    {% endfor %}

Every configuration file that will end up on leteenb, lteemme, etc can have predefined default values or values provided by the user.

# Software Profile

The software profile can be found at:

    $MASTER_URL/blob/master/slapos/software/lte/software.cfg

This file extends the stack and defines all the templates uses by SlapOS to run the instances. Additional configurations can be included here to differentiate eventual variations on how the stack will be used.

    [buildout]
    extends =
      buildout.hash.cfg
      ../../stack/amarisoft/buildout.cfg

    parts +=
      template

    # recipe to install SDR driver into ENB's libs
      sdr-driver

    [..]

# Software Types

In the software profile (`software.cfg`), everything is unified and enb, mme, ims, mbms binaries are deployed on the machine. You can only decide during the instantiation (`instance.cfg` which type of instance you want (corresponding to the software-type shown on the screenshot). This way you can decide to only run mme with appropriate configuration, for example.

The list of software types are defined in two main locations:

- `software.cfg.json` - https://lab.nexedi.com/nexedi/amarisoft/blob/master/slapos/software/lte/software.cfg.json
- `instance.cfg` - https://lab.nexedi.com/nexedi/amarisoft/blob/master/slapos/software/lte/instance.cfg

In softwate.cfg.json, you describe as json the list of Software types that will be displayed on the request form:

    {
        "name": "LTE",
        "description": "LTE",
        "serialisation": "json-in-xml",
        "software-type": {
            "enb": {
                 "title": "eNB",
                 "software-type": "enb",
                 "description": "eNodeB Configuration",
                 "request": "instance-enb-input-schema.json",
                 "response": "instance-enb-schema.json",
                 "index": 0
             },
    [..]

Each entry defines a form to render to the user (as shown in the screenshot)

On instance.cfg you can have find the list of types here:

    [switch-softwaretype]
    recipe = slapos.cookbook:softwaretype
    default = $${dynamic-template-lte-default:rendered}
    license = $${dynamic-template-lte-license:rendered}
    enb = $${dynamic-template-lte-enb:rendered}
    epc = $${dynamic-template-lte-mme:rendered}
    ims = $${dynamic-template-lte-ims:rendered}
    mbms = $${dynamic-template-lte-mbms:rendered}

Each entry defines a buildout profile, that will be used to instantiate the services.

# Parameter Form Input

The developer can define one or more json schemas for each software type. Each json schema will be rendered as a form in order for users to enter their preferences and configuration. Later, this input can be translated in a multitude of values.

The following example illustrates the rendering:

    [..]
    		"mme_addr": {
    			"title": "MME address",
    			"description": "address of MME for S1AP connection",
    			"type": "string",
    			"default": "127.0.1.100"
    		},
    [..]

This defines that a string input will be rendered for mme_addr resulting in:

You can program a combination of values to deploy a desirable configuration giving high flexibility to the model to generate thousand of configurations with minimal amount of inputs.

# Instantiation Templates and Service Deployment

When requesting to deploy an eNB, the following template will be used:

    $MASTER_URL//blob/master/slapos/
      software/lte/instance-enb.jinja2.cfg

This template defines which actions to take to run the service, such as create directories, wrapper scripts with proper values to render the final templates.

## Creating Directories

The following section creates the required directories:

    [directory]
    recipe = slapos.cookbook:mkdirectory
    home = ${buildout:directory}
    etc = ${:home}/etc
    var = ${:home}/var
    etc = ${:home}/etc
    bin = ${:home}/bin
    run = ${:var}/run
    script = ${:etc}/run
    service = ${:etc}/service
    promise = ${:etc}/promise
    log = ${:var}/log

## Script to Run eNB

This section defines the script to run eNB:

    [lte-enb-service]
    recipe = slapos.cookbook:wrapper
    init = ${ltelogs:rendered} ${directory:log}/enb.log; sleep 2
    command-line = {{ enb }}/lteenb ${directory:etc}/enb.cfg
    wrapper-path = ${directory:service}/lte-enb
    mode = 0775
    reserve-cpu = True
    pidfile = ${directory:run}/enb.pid
    {% if slapparameter_dict.get("license_key_path", None) %}
    environment = AMARISOFT_PATH={{ slapparameter_dict.get("license_key_path", None) }}
    {% endif %}

## Rendering of enb.cfg

The rendering of `enb.cfg` is done in this section:

    [config-base]
    recipe = slapos.recipe.template:jinja2
    mode = 0664
    extensions = jinja2.ext.do
    context =
      section directory directory
      section instance instance
      key slapparameter_dict instance:configuration
      import  netaddr netaddr

    [lte-enb-config]
    <= config-base
    template = {{ enb_template }}
    rendered = ${directory:etc}/enb.cfg

# Thank You

- Nexedi SA
- 147 Rue du Ballon
- 59110 La Madeleine
- France

- nexedi.com/contact