Project

General

Profile

Statistics
| Branch: | Revision:

root / include / cchannel.h @ b781545c

History | View | Annotate | Download (13.6 KB)

1 01873262 Georg Kunz
//==========================================================================
2
//   CCHANNEL.H  -  header for
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//
7
//  Declaration of the following classes:
8
//    cChannel : channel class
9
//
10
//==========================================================================
11
12
/*--------------------------------------------------------------*
13
  Copyright (C) 1992-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19
20
#ifndef __CCHANNEL_H
21
#define __CCHANNEL_H
22
23
#include "ccomponent.h"
24
#include "ccomponenttype.h"
25
#include "cmessage.h"
26
#include "ctimestampedvalue.h"
27
28
NAMESPACE_BEGIN
29
30
class cGate;
31
32
33
/**
34
 * Base class for channels.
35
 *
36
 * @ingroup SimCore
37
 */
38
class SIM_API cChannel : public cComponent //implies noncopyable
39
{
40
  protected:
41
    cGate *srcgatep; // gate the channel is attached to
42
    int connId;      // for cChannel::getProperties(); usually the NED connection element's id
43
44
  public:
45
    // internal: called from cGate
46
    void setSourceGate(cGate *g) {srcgatep=g;}
47
48
    // internal: sets/gets connId
49
    void setConnectionId(int id) {connId = id;}
50
    int getConnectionId() {return connId;}
51
52
    // internal: called from callInitialize(). Does one stage for this
53
    // channel, and returns true if there are more stages to do
54
    virtual bool initializeChannel(int stage);
55
56
    // internal: overridden to perform additional checks
57
    virtual void finalizeParameters();
58
59
  public:
60
    /**
61
     * Allows for returning multiple values from the processMessage() method.
62
     * The constructor initializes all fields to zero.
63
     */
64
    struct result_t
65
    {
66
        result_t() : delay(SIMTIME_ZERO), duration(SIMTIME_ZERO), discard(false) {}
67
        simtime_t delay;     //< propagation delay
68
        simtime_t duration;  //< transmission duration
69
        bool discard;        //< whether the channel has lost the message
70
    };
71
72
    /**
73
     * Signal value that acompanies the "messageSent" signal.
74
     */
75
    class MessageSentSignalValue : public cITimestampedValue, public cObject
76
    {
77
      public:
78
        simtime_t timestamp;
79
        cMessage *msg;
80
        result_t *result;
81
      public:
82
        /** Constructor. */
83
        MessageSentSignalValue(simtime_t_cref t, cMessage *m, result_t *r) {timestamp=t; msg=m; result=r;}
84
85
        /** @name cITimestampedValue methods */
86
        //@{
87
        /** Returns the timestamp; it represents the start of the transmission. */
88
        virtual simtime_t_cref getTimestamp(simsignal_t signalID) const {return timestamp;}
89
90
        /** Returns cITimestampedValue::OBJECT. */
91
        virtual Type getValueType(simsignal_t signalID) const {return OBJECT;}
92
93
        /** Returns the message (packet) as the stored object. */
94
        virtual cObject *objectValue(simsignal_t signalID) const {return msg;}
95
        //@}
96
97
        /** Returns the message (packet). */
98
        cObject *getMessage() const {return msg;}
99
100
        /** Returns the channel result. */
101
        result_t *getChannelResult() const {return result;}
102
103
        /** @name Other (non-cObject) getters throw an exception. */
104
        //@{
105
        virtual long longValue(simsignal_t signalID) const {error(); return 0;}
106
        virtual unsigned long unsignedLongValue(simsignal_t signalID) const {error(); return 0;}
107
        virtual double doubleValue(simsignal_t signalID) const {error(); return 0;}
108
        virtual SimTime simtimeValue(simsignal_t signalID) const {error(); return timestamp;}
109
        virtual const char *stringValue(simsignal_t signalID) const {error(); return NULL;}
110
        void error() const;
111
        //@}
112
    };
113
114
  public:
115
    /** @name Constructors, destructor */
116
    //@{
117
    /**
118
     * Constructor.
119
     */
120
    explicit cChannel(const char *name=NULL);
121
122
    /**
123
     * Destructor.
124
     */
125
    virtual ~cChannel();
126
    //@}
127
128
    /** @name Redefined cObject member functions. */
129
    //@{
130
    /**
131
     * Produces a one-line description of the object's contents.
132
     * See cObject for more details.
133
     */
134
    virtual std::string info() const;
135
136
    /**
137
     * Calls v->visit(this) for each contained object.
138
     * See cObject for more details.
139
     */
140
    virtual void forEachChild(cVisitor *v);
141
142
    /**
143
     * Serializes the object into a buffer.
144
     */
145
    virtual void parsimPack(cCommBuffer *buffer);
146
147
    /**
148
     * Deserializes the object from a buffer.
149
     */
150
    virtual void parsimUnpack(cCommBuffer *buffer);
151
    //@}
152
153
    /** @name Public methods for invoking initialize()/finish(), redefined from cComponent.
154
     * initialize(), numInitStages(), and finish() are themselves also declared in
155
     * cComponent, and can be redefined in channel classes by the user to perform
156
     * initialization and finalization (result recording, etc) tasks.
157
     */
158
    //@{
159
    /**
160
     * Interface for calling initialize() from outside. Implementation
161
     * performs multi-stage initialization for this channel object.
162
     */
163
    virtual void callInitialize();
164
165
    /**
166
     * Interface for calling initialize() from outside. It does a single stage
167
     * of initialization, and returns <tt>true</tt> if more stages are required.
168
     */
169
    virtual bool callInitialize(int stage);
170
171
    /**
172
     * Interface for calling finish() from outside.
173
     */
174
    virtual void callFinish();
175
    //@}
176
177
    /** @name Channel information. */
178
    //@{
179
    /**
180
     * Returns the compound module containing this channel. That is,
181
     * the channel is either between two submodules of getParentModule(),
182
     * or between getParentModule() and one of its submodules.
183
     * (For completeness, it may also connect two gates of getParentModule()
184
     * on the inside).
185
     */
186
    virtual cModule *getParentModule() const;
187
188
    /**
189
     * Convenience method: casts the return value of getComponentType() to cChannelType.
190
     */
191
    cChannelType *getChannelType() const  {return (cChannelType *)getComponentType();}
192
193
    /**
194
     * Return the properties for this channel. Properties cannot be changed
195
     * at runtime. Redefined from cComponent.
196
     */
197
    virtual cProperties *getProperties() const;
198
199
    /**
200
     * Returns the gate this channel is attached to.
201
     */
202
    cGate *getSourceGate() const  {return srcgatep;}
203
204
    /**
205
     * Returns true if the channel models a nonzero-duration transmission,
206
     * that is, sets the duration field of cPacket. Only one transmission
207
     * channel is allowed per connection path (see cGate methods getPreviousGate(),
208
     * getNextGate(), getPathStartGate(), getPathEndGate()).
209
     */
210
    virtual bool isTransmissionChannel() const = 0;
211
    //@}
212
213
    /** @name Channel functionality */
214
    //@{
215
    /**
216
     * This method encapsulates the channel's functionality. The method should
217
     * model the transmission of the given message starting at the given t time,
218
     * and store the results (propagation delay, transmission duration,
219
     * discard flag) in the result object. Only the relevant fields
220
     * in the result object need to be changed, others can be left untouched.
221
     *
222
     * Transmission duration and bit error modeling only applies to packets
223
     * (i.e. to instances of cPacket, where cMessage's isPacket() returns true),
224
     * it should be skipped for non-packet messages. The method does not need
225
     * to call the <tt>setDuration(duration)</tt> method on the packet; this is
226
     * done by the simulation kernel. However, the method should call
227
     * <tt>setBitError(true)</tt> on the packet if error modeling results
228
     * in bit errors.
229
     *
230
     * If the method sets the discard flag in the result object, it means
231
     * that the message object should be deleted by the simulation kernel;
232
     * this facility can be used to model that the message gets lost in the
233
     * channel.
234
     *
235
     * The method does not need to throw error on overlapping transmissions,
236
     * or if the packet's duration field is already set; these checks are
237
     * done by the simulation kernel before processMessage() is called.
238
     */
239
    virtual void processMessage(cMessage *msg, simtime_t t, result_t& result) = 0;
240
241
    /**
242
     * For transmission channels: Returns the nominal data rate of the channel.
243
     * The number returned from this method should be treated as informative;
244
     * there is no strict requirement that the channel calculates packet
245
     * duration by dividing the packet length by the nominal data rate.
246
     * For example, specialized channels may add the length of a lead-in
247
     * signal to the duration.
248
     *
249
     * @see isTransmissionChannel(), cDatarateChannel
250
     */
251
    virtual double getNominalDatarate() const = 0;
252
253
    /**
254
     * For transmission channels: Calculates the transmission duration
255
     * of the message with the current channel configuration (datarate, etc);
256
     * it does not check or modify channel state. For non-transmission channels
257
     * this method returns zero.
258
     *
259
     * This method is useful for transmitter modules that need to determine
260
     * the transmission time of a packet without actually sending the packet.
261
     *
262
     * Caveats: this method is "best-effort" -- there is no guarantee that
263
     * transmission time when the packet is actually sent will be the same as
264
     * the value returned by this method. The difference may be caused by
265
     * changed channel parameters (i.e. "datarate" being overwritten), or by
266
     * a non-time-invariant transmission algorithm.
267
     *
268
     * Note that there is no requirement that processMessage() relies on this
269
     * method to calculated the packet duration. That is, to change the
270
     * duration computation algorithm via subclassing you need to redefine
271
     * BOTH the processMessage() and calculateDuration() methods.
272
     *
273
     * @see isTransmissionChannel(), cDatarateChannel
274
     */
275
    virtual simtime_t calculateDuration(cMessage *msg) const = 0;
276
277
    /**
278
     * For transmission channels: Returns the simulation time
279
     * the sender gate will finish transmitting. If the gate is not
280
     * currently transmitting, the result is unspecified but less or equal
281
     * the current simulation time.
282
     *
283
     * @see isTransmissionChannel(), isBusy(), cDatarateChannel
284
     */
285
    virtual simtime_t getTransmissionFinishTime() const = 0;
286
287
    /**
288
     * For transmission channels: Returns whether the sender gate
289
     * is currently transmitting, ie. whether getTransmissionFinishTime()
290
     * is greater than the current simulation time.
291
     *
292
     * @see isTransmissionChannel(), getTransmissionFinishTime(), cDatarateChannel
293
     */
294
    virtual bool isBusy() const;
295
296
    /**
297
     * For transmission channels: Forcibly overwrites the finish time of the
298
     * current transmission in the channel (see getTransmissionFinishTime()).
299
     *
300
     * This method is a crude device that allows for implementing aborting
301
     * transmissions; it is not needed for normal packet transmissions.
302
     * Calling this method with the current simulation time will allow
303
     * you to immediately send another packet on the channel without the
304
     * channel reporting error due to its being busy.
305
     *
306
     * Note that this call does NOT affect the delivery of the packet being
307
     * transmitted: the packet object is delivered to the target module
308
     * at the time it would without the call to this method. The sender
309
     * needs to inform the target module in some other way that the
310
     * transmission was aborted and the packet should be treated accordingly
311
     * (i.e. discarded as incomplete); for example by sending an out-of-band
312
     * cMessage that the receiver has to understand.
313
     */
314
    virtual void forceTransmissionFinishTime(simtime_t t) = 0;
315
    //@}
316
};
317
318
319
/**
320
 * Channel with zero propagation delay, zero transmission delay (infinite
321
 * datarate), and always enabled.
322
 *
323
 * @ingroup SimCore
324
 */
