コード例 #1
0
ファイル: examplemodel.py プロジェクト: troglobit/core
class ExampleModel(emanemodel.EmaneModel):
    ### MAC Definition

    # Defines the emane model name that will show up in the GUI.
    name = "emane_example"

    # Defines that mac library that the model will reference.
    mac_library = "rfpipemaclayer"
    # Defines the mac manifest file that will be parsed to obtain configuration options, that will be displayed
    # within the GUI.
    mac_xml = "/usr/share/emane/manifest/rfpipemaclayer.xml"
    # Allows you to override options that are maintained within the manifest file above.
    mac_defaults = {
        "pcrcurveuri": "/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml",
    }
    # Parses the manifest file and converts configurations into core supported formats.
    mac_config = emanemanifest.parse(mac_xml, mac_defaults)

    ### PHY Definition
    # **NOTE: phy configuration will default to the universal model as seen below and the below section does not
    # have to be included.**

    # Defines that phy library that the model will reference, used if you need to provide a custom phy.
    phy_library = None
    # Defines the phy manifest file that will be parsed to obtain configuration options, that will be displayed
    # within the GUI.
    phy_xml = "/usr/share/emane/manifest/emanephy.xml"
    # Allows you to override options that are maintained within the manifest file above or for the default universal
    # model.
    phy_defaults = {
        "subid": "1",
        "propagationmodel": "2ray",
        "noisemode": "none"
    }
    # Parses the manifest file and converts configurations into core supported formats.
    phy_config = emanemanifest.parse(phy_xml, phy_defaults)

    ### Custom override options
    # **NOTE: these options default to what's seen below and do not have to be included.**

    # Allows you to ignore options within phy/mac, used typically if you needed to add a custom option for display
    # within the gui.
    config_ignore = set()
    # Allows you to override how options are displayed with the GUI, using the GUI format of
    # "name:1-2|othername:3-4". This will be parsed into tabs, split by "|" and account for items based on the indexed
    # numbers after ":" for including values in each tab.
    config_groups_override = None
    # Allows you to override the default config matrix list. This value by default is the mac_config + phy_config, in
    # that order.
    config_matrix_override = None
コード例 #2
0
    def load(cls, emane_prefix: Path) -> None:
        """
        Called after being loaded within the EmaneManager. Provides configured
        emane_prefix for parsing xml files.

        :param emane_prefix: configured emane prefix path
        :return: nothing
        """
        cls._load_platform_config(emane_prefix)
        # load mac configuration
        mac_xml_path = emane_prefix / MANIFEST_PATH / cls.mac_xml
        cls.mac_config = emanemanifest.parse(mac_xml_path, cls.mac_defaults)
        # load phy configuration
        phy_xml_path = emane_prefix / MANIFEST_PATH / cls.phy_xml
        cls.phy_config = emanemanifest.parse(phy_xml_path, cls.phy_defaults)
コード例 #3
0
ファイル: examplemodel.py プロジェクト: xiaoxiaopingzi/core
    def load(cls, emane_prefix: Path) -> None:
        """
        Called after being loaded within the EmaneManager. Provides configured
        emane_prefix for parsing xml files.

        :param emane_prefix: configured emane prefix path
        :return: nothing
        """
        manifest_path = "share/emane/manifest"
        # load mac configuration
        mac_xml_path = emane_prefix / manifest_path / cls.mac_xml
        cls.mac_config = emanemanifest.parse(mac_xml_path, cls.mac_defaults)
        # load phy configuration
        phy_xml_path = emane_prefix / manifest_path / cls.phy_xml
        cls.phy_config = emanemanifest.parse(phy_xml_path, cls.phy_defaults)
コード例 #4
0
ファイル: examplemodel.py プロジェクト: ullahhab/core
class ExampleModel(emanemodel.EmaneModel):
    """
    Custom emane model.

    :cvar name: defines the emane model name that will show up in the GUI

    Mac Definition:
    :cvar mac_library: defines that mac library that the model will reference
    :cvar mac_xml: defines the mac manifest file that will be parsed to obtain configuration options,
        that will be displayed within the GUI
    :cvar mac_defaults: allows you to override options that are maintained within the manifest file above
    :cvar mac_config: parses the manifest file and converts configurations into core supported formats

    Phy Definition:
    NOTE: phy configuration will default to the universal model as seen below and the below section does not
    have to be included
    :cvar phy_library: defines that phy library that the model will reference, used if you need to
        provide a custom phy
    :cvar phy_xml: defines the phy manifest file that will be parsed to obtain configuration options,
        that will be displayed within the GUI
    :cvar phy_defaults: allows you to override options that are maintained within the manifest file above
        or for the default universal model
    :cvar phy_config: parses the manifest file and converts configurations into core supported formats

    Custom Override Options:
    NOTE: these options default to what's seen below and do not have to be included
    :cvar config_ignore: allows you to ignore options within phy/mac, used typically if you needed to add
        a custom option for display within the gui
    """

    name: str = "emane_example"
    mac_library: str = "rfpipemaclayer"
    mac_xml: str = "/usr/share/emane/manifest/rfpipemaclayer.xml"
    mac_defaults: Dict[str, str] = {
        "pcrcurveuri": "/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml"
    }
    mac_config: List[Configuration] = emanemanifest.parse(mac_xml, mac_defaults)
    phy_library: Optional[str] = None
    phy_xml: str = "/usr/share/emane/manifest/emanephy.xml"
    phy_defaults: Dict[str, str] = {
        "subid": "1",
        "propagationmodel": "2ray",
        "noisemode": "none",
    }
    phy_config: List[Configuration] = emanemanifest.parse(phy_xml, phy_defaults)
    config_ignore: Set[str] = set()
