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/sixlowpan-helper.h"
31 #include "ns3/sixlowpan-net-device.h"
32 
33 using namespace ns3;
34 
35 /**
36  *
37  * This example shows the usage of UDP over 6LoWPAN to 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 ("Uan6lowpanExample");
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, Ipv6Address 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   SixLowPanHelper sixLowPanHelper;
147   NetDeviceContainer sixlowpanNetDevices = sixLowPanHelper.Install (netDeviceContainer);
148 
149   InternetStackHelper internetStackHelper;
150   internetStackHelper.Install (m_nodes);
151 
152   Ipv6AddressHelper ipv6AddressHelper;
153   ipv6AddressHelper.SetBase (Ipv6Address ("2002::"), Ipv6Prefix (64));
154   ipv6AddressHelper.Assign (sixlowpanNetDevices);
155 
156   node = m_nodes.Begin ();
157   while (node != m_nodes.End ())
158     {
159       (*node)->GetObject<Icmpv6L4Protocol> ()->SetAttribute ("DAD", BooleanValue (false));
160       (*node)->GetObject<Icmpv6L4Protocol> ()->SetAttribute ("ReachableTime", TimeValue (Seconds (3600)));
161       (*node)->GetObject<Icmpv6L4Protocol> ()->SetAttribute ("RetransmissionTime", TimeValue (Seconds (1000)));
162       node++;
163     }
164 }
165 
166 void
PrintReceivedPacket(Ptr<Socket> socket)167 UanExperiment::PrintReceivedPacket (Ptr<Socket> socket)
168 {
169   Address srcAddress;
170   while (socket->GetRxAvailable () > 0)
171     {
172       Ptr<Packet> packet = socket->RecvFrom (srcAddress);
173       uint8_t energyReading;
174       packet->CopyData (&energyReading, 1);
175 
176       if(Inet6SocketAddress::IsMatchingType (srcAddress))
177         {
178           NS_LOG_UNCOND ( "Time: " << Simulator::Now ().GetHours () << "h" << " | Node: " <<
179                           Inet6SocketAddress::ConvertFrom (srcAddress).GetIpv6 () << " | Energy: " <<
180                           +energyReading << "%");
181         }
182     }
183 }
184 
185 void
SetupApplications()186 UanExperiment::SetupApplications ()
187 {
188   NodeContainer::Iterator node = m_nodes.Begin ();
189   while (node != m_nodes.End ())
190     {
191       m_sockets[*node] = Socket::CreateSocket (*node, TypeId::LookupByName ("ns3::UdpSocketFactory"));
192       if((*node)->GetObject<Ipv6> () != NULL)
193         {
194           Inet6SocketAddress ipv6_local = Inet6SocketAddress (Ipv6Address::GetAny (), 9);
195           m_sockets[*node]->Bind (ipv6_local);
196         }
197 
198       m_sockets[*node]->SetRecvCallback (MakeCallback (&UanExperiment::PrintReceivedPacket, this));
199       node++;
200     }
201 }
202 
203 void
SendPackets()204 UanExperiment::SendPackets ()
205 {
206   Ptr<UniformRandomVariable> uniformRandomVariable = CreateObject<UniformRandomVariable> ();
207 
208   NodeContainer::Iterator node = m_nodes.Begin ();
209   Ipv6Address dst = (*node)->GetObject<Ipv6L3Protocol> ()->GetInterface (1)->GetAddress (1).GetAddress ();
210   node++;
211   while (node != m_nodes.End ())
212     {
213       uint8_t energy = ((*node)->GetObject<EnergySourceContainer> ()->Get (0)->GetEnergyFraction ()) * 100;
214 
215       Ptr<Packet> pkt = Create<Packet> (&energy, 1);
216 
217       double time = uniformRandomVariable->GetValue (0, 60);
218       Simulator::Schedule (Seconds (time), &UanExperiment::SendSinglePacket, this, *node, pkt, dst);
219       node++;
220     }
221   Simulator::Schedule (Hours (2), &UanExperiment::SendPackets, this);
222 }
223 
224 void
SendSinglePacket(Ptr<Node> node,Ptr<Packet> pkt,Ipv6Address dst)225 UanExperiment::SendSinglePacket (Ptr<Node> node, Ptr<Packet> pkt, Ipv6Address dst)
226 {
227   NS_LOG_UNCOND ( Simulator::Now ().GetHours () << "h" << " packet sent to " << dst );
228   Inet6SocketAddress ipv6_destination = Inet6SocketAddress (Ipv6Address::ConvertFrom (dst), 9);
229   m_sockets[node]->SendTo (pkt, 0, ipv6_destination);
230 }
231 
232 void
Prepare()233 UanExperiment::Prepare ()
234 {
235   m_nodes.Create (3);
236   SetupPositions ();
237   SetupEnergy ();
238   SetupCommunications ();
239   SetupApplications ();
240   SendPackets ();
241 }
242 
243 void
Teardown()244 UanExperiment::Teardown ()
245 {
246   std::map<Ptr<Node>, Ptr<Socket> >::iterator socket;
247 
248   for (socket = m_sockets.begin (); socket != m_sockets.end (); socket++)
249     {
250       socket->second->Close ();
251     }
252 }
253 
254 int
main(int argc,char * argv[])255 main (int argc, char *argv[])
256 {
257   CommandLine cmd (__FILE__);
258   cmd.Parse (argc, argv);
259 
260   UanExperiment experiment;
261   experiment.Prepare ();
262 
263   Simulator::Stop (Days (50));
264   Simulator::Run ();
265   Simulator::Destroy ();
266 
267   experiment.Teardown ();
268 
269   return 0;
270 }
271