\chapter{Messages}
\label{cha:messages}

\section{Messages and packets}

\subsection{The cMessage class}

\cclass{cMessage} is a central class in {\opp}. Objects of \cclass{cMessage} and
subclasses may model a number of things: events\index{events};
messages\index{message}; packets\index{packets},
frames\index{frames}, cells\index{cells}, bits or signals travelling
in a network; entities travelling in a system and so on.


\subsubsection{Attributes}


A \cclass{cMessage} object has number of attributes. Some are used by
the simulation kernel, others are provided just for the convenience
of the simulation programmer. A more-or-less complete list:

\begin{itemize}
  \item{The \textit{name} attribute is a string (\ttt{const char *}),
    which can be freely used by the simulation programmer. The message
    name appears in many places in Tkenv (for example, in animations),
    and it is generally very useful to choose a descriptive name.
    This attribute is inherited from \cclass{cObject} (see section
    \ref{sec:ch-sim-lib:cObject}).}
  \item{The \textit{message kind} attribute is supposed to carry some message
    type information. Zero and positive values can be freely used
    for any purpose. Negative values are reserved for use by the
    {\opp} simulation library.}
  \item{The \textit{length} attribute (understood in bits) is used to compute
    transmission delay when the message travels through a connection
    that has an assigned data rate.}
  \item{The \textit{bit error flag} attribute is set to true by the simulation
    kernel with a probability of $1-(1-\textit{ber})^{\mathit{length}}$ when the
    message is sent through a connection that has an assigned bit
    error rate (\textit{ber}).}
  \item{The \textit{priority} attribute is used by the simulation kernel to
    order messages in the message queue (FES) that have the same
    arrival time values.}
  \item{The \textit{time stamp} attribute is not used by the simulation kernel;
    you can use it for purposes like remembering the time when the
    message was enqueued or re-sent.}
  \item{Other attributes and data members make simulation programming
    easier, they will be discussed later: \textit{parameter list}, \textit{encapsulated
      message}, \textit{context pointer}.}
  \item{A number of read-only attributes store information about the
    message's (last) sending/scheduling: \textit{source/destination module
      and gate}, \textit{sending (scheduling) and arrival time}. They are
    mostly used by the simulation kernel while the message is in
    the FES, but the information is still in the message object when
    a module receives the message.}
\end{itemize}


\subsubsection{Basic usage}


The \cclass{cMessage} constructor accepts several arguments.
Most commonly, you would create a message using an \textit{object name}
(a \ttt{const char *} string) and a \textit{message kind} (\ttt{int}):

\begin{verbatim}
cMessage *msg = new cMessage("MessageName", msgKind);
\end{verbatim}

Both arguments are optional and initialize to the null string (\ttt{""})
and 0, so the following statements are also valid:

\begin{verbatim}
cMessage *msg = new cMessage();
cMessage *msg = new cMessage("MessageName");
\end{verbatim}

It is a good idea to \textit{always} use message names -- they can be
extremely useful when debugging or demonstrating your simulation.

Message kind is usually initialized with a symbolic constant
(e.g. an \textit{enum} value) which signals what the message object
represents in the simulation (i.e. a data packet, a jam signal, a job, etc.)
Please use \textit{positive values or zero} only as message kind --
negative values are reserved for use by the simulation kernel.


The \cclass{cMessage} constructor accepts further arguments too
(\textit{length}, \textit{priority}, \textit{bit error flag}),
but for readability of the code it is best to set them explicitly
via the \ttt{set...()} methods described below.
Length and priority are integers, and the bit error flag is boolean.

\index{message!data members}


Once a message has been created, its data members can be changed by the following functions:

\begin{verbatim}
msg->setKind( kind );
msg->setLength( length );
msg->setPriority( priority );
msg->setBitError( err );
msg->setTimestamp();
msg->setTimestamp( simtime );
\end{verbatim}


With these functions the user can set the message
kind\index{message!kind}, the message length\index{message@length},
the priority\index{message!priority}, the error
flag\index{message!error flag} and the time stamp\index{message!time
  stamp}. The \fname{setTimeStamp()} function without any argument
sets the time stamp to the current simulation time.


The values can be obtained by the following functions:

\begin{verbatim}
int k       = msg->kind();
int p       = msg->priority();
int l       = msg->length();
bool b      = msg->hasBitError();
simtime_t t = msg->timestamp();
\end{verbatim}


\subsubsection{Duplicating messages}

\index{message!duplication}

It is often needed to duplicate a message (for example, send
one and keep a copy). This can be done in the standard ways as
for any other {\opp} object:

\begin{verbatim}
cMessage *copy1 = (cMessage *) msg->dup();
cMessage *copy2 = new cMessage( *msg );
\end{verbatim}


The two are equivalent. The resulting message is an exact copy
of the original, including message parameters (\cclass{cPar} or other
object types) and encapsulated messages.




\subsection{Message encapsulation}

It is often necessary to encapsulate a
message\index{message!encapsulation} into another when you're modeling
layered protocols of computer networks. Although you can encapsulate
messages by adding them to the parameter list, there's a better way.