コード例 #5
0
class ExampleModel(emanemodel.EmaneModel):
    ### MAC Definition

    # Defines the emane model name that will show up in the GUI.
    name = "emane_example"

    # Defines that mac library that the model will reference.
    mac_library = "rfpipemaclayer"
    # Defines the mac manifest file that will be parsed to obtain configuration options, that will be displayed
    # within the GUI.
    mac_xml = "/usr/share/emane/manifest/rfpipemaclayer.xml"
    # Allows you to override options that are maintained within the manifest file above.
    mac_defaults = {
        "pcrcurveuri": "/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml",
    }
    # Parses the manifest file and converts configurations into core supported formats.
    mac_config = emanemanifest.parse(mac_xml, mac_defaults)

    ### PHY Definition
    # **NOTE: phy configuration will default to the universal model as seen below and the below section does not
    # have to be included.**

    # Defines that phy library that the model will reference, used if you need to provide a custom phy.
    phy_library = None
    # Defines the phy manifest file that will be parsed to obtain configuration options, that will be displayed
    # within the GUI.
    phy_xml = "/usr/share/emane/manifest/emanephy.xml"
    # Allows you to override options that are maintained within the manifest file above or for the default universal
    # model.
    phy_defaults = {
        "subid": "1",
        "propagationmodel": "2ray",
        "noisemode": "none"
    }
    # Parses the manifest file and converts configurations into core supported formats.
    phy_config = emanemanifest.parse(phy_xml, phy_defaults)

    ### Custom override options
    # **NOTE: these options default to what's seen below and do not have to be included.**

    # Allows you to ignore options within phy/mac, used typically if you needed to add a custom option for display
    # within the gui.
    config_ignore = set()
コード例 #6
0
class EmaneGlobalModel(EmaneModel):
    """
    Global EMANE configuration options.
    """

    _DEFAULT_DEV = "ctrl0"

    name = "emane"

    emulator_xml = "/usr/share/emane/manifest/nemmanager.xml"
    emulator_defaults = {
        "eventservicedevice": _DEFAULT_DEV,
        "eventservicegroup": "224.1.2.8:45703",
        "otamanagerdevice": _DEFAULT_DEV,
        "otamanagergroup": "224.1.2.8:45702",
    }
    emulator_config = emanemanifest.parse(emulator_xml, emulator_defaults)
    emulator_config.insert(
        0,
        Configuration(
            _id="platform_id_start",
            _type=ConfigDataTypes.INT32,
            default="1",
            label="Starting Platform ID (core)",
        ),
    )

    nem_config = [
        Configuration(
            _id="nem_id_start",
            _type=ConfigDataTypes.INT32,
            default="1",
            label="Starting NEM ID (core)",
        )
    ]

    @classmethod
    def configurations(cls):
        return cls.emulator_config + cls.nem_config

    @classmethod
    def config_groups(cls):
        emulator_len = len(cls.emulator_config)
        config_len = len(cls.configurations())
        return [
            ConfigGroup("Platform Attributes", 1, emulator_len),
            ConfigGroup("NEM Parameters", emulator_len + 1, config_len),
        ]

    def __init__(self, session, _id=None):
        super(EmaneGlobalModel, self).__init__(session, _id)

    def build_xml_files(self, config, interface=None):
        raise NotImplementedError
コード例 #7
0
ファイル: ieee80211abg.py プロジェクト: yrs1/core
class EmaneIeee80211abgModel(emanemodel.EmaneModel):
    # model name
    name = "emane_ieee80211abg"

    # mac configuration
    mac_library = "ieee80211abgmaclayer"
    mac_xml = "/usr/share/emane/manifest/ieee80211abgmaclayer.xml"
    mac_defaults = {
        "pcrcurveuri": "/usr/share/emane/xml/models/mac/ieee80211abg/ieee80211pcr.xml",
    }
    mac_config = emanemanifest.parse(mac_xml, mac_defaults)
