EMANE Paradigms

All EMANE components, applications and plugins, use common mechanisms to define, register, and access configuration parameters, statistics, and statistic tables. This commonality creates recognizable patterns in how you interact with a running emulation.

Configuration

All EMANE components use the ConfigurationRegistrar to register configuration parameters.

namespace EMANE
{
  class ConfigurationRegistrar
  {
  public:
    virtual ~ConfigurationRegistrar();

    template<typename T>
    void registerNumeric(const std::string & sName,
                         const ConfigurationProperties & properties = ConfigurationProperties::NONE,
                         const std::initializer_list<T> & values = {},
                         const std::string & sUsage = "",
                         T minValue = std::numeric_limits<T>::lowest(),
                         T maxValue = std::numeric_limits<T>::max(),
                         std::size_t minOccurs = 1,
                         std::size_t maxOccurs = 1,
                         const std::string & sRegexPattern = {});
    template<typename T>
    void registerNonNumeric(const std::string & sName,
                            const ConfigurationProperties & properties = ConfigurationProperties::NONE,
                            const std::initializer_list<T> & values = {},
                            const std::string & sUsage = "",
                            std::size_t minOccurs = 1,
                            std::size_t maxOccurs = 1,
                            const std::string & sRegexPattern = {});

    virtual void registerValidator(ConfigurationValidator validator) = 0;

  };
}

emane/include/emane/configurationregistrar.h


There are two registration template methods which allow components to register numeric and non-numeric configuration items: registerNumeric and registerNonNumeric respectively.

Numeric configuration item types may be any of the following:

  • std::int64_t
  • std::int32_t
  • std::int16_t
  • std::int8_t
  • std::uint64_t
  • std::uint32_t
  • std::uint16_t
  • std::uint8_t
  • bool
  • float
  • double

Non-numeric configuration item types are limited to:

Both calls have parameters to specify a description string, zero or more default values, minimum and maximum occurrence counts (multiplicity), item properties such as running-state modifiable and a regex for further validation. Additionally, registerNumeric adds support for specifying a value range.

Configuration properties may be or-combined (||):

  • NONE: No properties.
  • REQUIRED: The parameter is required. No effect when combined with DEFAULT.
  • DEFAULT: One or more default values are specified.
  • MODIFIABLE: Values may be modified while the emulator is in the running state.

The emulator enforces data type, value range, occurrence count, regex match and running-state modification permission without any component interaction, so radio models do not require code to guard against these conditions.

Below is a snippet of the configuration parameter registration within the RF Pipe radio model:

  auto & configRegistrar = registrar.configurationRegistrar();

  configRegistrar.registerNumeric<bool>("enablepromiscuousmode",
                                        ConfigurationProperties::DEFAULT |
                                        ConfigurationProperties::MODIFIABLE,
                                        {false},
                                        "Defines whether promiscuous mode is enabled or not."
                                        " If promiscuous mode is enabled, all received packets"
                                        " (intended for the given node or not) that pass the"
                                        " probability of reception check are sent upstream to"
                                        " the transport.");

  configRegistrar.registerNumeric<std::uint64_t>("datarate",
                                                 ConfigurationProperties::DEFAULT |
                                                 ConfigurationProperties::MODIFIABLE,
                                                 {1000000},
                                                 "Defines the transmit datarate in bps."
                                                 " The datarate is used by the transmitter"
                                                 " to compute the transmit delay (packet size/datarate)"
                                                 " between successive transmissions.",
                                                 1);

emane/src/models/mac/rfpipe/maclayer.cc lines: 116-137


Two running-state modifiable configuration variables are declared, each with a default value and description. Additionally, the datarate configuration parameter has a minimum value specified.

The EMANE configuration registration paradigm is used by all EMANE models, components, and applications, and its standardization makes it possible to have a standardized XML configuration file format processed directly by the emulator.