The \fname{encapsulate()} function encapsulates a message
into another one. The length of the message will grow by the length of
the encapsulated message. An exception: when the encapsulating (outer)
message has zero length, {\opp} assumes it is not a real packet but
some out-of-band signal, so its length is left at zero.

\begin{verbatim}
cMessage *userdata = new cMessage("userdata");

userdata->setLength(8*2000);
cMessage *tcpseg = new cMessage("tcp");
tcpseg->setLength(8*24);
tcpseg->encapsulate(userdata);
ev << tcpseg->length() << endl; // --> 8*2024 = 16192
\end{verbatim}


A message can only hold one encapsulated message at a time. The
second \fname{encapsulate()} call will result in an error. It is also
an error if the message to be encapsulated isn't owned by the
module.

You can get back the encapsulated message by \fname{decapsulate()}:

\begin{verbatim}
cMessage *userdata = tcpseg->decapsulate();
\end{verbatim}

\fname{decapsulate()} will decrease the length of the message accordingly,
except if it was zero. If the length would become negative, an
error occurs.


The \fname{encapsulatedMsg()} function returns a pointer to the encapsulated
message, or NULL if no message was encapsulated.





\subsection{Information about the last sending}

There are several variables in \cclass{cMessage} that store
information about the last time the message was sent or
scheduled. These variables can only be read.

\fname{isSelfMessage()} returns true if the message has been scheduled
(\fname{scheduleAt()}) as opposed to being sent with one of the
\fname{send...()} methods.

\begin{Verbatim}[commandchars=\\\{\}]
bool \fname{isSelfMessage()}
\end{Verbatim}

The following methods can tell where the message came from and
where it arrived (will arrive).

\begin{Verbatim}[commandchars=\\\{\}]
int \fname{senderModuleId()};
int \fname{senderGateId()};
int \fname{arrivalModuleId()};
int \fname{arrivalGateId()};
\end{Verbatim}

The following two methods are just convenience functions that
combine module id and gate id into a gate object pointer.

\begin{Verbatim}[commandchars=\\\{\}]
cGate *\fname{senderGate()};
cGate *\fname{arrivalGate()};
\end{Verbatim}

And there are further convenience functions to tell whether
the message arrived on a specific gate given with id or
name+index.

\begin{Verbatim}[commandchars=\\\{\}]
bool \fname[arrivedOn()]{arrivedOn}(int id);
bool \fname{arrivedOn}(const char *gname, int gindex=0);
\end{Verbatim}

The following methods return message creation time and the last sending
and arrival times.

\begin{Verbatim}[commandchars=\\\{\}]
simtime_t \fname{creationTime()}
simtime_t \fname{sendingTime()};
simtime_t \fname{arrivalTime()};
\end{Verbatim}




\subsection{Context pointer}

\cclass{cMessage} contains a void* pointer which is
set/returned by the \fname{setContextPointer()} and
\fname{contextPointer()} functions:

\begin{verbatim}
void *context =...;
msg->setContextPointer( context );
void *context2 = msg->contextPointer();
\end{verbatim}


It can be used for any purpose by the simulation programmer.
It is not used by the simulation kernel, and it is treated as
a mere pointer (no memory management is done on it).

Intended purpose: a module which schedules several self-messages
(timers) will need to identify a self-message when it arrives back to
the module, ie. the module will have to determine which timer went off
and what to do then. The context pointer\index{context pointer} can be
made to point at a data structure kept by the module which can carry
enough ``context'' information about the event.





\subsection{Modeling packets and frames}

The \cclass{cPacket} class is now deprecated. Please do not use it
in new models.
  \footnote{\cclass{cPacket} was a subclass of \cclass{cMessage}, and it
  was originally intended as a base class for packets or frames
  in a telecommunications network. \cclass{cPacket} added two data members:
  \textit{protocol} and \textit{PDU} (\textit{Protocol Data Unit}, an OSI term).
  It was envisioned that \textit{procotol} and \textit{PDU} would take
  their values from globally maintained enums. As it turned out,
  this was utopistic. In practice, usage of \textit{protocol} was inconsistent
  (\textit{protocol} and \textit{message kind} played similar roles,
  creating confusion), and models did not use \textit{PDU} at all.
  Hence the deprecation of \cclass{cPacket}.}

In future {\opp} models, the protocol should be represented
in the message subclass (i.e. instances of class
\texttt{IPv6Packet} represent IPv6 packets,
and \texttt{EthernetFrame} represents Ethernet frames) and/or
in the message kind value. PDU is usually represented
as a field inside the message class (a protocol header field).

If the former case, the C++ \ttt{dynamic\_cast} operator can be used
to determine if a message object is of a specific protocol:

\begin{verbatim}
cMessage *msg = receive();
if (dynamic_cast<IPv6Packet *>(msg) != NULL)
{
    IPv6Packet *ipv6packet = (IPv6Packet *)msg;
    ...
}
\end{verbatim}




\subsection{Attaching parameters and objects}

If you want to add parameters or objects to a message, the preferred
way to do that is via message definitions, described in chapter
\ref{ch:messages:message-definitions}.

\subsubsection{Attaching objects}