コード例 #8
0
ファイル: emanemanager.py プロジェクト: umr-ds/core
 def parse_config(self) -> None:
     emane_prefix = self.session.options.get_config(
         "emane_prefix", default=DEFAULT_EMANE_PREFIX)
     emulator_xml = os.path.join(emane_prefix,
                                 "share/emane/manifest/nemmanager.xml")
     emulator_defaults = {
         "eventservicedevice": DEFAULT_DEV,
         "eventservicegroup": "224.1.2.8:45703",
         "otamanagerdevice": DEFAULT_DEV,
         "otamanagergroup": "224.1.2.8:45702",
     }
     self.emulator_config = emanemanifest.parse(emulator_xml,
                                                emulator_defaults)
コード例 #9
0
 def _load_platform_config(cls, emane_prefix: Path) -> None:
     platform_xml_path = emane_prefix / MANIFEST_PATH / cls.platform_xml
     cls.platform_config = emanemanifest.parse(
         platform_xml_path, cls.platform_defaults
     )
     # remove controlport configuration, since core will set this directly
     controlport_index = None
     for index, configuration in enumerate(cls.platform_config):
         if configuration.id == cls.platform_controlport:
             controlport_index = index
             break
     if controlport_index is not None:
         cls.platform_config.pop(controlport_index)
コード例 #10
0
ファイル: tdma.py プロジェクト: rubiruchi/core
class EmaneTdmaModel(emanemodel.EmaneModel):
    # model name
    name = "emane_tdma"

    # mac configuration
    mac_library = "tdmaeventschedulerradiomodel"
    mac_xml = "/usr/share/emane/manifest/tdmaeventschedulerradiomodel.xml"
    mac_defaults = {
        "pcrcurveuri":
        "/usr/share/emane/xml/models/mac/tdmaeventscheduler/tdmabasemodelpcr.xml",
    }
    mac_config = emanemanifest.parse(mac_xml, mac_defaults)

    # add custom schedule options and ignore it when writing emane xml
    schedule_name = "schedule"
    default_schedule = os.path.join(constants.CORE_DATA_DIR, "examples",
                                    "tdma", "schedule.xml")
    mac_config.insert(
        0,
        Configuration(_id=schedule_name,
                      _type=ConfigDataTypes.STRING,
                      default=default_schedule,
                      label="TDMA schedule file (core)"))
    config_ignore = {schedule_name}

    def post_startup(self):
        """
        Logic to execute after the emane manager is finished with startup.

        :return: nothing
        """
        # get configured schedule
        config = self.session.emane.get_configs(node_id=self.object_id,
                                                config_type=self.name)
        if not config:
            return
        schedule = config[self.schedule_name]

        # get the set event device
        event_device = self.session.emane.event_device

        # initiate tdma schedule
        logging.info("setting up tdma schedule: schedule(%s) device(%s)",
                     schedule, event_device)
        utils.check_cmd(
            ["emaneevent-tdmaschedule", "-i", event_device, schedule])
コード例 #11
0
ファイル: tdma.py プロジェクト: troglobit/core
class EmaneTdmaModel(emanemodel.EmaneModel):
    # model name
    name = "emane_tdma"

    # mac configuration
    mac_library = "tdmaeventschedulerradiomodel"
    mac_xml = "/usr/share/emane/manifest/tdmaeventschedulerradiomodel.xml"
    mac_defaults = {
        "pcrcurveuri":
        "/usr/share/emane/xml/models/mac/tdmaeventscheduler/tdmabasemodelpcr.xml",
    }
    mac_config = emanemanifest.parse(mac_xml, mac_defaults)

    # add custom schedule options and ignore it when writing emane xml
    schedule_name = "schedule"
    default_schedule = os.path.join(constants.CORE_DATA_DIR, "examples",
                                    "tdma", "schedule.xml")
    mac_config.insert(0, (schedule_name, ConfigDataTypes.STRING.value,
                          default_schedule, "", "TDMA schedule file (core)"))
    config_ignore = {schedule_name}

    def post_startup(self, emane_manager):
        """
        Logic to execute after the emane manager is finished with startup.

        :param core.emane.emanemanager.EmaneManager emane_manager: emane manager for the session
        :return: nothing
        """
        # get configured schedule
        values = emane_manager.getconfig(self.object_id, self.name,
                                         self.getdefaultvalues())[1]
        if values is None:
            return
        schedule = self.valueof(self.schedule_name, values)

        event_device = emane_manager.event_device

        # initiate tdma schedule
        logger.info("setting up tdma schedule: schedule(%s) device(%s)",
                    schedule, event_device)
        utils.check_cmd(
            ["emaneevent-tdmaschedule", "-i", event_device, schedule])
