This section explains the basic concepts behind the Mobility Framework. The class hierarchy is explained and all relevant functions of the Basic* modules are introduced. For the detailed description of the functionality of the individual modules read Sections 5 - 7 and also refer to the Neddoc and API reference.
The BasicModule uses the multi-stage initialization of OMNeT++ so all modules in the MF have to be implemented with two-stage initialization. In case you use the Blackboard you have to do all your publish calls in stage 0 and the subscribe calls have to be done in stage 1! This is to explicitly avoid that a subscription to a parameter can happen before that parameter is published.
In the template files the initialize(int) functions already contain the call of the initialize(int) function of the Basic Module this module is derived from. Do not delete this line as the obligatory parameters of the Basic Modules have to be initialized, too!
Additionally the BasicModule provides the logName() function, which returns the ned module name and the OMNeT++ module index() of the Host module this module belongs to. logName() is used in the debug macro for identification of the host the debug output comes from. You can use the EV «``your debug output'' macro to print debug messages.
We use the OMNeT++ module id()s for addressing in the MF. The nic module id() is used as mac address and the netwLayer module id() as network layer address. The netwLayer id() is also used as application layer address. In order to obtain the address of the module we provide a myApplAddr(), myNetwAddr() and myMacAddr() function in the BasicApplLayer, BasicNetwLayer and BasicMacLayer modules respectively.
The netw2mac() function of the ChannelControl module provides a simple ARP like translation of network addresses to MAC addresses. However by redefining the getMacAddr() function of the BasicNetwLayer you can implement your own ARP functionality.
There are some naming conventions for the modules in the ned files, you have to follow. Not following these naming conventions will result in segmentation faults upon execution of your code!!!
All host modules have to include the characters host or Host somewhere in its name. Whereas most of the example networks just use host as a ned module name, you could also come up with names like baseStationHost and mobileHost in order to create a centralized base station network.
For more or less all the other ned modules the names cannot be changed. Those are: channelcontrol, blackboard, net, phy, snrEval. However, it is a good practice to also keep the default names for the other modules (namely, appl, nic, mobility).
In order to have clearly defined interfaces that are easy to understand - and extend if necessary - we provide a Basic* module for each layer which in turn is derived from the global BasicModule explained above. The concept of a Basic* module is to have a base class which takes care of the necessary work that has to be done but is not of specific importance for the real functionality. The general derivation structure of a Mobility Framework module is shown in Figure 3. The Basic* modules also provide a very basic functionality in terms of ``the BasicNetwLayer is capable of forwarding messages to and from upper and lower layers but has no routing functionality at all yet''. The idea is to have the possibility to easily extend or adapt modules of different layers to the specific requirements of the simulation. To serve this purpose we defined two kinds of functions: handle*Msg() functions and convenience functions.
The handle*Msg() functions contain the actual protocol functionality. They are called each time a corresponding message arrives and contain all necessary processing and forwarding information for messages where required. We provide three different functions to handle the three different kinds of message events possible:
The convenience functions are defined to facilitate common interfaces and to hide inevitable interface management from the user. Here we provide three different functions:
These six functions are provided (with slide differences) in the Basic* module for each layer of the MF. Usually the three handle*Msg() and the initialize(int) and finish() functions are the only functions a programmer has to re-implement to create his/her own module and the functionality of it. The convenience functions should be used to serve the above described tasks so that newly implemented modules remain compatible with (almost) any other module implemented for the MF. The convenience functions cannot be changed in derived modules.
The tasks of the different modules and a more detailed description of the Basic* modules can be found in the following sections.
In order to provide basic functionality like encapsulating and decapsulating messages in the Basic* modules we need to have fixed message formats for every layer. The provided message types have the most important fields needed for the corresponding layer. These message types with these fields are obligatory and can only be extended but not exchanged. Here is a list of all base message classes and their parameters:
AirFrame | Physical Layer Message | |
pSend | sending power | |
channelId | channel the message is sent on | |
id | id of the originator to get the position | |
duration | time needed to send the message on the channel | |
SnrControlInfo | Control Information class; used to pass Sn(i)r information to the decider |
MacPkt | Medium Access Control Message | |
destAddr | destination MAC address | |
srcAddr | source MAC address | |
channelId | channel the message is sent on |
NetwPkt | Network Layer Message | |
destAddr | destination network address | |
srcAddr | source network address | |
seqNum | sequence number | |
ttl | time to life | |
MacControlInfo | Control Information class; used to tell the MAC protocol the address of the next hop |
ApplPkt | Application Layer Message | |
destAddr | destination application address | |
srcAddr | source application address |
If you need additional parameters you can derive your own message class from one of the basic message classes in the OMNeT++ style, in case of the network layer message:
cplusplus {{ #include "NetwPkt_m.h" }}; class NetwPkt; message YourPkt extends NetwPkt { fields: int extraField1; double extraField2; };Please note that the name of the included .h file has to be extended with _m as this is the file OMNeT++ creates out of a .msg file.
Now you have defined your own message, the next step is to teach the framework how to create it. To do so, you have to overwrite the createCapsulePkt function in YourNetwModule.h:
virtual NetwPkt* createCapsulePkt() { return new YourPkt; };When creating a new YourPkt message within your simulation it has to be done like this:
YourPkt* pkt = static_cast<YourPkt *>(createCapsulePkt());The framework does the same and is hence able to create YourPkt without even knowing that such a thing would spring into existence.
These steps are necessary to be able to do the following unavoidable cast operation. A message is usually given to you as a parameter in the handleUpperMsg() and handleLowerMsg() function in the basic message format. So, if you want to have access to the extra fields you have to cast the message into your format. For YourNetwModule you could use the following code:
void YourNetwModule::handleUpperMsg(NetwPkt *packet) { YourPkt *pkt = check_and_cast<YourPkt *>(packet); // do something with the message... }
OMNeT++ (version 3.0a4 or higher) allows you to define Control Information classes. They can be used to add meta information to a message that is only relevant for the next processing layer. When that layer receives this message it then can remove and process this information. As you can see in the tables, AirFrame and the NetwPkt have such a control information class.
The SnrControlInfo is used to pass s(i)nr information to the decider so that it can calculate bit errors based on the s(i)nr information of that message. The MacControlInfo contains the next hop MAC address the message should be forwarded to. Currently the MF provides no means to extend the control information attached to a message. If you need to exchange additional meta information you would have to add it as a ``normal'' parameter to your derived message as only one control information is allowed per message. However please tell us in case you need additional control information as we might extend the SnrControlInfo or MacControlInfo respectively if appropriate. Currently we only provide the absolutely necessary information. But especially the MacControlInfo serves as interface between MAC and network layer that we want to provide as powerful as possible.
A nic is a network interface card that includes physical layer functions like transmitting, receiving, modulation as well as medium access mechanisms. The nic module in the MF therefore is divided into a physical layer like part (snrEval and decider) and a MAC layer (macLayer). The snrEval module can be used to compute some sn(i)r information for a received message whereas the decider module can process this information to decide whether a message got lost, has bit errors or is correctly received. Therefore the decider only handles received messages and not messages that should be sent. The corresponding compound module with its simple modules is shown in Figure 4.
The reason for putting the physical and the MAC components into one compound module is easily explained. For most lower layer protocols the MAC and the physical layer have to be coordinated, so for one protocol (e.g. IEEE 802.11) there will be a corresponding snrEval module as well as a corresponding decider module as well as a corresponding mac module. So, if you decide to run a certain routing protocol over a certain PHY/MAC protocol you simply need to choose the corresponding nic module when building the host (see Section 3.2).1
In the following the physical layer modules are explained in more detail.