The \cclass{cMessage} class has an internal \cclass{cArray} object which can
carry objects\index{message!attaching objects}. Only objects
that are derived from \cclass{cObject} (most {\opp} classes are so) can be attached.
The \fname{addObject()}, \fname{getObject()}, \fname{hasObject()},
\fname{removeObject()} methods use the object name
as the key to the array. An example:

\begin{verbatim}
cLongHistogram *pklen_distr = new cLongHistogram("pklen_distr");
msg->addObject( pklen_distr );
...
if (msg->hasObject("pklen_distr"))
{
   cLongHistogram *pklen_distr =
       (cLongHistogram *) msg->getObject("pklen_distr");
   ...
}
\end{verbatim}

You should take care that names of the attached objects do not
clash with each other or with \cclass{cPar} parameter names
(see next section).
If you do not attach anything to the message and do not call the
\fname{parList()} function, the internal \cclass{cArray} object
will not be created.
This saves both storage and execution time.

You can attach non-object types (or non-\cclass{cObject} objects) to
the message\index{message!attaching non-object types} by using
\cclass{cPar}'s void* pointer 'P') type (see later in the description
of \cclass{cPar}). An example:

\begin{verbatim}
struct conn_t *conn = new conn_t; // conn_t is a C struct
msg->addPar("conn") = (void *) conn;
msg->par("conn").configPointer(NULL,NULL,sizeof(struct conn_t));
\end{verbatim}




\subsubsection{Attaching parameters}

The preferred way of extending messages with new data fields is to use
message definitions (see section \ref{ch:messages:message-definitions}).

The old, deprecated way of adding new fields to messages is via
attaching \cclass{cPar} objects.
There are several downsides of this approach, the worst being
being large memory and execution time overhead. \fname{cPar}'s are
heavy-weight and fairly complex objects themselves.
It has been reported that using \cclass{cPar} message parameters
might account for a large part of execution time, sometimes as much as 80\%.
Using \cclass{cPar}s is also error-prone because \fname{cPar} objects
have to be added dynamically and individually to each message object.
In contrast, subclassing benefits from static type checking:
if you mistype the name of a field in the C++ code, already the compiler
can detect the mistake.


However, if you still need to use cPars, here's a short summary
how you can do it. You add a new parameter to the message with the
\fname{addPar()} member function, and get back a reference
to the parameter object with the \fname{par()} member function.
\fname{hasPar()} tells you if the message has a
given parameter or not.
Message parameters can be accessed also by index in the parameter
array. The \fname{findPar()} function returns the index of a parameter
or -1 if the parameter cannot be found. The parameter can then be
accessed using an overloaded \fname{par()} function.

Example:

\begin{verbatim}
msg->addPar("dest_addr");
msg->par("dest_addr") = 168;
...
long dest_addr = msg->par("dest_addr");
\end{verbatim}

%%
%% hide old examples...
%%
%%\ begin{verbatim}
%%if  (msg->hasPar("dest_addr")) {
%%   long dest_addr = msg->par("dest_addr");
%%   ...
%%}
%%int index = msg->findPar("dest_addr");
%%long dest_addr = msg->par(index);
%%\ end{verbatim}
%%


\section{Message definitions}
\label{ch:messages:message-definitions}

\subsection{Introduction}

In practice, you'll need to add various fields to \cclass{cMessage} to
make it useful. For example, if you're modelling packets in communication
networks, you need to have a way to store protocol header fields in message
objects. Since the simulation library is written in C++, the natural way
of extending \cclass{cMessage} is via subclassing it.
However, because for each field you need to write at least
three things (a private data member, a getter and a setter method),
and the resulting class has to integrate with the simulation framework,
writing the necessary C++ code can be a tedious and time-consuming task.

{\opp} offers a more convenient way called \textit{message definitions}.
Message definitions provide a very compact syntax to describe
message contents. C++ code is automatically generated from message
definitions, saving you a lot of typing.

A common source of complaint about code generators in general is
lost flexibility: if you have a different idea how the generated
code should look like, there's little you can do about it.
In {\opp}, however, there's nothing to worry about: you can
customize the generated class to any extent you like.
Even if you decide to heavily customize the generated class,
message definitions still save you a great deal of manual work.

The message subclassing feature in {\opp} is still somewhat experimental,
meaning that:

\begin{itemize}
  \item The message description syntax and features may slightly change
    in the future, based on feedback from the community;
  \item The compiler that translates message descriptions into C++ is
    a perl script \fprog{opp\_msgc}. This is a temporary solution until
    the C++-based \fprog{nedtool} is finished.
\end{itemize}

The subclassing approach for adding message parameters was originally
suggested by Nimrod Mesika.


\subsubsection{The first message class}

Let us begin with a simple example. Suppose that you need message objects to
carry source and destination addresses as well as a hop count. You could write
a \ttt{mypacket.msg} file with the following contents:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} MyPacket
\{
    \tbf{fields}:
       \tbf{int} srcAddress;
       \tbf{int} destAddress;
       \tbf{int} hops = 32;
\};
\end{Verbatim}

The task of the \textit{message subclassing compiler} is to generate C++ classes
you can use from your models as well as ``reflection'' classes that allow
Tkenv to inspect these data stuctures.

