Как я могу объединить свой модуль настройки с простым модулем Omnet ++ INET

Поскольку поведение всех простых модулей, таких как уровень 80211 mac, определено в модуле INET. Если я хочу добавить слой настройки между уровнем Mac и сетевым уровнем для обработки сетевого кодирования. Как я могу объединить модуль настройки и простой модуль INET?


person Thomas.ZHOU    schedule 14.04.2016    source источник


Ответы (1)


Чтобы добавить новый модуль между сетевым уровнем и MAC-уровнем, я предлагаю создать модифицированный хост в новом проекте. Для OMNeT++ 4.6 и INET 3.2.4 выполните следующие действия:

  1. Создайте новый OMNeT++ пустой проект с каталогами src и Simulation.
  2. В новом проекте откройте Properties | Project References и выберите inet.
  3. Щелкните правой кнопкой мыши src и выберите New | Simple module. Назовите это DummyLayer.ned.
  4. Откройте DummyLayer.ned и добавьте:

    @namespace(inet);
    import inet.linklayer.contract.INic;
    
    simple DummyLayer like INic {
    parameters:
        @display("i=block/buffer");
        // here you can add others parameter
    gates:
        input ifIn;
        output ifOut;
        input upperLayerIn;
        output upperLayerOut;
    }
    
  5. Измените DummyLayer.h и DummyLayer.cc (этот модуль просто передает каждое сообщение сверху и снизу, а также увеличивает счетчики):

    // DummyLayer.h
    #include <omnetpp.h>
    namespace inet {
    class DummyLayer: public cSimpleModule {
    protected:
        virtual void initialize();
        virtual void handleMessage(cMessage *msg);
    private:
        int upNumber;
        int downNumber;
    };
    } //namespace
    
    //----------------------------------------------
    // DummyLayer.cc
    #include "DummyLayer.h"
    namespace inet {
    Define_Module(DummyLayer);
    
    void DummyLayer::initialize() {
       upNumber = 0;
       downNumber = 0;
    }
    
    void DummyLayer::handleMessage(cMessage *msg) {
      if (msg->arrivedOn("upperLayerIn")) {
          send(msg, "ifOut");
          downNumber++;
      } else if (msg->arrivedOn("ifIn")) {
          send(msg, "upperLayerOut");
          upNumber++;
      } else {
          error("Incorrect gate");
      }
      char buf[128];
      sprintf(buf, "up: %d, down: %d", upNumber, downNumber);
      getDisplayString().setTagArg("t", 0, buf);
      }
    } //namespace
    
  6. Создайте новый составной модуль для собственного хоста, назовите его WirelessHostEx.ned:

    import inet.common.lifecycle.NodeStatus;
    import inet.linklayer.contract.IWiredNic;
    import inet.linklayer.contract.IWirelessNic;
    import inet.linklayer.loopback.LoopbackInterface;
    import inet.mobility.contract.IMobility;
    import inet.networklayer.contract.IRoutingTable;
    import inet.networklayer.common.InterfaceTable;
    import inet.networklayer.contract.INetworkLayer;
    import inet.power.contract.IEnergyStorage;
    import inet.power.contract.IEnergyGenerator;
    import inet.applications.contract.IPingApp;
    import inet.applications.contract.ISCTPApp;
    import inet.applications.contract.ITCPApp;
    import inet.applications.contract.IUDPApp;
    import inet.transportlayer.contract.ISCTP;
    import inet.transportlayer.contract.ITCP;
    import inet.transportlayer.contract.IUDP;
    import inet.node.inet.INetworkNode;
    
    module WirelessHostEx like INetworkNode
    {
        parameters:
            @networkNode;
            @display("i=device/wifilaptop");
            @labels(wireless-node);
            bool hasStatus = default(false);
            int numExtInterfaces = default(0);
            int numRadios = 1;
            int numTunInterfaces = default(0);
            string mobilityType = default(numRadios > 0 ? "StationaryMobility" : "");
            string networkLayerType = default("IPv4NetworkLayer");
            string routingTableType = default("IPv4RoutingTable");
            bool forwarding = default(true);
            bool multicastForwarding = default(false);
            string energyStorageType = default("");
            string energyGeneratorType = default("");
            routingTable.forwarding = forwarding;
            routingTable.multicastForwarding = multicastForwarding;  
            *.interfaceTableModule = default(absPath(".interfaceTable"));
            *.routingTableModule = default(routingTableType != "" ? absPath(".routingTable") : "");
            *.energySourceModule = default(energyStorageType != "" ? absPath(".energyStorage") : "");
            *.mobilityModule = default(mobilityType != "" ? absPath(".mobility") : "");
            int numTcpApps = default(0);
            int numUdpApps = default(0); 
            int numPingApps = default(0); 
            bool hasTcp = default(numTcpApps > 0);
            bool hasUdp = default(numUdpApps > 0);
            string tcpType = default(firstAvailableOrEmpty("TCP", "TCP_lwIP", "TCP_NSC"));  // tcp implementation (e.g. ~TCP, ~TCP_lwIP, ~TCP_NSC) or ~TCPSpoof
            string udpType = default(firstAvailableOrEmpty("UDP"));
            forwarding = default(false);  // disable routing by default
            networkLayer.proxyARP = default(false);
        gates:
            input radioIn[numRadios] @directIn;
            inout pppg[] @labels(PPPFrame-conn);
            inout ethg[] @labels(EtherFrame-conn);
        submodules:
            status: NodeStatus if hasStatus {
                @display("p=50,50");
            }
            energyStorage: <energyStorageType> like IEnergyStorage if energyStorageType != "" {
                parameters:
                    @display("p=50,100;i=block/plug;is=s");
            }
            energyGenerator: <energyGeneratorType> like IEnergyGenerator if energyGeneratorType != "" {
                parameters:
                    @display("p=50,150;i=block/plug;is=s");
            }
            mobility: <mobilityType> like IMobility if mobilityType != "" {
                parameters:
                    @display("p=53,200");
            }
            networkLayer: <networkLayerType> like INetworkLayer {
                parameters:
                    @display("p=329,287;q=queue");
            }
            routingTable: <routingTableType> like IRoutingTable if routingTableType != "" {
                parameters:
                    @display("p=53,250;is=s");
            }
            interfaceTable: InterfaceTable {
                parameters:
                    @display("p=53,300;is=s");
            }
            lo0: LoopbackInterface {
                @display("p=78,406");
            }
            wlan[numRadios]: <default("Ieee80211Nic")> like IWirelessNic {
                parameters:
                    @display("p=216,406,row,60;q=queue");
            }
            eth[sizeof(ethg)]: <default("EthernetInterface")> like IWiredNic {
                parameters:
                    @display("p=368,406,row,60;q=txQueue");
            }
            ppp[sizeof(pppg)]: <default("PPPInterface")> like IWiredNic {
                parameters:
                    @display("p=558,406,row,60;q=txQueue");
            }
            tcpApp[numTcpApps]: <> like ITCPApp {
                parameters:
                    @display("p=147,54,row,60");
            }
            tcp: <tcpType> like ITCP if hasTcp {
                parameters:
                    @display("p=147,141");
            }
            udpApp[numUdpApps]: <> like IUDPApp {
                parameters:
                    @display("p=329,54,row,60");
            }
            udp: <udpType> like IUDP if hasUdp {
                parameters:
                    @display("p=329,141");
            }
            pingApp[numPingApps]: <default("PingApp")> like IPingApp {
                parameters:
                    @display("p=635,141,row,60");
            }
            dummy: DummyLayer {
                @display("p=273,350");
            }
        connections allowunconnected:
            radioIn[0] --> { @display("m=s"); } --> wlan[0].radioIn;
            // the order of connections is important here
            wlan[0].upperLayerOut --> dummy.ifIn;
            dummy.upperLayerOut --> networkLayer.ifIn++;
            wlan[0].upperLayerIn <-- dummy.ifOut;
            dummy.upperLayerIn <-- networkLayer.ifOut++;
            networkLayer.ifOut++ --> lo0.upperLayerIn;
            lo0.upperLayerOut --> networkLayer.ifIn++;
            for i=0..sizeof(ethg)-1 {
                ethg[i] <--> { @display("m=s"); } <--> eth[i].phys;
                eth[i].upperLayerOut --> networkLayer.ifIn++;
                eth[i].upperLayerIn <-- networkLayer.ifOut++;
            }
            for i=0..sizeof(pppg)-1 {
                pppg[i] <--> { @display("m=s"); } <--> ppp[i].phys;
                ppp[i].upperLayerOut --> networkLayer.ifIn++;
                ppp[i].upperLayerIn <-- networkLayer.ifOut++;
            }
            for i=0..numTcpApps-1 {
                tcpApp[i].tcpOut --> tcp.appIn++;
                tcpApp[i].tcpIn <-- tcp.appOut++;
            }
            tcp.ipOut --> networkLayer.transportIn++ if hasTcp;
            tcp.ipIn <-- networkLayer.transportOut++ if hasTcp;
            for i=0..numUdpApps-1 {
                udpApp[i].udpOut --> udp.appIn++;
                udpApp[i].udpIn <-- udp.appOut++;
            }
            udp.ipOut --> networkLayer.transportIn++ if hasUdp;
            udp.ipIn <-- networkLayer.transportOut++ if hasUdp;
            for i=0..numPingApps-1 {
                networkLayer.pingOut++ --> pingApp[i].pingIn;
                networkLayer.pingIn++ <-- pingApp[i].pingOut;
            }
    }
    