Below is node-1’s radio model XML from the rfpipe-01 example illustrating how enablepromiscuousmode and datarate configuration parameters are set:

<!DOCTYPE mac SYSTEM "file:///usr/share/emane/dtd/mac.dtd">
<mac library='rfpipemaclayer'>
  <param name='enablepromiscuousmode' value='off'/>
  <param name='datarate'              value='150M'/>
  <param name='jitter'                value='0'/>
  <param name='delay'                 value='0'/>
  <param name='flowcontrolenable'     value='off'/>
  <param name='flowcontroltokens'     value='10'/>
  <param name='pcrcurveuri'
         value='emane-rfpipe-pcr.xml'/>
</mac>

emane-guide/examples/rfpipe-01/node-1/emane-rfpipe-radiomodel.xml


All configuration parameters in EMANE XML use a <param> element with a name and value attribute, or for a configuration parameter with multiple values — <paramlist> with name attribute and a sequence of <item> elements each with a value attribute. Where, name matches the name given during configuration registration and value is the configured value.

The following Bent Pipe Model XML snippet shows how <paramlist> is used for configuration parameters with more than one value:

  <!-- syntax: '<transponder id>:<rx freqeuncy Hz>' -->
  <paramlist name='transponder.receive.frequency'>
    <item value='0:29.910G'/>
    <item value='1:29.745G'/>
    <item value='2:29.580G'/>
  </paramlist>

emane-guide/examples/bentpipe-02/node-2/emane-bentpipe-radiomodel.xml lines: 7-13


Querying/Modifying Configuration

Running emane-guide/examples/rfpipe-01, the emanesh application is used to connect to a running emane instance and query and/or clear statistics.

To establish an shell connection and query one ore more configuration parameters of a running radio model:

$ emanesh node-1
[emanesh (node-1:47000)] ## get config nems mac
nem 1   mac  datarate = 150000000
nem 1   mac  delay = 0.0
nem 1   mac  enablepromiscuousmode = False
nem 1   mac  flowcontrolenable = False
nem 1   mac  flowcontroltokens = 10
nem 1   mac  jitter = 0.0
nem 1   mac  neighbormetricdeletetime = 60.0
nem 1   mac  pcrcurveuri = emane-rfpipe-pcr.xml
nem 1   mac  radiometricenable = False
nem 1   mac  radiometricreportinterval = 1.0
nem 1   mac  rfsignaltable.averageallantennas = False
nem 1   mac  rfsignaltable.averageallfrequencies = False

You can also use emanesh to issue any command as one-shot from the command line:

$ emanesh node-1 get config nems mac jitter datarate
nem 1   mac  datarate = 150000000
nem 1   mac  jitter = 0.0

To change one or more configuration parameters of a running radio model:

[emanesh (node-1:47000)] ## set config nems mac delay=1.5
nem 1   mac  configuration updated

[emanesh (node-1:47000)] ## get config nems mac delay
nem 1   mac  delay = 1.5

To query the configuration parameter descriptions of a running radio model:

[emanesh (node-1:47000)] ## info config rfpipemaclayer delay

    Configuration parameter information for rfpipemaclayer delay

    Defines an additional fixed delay in seconds applied to each
    transmitted packet.

     default   : True
     required  : False
     modifiable: True
     type      : float
     range     : [0.000000,340282346638528859811704183484516925440.000000]
     regex     :
     occurs    : [1,1]
     default   : 0.000000

Statistics

All EMANE components use the StatisticRegistrar to register statistics.

namespace EMANE
{
  class StatisticRegistrar
  {
  public:
    virtual ~StatisticRegistrar(){}

    template<typename T>
    StatisticNumeric<T> * registerNumeric(const std::string & sName,
                                          const StatisticProperties & properties = StatisticProperties::NONE,
                                          const std::string & sDescription = "");

    template<typename T>
    StatisticNonNumeric<T> * registerNonNumeric(const std::string & sName,
                                                const StatisticProperties & properties = StatisticProperties::NONE,
                                                const std::string & sDescription = "");