If you process \ttt{mypacket.msg} with the message subclassing compiler, it will
create the following files for you: \ttt{mypacket\_m.h} and \ttt{mypacket\_m.cc}.
\ttt{mypacket\_m.h} contains the declaration of the \fname{MyPacket} C++ class, and
it should be included into your C++ sources where you need to handle
\ttt{MyPacket} objects.

The generated \ttt{mypacket\_m.h} will contain the following class declaration:

\begin{verbatim}
class MyPacket : public cMessage {
    ...
    virtual int getSrcAddress() const;
    virtual void setSrcAddress(int srcAddress);
    ...
};
\end{verbatim}

So in your C++ file, you could use the \ttt{MyPacket} class like this:

\begin{verbatim}
#include "mypacket_m.h"

...
MyPacket *pkt = new MyPacket("pkt");
pkt->setSrcAddress( localAddr );
...
\end{verbatim}

The \ttt{mypacket\_m.cc} file contains implementation of the generated \fname{MyPacket}
class, as well as ``reflection'' code that allows you to inspect these data
stuctures in the Tkenv GUI. The \ttt{mypacket\_m.cc} file should be compiled and
linked into your simulation. (If you use the \fname{opp\_makemake} tool
to generate your makefiles, the latter will be automatically taken care of.)


\subsubsection{What is message subclassing \textit{not?}}

There's might be some misunderstanding around the purpose and
concept of message definitions, so it seems to be a good idea
to deal with them right here.

It is \textit{\textbf{not:}}

\begin{itemize}
  \item{\textit{... an attempt to reproduce the functionality of C++ with another
     syntax.} Do not look for complex C++ types, templates, conditional compilation, etc.
     Also, it defines \textit{data} only (or rather: an interface to access
     data) -- not any kind of active behaviour.}
  \item{\textit{... a generic class generator.} This is meant for defining message
     contents, and data structure you put in messages.
     Defining methods is not supported on purpose.
     Also, while you can probably (ab)use the syntax to
     generate classes and structs used internally in simple modules,
     this is probably not a good idea.}
\end{itemize}

The goal is to define the \textit{interface} (getter/setter methods) of messages
rather than their implementations in C++. A simple and straightforward
implementation of fields is provided -- if you'd like a different internal
representation for some field, you can have it by customizing the class.

There are questions you might ask:

\begin{itemize}
  \item{\textit{Why doesn't it support \ttt{std::vector} and other STL classes?}
     Well, it does... Message definitions focus on the interface
     (getter/setter methods) of the classes, optionally leaving the implementation
     to you -- so you can implement fields (dynamic array fields)
     using \ttt{std::vector}.
     (This aligns with the idea behind STL -- it was designed to be
     \textit{nuts and bolts} for C++ programs).}
  \item{\textit{Why does it support C++ data types and not octets,
     bytes, bits, etc..?}
     That would restrict the scope of message definitions to networking,
     and {\opp} wants to support other application areas as well.
     Furthermore, the set of necessary concepts to be supported is
     probably not bounded, there would always be new data types to
     be adopted.}
  \item{\textit{Why no embedded classes?} Good question. As it does not
     conflict with the above principles, it might be added someday.}
\end{itemize}



The following sections describe the message syntax and features in detail.


\subsection{Declaring enums}

An \fname{enum \{..\}} generates a normal C++ enum, plus creates an object
which stores text representations of the constants. The latter makes it possible
to display symbolic names in Tkenv.
An example:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{enum} ProtocolTypes
\{
   IP = 1;
   TCP = 2;
\};
\end{Verbatim}

Enum values need to be unique.


% It is possible to ``extend'' an enum with new values.
%
% begin{Verbatim}[commandchars=\\\{\}]
% // add new values to ProtocolTypes
% \tbf{enum} MoreProtocolTypes \tbf{extends} ProtocolTypes
% \{
%   CLNP = 3;
%   TP4 = 4;
% \};
% end{Verbatim}

\subsection{Message declarations}

\subsubsection{Basic use}

You can describe messages with the following syntax:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
    \tbf{fields}:
        \tbf{int} sourceAddress;
        \tbf{int} destAddress;
        \tbf{bool} hasPayload;
\};
\end{Verbatim}

Processing this description with the message compiler will produce
a C++ header file with a generated class, \fname{FooPacket}.
\fname{FooPacket} will be a subclass of \fname{cMessage}.

For each field in the above description, the generated class will have
a protected data member, a getter and a setter method. The names of the
methods will begin with \fname{get} and \fname{set},
followed by the field name with its first letter converted to uppercase.
Thus, \fname{FooPacket} will contain the following methods:

\begin{verbatim}
virtual int getSourceAddress() const;
virtual void setSourceAddress(int sourceAddress);

virtual int getDestAddress() const;
virtual void setDestAddress(int destAddress);

virtual bool getHasPayload() const;
virtual void setHasPayload(bool hasPayload);
\end{verbatim}

Note that the methods are all declared \fname{virtual} to give you the possibility
of overriding them in subclasses.

Two constructors will be generated: one that optionally accepts object name and
(for \cclass{cMessage} subclasses) message kind, and a copy constructor:

