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 
29 using namespace ns3;
30 
43 NS_LOG_COMPONENT_DEFINE("sat-multicast-example");
44 
50 static void
51 SinkReceive(std::string context, Ptr<const Packet>, const Address&)
52 {
53  NS_LOG_INFO(" Packet received from/by: " << context);
54 }
55 
63 static std::string
64 GetUserInfo(Ptr<SatHelper> helper, Ptr<Node> node)
65 {
66  std::stringstream ss; // create a string stream
67  Ptr<Node> utNode = helper->GetUserHelper()->GetUtNode(node);
68  NodeContainer nodeUsers;
69 
70  if (utNode)
71  {
72  nodeUsers = helper->GetUserHelper()->GetUtUsers(utNode);
73  ss << "UT"
74  << Singleton<SatIdMapper>::Get()->GetUtIdWithMac(
75  Singleton<SatIdMapper>::Get()->GetUtMacWithNode(utNode))
76  << "-user-";
77  }
78  else
79  {
80  nodeUsers = helper->GetUserHelper()->GetGwUsers();
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 
102 static void
104 {
105  NS_LOG_INFO("");
106 }
107 
120 static Time
121 EstablishMulticastGroup(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(helper->GetUserHelper()->GetGwUsers(),
160  helper->GetUserHelper()->GetUtUsers());
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 
217 int
218 main(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  // Creating the reference system. Note, currently the satellite module supports
303  // only one reference system, which is named as "Scenario72". The string is utilized
304  // in mapping the scenario to the needed reference system configuration files. Arbitrary
305  // scenario name results in fatal error.
306  Ptr<SatHelper> helper = simulationHelper->CreateSatScenario(satScenario);
307 
308  NS_LOG_INFO("--- Creating scenario: " << scenario << " ---");
309 
310  if (sinkToAll)
311  {
312  NS_LOG_INFO("--- Add sink to each users ---");
313  }
314 
315  uint16_t multicastPort = 9; // Discard port (RFC 863)
316 
318  NodeContainer utUsers = helper->GetUtUsers();
319  NodeContainer gwUsers = helper->GetGwUsers();
320 
321  if (scenario == "larger")
322  {
323  uint32_t currentGroup = preDefinedGroup;
324 
325  if (preDefinedGroup == ALL_GROUPS)
326  {
327  currentGroup = 1;
328  }
329 
330  for (uint32_t i = currentGroup; i < END_OF_GROUP; i++)
331  {
332  groupReceivers = NodeContainer();
333 
334  switch (i)
335  {
336  // Pre-defined group 1, Source= GW-user-1, Receivers= UT1-user-1, UT1-user-2,
337  // UT2-user-1, UT3-user-1, UT4-user-1
338  case GROUP_1:
339  groupSource = gwUsers.Get(0);
340  groupReceivers.Add(utUsers.Get(0));
341  groupReceivers.Add(utUsers.Get(1));
342  groupReceivers.Add(utUsers.Get(2));
343  groupReceivers.Add(utUsers.Get(3));
344  groupReceivers.Add(utUsers.Get(4));
345  break;
346 
347  case GROUP_2:
348  // Pre-defined group 2, Source= GW-user-1, Receivers= UT1-user-2, UT2-user-1,
349  // UT4-user-1
350  groupSource = gwUsers.Get(0);
351  groupReceivers.Add(utUsers.Get(1));
352  groupReceivers.Add(utUsers.Get(2));
353  groupReceivers.Add(utUsers.Get(4));
354  break;
355 
356  case GROUP_3:
357  // Pre-defined group 3, Source= UT1-user-1, Receivers= UT1-user-2, UT2-user-1,
358  // UT4-user-1
359  groupSource = utUsers.Get(0);
360  groupReceivers.Add(utUsers.Get(1));
361  groupReceivers.Add(utUsers.Get(2));
362  groupReceivers.Add(utUsers.Get(4));
363  break;
364 
365  case GROUP_4:
366  // Pre-defined group 4, Source= UT1-user-2, Receivers= UT2-user-1, UT4-user-1
367  groupSource = utUsers.Get(1);
368  groupReceivers.Add(utUsers.Get(2));
369  groupReceivers.Add(utUsers.Get(4));
370  break;
371 
372  case GROUP_5:
373  // Pre-defined group 5, Source= UT1-user-1, Receivers= UT3-user-1, UT4-user-1
374  groupSource = utUsers.Get(0);
375  groupReceivers.Add(utUsers.Get(3));
376  groupReceivers.Add(utUsers.Get(4));
377  break;
378 
379  case GROUP_6:
380  // Pre-defined group 6, Source= UT1-user-2, Receivers= UT2-user-1, GW-user-1
381  groupSource = utUsers.Get(1);
382  groupReceivers.Add(utUsers.Get(2));
383  groupReceivers.Add(gwUsers.Get(0));
384  break;
385 
386  case GROUP_7:
387  // Pre-defined group 7, Source= UT1-user-1, Receivers= GW-user-1
388  groupSource = utUsers.Get(0);
389  groupReceivers.Add(gwUsers.Get(0));
390  break;
391 
392  case GROUP_8:
393  // Pre-defined group 8, Source= UT1-user-2, Receivers= UT2-user-1
394  groupSource = utUsers.Get(1);
395  groupReceivers.Add(utUsers.Get(2));
396  break;
397 
398  case GROUP_9:
399  // Pre-defined group 9, Source= UT1-user-1, Receivers= GW-user-1, UT4-user-1
400  groupSource = utUsers.Get(0);
401  groupReceivers.Add(gwUsers.Get(0));
402  groupReceivers.Add(utUsers.Get(4));
403  break;
404 
405  case GROUP_10:
406  // Pre-defined group 10, Source= UT1-user-1, UT3-user-1
407  groupSource = utUsers.Get(0);
408  groupReceivers.Add(utUsers.Get(3));
409  break;
410 
411  case GROUP_11:
412  // Pre-defined group 10, Source= UT1-user-1, UT4-user-1
413  groupSource = utUsers.Get(0);
414  groupReceivers.Add(utUsers.Get(4));
415  break;
416 
417  case GROUP_12:
418  // Pre-defined group 10, Source= UT1-user-1, UT2-user-1
419  groupSource = utUsers.Get(0);
420  groupReceivers.Add(utUsers.Get(2));
421  break;
422 
423  default:
424  NS_FATAL_ERROR("Not supported pre-defined group!!!");
425  break;
426  }
427 
428  NS_LOG_INFO("--- Creating multicast pre-defined group " << preDefinedGroup << " ---");
429 
431 
432  std::stringstream groupAddress;
433  groupAddress << "225.1." << i << ".1";
434  Ipv4Address multicastGroup(groupAddress.str().c_str());
435 
436  startTime = EstablishMulticastGroup(helper,
437  groupSource,
438  groupReceivers,
439  multicastGroup,
440  multicastPort,
441  startTime,
442  sinkToAll);
443  }
444  }
445  else
446  {
447  NS_LOG_INFO("--- Creating multicast group in full scenario ---");
448 
449  // get all users
450  NodeContainer users = NodeContainer(gwUsers, utUsers);
451 
452  // add two sources from GW users and UT users randomly
453  std::vector<uint32_t> sources;
454  sources.push_back(std::rand() % gwUsers.GetN());
455  sources.push_back((std::rand() % utUsers.GetN()) + gwUsers.GetN());
456 
457  // create two multicast groups with UT and GW sources
458  for (uint32_t i = 0; i < sources.size(); i++)
459  {
460  std::vector<uint32_t> ids;
461 
462  for (uint32_t j = 0; j < users.GetN(); j++)
463  {
464  // add user only to possible receivers only if not source
465  if (j != sources[i])
466  {
467  ids.push_back(j);
468  }
469  }
470 
471  // randomize users
472  std::random_shuffle(ids.begin(), ids.end());
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.