コード例 #12
0
 def parse_config(self) -> None:
     emane_prefix = self.session.options.get_config(
         "emane_prefix", default=DEFAULT_EMANE_PREFIX
     )
     emulator_xml = os.path.join(emane_prefix, "share/emane/manifest/nemmanager.xml")
     emulator_defaults = {
         "eventservicedevice": DEFAULT_DEV,
         "eventservicegroup": "224.1.2.8:45703",
         "otamanagerdevice": DEFAULT_DEV,
         "otamanagergroup": "224.1.2.8:45702",
     }
     self.emulator_config = emanemanifest.parse(emulator_xml, emulator_defaults)
     self.emulator_config.insert(
         0,
         Configuration(
             _id="platform_id_start",
             _type=ConfigDataTypes.INT32,
             default="1",
             label="Starting Platform ID (core)",
         ),
     )
コード例 #13
0
ファイル: emanemanager.py プロジェクト: troglobit/core
class EmaneGlobalModel(EmaneModel):
    """
    Global EMANE configuration options.
    """
    _DEFAULT_DEV = "ctrl0"

    name = "emane"

    emulator_xml = "/usr/share/emane/manifest/nemmanager.xml"
    emulator_defaults = {
        "eventservicedevice": _DEFAULT_DEV,
        "eventservicegroup": "224.1.2.8:45703",
        "otamanagerdevice": _DEFAULT_DEV,
        "otamanagergroup": "224.1.2.8:45702"
    }
    emulator_config = emanemanifest.parse(emulator_xml, emulator_defaults)
    emulator_config.insert(0,
                           ("platform_id_start", ConfigDataTypes.INT32.value,
                            "1", "", "Starting Platform ID (core)"))

    nem_config = [
        ("nem_id_start", ConfigDataTypes.INT32.value, "1", "",
         "Starting NEM ID (core)"),
    ]

    config_matrix_override = emulator_config + nem_config
    config_groups_override = "Platform Attributes:1-%d|NEM Parameters:%d-%d" % (
        len(emulator_config), len(emulator_config) + 1,
        len(config_matrix_override))

    def __init__(self, session, object_id=None):
        EmaneModel.__init__(self, session, object_id)

    def build_xml_files(self, emane_manager, interface):
        """
        Build the necessary nem, mac, and phy XMLs in the given path.
        """
        raise NotImplementedError
コード例 #14
0
 def load(cls, emane_prefix):
     shim_xml_path = os.path.join(emane_prefix, "share/emane/manifest", cls.shim_xml)
     cls.config_shim = emanemanifest.parse(shim_xml_path, cls.shim_defaults)
コード例 #15
0
ファイル: commeffect.py プロジェクト: yrs1/core
class EmaneCommEffectModel(emanemodel.EmaneModel):
    name = "emane_commeffect"

    shim_library = "commeffectshim"
    shim_xml = "/usr/share/emane/manifest/commeffectshim.xml"
    shim_defaults = {}
    config_shim = emanemanifest.parse(shim_xml, shim_defaults)

    # comm effect does not need the default phy and external configurations
    phy_config = ()
    external_config = ()

    @classmethod
    def configurations(cls):
        return cls.config_shim

    @classmethod
    def config_groups(cls):
        return [
            ConfigGroup("CommEffect SHIM Parameters", 1,
                        len(cls.configurations()))
        ]

    def build_xml_files(self, config, interface=None):
        """
        Build the necessary nem and commeffect XMLs in the given path.
        If an individual NEM has a nonstandard config, we need to build
        that file also. Otherwise the WLAN-wide
        nXXemane_commeffectnem.xml, nXXemane_commeffectshim.xml are used.

        :param dict config: emane model configuration for the node and interface
        :param interface: interface for the emane node
        :return: nothing
        """
        # retrieve xml names
        nem_name = emanexml.nem_file_name(self, interface)
        shim_name = emanexml.shim_file_name(self, interface)

        # create and write nem document
        nem_element = etree.Element("nem",
                                    name="%s NEM" % self.name,
                                    type="unstructured")
        transport_type = "virtual"
        if interface and interface.transport_type == "raw":
            transport_type = "raw"
        transport_file = emanexml.transport_file_name(self.object_id,
                                                      transport_type)
        etree.SubElement(nem_element, "transport", definition=transport_file)

        # set shim configuration
        etree.SubElement(nem_element, "shim", definition=shim_name)

        nem_file = os.path.join(self.session.session_dir, nem_name)
        emanexml.create_file(nem_element, "nem", nem_file)

        # create and write shim document
        shim_element = etree.Element("shim",
                                     name="%s SHIM" % self.name,
                                     library=self.shim_library)

        # append all shim options (except filterfile) to shimdoc
        for configuration in self.config_shim:
            name = configuration.id
            if name == "filterfile":
                continue
            value = config[name]
            emanexml.add_param(shim_element, name, value)

        # empty filterfile is not allowed
        ff = config["filterfile"]
        if ff.strip() != "":
            emanexml.add_param(shim_element, "filterfile", ff)

        shim_file = os.path.join(self.session.session_dir, shim_name)
        emanexml.create_file(shim_element, "shim", shim_file)

    def linkconfig(self,
                   netif,
                   bw=None,
                   delay=None,
                   loss=None,
                   duplicate=None,
                   jitter=None,
                   netif2=None):
        """
        Generate CommEffect events when a Link Message is received having
        link parameters.
        """
        service = self.session.emane.service
        if service is None:
            logging.warn("%s: EMANE event service unavailable", self.name)
            return

        if netif is None or netif2 is None:
            logging.warn("%s: missing NEM information", self.name)
            return

        # TODO: batch these into multiple events per transmission
        # TODO: may want to split out seconds portion of delay and jitter
        event = CommEffectEvent()
        emane_node = self.session.get_object(self.object_id)
        nemid = emane_node.getnemid(netif)
        nemid2 = emane_node.getnemid(netif2)
        mbw = bw
        logging.info("sending comm effect event")
        event.append(nemid,
                     latency=convert_none(delay),
                     jitter=convert_none(jitter),
                     loss=convert_none(loss),
                     duplicate=convert_none(duplicate),
                     unicast=long(convert_none(bw)),
                     broadcast=long(convert_none(mbw)))
        service.publish(nemid2, event)