\begin{verbatim}
FooPacket(const char *name=NULL, int kind=0);
FooPacket(const FooPacket& other);
\end{verbatim}

Appropriate assignment operator (\fname{operator=()}) and \fname{dup()} methods will
also be generated.

Data types for fields are not limited to \fname{int} and \fname{bool}. You can use the
following primitive types (i.e. primitive types as defined in the C++ language):

\begin{itemize}
   \item \fname{bool}
   \item \fname{char}, \fname{unsigned char}
   \item \fname{short}, \fname{unsigned short}
   \item \fname{int}, \fname{unsigned int}
   \item \fname{long}, \fname{unsigned long}
   \item \fname{double}
\end{itemize}

Field values are initialized to zero.


\subsubsection{Initial values}

You can initialize field values with the following syntax:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
   \tbf{fields}:
        \tbf{int} sourceAddress = 0;
        \tbf{int} destAddress = 0;
        \tbf{bool} hasPayload = false;
\};
\end{Verbatim}

Initialization code will be placed in the constructor of the generated class.


\subsubsection{Enum declarations}

You can declare that an \fname{int} (or other integral type) field
takes values from an enum. The message compiler can than generate code
that allows Tkenv display the symbolic value of the field.

Example:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
  \tbf{fields}:
      \tbf{int} payloadType \tbf{enum}(PayloadTypes);
\};
\end{Verbatim}

The enum has to be declared separately in the message file.


\subsubsection{Fixed-size arrays}

You can specify fixed size arrays:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
    \tbf{fields}:
        \tbf{long} route[4];
\};
\end{Verbatim}

The generated getter and setter methods will have an extra \fname{k} argument,
the array index:

\begin{verbatim}
virtual long getRoute(unsigned k) const;
virtual void setRoute(unsigned k, long route);
\end{verbatim}

If you call the methods with an index that is out of bounds, an exception
will be thrown.


\subsubsection{Dynamic arrays}

If the array size is not known in advance, you can declare the field
to be a dynamic array:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
   \tbf{fields}:
       \tbf{long} route[];
\};
\end{Verbatim}

In this case, the generated class will have two extra methods in addition
to the getter and setter methods: one for setting the array size, and another
one for returning the current array size.

\begin{verbatim}
virtual long getRoute(unsigned k) const;
virtual void setRoute(unsigned k, long route);
virtual unsigned getRouteArraySize() const;
virtual void setRouteArraySize(unsigned n);
\end{verbatim}

The \fname{set...ArraySize()} method internally allocates a new array. Existing
values in the array will be preserved (copied over to the new array.)

The default array size is zero. This means that you need to call the
\fname{set...ArraySize()} before you can start filling array elements.


\subsubsection{String members}

You can declare string-valued fields with the following syntax:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
   \tbf{fields}:
       \tbf{string} hostName;
\};
\end{Verbatim}

The generated getter and setter methods will return and accept \fname{const char*}
pointers:

\begin{verbatim}
virtual const char *getHostName() const;
virtual void setHostName(const char *hostName);
\end{verbatim}

The generated object will have its own copy of the string.

NOTE: a string member is different from a character array,
which is treated as an array of any other type. For example,

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
   \tbf{fields}:
       \tbf{char} chars[10];
\};
\end{Verbatim}

will generate the following methods:

\begin{verbatim}
virtual char getChars(unsigned k);
virtual void setChars(unsigned k, char a);
\end{verbatim}


\subsection{Inheritance, composition}

So far we have discussed how to add fields of primitive types
(\fname{int}, \fname{double}, \fname{char}, ...) to \fname{cMessage}.
This might be sufficient for simple models, but if you have
more complex models, you'll probably need to:

\begin{itemize}
  \item set up a hierarchy of message (packet) classes, that is,
    not only subclass from \fname{cMessage} but also from your
    own message classes;
  \item use not only primitive types as fields, but also structs,
    classes or typedefs. Sometimes you'll want to use a C++ type
    present in an already existing header file, another time you'll
    want a struct or class to be generated by the message
    compiler so that you can benefit from Tkenv inspectors.
\end{itemize}

The following section describes how to do these tasks.


\subsubsection{Inheritance among message classes}

By default, messages are subclassed from \fname{cMessage}. However, you can
explicitly specify the base class using the \fname{extends} keyword:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket \tbf{extends} FooBase
\{
    \tbf{fields}:
        ...
\};
\end{Verbatim}

For the above example, the generated C++ code will look like:

\begin{verbatim}
class FooPacket : public FooBase { ... };
\end{verbatim}

Inheritance also works for structs and classes (see next sections
for details).



\subsubsection{Defining classes}

Until now we have used the \fname{message} keyword to define classes, which
implies that the base class is \fname{cMessage}, either directly or indirectly.

But as part of complex messages, you'll need structs and other classes
(rooted or not rooted in \fname{cObject}) as building blocks.
Classes can be created with the \fname{class} class keyword;
structs we'll cover in the next section.

The syntax for defining classes is almost the same as defining messages,
only the \fname{class} keyword is used instead of \fname{message}.

