MIH implementation: Difference between revisions
Line 165: | Line 165: | ||
An example can be taken from the definition of the LinkUp primitive in the MihLinkSap class: | An example can be taken from the definition of the LinkUp primitive in the MihLinkSap class: | ||
The event flow is : | The event flow is : | ||
(LinkUpInd) WifiNetDevice ===> WifiMihLinkSap ===> MihFunction (MihLinkUpInd) ===> MihSap ===> Application/MobilityManagementProtocol (MIH USER) | |||
*virtual void LinkUp (Ptr<MihLinkSap>, Ptr<LinkUpInd>) = 0; | *virtual void LinkUp (Ptr<MihLinkSap>, Ptr<LinkUpInd>) = 0; | ||
**Invoked by the client (aggregated) NetDevice whenever it needs to trigger a LinkUp indication | **Invoked by the client (aggregated) NetDevice whenever it needs to trigger a LinkUp indication |
Revision as of 14:09, 1 November 2008
The goal of this article is to describe the ongoing implementation framework of the emerging 802.21 standard in ns-3. If you arrived here following your high curiosity line, that's great but assure that you have first read a few documents regarding that draft standard.
Main Page - Roadmap - Summer Projects - Project Ideas - Developer FAQ - Tools - Related Projects
HOWTOs - Installation - Troubleshooting - User FAQ - Samples - Models - Education - Contributed Code - Papers
Overview
MIH framework in NS-3
In MIH, the main blocks are:
- MIH Function
- MIH User
- Link -- called NetDevice in ns-3
- SAP -- interfaces between them.
In ns-3, the MIH framework is being implemented by taking profit of the native "Object Aggregation" mechanism. You have to consider the following classes if you want to make any interaction with the MIH framework:
- MihLinkSap -- a generic class exposing the MIH_LINK_SAP interface to NetDevice
- MihSap -- a generic class exposing the media independent MIH_SAP to MIH_USER
- MihFunction -- defined as a final class
For each technology type you want to have support from the MIH framework, you need to subclass the MihLinkSap and "add" (AggregateObject) such an implementation as an interface to your NetDevice. This makes it possible for the MihFunction to query your NetDevice for the generic MihLinkSap interface.
The same applies when defining an MIH USER application. You will need to subclass the MihSap and aggregate it to your MIH USER entity so that the MihFunction can query for its generic MihSap interface.
API description
Where is what?
Several data types come shipped within the MIH framework. Specially, you will find some in the related files:
- General data types -- src/mih/mih-define.h
- Status -- the status of the primitive execution
- Data types for addresses -- use the native Address class
- Data types for links manipulation -- src/mih/mih-link.h
- BattLevel -- percentage of battery charge remaining
- ChannelId -- channels identifier
- DevStatesReq -- list of device state requests
- DevStatesRsp -- a device status
- ...
- QoS-related data types -- src/mih/mih-qos.h
- DIP configuration related data types -- src/mih/mih-ip-configuration.h
- Information Element related data types -- src/mih/mih-information-element.h
- MIHF identification related data -- src/mih/mihf-id.h
- MIHF registration related data -- src/mih/mih-registration.h
- ...
- MIH_LINK_SAP generic class -- src/mih/mih-link-sap.h
- MIH_SAP generic class -- src/mih/mih-sap.h
- MIH_FUNCTION class -- src/mih/mih-function.h
Use of smart pointers
Most of the data structures used in the MIH framework can be accessed via the native smart pointer (Ptr<>) API. This is done by adding the macro definitions PTR_HELPER_HEADER (MyClass) and PTR_HELPER_IMPLEM (MyClass) in the files "my-class.h" and "my-class.cc" respectively. You can browse these macros in src/mih/mih-define.{h,cc} files.
As an example, let's assume that you are defining a new class called "MyClass" and you want it to be accessible through smart pointers.
In my-class.h, you will have:
class MyClass { public: MyClass (void); // Constructor PTR_HELPER_HEADER (MyClass); // ptr-ize uint8_t GetData (void); protected: uint8_t m_data; // inner data }
In my-class.cc,
MyClass::MyClass (void) : m_refCount (1), // this first! <===== Required by PTR API m_data (0) // Inner data after! {} PTR_HELPER_IMPLEM (MyClass) // ptr-ize uint8_t MyClass::GetData (void) { return m_data; }
Designing choice structures
Various data types in the MIH framework are choices among unrelated data structures. For example, a device status response to a device status query can be either a device info (string representing the manufacturer information, the model number, the revision number of the firmware) or a percentage of battery charge remaining (integer between 1 and 100).
To deal with this frequent requirement, a set of macro are introduced.:
- CHOICE_HELPER_PURE_VIRTUAL_HEADER (MyChoiceDataType)
- CHOICE_HELPER_PURE_VIRTUAL_IMPLEM (MyChoiceDataType)
- CHOICE_HELPER_HEADER (MyFirstChoiceDataType, MyChoiceDataType)
- CHOICE_HELPER_IMPLEM (MyFirstChoiceDataType, MyChoiceDataType)
Assume that we have to define a data choice structure, called MyChoiceDataType, and we have to choose between elements of types MyFirstChoiceDataType (containing a string) and MySecondChoiceDataType (shipping an integer). Here is how we implement this:
In my-choice-data-type.h, MyChoiceDataType is declared as a generic class:
class MyChoiceDataType { public: PTR_HELPER_PURE_VIRTUAL_HEADER (MyChoiceDataType); // ptr-ize of a generic class CHOICE_HELPER_PURE_VIRTUAL_HEADER (MyChoiceDataType); // choice data type declaration protected: };
In my-choice-data-type.cc, add the following:
CHOICE_HELPER_PURE_VIRTUAL_IMPLEM (MyChoiceDataType)
In my-first-choice-data-type.h,
class MyFirstChoiceDataType : public MyChoiceDataType { public: MyFirstChoiceDataType (void); PTR_HELPER_HEADER (MyFirstChoiceDataType); CHOICE_HELPER_HEADER (MyFirstChoiceDataType, MyChoiceDataType); // relate to the base choice data type protected: };
In my-first-choice-data-type.cc,
MyFirstChoiceDataType::MyFirstChoiceDataType (void) : m_refCount (1) // ptr-ize {} PTR_HELPER_IMPLEM (MyFirstChoiceDataType) // ptr-ize CHOICE_HELPER_IMPLEM (MyFirstChoiceDataType, MyChoiceDataType) // choice definition
The same stands for all other elementary choices that you'll need to have as follows:
In my-second-choice-data-type.h,
class MySecondChoiceDataType : public MyChoiceDataType { public: MySecondChoiceDataType (void); PTR_HELPER_HEADER (MySecondChoiceDataType); CHOICE_HELPER_HEADER (MySecondChoiceDataType, MyChoiceDataType); // relate to the base choice data type protected: };
In my-second-choice-data-type.cc,
MySecondChoiceDataType::MySecondChoiceDataType (void) : m_refCount (1) // ptr-ize {} PTR_HELPER_IMPLEM (MySecondChoiceDataType) // ptr-ize CHOICE_HELPER_IMPLEM (MySecondChoiceDataType, MyChoiceDataType) // choice definition
You might now want to see how to deal with these macros in a real example:
typedef std::vectro<Ptr<MyChoiceDataType> > MyChoiceDataTypeContainer; MyChoiceDataTypeContainer myCurrentChoices; Ptr<MyChoiceDataType> myChoice; myCurrentChoice = Create<MyFirstChoiceDataType> (); myChoices.push_back (myCurrentChoice); myCurrentChoice = Create<MySecondChoiceDataType> (); myChoices.push_back (myCurrentChoice); for (MyChoiceDataTypeContainer::iterator i = myCurrentChoices.begin (); i != myCurrentChoices.end (); i++) { if (i->GetType () == MyFirstChoiceDataType::GetClassType ()) { std::cout << "This choice is of type : MyFirstChoiceDataType" << std::endl; } if (i->GetType () == MySecondChoiceDataType::GetClassType ()) { std::cout << "This choice is of type : MySecondChoiceDataType" << std::endl; } }
A deeper example of how to use this design can be found in src/mih/mih-test-device-states-response.cc (where the choice is made between an DeviceInfo and a BattLevel). This can be run with
./waf --run mih-test-device-states-response
Primitives and parameters
Each primitive in a given SAP comprises two key elements:
- its name -- used by its clients to make call to some of its callbacks
- its set of parameters -- a wrapper class of all the required parameters so that only one parameter is passed to the primitive
Most of the primitives define internal Callback<> that are used only inside the MIH framework.
An example can be taken from the definition of the LinkUp primitive in the MihLinkSap class: The event flow is : (LinkUpInd) WifiNetDevice ===> WifiMihLinkSap ===> MihFunction (MihLinkUpInd) ===> MihSap ===> Application/MobilityManagementProtocol (MIH USER)
- virtual void LinkUp (Ptr<MihLinkSap>, Ptr<LinkUpInd>) = 0;
- Invoked by the client (aggregated) NetDevice whenever it needs to trigger a LinkUp indication
- Relays the call to the internal LinkUpIndCallback m_linkUpIndCb;
- m_linkUpIndCb (m_mihLinkSap, linkUpInd) makes call to m_mihFunction->LinkUpIndication (m_mihLinkSap, linkUpInd)
Asynchronism
Tasks completed so far
By now, the following MIH blocks are defined:
- An abstract MIH_LINK_SAP class and its primitives
- An abstract MIH_SAP class and its primitives (except those related to remote communication)
Ongoing development
The following tasks are being held currently:
- Implementation of the MIH_FUNCTION for local MIH events and commands exchanges:
- Link events delivery from MIH_LINK_SAPs to MIH_USERs (through MIH_SAPs)
- Command delivery from MIH_USERs to MIH_LINK_SAPs
Foresights
In this section, you will find various components that are still needed to have start some MIH framework tests.
They are presented in their order of priority:
Local MIH exchanges
- Integration with WifiNetDevice and WimaxNetDevice
- WifiMihLinkSap -- ready to be done
- WimaxMihLinkSap -- until Wimax is validated
- Examples of MIH Users entities:
- A simple application is to be defined later.
Remote MIH exchanges
(design discussion is first needed)
- The MIH Protocol including:
- Packet TLV formats
- MIH message header format
- Transport of MIH messages over L3+ plane
- MIIS
- RDF schemas