コード例 #16
0
ファイル: emanemodel.py プロジェクト: troglobit/core
class EmaneModel(WirelessModel):
    """
    EMANE models inherit from this parent class, which takes care of
    handling configuration messages based on the list of
    configurable parameters. Helper functions also live here.
    """
    __metaclass__ = EmaneModelMetaClass

    # default mac configuration settings
    mac_library = None
    mac_xml = None
    mac_defaults = {}
    mac_config = []

    # default phy configuration settings, using the universal model
    phy_library = None
    phy_xml = "/usr/share/emane/manifest/emanephy.xml"
    phy_defaults = {
        "subid": "1",
        "propagationmodel": "2ray",
        "noisemode": "none"
    }
    phy_config = emanemanifest.parse(phy_xml, phy_defaults)

    config_ignore = set()
    config_groups_override = None
    config_matrix_override = None

    def __init__(self, session, object_id=None):
        WirelessModel.__init__(self, session, object_id)

    def build_xml_files(self, emane_manager, interface):
        """
        Builds xml files for emane. Includes a nem.xml file that points to both mac.xml and phy.xml definitions.

        :param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
        :param interface: interface for the emane node
        :return: nothing
        """
        # retrieve configuration values
        values = emane_manager.getifcconfig(self.object_id, self.name,
                                            self.getdefaultvalues(), interface)
        if values is None:
            return

        # create document and write to disk
        nem_name = self.nem_name(interface)
        nem_document = self.create_nem_doc(emane_manager, interface)
        emane_manager.xmlwrite(nem_document, nem_name)

        # create mac document and write to disk
        mac_name = self.mac_name(interface)
        mac_document = self.create_mac_doc(emane_manager, values)
        emane_manager.xmlwrite(mac_document, mac_name)

        # create phy document and write to disk
        phy_name = self.phy_name(interface)
        phy_document = self.create_phy_doc(emane_manager, values)
        emane_manager.xmlwrite(phy_document, phy_name)

    def create_nem_doc(self, emane_manager, interface):
        """
        Create the nem xml document.

        :param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
        :param interface: interface for the emane node
        :return: nem document
        :rtype: xml.dom.minidom.Document
        """
        mac_name = self.mac_name(interface)
        phy_name = self.phy_name(interface)

        nem_document = emane_manager.xmldoc("nem")
        nem_element = nem_document.getElementsByTagName("nem").pop()
        nem_element.setAttribute("name", "%s NEM" % self.name)
        emane_manager.appendtransporttonem(nem_document, nem_element,
                                           self.object_id, interface)

        mac_element = nem_document.createElement("mac")
        mac_element.setAttribute("definition", mac_name)
        nem_element.appendChild(mac_element)

        phy_element = nem_document.createElement("phy")
        phy_element.setAttribute("definition", phy_name)
        nem_element.appendChild(phy_element)

        return nem_document

    def create_mac_doc(self, emane_manager, values):
        """
        Create the mac xml document.

        :param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
        :param tuple values: all current configuration values, mac + phy
        :return: nem document
        :rtype: xml.dom.minidom.Document
        """
        names = list(self.getnames())
        mac_names = names[:len(self.mac_config)]

        mac_document = emane_manager.xmldoc("mac")
        mac_element = mac_document.getElementsByTagName("mac").pop()
        mac_element.setAttribute("name", "%s MAC" % self.name)

        if not self.mac_library:
            raise ValueError("must define emane model library")
        mac_element.setAttribute("library", self.mac_library)

        for name in mac_names:
            # ignore custom configurations
            if name in self.config_ignore:
                continue

            # check if value is a multi param
            value = self.valueof(name, values)
            param = value_to_params(mac_document, name, value)
            if not param:
                param = emane_manager.xmlparam(mac_document, name, value)

            mac_element.appendChild(param)

        return mac_document

    def create_phy_doc(self, emane_manager, values):
        """
        Create the phy xml document.

        :param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
        :param tuple values: all current configuration values, mac + phy
        :return: nem document
        :rtype: xml.dom.minidom.Document
        """
        names = list(self.getnames())
        phy_names = names[len(self.mac_config):]

        phy_document = emane_manager.xmldoc("phy")
        phy_element = phy_document.getElementsByTagName("phy").pop()
        phy_element.setAttribute("name", "%s PHY" % self.name)

        if self.phy_library:
            phy_element.setAttribute("library", self.phy_library)

        # append all phy options
        for name in phy_names:
            # ignore custom configurations
            if name in self.config_ignore:
                continue

            # check if value is a multi param
            value = self.valueof(name, values)
            param = value_to_params(phy_document, name, value)
            if not param:
                param = emane_manager.xmlparam(phy_document, name, value)

            phy_element.appendChild(param)

        return phy_document

    @classmethod
    def configure_emane(cls, session, config_data):
        """
        Handle configuration messages for configuring an emane model.

        :param core.session.Session session: session to configure emane
        :param core.conf.ConfigData config_data: configuration data for carrying out a configuration
        """
        return cls.configure(session.emane, config_data)

    def post_startup(self, emane_manager):
        """
        Logic to execute after the emane manager is finished with startup.

        :param core.emane.emanemanager.EmaneManager emane_manager: emane manager for the session
        :return: nothing
        """
        logger.info("emane model(%s) has no post setup tasks", self.name)

    def build_nem_xml(self, doc, emane_node, interface):
        """
        Build the NEM definition that goes into the platform.xml file.

        This returns an XML element that will be added to the <platform/> element.

        This default method supports per-interface config (e.g. <nem definition="n2_0_63emane_rfpipe.xml" id="1">
        or per-EmaneNode config (e.g. <nem definition="n1emane_rfpipe.xml" id="1">.

        This can be overriden by a model for NEM flexibility; n is the EmaneNode.

            <nem name="NODE-001" definition="rfpipenem.xml">

        :param xml.dom.minidom.Document doc: xml document
        :param core.emane.nodes.EmaneNode emane_node: emane node to get information from
        :param interface: interface for the emane node
        :return: created platform xml
        """
        # if this netif contains a non-standard (per-interface) config,
        #  then we need to use a more specific xml file here
        nem_name = self.nem_name(interface)
        nem = doc.createElement("nem")
        nem.setAttribute("name", interface.localname)
        nem.setAttribute("definition", nem_name)
        return nem

    def build_transport_xml(self, doc, emane_node, interface):
        """
        Build the transport definition that goes into the platform.xml file.
        This returns an XML element that will be added to the nem definition.
        This default method supports raw and virtual transport types, but may be
        overridden by a model to support the e.g. pluggable virtual transport.

            <transport definition="transvirtual.xml" group="1">
               <param name="device" value="n1.0.158" />
            </transport>

        :param xml.dom.minidom.Document doc: xml document
        :param core.emane.nodes.EmaneNode emane_node: emane node to get information from
        :param interface: interface for the emane node
        :return: created transport xml
        """
        transport_type = interface.transport_type
        if not transport_type:
            logger.info("warning: %s interface type unsupported!",
                        interface.name)
            transport_type = "raw"
        transport_name = emane_node.transportxmlname(transport_type)

        transport = doc.createElement("transport")
        transport.setAttribute("definition", transport_name)

        param = doc.createElement("param")
        param.setAttribute("name", "device")
        param.setAttribute("value", interface.name)

        transport.appendChild(param)
        return transport

    def _basename(self, interface=None):
        """
        Create name that is leveraged for configuration file creation.

        :param interface: interface for this model
        :return: basename used for file creation
        :rtype: str
        """
        name = "n%s" % self.object_id
        emane_manager = self.session.emane

        if interface:
            node_id = interface.node.objid
            if emane_manager.getifcconfig(node_id, self.name, None,
                                          interface) is not None:
                name = interface.localname.replace(".", "_")

        return "%s%s" % (name, self.name)

    def nem_name(self, interface=None):
        """
        Return the string name for the NEM XML file, e.g. "n3rfpipenem.xml"

        :param interface: interface for this model
        :return: nem xml filename
        :rtype: str
        """
        basename = self._basename(interface)
        append = ""
        if interface and interface.transport_type == "raw":
            append = "_raw"
        return "%snem%s.xml" % (basename, append)

    def shim_name(self, interface=None):
        """
        Return the string name for the SHIM XML file, e.g. "commeffectshim.xml"

        :param interface: interface for this model
        :return: shim xml filename
        :rtype: str
        """
        return "%sshim.xml" % self._basename(interface)

    def mac_name(self, interface=None):
        """
        Return the string name for the MAC XML file, e.g. "n3rfpipemac.xml"

        :param interface: interface for this model
        :return: mac xml filename
        :rtype: str
        """
        return "%smac.xml" % self._basename(interface)

    def phy_name(self, interface=None):
        """
        Return the string name for the PHY XML file, e.g. "n3rfpipephy.xml"

        :param interface: interface for this model
        :return: phy xml filename
        :rtype: str
        """
        return "%sphy.xml" % self._basename(interface)

    def update(self, moved, moved_netifs):
        """
        Invoked from MobilityModel when nodes are moved; this causes
        emane location events to be generated for the nodes in the moved
        list, making EmaneModels compatible with Ns2ScriptedMobility.

        :param bool moved: were nodes moved
        :param list moved_netifs: interfaces that were moved
        :return:
        """
        try:
            wlan = self.session.get_object(self.object_id)
            wlan.setnempositions(moved_netifs)
        except KeyError:
            logger.exception("error during update")

    def linkconfig(self,
                   netif,
                   bw=None,
                   delay=None,
                   loss=None,
                   duplicate=None,
                   jitter=None,
                   netif2=None):
        """
        Invoked when a Link Message is received. Default is unimplemented.

        :param core.netns.vif.Veth netif: interface one
        :param bw: bandwidth to set to
        :param delay: packet delay to set to
        :param loss: packet loss to set to
        :param duplicate: duplicate percentage to set to
        :param jitter: jitter to set to
        :param core.netns.vif.Veth netif2: interface two
        :return: nothing
        """
        logger.warn("emane model(%s) does not support link configuration",
                    self.name)