Slightly different code is generated for classes that are rooted in
\fname{cObject} than for those which are not.
If there is no \ttt{extends}, the generated class will not be
derived from \fname{cObject}, thus it will not have \fname{name()},
\fname{className()}, etc. methods.
To create a class with those methods, you have to explicitly write
\ttt{extends cObject}.

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{class} MyClass \tbf{extends} cObject
\{
    \tbf{fields}:
        ...
\};
\end{Verbatim}



\subsubsection{Defining plain C structs}

You can define C-style structs to be used as fields in message classes,
``C-style'' meaning ``containing only data and no methods''.
(Actually, in the C++ language a struct can have methods,
and in general it can do anything a class can.)

The syntax is similar to that of defining messages:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{struct} MyStruct
\{
    \tbf{fields}:
        \tbf{char} array[10];
        \tbf{short} version;
\};
\end{Verbatim}

However, the generated code is different. The generated struct has
no getter or setter methods, instead the fields are represented
by public data members. For the above definition, the
following code is generated:

\begin{verbatim}
// generated C++
struct MyStruct
{
    char array[10];
    short version;
};
\end{verbatim}

A struct can have primitive types or other structs are fields. It cannot
have string or class as field.

Inheritance is supported for structs:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{struct} Base
\{
    ...
\};

\tbf{struct} MyStruct extends Base
\{
    ...
\};
\end{Verbatim}

But because a struct has no member functions, there are limitations:

\begin{itemize}
   \item field initialization is not supported (it would need constructor)
   \item struct fields are not initialized to zero (it would need constructor)
   \item dynamic arrays are not supported (no place for the array allocation code)
   \item ``generation gap'' or abstract fields (see later) cannot be used,
      because they would build upon virtual functions.
\end{itemize}


\subsubsection{Using structs and classes as fields}

In addition to primitive types, you can also use other structs or objects
as a field. For example, if you have a struct named \fname{IPAddress},
you can write the following:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
   \tbf{fields}:
       IPAddress src;
\};
\end{Verbatim}

The \fname{IPAddress} structure must be known in advance to the message compiler;
that is, it must either be a struct or class defined earlier in the message
description file, or it must be a C++ type with its header file
included via \ttt{cplusplus \{\{...\}\}} and its type announced
(see Announcing C++ types).

The generated class will contain an \fname{IPAddress} data member
(that is, \textbf{not} a pointer to an \fname{IPAddress}).
The following getter and setter methods will be generated:

\begin{verbatim}
virtual const IPAddress& getSrc() const;
virtual void setSrc(const IPAddress& src);
\end{verbatim}


\subsubsection{Pointers}

Not supported yet.



\subsection{Using existing C++ types}


\subsubsection{Announcing C++ types}

If you want to use one of your own types (a class, struct or typedef,
declared in a C++ header) in a message definition, you have to
announce those types to the message compiler. You also have to make sure
that your header file gets included into the generated \ttt{\_m.h} file
so that the C++ compiler can compile it.

Suppose you have an \fname{IPAddress} structure, defined in an \ttt{ipaddress.h}
file:

\begin{verbatim}
// ipaddress.h
struct IPAddress {
    int byte0, byte1, byte2, byte3;
};
\end{verbatim}

To be able to use \fname{IPAddress} in a message definition, the message
file (say \ttt{foopacket.msg}) should contain the following lines:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{cplusplus} \{\{
#include "ipaddress.h"
\}\};

\tbf{struct} IPAddress;
\end{Verbatim}

The effect of the first three lines is simply that the \fname{\#include}
statement will be copied into the generated \ttt{foopacket\_m.h}
file to let the C++ compiler know about the \fname{IPAddress} class.
The message compiler itself will not try to make sense of the
text in the body of the \ttt{cplusplus \{\{ ... \}\}} directive.

The next line, \ttt{struct IPAddress}, tells the message compiler that
\fname{IPAddress} is a C++ struct. This information will (among others)
affect the generated code.

Classes can be announced using the \fname{class} keyword:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{class} cSubQueue;
\end{Verbatim}

The above syntax assumes that the class is derived from \fname{cObject}
either directly or indirectly. If it is not, the \fname{noncobject}
keyword should be used:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{class} \tbf{noncobject} IPAddress;
\end{Verbatim}

The distinction between classes derived and not derived from \fname{cObject}
is important because the generated code differs at places.
The generated code is set up so that if you incidentally
forget the \fname{noncobject} keyword (and so you mislead the
message compiler into thinking that your class is rooted in
\fname{cObject} when in fact it is not), you'll get a C++ compiler
error in the generated header file.


\subsection{Customizing the generated class}


\subsubsection{The Generation Gap pattern}

Sometimes you need the generated code to something
more or do something differently than the version generated
by the message compiler.
For example, when setting a integer field named \fname{payloadLength},
you might also need to adjust the packet length. That is,
the following default (generated) version of the
\fname{setPayloadLength()} method is not suitable:

\begin{verbatim}
void FooPacket::setPayloadLength(int payloadLength)
{
    this->payloadLength = payloadLength;
}
\end{verbatim}

Instead, it should look something like this:

\begin{verbatim}
void FooPacket::setPayloadLength(int payloadLength)
{
    int diff = payloadLength - this->payloadLength;
    this->payloadLength = payloadLength;
    setLength( length() + diff );
}
\end{verbatim}

According to common belief, the largest drawback of generated code
is that it is difficult or impossible to fulfill such wishes.
Hand-editing of the generated files is worthless, because
they will be overwritten and changes will be lost
in the code generation cycle.

However, object oriented programming offers a solution.
A generated class can simply be customized by subclassing
from it and redefining whichever methods need to be
different from their generated versions. This practice
is known as the \textit{Generation Gap} design pattern.
It is enabled with the following syntax:

\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
   \tbf{properties}:
       customize = true;
   \tbf{fields}:
       \tbf{int} payloadLength;
\};
\end{Verbatim}

