4

As all the simple modules' behavior like 80211 mac layer has been defined in the INET module. If I want to add a customize layer between mac layer and network layer to handle network coding. How can I combine the customize module and INET's simple module ?

Thomas.ZHOU
  • 57
  • 1
  • 8

1 Answers1

7

To add a new module between network layer and MAC layer I suggest creating a modified host in a new project. For OMNeT++ 4.6 and INET 3.2.4 do the following:

  1. Create a new OMNeT++ empty project with src and simulation directories.
  2. In the new project open Properties | Project References and select inet.
  3. Right click on src and select New | Simple module. Call it DummyLayer.ned.
  4. Open DummyLayer.ned and add:

    @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. Modify DummyLayer.h and DummyLayer.cc (this module just passes every message from up and down, as well as increments counters):

    // 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. Create a new compound module for own host, call it 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;
            }
    }
    

An own host module is necessary because StandardHost from INET creates connection between MAC and network layer automatically and it is not possible to add own module between these layers.

  1. Create a network (for test):

    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. Modify 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
    

After starting the simulation one can see that in each host dummyLayer send messages forward.

Jerzy D.
  • 5,417
  • 2
  • 12
  • 16
  • Thank you very much Jerzy. It helps me a lot. I have some questions after reading the codes. Because I am not familiar with NED's language so can you explain the code like `wlan[numRadios]: like IWirelessNic`. What is the meaning of and like. Is there any language like NED's language ? And in the DummyLayer.cc, what's the meaning of `getDisplayString().setTagArg("t", 0, buf);` ? – Thomas.ZHOU Apr 18 '16 at 08:06
  • The line `wlan[numRadios]: like IWirelessNic` means: create `numRadios` instances of wlan modules, each one of `Ieee80211Nic` NED type unless in `omnetpp.ini` is selected another type. To select another type of `wlan` module one should write in `omnetpp.ini` for example: `**.wlan[*].typename = "IdealWirelessNic"` where `IdealWirelessNic` is the name of compound module which has to inherit from `IWirelessNic`. The `typename` word is part of NED grammar, see in the OMNeT++ Manual. – Jerzy D. Apr 18 '16 at 08:10
  • The line `getDisplayString().setTagArg("t", 0, buf);` just adds a text from `buf` above icon of the module. Display Strings are described in details in chapter 8.1 of OMNeT++ Manual. Generally speaking, display strings allow adding any text to icon of module, as well as changing colour, position, adding a tooltip etc. – Jerzy D. Apr 18 '16 at 08:15
  • So the code ` like IWirelessNic` means the Ieee80211Nic inherit from `IWirelessNic` ? As you say the line`getDisplayString().setTagArg("t", 0, buf);` adds a text form `buf` above icon of the module, but where can I see it ? – Thomas.ZHOU Apr 18 '16 at 08:58
  • Yes. The part `like IWirelessNic` means that a NED module selected for wlan **has to** inherit from `IWirelessNic`. So `Ieee80211Nic` has to inherit from `IWirelessNic` as well as any other module selected in `omnetpp.ini` has to inherit from `IWirelessNic`. In order to see a text above dummy layer module you should start simulation in graphical mode (usually it is default), then double click on a host. You will see internal structure of the host including the dummy layer module. Then start a simulation. – Jerzy D. Apr 18 '16 at 09:09
  • 1
    Hi, Jerzy. When I look inside the host and start a simulation, I found that the transmission is only based on the mac layer but don't go through the dummy layer. What is the protocol used in this model ? – Thomas.ZHOU Apr 19 '16 at 03:10
  • I have prepared a general model of host, which is the same as `StandardHost` except an additional dummy module between MAC and NET. By default it uses IPv4 protocol and it is ready to use any of `OMNeT++` application for UDP or TCP. One can add this application manipulating `omnetpp.ini` only (look at examples in inet). I have only added ping application in `omnetpp.ini`from my answer. The ping is send in 1 s interval, so start the simulation and wait until e.g. t=3s, then stop the simulation and look inside a host. You will see that some packet were passed by dummy layer. – Jerzy D. Apr 19 '16 at 08:35
  • Hi, Jerzy, thank you for your detailed answer. I have some new questons now. When I start the simulation, there are some messages like Beacon, ProbeReq, ProbeResp, Auth, Auth-ok, Assoc, AssocResp-ok and arpREQ. What do these messages used for? Is these messages used for detecting the nodes around AP ? And when do the ping application, are the messages broadcasting and must go through the access point and will ignore the messages from other point directly ? – Thomas.ZHOU May 11 '16 at 08:06
  • How can i send messages between node 0 and node 1 ? – Thomas.ZHOU May 11 '16 at 08:16
  • What type of message are you intend to send - a UDP packet or a TCP packet? Do you want send one packet or more? – Jerzy D. May 11 '16 at 18:23
  • I want to send the UDP packet and the coding node can multiply the native packets together like a1*packet1+a2*packet2. The coefficient are coming from the Galois field. And the the coding node can store the coded packets in the batch. I am confused that how to multiply the coefficient and data of packet together and add them together to form a new packet. – Thomas.ZHOU May 12 '16 at 05:51
  • What do you mean by _multiply_ packets? Could you provide any example? Generally speaking sending a UDP or TCP packet using `WirelessHostEx` module will be the same as sending packets from `StandardHost` or `WirelessHost`. Therefore I suggest adding a new question and explain what exactly and when you want to send to another node and what another node should do with received packet. – Jerzy D. May 12 '16 at 06:20
  • Fine, I will add a new question and tell you the name when I finish it. – Thomas.ZHOU May 12 '16 at 06:25
  • Hi, Jerzy,the question's name is How to build a network-coding based wireless sensor network in Omnet with INET. – Thomas.ZHOU May 12 '16 at 08:38
  • Hi, Jerzy, I put the calculation in the question called The calculation in Galois field and this method can also solve the problem of overflow. – Thomas.ZHOU May 17 '16 at 13:34