コード例 #17
0
ファイル: emanemodel.py プロジェクト: yrs1/core
class EmaneModel(WirelessModel):
    """
    EMANE models inherit from this parent class, which takes care of
    handling configuration messages based on the list of
    configurable parameters. Helper functions also live here.
    """
    # default mac configuration settings
    mac_library = None
    mac_xml = None
    mac_defaults = {}
    mac_config = []

    # default phy configuration settings, using the universal model
    phy_library = None
    phy_xml = "/usr/share/emane/manifest/emanephy.xml"
    phy_defaults = {
        "subid": "1",
        "propagationmodel": "2ray",
        "noisemode": "none"
    }
    phy_config = emanemanifest.parse(phy_xml, phy_defaults)

    # support for external configurations
    external_config = [
        Configuration("external", ConfigDataTypes.BOOL, default="0"),
        Configuration("platformendpoint",
                      ConfigDataTypes.STRING,
                      default="127.0.0.1:40001"),
        Configuration("transportendpoint",
                      ConfigDataTypes.STRING,
                      default="127.0.0.1:50002")
    ]

    config_ignore = set()

    @classmethod
    def configurations(cls):
        return cls.mac_config + cls.phy_config + cls.external_config

    @classmethod
    def config_groups(cls):
        mac_len = len(cls.mac_config)
        phy_len = len(cls.phy_config) + mac_len
        config_len = len(cls.configurations())
        return [
            ConfigGroup("MAC Parameters", 1, mac_len),
            ConfigGroup("PHY Parameters", mac_len + 1, phy_len),
            ConfigGroup("External Parameters", phy_len + 1, config_len)
        ]

    def build_xml_files(self, config, interface=None):
        """
        Builds xml files for this emane model. Creates a nem.xml file that points to both mac.xml and phy.xml
        definitions.

        :param dict config: emane model configuration for the node and interface
        :param interface: interface for the emane node
        :return: nothing
        """
        nem_name = emanexml.nem_file_name(self, interface)
        mac_name = emanexml.mac_file_name(self, interface)
        phy_name = emanexml.phy_file_name(self, interface)

        # check if this is external
        transport_type = "virtual"
        if interface and interface.transport_type == "raw":
            transport_type = "raw"
        transport_name = emanexml.transport_file_name(self.object_id,
                                                      transport_type)

        # create nem xml file
        nem_file = os.path.join(self.session.session_dir, nem_name)
        emanexml.create_nem_xml(self, config, nem_file, transport_name,
                                mac_name, phy_name)

        # create mac xml file
        mac_file = os.path.join(self.session.session_dir, mac_name)
        emanexml.create_mac_xml(self, config, mac_file)

        # create phy xml file
        phy_file = os.path.join(self.session.session_dir, phy_name)
        emanexml.create_phy_xml(self, config, phy_file)

    def post_startup(self):
        """
        Logic to execute after the emane manager is finished with startup.

        :return: nothing
        """
        logging.info("emane model(%s) has no post setup tasks", self.name)

    def update(self, moved, moved_netifs):
        """
        Invoked from MobilityModel when nodes are moved; this causes
        emane location events to be generated for the nodes in the moved
        list, making EmaneModels compatible with Ns2ScriptedMobility.

        :param bool moved: were nodes moved
        :param list moved_netifs: interfaces that were moved
        :return:
        """
        try:
            wlan = self.session.get_object(self.object_id)
            wlan.setnempositions(moved_netifs)
        except KeyError:
            logging.exception("error during update")

    def linkconfig(self,
                   netif,
                   bw=None,
                   delay=None,
                   loss=None,
                   duplicate=None,
                   jitter=None,
                   netif2=None):
        """
        Invoked when a Link Message is received. Default is unimplemented.

        :param core.netns.vif.Veth netif: interface one
        :param bw: bandwidth to set to
        :param delay: packet delay to set to
        :param loss: packet loss to set to
        :param duplicate: duplicate percentage to set to
        :param jitter: jitter to set to
        :param core.netns.vif.Veth netif2: interface two
        :return: nothing
        """
        logging.warn("emane model(%s) does not support link configuration",
                     self.name)
