Loading...
Searching...
No Matches
sat-multicast-example.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014 Magister Solutions
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
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 * Author: Frans Laakso <frans.laakso@magister.fi>
19 *
20 */
21
22#include "ns3/applications-module.h"
23#include "ns3/core-module.h"
24#include "ns3/internet-module.h"
25#include "ns3/network-module.h"
26#include "ns3/satellite-module.h"
27#include "ns3/traffic-module.h"
28
29using namespace ns3;
30
42
43NS_LOG_COMPONENT_DEFINE("sat-multicast-example");
44
50static void
51SinkReceive(std::string context, Ptr<const Packet>, const Address&)
52{
53 NS_LOG_INFO(" Packet received from/by: " << context);
54}
55
63static std::string
64GetUserInfo(Ptr<SatHelper> helper, Ptr<Node> node)
65{
66 std::stringstream ss; // create a string stream
67 Ptr<Node> utNode = Singleton<SatTopology>::Get()->GetUtNode(node);
68 NodeContainer nodeUsers;
69
70 if (utNode)
71 {
72 nodeUsers = Singleton<SatTopology>::Get()->GetUtUserNodes(utNode);
73 ss << "UT"
74 << Singleton<SatIdMapper>::Get()->GetUtIdWithMac(
75 Singleton<SatIdMapper>::Get()->GetUtMacWithNode(utNode))
76 << "-user-";
77 }
78 else
79 {
80 nodeUsers = Singleton<SatTopology>::Get()->GetGwUserNodes();
81 ss << "GW-user-";
82 }
83
84 uint32_t userIndex = 0;
85
86 for (uint32_t j = 0; ((j < nodeUsers.GetN()) && (userIndex == 0)); j++)
87 {
88 if (nodeUsers.Get(j) == node)
89 {
90 userIndex = j + 1;
91 }
92 }
93
94 ss << userIndex;
95
96 return ss.str();
97}
98
102static void
104{
105 NS_LOG_INFO("");
106}
107
120static Time
121EstablishMulticastGroup(Ptr<SatHelper> helper,
122 Ptr<Node> source,
123 NodeContainer groupReceivers,
124 Ipv4Address groupAddress,
125 uint16_t port,
126 Time startTime,
127 bool sinkToAll)
128{
129 Time time = startTime;
130
131 NS_LOG_INFO("--- Create multicast group " << groupAddress << " ---");
132
133 helper->SetMulticastGroupRoutes(source,
134 groupReceivers,
135 helper->GetUserAddress(source),
136 groupAddress);
137
138 NS_LOG_INFO("--- Creating traffic generator for " << groupAddress << " ---");
139
140 // CBR traffic generator for multicast group with interval 0.4s and packet size 512 bytes
141 CbrHelper cbrHelper("ns3::UdpSocketFactory", InetSocketAddress(groupAddress, port));
142 cbrHelper.SetAttribute("Interval", StringValue("0.4s"));
143 cbrHelper.SetAttribute("PacketSize", UintegerValue(512));
144
145 ApplicationContainer cbr = cbrHelper.Install(source);
146 cbr.Start(startTime + Seconds(0.4));
147 cbr.Stop(startTime + Seconds(1.0));
148
149 NS_LOG_INFO("--- Group " << groupAddress << " source: " << GetUserInfo(helper, source)
150 << " ---");
151
152 ApplicationContainer sink;
153
154 std::stringstream receiverInfo;
155 receiverInfo << "--- Group " << groupAddress << " receivers: ";
156
157 if (sinkToAll)
158 {
159 NodeContainer users = NodeContainer(Singleton<SatTopology>::Get()->GetGwUserNodes(),
160 Singleton<SatTopology>::Get()->GetUtUserNodes());
161
162 PacketSinkHelper sinkHelperGroup("ns3::UdpSocketFactory",
163 InetSocketAddress(groupAddress, port));
164
165 // Sinks for group receivers
166 for (uint32_t i = 0; i < users.GetN(); i++)
167 {
168 sink.Add(sinkHelperGroup.Install(users.Get(i)));
169
170 std::string nodeName = GetUserInfo(helper, users.Get(i));
171 std::stringstream context;
172 context << groupAddress << "/" << nodeName;
173
174 DynamicCast<PacketSink>(sink.Get(i))
175 ->TraceConnect("Rx", context.str(), MakeCallback(&SinkReceive));
176 }
177
178 // output real group receivers
179 for (uint32_t i = 0; i < groupReceivers.GetN(); i++)
180 {
181 std::string nodeName = GetUserInfo(helper, groupReceivers.Get(i));
182 receiverInfo << nodeName << " ";
183 }
184 }
185 else
186 {
187 PacketSinkHelper sinkHelperGroup("ns3::UdpSocketFactory",
188 InetSocketAddress(groupAddress, port));
189
190 // Sinks for group receivers
191 for (uint32_t i = 0; i < groupReceivers.GetN(); i++)
192 {
193 sink.Add(sinkHelperGroup.Install(groupReceivers.Get(i)));
194
195 std::string nodeName = GetUserInfo(helper, groupReceivers.Get(i));
196 receiverInfo << nodeName << " ";
197
198 std::stringstream context;
199 context << groupAddress << "/" << nodeName;
200
201 DynamicCast<PacketSink>(sink.Get(i))
202 ->TraceConnect("Rx", context.str(), MakeCallback(&SinkReceive));
203 }
204 }
205
206 receiverInfo << "---";
207 NS_LOG_INFO(receiverInfo.str());
208
209 sink.Start(startTime);
210 sink.Stop(startTime + Seconds(2));
211
212 Simulator::Schedule(startTime + Seconds(1.41), &LogEmptyLine);
213
214 return startTime + Seconds(1);
215}
216
217int
218main(int argc, char* argv[])
219{
221 LogComponentEnable("CbrApplication", LOG_LEVEL_INFO);
222 LogComponentEnable("PacketSink", LOG_LEVEL_INFO);
223 LogComponentEnable("sat-multicast-example", LOG_LEVEL_INFO);
224
225 NS_LOG_INFO("--- Starting sat-multicast-example ---");
226
227 enum PreDefinedGroup
228 {
229 ALL_GROUPS,
230 GROUP_1,
231 GROUP_2,
232 GROUP_3,
233 GROUP_4,
234 GROUP_5,
235 GROUP_6,
236 GROUP_7,
237 GROUP_8,
238 GROUP_9,
239 GROUP_10,
240 GROUP_11,
241 GROUP_12,
242 END_OF_GROUP
243 };
244
245 uint32_t preDefinedGroup = (uint32_t)GROUP_1;
246 uint32_t fullScenarioReceivers = 10;
247 std::string scenario = "larger";
249 bool sinkToAll = false; // when set sink(s) are added to all user nodes in order to test that
250 // unnecessary routes are not added
251
252 Ptr<Node> groupSource;
253 NodeContainer groupReceivers;
254
256 auto simulationHelper = CreateObject<SimulationHelper>("example-multicast");
257 Config::SetDefault("ns3::SatHelper::ScenarioCreationTraceEnabled", BooleanValue(true));
258 Config::SetDefault("ns3::SatHelper::PacketTraceEnabled", BooleanValue(true));
259
261 CommandLine cmd;
262 cmd.AddValue("scenario", "Test scenario to use. (larger or full", scenario);
263 cmd.AddValue("preDefinedGroup",
264 "Pre-defined multicast group for larger scenario. (0 = all)",
265 preDefinedGroup);
266 cmd.AddValue("fullScenarioReceivers",
267 "Number of the receivers in full scenario",
268 fullScenarioReceivers);
269 cmd.AddValue("sinkToAll", "Add multicast sink to all users.", sinkToAll);
270 simulationHelper->AddDefaultUiArguments(cmd);
271 cmd.Parse(argc, argv);
272
274 Config::SetDefault("ns3::SatUserHelper::BackboneNetworkType",
276 Config::SetDefault("ns3::SatUserHelper::SubscriberNetworkType",
278
279 Time startTime = Seconds(1.2);
280 simulationHelper->SetOutputTag(scenario);
281 simulationHelper->SetSimulationTime(startTime + Seconds(3.0));
282
283 if (scenario == "larger")
284 {
285 satScenario = SatHelper::LARGER;
286 }
287 else if (scenario == "full")
288 {
289 satScenario = SatHelper::FULL;
290 }
291 else
292 {
293 NS_FATAL_ERROR(satScenario << " not supported!!!");
294 }
295
297 // GlobalValue::Bind ("SimulatorImplementationType", StringValue
298 // ("ns3::RealtimeSimulatorImpl"));
299
301
302 simulationHelper->LoadScenario("geo-33E");
303
304 // Creating the reference system.
305 Ptr<SatHelper> helper = simulationHelper->CreateSatScenario(satScenario);
306
307 NS_LOG_INFO("--- Creating scenario: " << scenario << " ---");
308
309 if (sinkToAll)
310 {
311 NS_LOG_INFO("--- Add sink to each users ---");
312 }
313
314 uint16_t multicastPort = 9; // Discard port (RFC 863)
315
317 NodeContainer utUsers = Singleton<SatTopology>::Get()->GetUtUserNodes();
318 NodeContainer gwUsers = Singleton<SatTopology>::Get()->GetGwUserNodes();
319
320 if (scenario == "larger")
321 {
322 uint32_t currentGroup = preDefinedGroup;
323
324 if (preDefinedGroup == ALL_GROUPS)
325 {
326 currentGroup = 1;
327 }
328
329 for (uint32_t i = currentGroup; i < END_OF_GROUP; i++)
330 {
331 groupReceivers = NodeContainer();
332
333 switch (i)
334 {
335 // Pre-defined group 1, Source= GW-user-1, Receivers= UT1-user-1, UT1-user-2,
336 // UT2-user-1, UT3-user-1, UT4-user-1
337 case GROUP_1:
338 groupSource = gwUsers.Get(0);
339 groupReceivers.Add(utUsers.Get(0));
340 groupReceivers.Add(utUsers.Get(1));
341 groupReceivers.Add(utUsers.Get(2));
342 groupReceivers.Add(utUsers.Get(3));
343 groupReceivers.Add(utUsers.Get(4));
344 break;
345
346 case GROUP_2:
347 // Pre-defined group 2, Source= GW-user-1, Receivers= UT1-user-2, UT2-user-1,
348 // UT4-user-1
349 groupSource = gwUsers.Get(0);
350 groupReceivers.Add(utUsers.Get(1));
351 groupReceivers.Add(utUsers.Get(2));
352 groupReceivers.Add(utUsers.Get(4));
353 break;
354
355 case GROUP_3:
356 // Pre-defined group 3, Source= UT1-user-1, Receivers= UT1-user-2, UT2-user-1,
357 // UT4-user-1
358 groupSource = utUsers.Get(0);
359 groupReceivers.Add(utUsers.Get(1));
360 groupReceivers.Add(utUsers.Get(2));
361 groupReceivers.Add(utUsers.Get(4));
362 break;
363
364 case GROUP_4:
365 // Pre-defined group 4, Source= UT1-user-2, Receivers= UT2-user-1, UT4-user-1
366 groupSource = utUsers.Get(1);
367 groupReceivers.Add(utUsers.Get(2));
368 groupReceivers.Add(utUsers.Get(4));
369 break;
370
371 case GROUP_5:
372 // Pre-defined group 5, Source= UT1-user-1, Receivers= UT3-user-1, UT4-user-1
373 groupSource = utUsers.Get(0);
374 groupReceivers.Add(utUsers.Get(3));
375 groupReceivers.Add(utUsers.Get(4));
376 break;
377
378 case GROUP_6:
379 // Pre-defined group 6, Source= UT1-user-2, Receivers= UT2-user-1, GW-user-1
380 groupSource = utUsers.Get(1);
381 groupReceivers.Add(utUsers.Get(2));
382 groupReceivers.Add(gwUsers.Get(0));
383 break;
384
385 case GROUP_7:
386 // Pre-defined group 7, Source= UT1-user-1, Receivers= GW-user-1
387 groupSource = utUsers.Get(0);
388 groupReceivers.Add(gwUsers.Get(0));
389 break;
390
391 case GROUP_8:
392 // Pre-defined group 8, Source= UT1-user-2, Receivers= UT2-user-1
393 groupSource = utUsers.Get(1);
394 groupReceivers.Add(utUsers.Get(2));
395 break;
396
397 case GROUP_9:
398 // Pre-defined group 9, Source= UT1-user-1, Receivers= GW-user-1, UT4-user-1
399 groupSource = utUsers.Get(0);
400 groupReceivers.Add(gwUsers.Get(0));
401 groupReceivers.Add(utUsers.Get(4));
402 break;
403
404 case GROUP_10:
405 // Pre-defined group 10, Source= UT1-user-1, UT3-user-1
406 groupSource = utUsers.Get(0);
407 groupReceivers.Add(utUsers.Get(3));
408 break;
409
410 case GROUP_11:
411 // Pre-defined group 10, Source= UT1-user-1, UT4-user-1
412 groupSource = utUsers.Get(0);
413 groupReceivers.Add(utUsers.Get(4));
414 break;
415
416 case GROUP_12:
417 // Pre-defined group 10, Source= UT1-user-1, UT2-user-1
418 groupSource = utUsers.Get(0);
419 groupReceivers.Add(utUsers.Get(2));
420 break;
421
422 default:
423 NS_FATAL_ERROR("Not supported pre-defined group!!!");
424 break;
425 }
426
427 NS_LOG_INFO("--- Creating multicast pre-defined group " << preDefinedGroup << " ---");
428
430
431 std::stringstream groupAddress;
432 groupAddress << "225.1." << i << ".1";
433 Ipv4Address multicastGroup(groupAddress.str().c_str());
434
435 startTime = EstablishMulticastGroup(helper,
436 groupSource,
437 groupReceivers,
438 multicastGroup,
439 multicastPort,
440 startTime,
441 sinkToAll);
442 }
443 }
444 else
445 {
446 NS_LOG_INFO("--- Creating multicast group in full scenario ---");
447
448 // get all users
449 NodeContainer users = NodeContainer(gwUsers, utUsers);
450
451 // add two sources from GW users and UT users randomly
452 std::vector<uint32_t> sources;
453 sources.push_back(std::rand() % gwUsers.GetN());
454 sources.push_back((std::rand() % utUsers.GetN()) + gwUsers.GetN());
455
456 // create two multicast groups with UT and GW sources
457 for (uint32_t i = 0; i < sources.size(); i++)
458 {
459 std::vector<uint32_t> ids;
460
461 for (uint32_t j = 0; j < users.GetN(); j++)
462 {
463 // add user only to possible receivers only if not source
464 if (j != sources[i])
465 {
466 ids.push_back(j);
467 }
468 }
469
470 // randomize users
471 Ptr<UniformRandomVariable> r = CreateObject<UniformRandomVariable>();
472 Shuffle(ids.begin(), ids.end(), r);
473
474 // set source GW or UT users
475 groupSource = users.Get(sources[i]);
476
477 // select reeivers
478 groupReceivers = NodeContainer();
479
480 for (uint32_t j = 0; ((j < fullScenarioReceivers) && (j < ids.size())); j++)
481 {
482 groupReceivers.Add(users.Get(ids.at(j)));
483 }
484
485 std::stringstream groupAddress;
486 groupAddress << "225.1." << i << ".1";
487 Ipv4Address multicastGroup(groupAddress.str().c_str());
488
489 startTime = EstablishMulticastGroup(helper,
490 groupSource,
491 groupReceivers,
492 multicastGroup,
493 multicastPort,
494 startTime,
495 sinkToAll);
496 }
497 }
498
499 NS_LOG_INFO("--- Running simulation ---");
500
501 simulationHelper->RunSimulation();
502
503 NS_LOG_INFO("--- Finished ---");
504 return 0;
505}
PreDefinedScenario_t
Values for pre-defined scenarios to be used by helper when building satellite network topology base.
@ LARGER
LARGER Larger scenario used as base.
@ FULL
FULL Full scenario used as base.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
static std::string GetUserInfo(Ptr< SatHelper > helper, Ptr< Node > node)
Construct information of the given user node.
static Time EstablishMulticastGroup(Ptr< SatHelper > helper, Ptr< Node > source, NodeContainer groupReceivers, Ipv4Address groupAddress, uint16_t port, Time startTime, bool sinkToAll)
Establish multicast group and generate traffic in that group.
static void SinkReceive(std::string context, Ptr< const Packet >, const Address &)
Receive RX traces from packet sinks.
static void LogEmptyLine()
Log empty line.