Необходим собственный хост-модуль, потому что StandardHost из INET автоматически создает соединение между MAC и сетевым уровнем, и невозможно добавить собственный модуль между этими уровнями.

  1. Создадим сеть (для теста):

    import inet.networklayer.configurator.ipv4.IPv4NetworkConfigurator;
    import inet.physicallayer.ieee80211.packetlevel.Ieee80211ScalarRadioMedium;
    import inet.node.wireless.AccessPoint;
    
    network WirelessNetwork {
        submodules:
            configurator: IPv4NetworkConfigurator {
                @display("p=33,81");
            }
            radioMedium: Ieee80211ScalarRadioMedium {
                @display("p=33,30");
            }
            node0: WirelessHostEx {
                @display("p=128,121");
            }
            node1: WirelessHostEx {
                @display("p=384,115");
            }
            ap: AccessPoint {
                @display("p=273,54");
            }
    }
    
  2. Изменить omnetpp.ini:

    [General]
    network = WirelessNetwork
    
    // node0 will send ping to node1
    **.node0.numPingApps = 1
    **.node0.pingApp[0].destAddr = "node1" // using IP address here is allowed too
    

После запуска моделирования видно, что на каждом хосте dummyLayer отправляются сообщения вперед.

person Jerzy D.    schedule 15.04.2016
comment
Большое спасибо Ежи. Это мне очень помогает. После прочтения кодов у меня возникли вопросы. Поскольку я не знаком с языком NED, вы можете объяснить код, например wlan[numRadios]: <default("Ieee80211Nic")> like IWirelessNic. Что означает ‹default (Ieee80211Nic)› и т.п. Есть ли такой язык, как язык NED? А в DummyLayer.cc что означает getDisplayString().setTagArg("t", 0, buf);? - person Thomas.ZHOU; 18.04.2016
comment
Строка wlan[numRadios]: <default("Ieee80211Nic")> like IWirelessNic означает: создавать numRadios экземпляры модулей wlan, каждый из Ieee80211Nic типа NED, если в omnetpp.ini не выбран другой тип. Чтобы выбрать другой тип wlan модуля, нужно написать в omnetpp.ini, например: **.wlan[*].typename = "IdealWirelessNic", где IdealWirelessNic - имя составного модуля, который должен унаследовать от IWirelessNic. Слово typename является частью грамматики NED, см. Руководство по OMNeT ++. - person Jerzy D.; 18.04.2016
comment
Строка getDisplayString().setTagArg("t", 0, buf); просто добавляет текст из buf над значком модуля. Отображаемые строки подробно описаны в главе 8.1 руководства OMNeT ++. Вообще говоря, отображаемые строки позволяют добавлять любой текст к значку модуля, а также изменять цвет, положение, добавлять всплывающие подсказки и т. Д. - person Jerzy D.; 18.04.2016
comment
Итак, код <default("Ieee80211Nic")> like IWirelessNic означает, что Ieee80211Nic унаследован от IWirelessNic? Как вы говорите, строкаgetDisplayString().setTagArg("t", 0, buf); добавляет текстовую форму buf над значком модуля, но где я могу ее увидеть? - person Thomas.ZHOU; 18.04.2016
comment
да. Часть like IWirelessNic означает, что модуль NED, выбранный для wlan, должен наследовать от IWirelessNic. Таким образом, Ieee80211Nic должен наследовать от IWirelessNic, а любой другой модуль, выбранный в omnetpp.ini, должен наследовать от IWirelessNic. Чтобы увидеть текст над модулем фиктивного слоя, вы должны запустить симуляцию в графическом режиме (обычно это по умолчанию), а затем дважды щелкнуть по хосту. Вы увидите внутреннюю структуру хоста, включая модуль фиктивного уровня. Затем запустите моделирование. - person Jerzy D.; 18.04.2016
comment
Привет, Ежи. Когда я смотрю внутрь хоста и запускаю симуляцию, я обнаружил, что передача основана только на уровне Mac, но не проходит через фиктивный слой. Какой протокол используется в этой модели? - person Thomas.ZHOU; 19.04.2016
comment
Я подготовил общую модель хоста, аналогичную StandardHost, за исключением дополнительного фиктивного модуля между MAC и NET. По умолчанию он использует протокол IPv4 и готов к использованию любого OMNeT++ приложения для UDP или TCP. Можно добавить это приложение, манипулирующее только omnetpp.ini (см. Примеры в inet). Я добавил приложение ping только в omnetpp.ini из своего ответа. Пинг отправляется с интервалом в 1 с, поэтому запустите моделирование и дождитесь, например, t = 3 с, затем остановите моделирование и загляните внутрь хоста. Вы увидите, что какой-то пакет был передан фиктивным слоем. - person Jerzy D.; 19.04.2016
comment
Привет, Ежи, спасибо за подробный ответ. У меня есть несколько новых квестонов. Когда я запускаю симуляцию, появляются сообщения вроде Beacon, ProbeReq, ProbeResp, Auth, Auth-ok, Assoc, AssocResp-ok и arpREQ. Для чего используются эти сообщения? Используются ли эти сообщения для обнаружения узлов вокруг точки доступа? И когда приложение ping выполняет широковещательную передачу сообщений, должно проходить через точку доступа и игнорировать сообщения из другой точки напрямую? - person Thomas.ZHOU; 11.05.2016
comment
Как я могу отправлять сообщения между узлом 0 и узлом 1? - person Thomas.ZHOU; 11.05.2016
comment
Сообщение какого типа вы собираетесь отправить - пакет UDP или пакет TCP? Вы хотите отправить один или несколько пакетов? - person Jerzy D.; 11.05.2016
comment
Я хочу отправить пакет UDP, и узел кодирования может умножить собственные пакеты вместе, например a1 * packet1 + a2 * packet2. Коэффициент взят из поля Галуа. Узел кодирования может хранить закодированные пакеты в пакете. Меня смущает то, как умножить коэффициент и данные пакета вместе и сложить их вместе, чтобы сформировать новый пакет. - person Thomas.ZHOU; 12.05.2016
comment
Что вы имеете в виду под умножением пакетов? Не могли бы вы привести какой-нибудь пример? Вообще говоря, отправка пакета UDP или TCP с использованием модуля WirelessHostEx будет такой же, как отправка пакетов от StandardHost или WirelessHost. Поэтому я предлагаю добавить новый вопрос и объяснить, что именно и когда вы хотите отправить другому узлу и что другой узел должен делать с полученным пакетом. - person Jerzy D.; 12.05.2016
comment
Хорошо, я добавлю новый вопрос и назову тебе имя, когда закончу его. - person Thomas.ZHOU; 12.05.2016
comment
Привет, Ежи, вопрос называется «Как построить сеть беспроводных датчиков на основе сетевого кодирования в Omnet с помощью INET». - person Thomas.ZHOU; 12.05.2016
comment
Привет, Ежи, я поместил расчет в вопрос под названием «Расчет в поле Галуа», и этот метод также может решить проблему переполнения. - person Thomas.ZHOU; 17.05.2016