    template<typename Key,
             typename Compare = std::less<EMANE::Any>,
             std::size_t scolumn = 0>
    StatisticTable<Key,Compare,scolumn> *
    registerTable(const std::string & sName,
                  const StatisticTableLabels & labels,
                  const StatisticProperties & properties = StatisticProperties::NONE,
                  const std::string & sDescription = "");

    template<typename Key,
             typename Function,
             typename Compare = std::less<EMANE::Any>,
             std::size_t scolumn = 0>
    StatisticTable<Key,Compare,scolumn> *
    registerTable(const std::string & sName,
                  const StatisticTableLabels & labels,
                  Function clearFunc,
                  const std::string & sDescription = "");

  };
}

emane/include/emane/statisticregistrar.h


There are two registration template methods which allow components to register numeric and non-numeric statistics: registerNumeric and registerNonNumeric respectively.

Numeric statistic types may be any of the following:

  • std :int64_t
  • std::int32_t
  • std::int16_t
  • std::int8_t
  • std::uint64_t
  • std::uint32_t
  • std::uint16_t
  • std::uint8_t
  • bool
  • float
  • double

Non-numeric statistic types are limited to:

Both calls have parameters to specify the statistic name, properties, and an optional description string.

Statistic properties are one of the following:

  • NONE: No properties.
  • CLEARABLE: The value is clearable while the emulator is in the running state.

Below is a snippet of statistic registration from the RF Pipe radio model:

  pNumHighWaterMark_ =
     statisticRegistrar.registerNumeric<std::uint32_t>("numHighWaterMark",
                                                       StatisticProperties::CLEARABLE,
                                                       "Downstream queue high water mark in packets.");

emane/src/models/mac/rfpipe/downstreamqueue.cc lines: 55-58


An unsigned 32-bit integer statistic variable is declared with the CLEARABLE propriety.

Querying/Clearing Statistics

Running emane-guide/examples/rfpipe-01, we can use the emanesh application to connect to a running emane instance and query and/or clear statistics.

To establish an shell connection to query the statistics of a running radio model:

$ emanesh node-1
[emanesh (node-1:47000)] ## get stat nems mac
nem 1   mac  avgDownstreamProcessingDelay0 = 9148752.0
nem 1   mac  avgDownstreamQueueDelay = 9148752.0                                                                                                                
nem 1   mac  avgProcessAPIQueueDepth = 1.2433922547802265
nem 1   mac  avgProcessAPIQueueWait = 50.888313472666326
nem 1   mac  avgTimedEventLatency = 142.49969021065615
nem 1   mac  avgTimedEventLatencyRatio = 0.2250635999012512
nem 1   mac  avgUpstreamProcessingDelay0 = 19.191591262817383                                                                                                   
nem 1   mac  numAPIQueued = 11354

...

nem 1   mac  processedConfiguration = 1
nem 1   mac  processedDownstreamControl = 0
nem 1   mac  processedDownstreamPackets = 24499
nem 1   mac  processedEvents = 0
nem 1   mac  processedTimedEvents = 3228 
nem 1   mac  processedUpstreamControl = 0
nem 1   mac  processedUpstreamPackets = 85813

To clear those statistics that were registered as CLEARABLE:

[emanesh (node-1:47000)] ## clear stat nems mac
nem 1   mac  statistics cleared

To query the statistic descriptions of a running radio model:

emanesh (node-1:47000)] ## info stat rfpipemaclayer numHighWaterMark

    Statistic element information for rfpipemaclayer numHighWaterMark


     clearable : True
     type      : uint32

Statistic Tables

All EMANE components use the StatisticRegistrar to register statistic tables.

namespace EMANE
{
  class StatisticRegistrar
  {
  public:
    virtual ~StatisticRegistrar(){}

