1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  *
17  * Author: Hossam Khader <hossamkhader@gmail.com>
18  */
19 
20 #include "ns3/core-module.h"
21 #include "ns3/internet-module.h"
22 #include "ns3/node-container.h"
23 #include "ns3/mobility-helper.h"
24 #include "ns3/mobility-model.h"
25 #include "ns3/basic-energy-source-helper.h"
26 #include "ns3/energy-source-container.h"
27 #include "ns3/uan-helper.h"
28 #include "ns3/uan-channel.h"
29 #include "ns3/acoustic-modem-energy-model-helper.h"
30 
31 using namespace ns3;
32 
33 /**
34  *
35  * This example shows the usage of UDP over IPv4 to transfer data.
36  * Two nodes are sending their remaining energy percentage (1 byte)
37  * to a gateway node, that prints the received data.
38  * The transmissions are scheduled at random times to avoid collisions
39  *
40  */
41 
42 NS_LOG_COMPONENT_DEFINE ("UanIpv4Example");
43 
44 
45 class UanExperiment
46 {
47 public:
48   UanExperiment ();
49 
50   /**
51    * Set the UAN nodes position
52    */
53   void SetupPositions ();
54 
55   /**
56    * Set the UAN nodes energy
57    */
58   void SetupEnergy ();
59 
60   /**
61    * Set the UAN nodes communication channels
62    */
63   void SetupCommunications ();
64 
65   /**
66    * Set the UAN nodes communication channels
67    */
68   void SetupApplications ();
69 
70   /**
71    * Send a packet from all the nodes
72    */
73   void SendPackets ();
74 
75   /**
76    * Send a packet from one of the nodes
77    * \param node The sending node
78    * \param pkt The packet
79    * \param dst the destination
80    */
81   void SendSinglePacket (Ptr<Node> node, Ptr<Packet> pkt, Ipv4Address dst);
82 
83   /**
84    * Print the received packet
85    * \param socket The receiving socket
86    */
87   void PrintReceivedPacket (Ptr<Socket> socket);
88 
89   /**
90    * Prepare the experiment
91    */
92   void Prepare ();
93 
94   /**
95    * Teardown the experiment
96    */
97   void Teardown ();
98 
99 private:
100   NodeContainer m_nodes; //!< UAN nodes
101   std::map<Ptr<Node>, Ptr<Socket> > m_sockets; //!< send and receive sockets
102 };
103 
104 
UanExperiment()105 UanExperiment::UanExperiment ()
106 {
107 }
108 
109 void
SetupPositions()110 UanExperiment::SetupPositions ()
111 {
112   MobilityHelper mobilityHelper;
113   mobilityHelper.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
114   mobilityHelper.Install (m_nodes);
115   m_nodes.Get (0)->GetObject<MobilityModel> ()->SetPosition (Vector (0, 0, 0));
116   m_nodes.Get (1)->GetObject<MobilityModel> ()->SetPosition (Vector (100, 0, 0));
117   m_nodes.Get (2)->GetObject<MobilityModel> ()->SetPosition (Vector (-100, 0, 0));
118 }
119 
120 void
SetupEnergy()121 UanExperiment::SetupEnergy ()
122 {
123   BasicEnergySourceHelper energySourceHelper;
124   energySourceHelper.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (900000));
125   energySourceHelper.Install (m_nodes);
126 }
127 
128 void
SetupCommunications()129 UanExperiment::SetupCommunications ()
130 {
131   Ptr<UanChannel> channel = CreateObject<UanChannel> ();
132   UanHelper uanHelper;
133   NetDeviceContainer netDeviceContainer = uanHelper.Install (m_nodes, channel);
134   EnergySourceContainer energySourceContainer;
135   NodeContainer::Iterator node = m_nodes.Begin ();
136   while (node != m_nodes.End ())
137     {
138       energySourceContainer.Add ((*node)->GetObject<EnergySourceContainer> ()->Get (0));
139       node++;
140     }
141   AcousticModemEnergyModelHelper acousticModemEnergyModelHelper;
142   acousticModemEnergyModelHelper.Install (netDeviceContainer, energySourceContainer);
143 
144   InternetStackHelper internetStackHelper;
145   internetStackHelper.Install (m_nodes);
146 
147   Ipv4AddressHelper ipv4AddressHelper;
148   ipv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.0");
149   ipv4AddressHelper.Assign (netDeviceContainer);
150   node = m_nodes.Begin ();
151   while (node != m_nodes.End ())
152     {
153       (*node)->GetObject<Ipv4L3Protocol> ()->GetInterface (1)->GetArpCache ()->SetWaitReplyTimeout (Seconds (10));
154       node++;
155     }
156 }
157 
158 void
PrintReceivedPacket(Ptr<Socket> socket)159 UanExperiment::PrintReceivedPacket (Ptr<Socket> socket)
160 {
161   Address srcAddress;
162   while (socket->GetRxAvailable () > 0)
163     {
164       Ptr<Packet> packet = socket->RecvFrom (srcAddress);
165       uint8_t energyReading;
166       packet->CopyData (&energyReading, 1);
167 
168       if(InetSocketAddress::IsMatchingType (srcAddress))
169         {
170           NS_LOG_UNCOND ( "Time: " << Simulator::Now ().GetHours () << "h" << " | Node: " <<
171                           InetSocketAddress::ConvertFrom (srcAddress).GetIpv4 () << " | Energy: " <<
172                           +energyReading << "%");
173         }
174     }
175 }
176 
177 void
SetupApplications()178 UanExperiment::SetupApplications ()
179 {
180   NodeContainer::Iterator node = m_nodes.Begin ();
181   while (node != m_nodes.End ())
182     {
183       m_sockets[*node] = Socket::CreateSocket (*node, TypeId::LookupByName ("ns3::UdpSocketFactory"));
184       if((*node)->GetObject<Ipv4> () != NULL)
185         {
186           InetSocketAddress ipv4_local = InetSocketAddress (Ipv4Address::GetAny (), 9);
187           m_sockets[*node]->Bind (ipv4_local);
188         }
189 
190       m_sockets[*node]->SetRecvCallback (MakeCallback (&UanExperiment::PrintReceivedPacket, this));
191       node++;
192     }
193 }
194 
195 void
SendPackets()196 UanExperiment::SendPackets ()
197 {
198   Ptr<UniformRandomVariable> uniformRandomVariable = CreateObject<UniformRandomVariable> ();
199 
200   NodeContainer::Iterator node = m_nodes.Begin ();
201   Ipv4Address dst = (*node)->GetObject<Ipv4L3Protocol> ()->GetInterface (1)->GetAddress (0).GetLocal ();
202   node++;
203   while (node != m_nodes.End ())
204     {
205       uint8_t energy = ((*node)->GetObject<EnergySourceContainer> ()->Get (0)->GetEnergyFraction ()) * 100;
206 
207       Ptr<Packet> pkt = Create<Packet> (&energy, 1);
208 
209       double time = uniformRandomVariable->GetValue (0, 60);
210       Simulator::Schedule (Seconds (time), &UanExperiment::SendSinglePacket, this, *node, pkt, dst);
211       node++;
212     }
213   Simulator::Schedule (Hours (2), &UanExperiment::SendPackets, this);
214 }
215 
216 void
SendSinglePacket(Ptr<Node> node,Ptr<Packet> pkt,Ipv4Address dst)217 UanExperiment::SendSinglePacket (Ptr<Node> node, Ptr<Packet> pkt, Ipv4Address dst)
218 {
219   NS_LOG_UNCOND ( Simulator::Now ().GetHours () << "h" << " packet sent to " << dst );
220   InetSocketAddress ipv4_destination = InetSocketAddress (dst, 9);
221   m_sockets[node]->SendTo (pkt, 0, ipv4_destination);
222 }
223 
224 void
Prepare()225 UanExperiment::Prepare ()
226 {
227   m_nodes.Create (3);
228   SetupPositions ();
229   SetupEnergy ();
230   SetupCommunications ();
231   SetupApplications ();
232   SendPackets ();
233 }
234 
235 void
Teardown()236 UanExperiment::Teardown ()
237 {
238   std::map<Ptr<Node>, Ptr<Socket> >::iterator socket;
239 
240   for (socket = m_sockets.begin (); socket != m_sockets.end (); socket++)
241     {
242       socket->second->Close ();
243     }
244 }
245 
246 int
main(int argc,char * argv[])247 main (int argc, char *argv[])
248 {
249   CommandLine cmd (__FILE__);
250   cmd.Parse (argc, argv);
251 
252   UanExperiment experiment;
253   experiment.Prepare ();
254 
255   Simulator::Stop (Days (50));
256   Simulator::Run ();
257   Simulator::Destroy ();
258 
259   experiment.Teardown ();
260 
261   return 0;
262 }
263