325
class SIM_API cIdealChannel : public cChannel //implies noncopyable
326
{
327
  public:
328
    /** @name Constructors, destructor */
329
    //@{
330
    /**
331
     * Constructor. This is only for internal purposes, and should not
332
     * be used when creating channels dynamically; use the create()
333
     * factory method instead.
334
     */
335
    explicit cIdealChannel(const char *name=NULL) : cChannel(name) {}
336
337
    /**
338
     * Destructor.
339
     */
340
    virtual ~cIdealChannel() {}
341
342
    /**
343
     * Utility function for dynamic channel creation. Equivalent to
344
     * <tt>cChannelType::getIdealChannelType()->create(name)</tt>.
345
     */
346
    static cIdealChannel *create(const char *name);
347
    //@}
348
349
    /** @name Redefined cChannel member functions. */
350
    //@{
351
    /**
352
     * The cIdealChannel implementation of this method does nothing.
353
     */
354
    virtual void processMessage(cMessage *msg, simtime_t t, result_t& result) {}
355
356
    /**
357
     * The cIdealChannel implementation of this method does nothing.
358
     */
359
    virtual double getNominalDatarate() const {return 0;}
360
361
    /**
362
     * The cIdealChannel implementation of this method always returns false.
363
     */
364
    virtual bool isTransmissionChannel() const {return false;}
365
366
    /**
367
     * The cIdealChannel implementation of this method always returns zero.
368
     */
369
    virtual simtime_t calculateDuration(cMessage *msg) const {return SIMTIME_ZERO;}
370
371
    /**
372
     * The cIdealChannel implementation of this method always returns zero.
373
     */
374
    virtual simtime_t getTransmissionFinishTime() const {return SIMTIME_ZERO;}
375
376
    /**
377
     * The cIdealChannel implementation of this method always returns false.
378
     */
379
    virtual bool isBusy() const {return false;}
380
381
    /**
382
     * The cIdealChannel implementation of this method does nothing.
383
     */
384
    virtual void forceTransmissionFinishTime(simtime_t t) {}
385
    //@}
386
};
387
388
NAMESPACE_END
389
390
391
#endif
392