    template<typename T>
    StatisticNumeric<T> * registerNumeric(const std::string & sName,
                                          const StatisticProperties & properties = StatisticProperties::NONE,
                                          const std::string & sDescription = "");

    template<typename T>
    StatisticNonNumeric<T> * registerNonNumeric(const std::string & sName,
                                                const StatisticProperties & properties = StatisticProperties::NONE,
                                                const std::string & sDescription = "");

    template<typename Key,
             typename Compare = std::less<EMANE::Any>,
             std::size_t scolumn = 0>
    StatisticTable<Key,Compare,scolumn> *
    registerTable(const std::string & sName,
                  const StatisticTableLabels & labels,
                  const StatisticProperties & properties = StatisticProperties::NONE,
                  const std::string & sDescription = "");

    template<typename Key,
             typename Function,
             typename Compare = std::less<EMANE::Any>,
             std::size_t scolumn = 0>
    StatisticTable<Key,Compare,scolumn> *
    registerTable(const std::string & sName,
                  const StatisticTableLabels & labels,
                  Function clearFunc,
                  const std::string & sDescription = "");

  };
}

emane/include/emane/statisticregistrar.h


There are two template methods for registering a statistic table, both named registerTable. Both methods have parameters for specifying the table name, column labels, and an optional description. One version includes table properties and the other is specifically for CLEARABLE tables with a callback to invoke when a table is cleared.

All rows in a statistic table must have the same number of columns, where each row value may be of any type allowed for an individual statistic.

Below is a snippet of statistic table registration from the Physical Layer:

  pPathlossTable_ =
    statisticRegistrar.registerTable<NEMId>("PathlossEventInfoTable",
                                            {"NEM","Forward Pathloss","Reverse Pathloss"},
                                            StatisticProperties::NONE,
                                            "Shows the precomputed pathloss information received");

  pAntennaProfileTable_ =
    statisticRegistrar.registerTable<NEMId>("AntennaProfileEventInfoTable",
                                            {"NEM","Antenna Profile","Antenna Azimuth","Antenna Elevation"},
                                            StatisticProperties::NONE,
                                            "Shows the antenna profile information received");

  pFadingSelectionTable_ =
    statisticRegistrar.registerTable<NEMId>("FadingSelectionInfoTable",
                                            {"NEM","Model"},
                                            StatisticProperties::NONE,
                                            "Shows the selected fading model information received");

emane/src/libemane/eventtablepublisher.cc lines: 47-64


These registered statistic tables provide the current event information used by the model. Each table uses an NEM id key and is not clearable.

Querying/Clearing Statistic Tables

Running emane-guide/examples/rfpipe-01, the emanesh application is used to connect to a running emane instance and query and/or clear statistic tables.

To establish an shell connection to query statistic tables of a running radio model:

$ emanesh node-1
[emanesh (node-1:47000)] ## get table nems phy LocationEventInfoTable PathlossEventInfoTable AntennaProfileEventInfoTable
nem 1   phy AntennaProfileEventInfoTable
| NEM | Antenna Profile | Antenna Azimuth | Antenna Elevation |

nem 1   phy LocationEventInfoTable
| NEM | Latitude | Longitude | Altitude | Pitch | Roll | Yaw | Azimuth | Elevation | Magnitude |

nem 1   phy PathlossEventInfoTable
| NEM | Forward Pathloss | Reverse Pathloss |
| 2   | 70.0             | 70.0             |
| 3   | 70.0             | 70.0             |
| 4   | 70.0             | 70.0             |
| 5   | 70.0             | 70.0             |

To clear those statistic tables that were registered as CLEARABLE:

[emanesh (node-1:47000)] ## clear table nems phy
nem 1   phy  tables cleared

To query the statistic table descriptions of a running radio model:

[emanesh (node-1:47000)] ## info table emanephy PathlossEventInfoTable

    Table information for emanephy PathlossEventInfoTable

    Shows the precomputed pathloss information received

     clearable : False