コード例 #18
0
 def load(cls, emane_prefix: Path) -> None:
     cls._load_platform_config(emane_prefix)
     shim_xml_path = emane_prefix / "share/emane/manifest" / cls.shim_xml
     cls.config_shim = emanemanifest.parse(shim_xml_path, cls.shim_defaults)
コード例 #19
0
class EmaneCommEffectModel(emanemodel.EmaneModel):
    name = "emane_commeffect"

    shim_library = "commeffectshim"
    shim_xml = "/usr/share/emane/manifest/commeffectshim.xml"
    shim_defaults = {}
    config_shim = emanemanifest.parse(shim_xml, shim_defaults)

    config_groups_override = "CommEffect SHIM Parameters:1-%d" % len(
        config_shim)
    config_matrix_override = config_shim

    def build_xml_files(self, emane_manager, interface):
        """
        Build the necessary nem and commeffect XMLs in the given path.
        If an individual NEM has a nonstandard config, we need to build
        that file also. Otherwise the WLAN-wide
        nXXemane_commeffectnem.xml, nXXemane_commeffectshim.xml are used.

        :param core.emane.emanemanager.EmaneManager emane_manager: core emane manager
        :param interface: interface for the emane node
        :return: nothing
        """
        values = emane_manager.getifcconfig(self.object_id, self.name,
                                            self.getdefaultvalues(), interface)
        if values is None:
            return

        # retrieve xml names
        nem_name = self.nem_name(interface)
        shim_name = self.shim_name(interface)

        nem_document = emane_manager.xmldoc("nem")
        nem_element = nem_document.getElementsByTagName("nem").pop()
        nem_element.setAttribute("name", "%s NEM" % self.name)
        nem_element.setAttribute("type", "unstructured")
        emane_manager.appendtransporttonem(nem_document, nem_element,
                                           self.object_id, interface)

        shim_xml = emane_manager.xmlshimdefinition(nem_document, shim_name)
        nem_element.appendChild(shim_xml)
        emane_manager.xmlwrite(nem_document, nem_name)

        names = self.getnames()
        shim_names = list(names)
        shim_names.remove("filterfile")

        shim_document = emane_manager.xmldoc("shim")
        shim_element = shim_document.getElementsByTagName("shim").pop()
        shim_element.setAttribute("name", "%s SHIM" % self.name)
        shim_element.setAttribute("library", self.shim_library)

        # append all shim options (except filterfile) to shimdoc
        for name in shim_names:
            value = self.valueof(name, values)
            param = emane_manager.xmlparam(shim_document, name, value)
            shim_element.appendChild(param)

        # empty filterfile is not allowed
        ff = self.valueof("filterfile", values)
        if ff.strip() != "":
            shim_element.appendChild(
                emane_manager.xmlparam(shim_document, "filterfile", ff))
        emane_manager.xmlwrite(shim_document, shim_name)

    def linkconfig(self,
                   netif,
                   bw=None,
                   delay=None,
                   loss=None,
                   duplicate=None,
                   jitter=None,
                   netif2=None):
        """
        Generate CommEffect events when a Link Message is received having
        link parameters.
        """
        service = self.session.emane.service
        if service is None:
            logger.warn("%s: EMANE event service unavailable", self.name)
            return

        if netif is None or netif2 is None:
            logger.warn("%s: missing NEM information", self.name)
            return

        # TODO: batch these into multiple events per transmission
        # TODO: may want to split out seconds portion of delay and jitter
        event = CommEffectEvent()
        emane_node = self.session.get_object(self.object_id)
        nemid = emane_node.getnemid(netif)
        nemid2 = emane_node.getnemid(netif2)
        mbw = bw
        logger.info("sending comm effect event")
        event.append(nemid,
                     latency=convert_none(delay),
                     jitter=convert_none(jitter),
                     loss=convert_none(loss),
                     duplicate=convert_none(duplicate),
                     unicast=long(convert_none(bw)),
                     broadcast=long(convert_none(mbw)))
        service.publish(nemid2, event)