The \fname{properties} section within the message declaration contains
meta-info that affects how generated code will look like.
The customize property enables the use of the Generation Gap
pattern.

If you process the above code with the message compiler,
the generated code will contain a \fname{FooPacket\_Base} class
instead of \fname{FooPacket}. The idea is that you have
to subclass from \fname{FooPacket\_Base} to produce
\fname{FooPacket}, while doing your customizations
by redefining the necessary methods.

\begin{verbatim}
class FooPacket_Base : public cMessage
{
  protected:
    int src;
    // make constructors protected to avoid instantiation
    FooPacket_Base(const char *name=NULL);
    FooPacket_Base(const FooPacket_Base& other);
  public:
    ...
    virtual int getSrc() const;
    virtual void setSrc(int src);
};
\end{verbatim}

There is a minimum amount of code you have to write
for \fname{FooPacket}, because not everything can be
pre-generated as part of \fname{FooPacket\_Base}, e.g.
constructors cannot be inherited. This minimum
code is the following (you'll find it the generated C++ header
too, as a comment):

\begin{verbatim}
class FooPacket : public FooPacket_Base
{
  public:
    FooPacket(const char *name=NULL) : FooPacket_Base(name) {}
    FooPacket(const FooPacket& other) : FooPacket_Base(other) {}
    FooPacket& operator=(const FooPacket& other)
        {FooPacket_Base::operator=(other); return *this;}
    virtual cObject *dup() {return new FooPacket(*this);}
};

Register_Class(FooPacket);
\end{verbatim}

So, returning to our original example about payload length
affecting packet length, the code you'd write is the following:

\begin{verbatim}
class FooPacket : public FooPacket_Base
{
    // here come the mandatory methods: constructor,
    // copy contructor, operator=(), dup()
    // ...

    virtual void setPayloadLength(int newlength);
}

void FooPacket::setPayloadLength(int newlength)
{
    // adjust message length
    setLength(length()-getPayloadLength()+newlength);

    // set the new length
    FooPacket_Base::setPayloadLength(newlength);
}
\end{verbatim}



\subsubsection{Abstract fields}

The purpose of abstract fields is to let you to override
the way the value is stored inside the class,
and still benefit from inspectability in Tkenv.

For example, this is the situation when you want to store a bitfield
in a single \fname{int} or \fname{short}, and still you want
to present bits as individual packet fields.
It is also useful for implementing computed fields.

You can declare any field to be abstract with the following syntax:

%
% FIXME TBD: is customize=true really needed?
%
\begin{Verbatim}[commandchars=\\\{\}]
\tbf{message} FooPacket
\{
   \tbf{properties}:
       customize = true;
   \tbf{fields}:
       \tbf{abstract} \tbf{bool} urgentBit;
\};
\end{Verbatim}

For an \fname{abstract} field, the message compiler generates
no data member, and generated getter/setter methods will be pure
virtual:

\begin{verbatim}
virtual bool getUrgentBit() const = 0;
virtual void setUrgentBit(bool urgentBit) = 0;
\end{verbatim}


Usually you'll want to use abstract fields together with
the Generation Gap pattern, so that you can immediately
redefine the abstract (pure virtual) methods and
supply your implementation.


\subsection{Summary}

This section attempts to summarize the possibilities.

You can generate:

\begin{itemize}
  \item  classes rooted in \cclass{cObject}
  \item  messages (default base class is \cclass{cMessage})
  \item  classes not rooted in \cclass{cObject}
  \item  plain C structs
\end{itemize}

The following data types are supported for fields:

\begin{itemize}
  \item  primitive types: \ttt{bool}, \ttt{char}, \ttt{short},
    \ttt{int}, \ttt{long}, \ttt{unsigned short}, \ttt{unsigned int},
    \ttt{unsigned long}, \ttt{double}
  \item  \ttt{string}, a dynamically allocated string, presented as \ttt{const char *}
  \item  fixed-size arrays of the above types
  \item  structs, classes (both rooted and not rooted in \cclass{cObject}),
    declared with the message syntax or externally in C++ code
  \item  variable-sized arrays of the above types (stored as a dynamically
    allocated array plus an integer for the array size)
\end{itemize}

Further features:

\begin{itemize}
  \item  fields initialize to zero (except struct members)
  \item  fields initializers can be specified (except struct members)
  \item  assigning \ttt{enum}s to variables of integral types.
  \item  inheritance
  \item  customizing the generated class via subclassing (\textit{Generation Gap} pattern)
  \item  abstract fields (for nonstandard storage and calculated fields)
