OverSim
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
MyOverlay.cc
Go to the documentation of this file.
1
//
2
// Copyright (C) 2009 Institut fuer Telematik, Universitaet Karlsruhe (TH)
3
//
4
// This program is free software; you can redistribute it and/or
5
// modify it under the terms of the GNU General Public License
6
// as published by the Free Software Foundation; either version 2
7
// of the License, or (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
//
18
23
#include <iostream>
24
25
#include <
UnderlayConfigurator.h
>
26
#include <
GlobalStatistics.h
>
27
28
#include "
MyOverlay_m.h
"
29
30
#include "
MyOverlay.h
"
31
32
33
// Important! This line must be present for each module you extend (see BaseApp)
34
Define_Module
(
MyOverlay
);
35
36
// To convert between IP addresses (which have bit 24 active), and keys (which don't), we'll need to set or remove this bit.
37
#define BIGBIT (1 << 24)
38
39
40
// Called when the module is being initialized
41
void
MyOverlay::initializeOverlay
(
int
stage)
42
{
43
// see BaseApp.cc
44
if
(stage !=
MIN_STAGE_OVERLAY
)
return
;
45
46
// get our key from our IP address
47
myKey
=
thisNode
.
getIp
().get4().getInt() & ~
BIGBIT
;
48
49
// initialize the rest of variables
50
numDropped
= 0;
51
if
(!(par(
"enableDrops"
))) {
52
dropChance
= 0;
53
}
else
{
54
dropChance
= par(
"dropChance"
);
55
}
56
57
rpcTimer
=
new
cMessage(
"RPC timer"
);
58
scheduleAt(simTime() + 5,
rpcTimer
);
59
}
60
61
// Called to set our own overlay key (optional)
62
void
MyOverlay::setOwnNodeID
()
63
{
64
// create the corresponding overlay key
65
thisNode
.
setKey
(
OverlayKey
(
myKey
));
66
}
67
68
69
// Called when the module is ready to join the overlay
70
void
MyOverlay::joinOverlay
()
71
{
72
// Set the information of the previous step in the chain
73
prevNode
.
setIp
(IPAddress(
BIGBIT
| (
myKey
- 1)));
74
prevNode
.
setPort
(
thisNode
.
getPort
());
75
prevNode
.
setKey
(
OverlayKey
(
myKey
- 1));
76
77
// Set the information of the next step in the chain
78
nextNode
.
setIp
(IPAddress(
BIGBIT
| (
myKey
+ 1)));
79
nextNode
.
setPort
(
thisNode
.
getPort
());
80
nextNode
.
setKey
(
OverlayKey
(
myKey
+ 1));
81
82
// tell the simulator that we're ready
83
setOverlayReady
(
true
);
84
}
85
86
void
MyOverlay::handleTimerEvent
(cMessage *msg)
87
{
88
if
(msg ==
rpcTimer
) {
89
// reschedule the timer
90
scheduleAt(simTime() + 5,
rpcTimer
);
91
92
// if the simulator is still busy creating the network, let's wait a bit longer
93
if
(
underlayConfigurator
->
isInInitPhase
())
return
;
94
95
// pick either or next neighbor, or our previous neighbor, and request their neighbors
96
OverlayKey
key;
97
int
neighborToAsk = intuniform(0, 1);
98
99
if
(neighborToAsk == 0) key =
prevNode
.
getKey
();
100
else
key =
nextNode
.
getKey
();
101
102
getNeighbors
(key);
103
}
104
}
105
106
// Return whether the given node is responsible for the key
107
bool
MyOverlay::isSiblingFor
(
const
NodeHandle
& node,
108
const
OverlayKey
& key,
109
int
numSiblings,
110
bool
* err)
111
{
112
// is it our node and our key?
113
if
(node ==
thisNode
&& key ==
thisNode
.
getKey
()) {
114
return
true
;
115
}
116
// we don't know otherwise
117
return
false
;
118
}
119
120
// Return the next step for the routing of the given message
121
NodeVector
*
MyOverlay::findNode
(
const
OverlayKey
& key,
122
int
numRedundantNodes,
123
int
numSiblings,
124
BaseOverlayMessage
* msg)
125
{
126
NodeVector
* nextHops;
127
128
// do we drop the packet?
129
if
(uniform(0, 1) <
dropChance
) {
130
// if yes, return an empty node vector
131
nextHops =
new
NodeVector
(0);
132
numDropped
++;
133
return
nextHops;
134
}
135
136
// else, set the response vector with one node
137
nextHops =
new
NodeVector
(1);
138
139
// are we responsible? next step is this node
140
if
(key ==
thisNode
.
getKey
()) {
141
nextHops->
add
(
thisNode
);
142
}
143
// is the key behind us? next step is the previous node
144
else
if
(key <
thisNode
.
getKey
()) {
145
nextHops->
add
(
prevNode
);
146
}
147
// otherwise, the next step is the next node
148
else
{
149
nextHops->
add
(
nextNode
);
150
}
151
return
nextHops;
152
}
153
154
// Called when the module is about to be destroyed
155
void
MyOverlay::finishOverlay
()
156
{
157
// remove this node from the overlay
158
setOverlayReady
(
false
);
159
160
// save the statistics (see BaseApp)
161
globalStatistics
->
addStdDev
(
"MyOverlay: Dropped packets"
,
numDropped
);
162
}
163
164
// Return the max amount of siblings that can be queried about
165
int
MyOverlay::getMaxNumSiblings
()
166
{
167
return
1;
168
}
169
170
// Return the max amount of redundant that can be queried about
171
int
MyOverlay::getMaxNumRedundantNodes
()
172
{
173
return
1;
174
}
175
176
177
void
MyOverlay::getNeighbors
(
const
OverlayKey
&neighborKey)
178
{
179
MyNeighborCall
*msg =
new
MyNeighborCall
();
180
msg->
setDestinationKey
(neighborKey);
181
182
// The function we'll be using to send an RPC is sendRouteRpcCall.
183
// The first value is to which tier we'll be talking. Can be either
184
// OVERLAY_COMP, TIER1_COMP, TIER2_COMP, and so on.
185
// The second parameter is the node to which we'll send the message.
186
// Can be either an OverlayKey or a TransportAddress.
187
// The third parameter is the message.
188
189
EV <<
thisNode
<<
": (RPC) Sending query to "
190
<< neighborKey <<
"!"
<< std::endl;
191
192
sendRouteRpcCall
(
OVERLAY_COMP
, neighborKey, msg);
193
}
194
195
// Handle an incoming Call message
196
// Only delete msg if the RPC is handled here, and you won't respond using sendRpcResponse!
197
bool
MyOverlay::handleRpcCall
(
BaseCallMessage
*msg)
198
{
199
// There are many macros to simplify the handling of RPCs. The full list is in <OverSim>/src/common/RpcMacros.h.
200
201
// start a switch
202
RPC_SWITCH_START
(msg);
203
204
// enters the following block if the message is of type MyNeighborCall (note the shortened parameter!)
205
RPC_ON_CALL
(MyNeighbor) {
206
// get Call message
207
MyNeighborCall
*mrpc = (
MyNeighborCall
*)msg;
208
209
// create response
210
MyNeighborResponse
*rrpc =
new
MyNeighborResponse
();
211
rrpc->
setRespondingNode
(
thisNode
);
212
rrpc->
setPrevNeighbor
(
prevNode
);
213
rrpc->
setNextNeighbor
(
nextNode
);
214
215
// now send the response. sendRpcResponse can automatically tell where
216
// to send it to. Note that sendRpcResponse will delete mrpc (aka msg)!
217
sendRpcResponse
(mrpc, rrpc);
218
219
RPC_HANDLED
=
true
;
// set to true, since we did handle this RPC (default is false)
220
}
221
222
// end the switch
223
RPC_SWITCH_END
();
224
225
// return whether we handled the message or not.
226
// don't delete unhandled messages!
227
return
RPC_HANDLED
;
228
}
229
230
// Called when an RPC we sent has timed out.
231
// Don't delete msg here!
232
233
void
MyOverlay::handleRpcTimeout
(
BaseCallMessage
* msg,
234
const
TransportAddress
& dest,
235
cPolymorphic* context,
int
rpcId,
236
const
OverlayKey
&)
237
{
238
// Same macros as in handleRpc
239
240
// start a switch
241
RPC_SWITCH_START
(msg);
242
243
// enters the following block if the message is of type MyNeighborCall (note the shortened parameter!)
244
RPC_ON_CALL
(MyNeighbor) {
245
MyNeighborCall
*mrpc = (
MyNeighborCall
*)msg;
// get Call message
246
callbackTimeout
(mrpc->
getDestinationKey
());
// call interface function
247
}
248
// end the switch
249
RPC_SWITCH_END
();
250
}
251
252
// Called when we receive an RPC response from another node.
253
// Don't delete msg here!
254
255
void
MyOverlay::handleRpcResponse
(
BaseResponseMessage
* msg,
256
cPolymorphic* context,
257
int
rpcId,
258
simtime_t rtt)
259
{
260
// The macros are here similar. Just use RPC_ON_RESPONSE instead of RPC_ON_CALL.
261
262
// start a switch
263
RPC_SWITCH_START
(msg);
264
265
// enters the following block if the message is of type MyNeighborCall (note the shortened parameter!)
266
RPC_ON_RESPONSE
(MyNeighbor) {
267
// get Response message
268
MyNeighborResponse
*mrpc = (
MyNeighborResponse
*)msg;
269
// call our interface function
270
callbackNeighbors
(mrpc->
getRespondingNode
(),
271
mrpc->
getPrevNeighbor
(),
272
mrpc->
getNextNeighbor
());
273
}
274
// end the switch
275
RPC_SWITCH_END
();
276
}
277
278
void
MyOverlay::callbackNeighbors
(
const
NodeHandle
& neighborKey,
279
const
NodeHandle
& prevNeighbor,
280
const
NodeHandle
& nextNeighbor)
281
{
282
EV <<
thisNode
<<
": (RPC) Got response from "
283
<< neighborKey <<
"\n"
284
<<
thisNode
<<
": (RPC) Neighbors: "
285
<< prevNeighbor.
getIp
() <<
", "
286
<< nextNeighbor.
getIp
() << std::endl;
287
}
288
289
void
MyOverlay::callbackTimeout
(
const
OverlayKey
&neighborKey)
290
{
291
EV <<
thisNode
<<
": (RPC) Query to "
<< neighborKey
292
<<
" timed out!"
<< std::endl;
293
}
src
overlay
myoverlay
MyOverlay.cc
Generated on Fri Dec 7 2012 13:37:52 for OverSim by
1.8.1.2