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 #include "ns3/packet-socket-helper.h"
31 #include "ns3/packet-socket-address.h"
32 
33 using namespace ns3;
34 
35 /**
36  *
37  * This example shows the usage of raw packets transfer data.
38  * Two nodes are sending their remaining energy percentage (1 byte)
39  * to a gateway node, that prints the received data.
40  * The transmissions are scheduled at random times to avoid collisions
41  *
42  */
43 
44 NS_LOG_COMPONENT_DEFINE ("UanRawExample");
45 
46 
47 class UanExperiment
48 {
49 public:
50   UanExperiment ();
51 
52   /**
53    * Set the UAN nodes position
54    */
55   void SetupPositions ();
56 
57   /**
58    * Set the UAN nodes energy
59    */
60   void SetupEnergy ();
61 
62   /**
63    * Set the UAN nodes communication channels
64    */
65   void SetupCommunications ();
66 
67   /**
68    * Set the UAN nodes communication channels
69    */
70   void SetupApplications ();
71 
72   /**
73    * Send a packet from all the nodes
74    */
75   void SendPackets ();
76 
77   /**
78    * Send a packet from one of the nodes
79    * \param node The sending node
80    * \param pkt The packet
81    * \param dst the destination
82    */
83   void SendSinglePacket (Ptr<Node> node, Ptr<Packet> pkt, Mac8Address dst);
84 
85   /**
86    * Print the received packet
87    * \param socket The receiving socket
88    */
89   void PrintReceivedPacket (Ptr<Socket> socket);
90 
91   /**
92    * Prepare the experiment
93    */
94   void Prepare ();
95 
96   /**
97    * Teardown the experiment
98    */
99   void Teardown ();
100 
101 private:
102   NodeContainer m_nodes; //!< UAN nodes
103   std::map<Ptr<Node>, Ptr<Socket> > m_sockets; //!< send and receive sockets
104 };
105 
106 
UanExperiment()107 UanExperiment::UanExperiment ()
108 {
109 }
110 
111 void
SetupPositions()112 UanExperiment::SetupPositions ()
113 {
114   MobilityHelper mobilityHelper;
115   mobilityHelper.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
116   mobilityHelper.Install (m_nodes);
117   m_nodes.Get (0)->GetObject<MobilityModel> ()->SetPosition (Vector (0, 0, 0));
118   m_nodes.Get (1)->GetObject<MobilityModel> ()->SetPosition (Vector (100, 0, 0));
119   m_nodes.Get (2)->GetObject<MobilityModel> ()->SetPosition (Vector (-100, 0, 0));
120 }
121 
122 void
SetupEnergy()123 UanExperiment::SetupEnergy ()
124 {
125   BasicEnergySourceHelper energySourceHelper;
126   energySourceHelper.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (900000));
127   energySourceHelper.Install (m_nodes);
128 }
129 
130 void
SetupCommunications()131 UanExperiment::SetupCommunications ()
132 {
133   Ptr<UanChannel> channel = CreateObject<UanChannel> ();
134   UanHelper uanHelper;
135   NetDeviceContainer netDeviceContainer = uanHelper.Install (m_nodes, channel);
136   EnergySourceContainer energySourceContainer;
137   NodeContainer::Iterator node = m_nodes.Begin ();
138   while (node != m_nodes.End ())
139     {
140       energySourceContainer.Add ((*node)->GetObject<EnergySourceContainer> ()->Get (0));
141       node++;
142     }
143   AcousticModemEnergyModelHelper acousticModemEnergyModelHelper;
144   acousticModemEnergyModelHelper.Install (netDeviceContainer, energySourceContainer);
145 }
146 
147 void
PrintReceivedPacket(Ptr<Socket> socket)148 UanExperiment::PrintReceivedPacket (Ptr<Socket> socket)
149 {
150   Address srcAddress;
151   while (socket->GetRxAvailable () > 0)
152     {
153       Ptr<Packet> packet = socket->RecvFrom (srcAddress);
154       PacketSocketAddress packetSocketAddress = PacketSocketAddress::ConvertFrom (srcAddress);
155       srcAddress = packetSocketAddress.GetPhysicalAddress ();
156       uint8_t energyReading;
157       packet->CopyData (&energyReading, 1);
158 
159       if(Mac8Address::IsMatchingType (srcAddress))
160         {
161           NS_LOG_UNCOND ( "Time: " << Simulator::Now ().GetHours () << "h" << " | Node: " <<
162                           Mac8Address::ConvertFrom (srcAddress) << " | Energy: " <<
163                           +energyReading << "%");
164         }
165     }
166 }
167 
168 void
SetupApplications()169 UanExperiment::SetupApplications ()
170 {
171   NodeContainer::Iterator node = m_nodes.Begin ();
172   PacketSocketHelper packetSocketHelper;
173   while (node != m_nodes.End ())
174     {
175       packetSocketHelper.Install (*node);
176       PacketSocketAddress socketAddress;
177       socketAddress.SetSingleDevice ((*node)->GetDevice (0)->GetIfIndex ());
178       socketAddress.SetProtocol (0);
179       m_sockets[*node] = Socket::CreateSocket (*node, TypeId::LookupByName ("ns3::PacketSocketFactory"));
180       m_sockets[*node]->Bind ();
181       m_sockets[*node]->Connect (socketAddress);
182       m_sockets[*node]->SetRecvCallback (MakeCallback (&UanExperiment::PrintReceivedPacket, this));
183       node++;
184     }
185 }
186 
187 void
SendPackets()188 UanExperiment::SendPackets ()
189 {
190   Ptr<UniformRandomVariable> uniformRandomVariable = CreateObject<UniformRandomVariable> ();
191 
192   NodeContainer::Iterator node = m_nodes.Begin ();
193   Mac8Address dst = Mac8Address::ConvertFrom ((*node)->GetDevice (0)->GetAddress ());
194   node++;
195   while (node != m_nodes.End ())
196     {
197       uint8_t energy = ((*node)->GetObject<EnergySourceContainer> ()->Get (0)->GetEnergyFraction ()) * 100;
198 
199       Ptr<Packet> pkt = Create<Packet> (&energy, 1);
200 
201       double time = uniformRandomVariable->GetValue (0, 60);
202       Simulator::Schedule (Seconds (time), &UanExperiment::SendSinglePacket, this, *node, pkt, dst);
203       node++;
204     }
205   Simulator::Schedule (Hours (2), &UanExperiment::SendPackets, this);
206 }
207 
208 void
SendSinglePacket(Ptr<Node> node,Ptr<Packet> pkt,Mac8Address dst)209 UanExperiment::SendSinglePacket (Ptr<Node> node, Ptr<Packet> pkt, Mac8Address dst)
210 {
211   NS_LOG_UNCOND ( Simulator::Now ().GetHours () << "h" << " packet sent to " << dst );
212   PacketSocketAddress socketAddress;
213   socketAddress.SetSingleDevice (node->GetDevice (0)->GetIfIndex ());
214   socketAddress.SetPhysicalAddress (dst);
215   socketAddress.SetProtocol (0);
216   m_sockets[node]->SendTo (pkt, 0, socketAddress);
217 }
218 
219 void
Prepare()220 UanExperiment::Prepare ()
221 {
222   m_nodes.Create (3);
223   SetupPositions ();
224   SetupEnergy ();
225   SetupCommunications ();
226   SetupApplications ();
227   SendPackets ();
228 }
229 
230 void
Teardown()231 UanExperiment::Teardown ()
232 {
233   std::map<Ptr<Node>, Ptr<Socket> >::iterator socket;
234 
235   for (socket = m_sockets.begin (); socket != m_sockets.end (); socket++)
236     {
237       socket->second->Close ();
238     }
239 }
240 
241 int
main(int argc,char * argv[])242 main (int argc, char *argv[])
243 {
244   CommandLine cmd (__FILE__);
245   cmd.Parse (argc, argv);
246 
247   UanExperiment experiment;
248   experiment.Prepare ();
249 
250   Simulator::Stop (Days (50));
251   Simulator::Run ();
252   Simulator::Destroy ();
253 
254   experiment.Teardown ();
255 
256   return 0;
257 }
258