\end{itemize}

Generated code (all generated methods are \ttt{virtual}, although
this is not written out in the following table):

\begin{longtable}{|p{4cm}|p{10cm}|}
\hline
\tabheadcol

\tbf{Field declaration}
    &
\tbf{Generated code}
\\\hline

primitive types
\begin{verbatim}
double field;
\end{verbatim}
     &
\begin{verbatim}
double getField();
void setField(double d);
\end{verbatim}
\\\hline

string type
\begin{verbatim}
string field;
\end{verbatim}
     &
\begin{verbatim}
const char *getField();
void setField(const char *);
\end{verbatim}
\\\hline

fixed-size arrays
\begin{verbatim}
double field[4];
\end{verbatim}
     &
\begin{verbatim}
double getField(unsigned k);
void setField(unsigned k, double d);
unsigned getFieldArraySize();
\end{verbatim}

\\\hline

dynamic arrays
\begin{verbatim}
double field[];
\end{verbatim}
     &
\begin{verbatim}
void setFieldArraySize(unsigned n);
unsigned getFieldArraySize();
double getField(unsigned k);
void setField(unsigned k, double d);
\end{verbatim}
\\\hline

customized class
\begin{verbatim}
class Foo {
  properties:
    customize=true;
\end{verbatim}
     &
\begin{verbatim}
class Foo_Base { ... };
\end{verbatim}
and you have to write:
\begin{verbatim}
class Foo : public Foo_Base {
   ...
};
\end{verbatim}
\\\hline

abstract fields
\begin{verbatim}
abstract double field;
\end{verbatim}
     &
\begin{verbatim}
double getField() = 0;
void setField(double d) = 0;
\end{verbatim}
\\\hline

\end{longtable}


\subsubsection{Example simulations}

Several of the example simulations (Token Ring, Dyna2, Hypercube)
use message definitions. For example, in Dyna2 you'll find this:

\begin{itemize}
 \item \ttt{dynapacket.msg} defines \fname{DynaPacket} and \fname{DynaDataPacket};
 \item \ttt{dynapacket\_m.h} and \ttt{dynapacket\_m.cc} are produced
   by the message subclassing compiler from it, and they contain
   the generated \fname{DynaPacket} and \fname{DynaDataPacke}t
   C++ classes (plus code for Tkenv inspectors);
 \item other model files (\ttt{client.cc}, \ttt{server.cc}, ...)
   use the generated message classes
\end{itemize}



\subsection{What else is there in the generated code?}

In addition to the message class and its implementation,
the message compiler also generates reflection code which makes it
possible to inspect message contents in Tkenv.
To illustrate the why this is necessary, suppose you manually subclass
\cclass{cMessage} to get a new message class. You could write the following:
  \footnote{Note that the code is only for illustration.
  In real code, \fname{freq} and \fname{power} should be private members,
  and getter/setter methods should exist to access them.
  Also, the above class definition misses several member functions
  (constructor, assignment operator, etc.) that should be written.}

\begin{verbatim}
class RadioMsg : public cMessage
{
  public:
    int freq;
    double power;
    ...
};
\end{verbatim}

Now it is possible to use \ttt{RadioMsg} in your simple modules:

\begin{verbatim}
RadioMsg *msg = new RadioMsg();
msg->freq = 1;
msg->power = 10.0;
...
\end{verbatim}

You'd notice one drawback of this solution when you try to use
Tkenv for debugging. While \fname{cPar}-based message parameters can be viewed in
message inspector windows, fields added via subclassing do not appear
there. The reason is that Tkenv, being just another C++ library in your
simulation program, doesn't know about your C++ instance variables.
The problem cannot be solved entirely within Tkenv, because the C++ language
does not support ``reflection'' (extracting class information at runtime)
like for example Java does.

There is a solution however: one can supply Tkenv with missing ``reflection''
information about the new class. Reflection info might take the form of
a separate C++ class whose methods return information about the
\fname{RadioMsg} fields. This descriptor class might look like this:

\begin{verbatim}
class RadioMsgDescriptor : public Descriptor
{
  public:
    virtual int getFieldCount() {return 2;}

    virtual const char *getFieldName(int k) {
        const char *fieldname[] = {"freq", "power";}
        if (k<0 || k>=2) return NULL;
        return fieldname[k];
    }

    virtual double getFieldAsDouble(RadioMsg *msg, int k) {
        if (k==0) return msg->freq;
        if (k==1) return msg->power;
        return 0.0; // not found
    }
    //...
};
\end{verbatim}

Then you have to inform Tkenv that a \fname{RadioMsgDescriptor} exists and that it
should be used whenever Tkenv finds messages of type \fname{RadioMsg} (as it is
currently implemented, whenever the object's \fname{className()} method returns
\ttt{"RadioMsg"}). So when you inspect a \fname{RadioMsg} in your simulation, Tkenv
can use \fname{RadioMsgDescriptor} to extract and display the values of
the \fname{freq} and \fname{power} variables.

The actual implementation is somewhat more complicated than this, but not
much.

