1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 The Boeing Company
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: Tom Henderson <thomas.r.henderson@boeing.com>
19  */
20 #include <ns3/test.h>
21 #include <ns3/log.h>
22 #include <ns3/callback.h>
23 #include <ns3/packet.h>
24 #include <ns3/simulator.h>
25 #include <ns3/lr-wpan-error-model.h>
26 #include <ns3/propagation-loss-model.h>
27 #include <ns3/lr-wpan-net-device.h>
28 #include <ns3/lr-wpan-mac.h>
29 #include <ns3/node.h>
30 #include <ns3/net-device.h>
31 #include <ns3/single-model-spectrum-channel.h>
32 #include <ns3/mac16-address.h>
33 #include <ns3/constant-position-mobility-model.h>
34 #include "ns3/rng-seed-manager.h"
35 
36 using namespace ns3;
37 
38 NS_LOG_COMPONENT_DEFINE ("lr-wpan-error-model-test");
39 
40 /**
41  * \ingroup lr-wpan-test
42  * \ingroup tests
43  *
44  * \brief LrWpan Error Vs Distance Test
45  */
46 class LrWpanErrorDistanceTestCase : public TestCase
47 {
48 public:
49   LrWpanErrorDistanceTestCase ();
50   virtual ~LrWpanErrorDistanceTestCase ();
51 
52   /**
53    * \brief Get the number of received packets.
54    * \returns The number of received packets.
55    */
GetReceived(void) const56   uint32_t GetReceived (void) const
57   {
58     return m_received;
59   }
60 
61 private:
62   virtual void DoRun (void);
63 
64   /**
65    * \brief Function to be called when a packet is received.
66    * \param params MCPS params.
67    * \param p The packet.
68    */
69   void Callback (McpsDataIndicationParams params, Ptr<Packet> p);
70   uint32_t m_received; //!< The number of received packets.
71 };
72 
73 /**
74  * \ingroup lr-wpan-test
75  * \ingroup tests
76  *
77  * \brief LrWpan Error model Test
78  */
79 class LrWpanErrorModelTestCase : public TestCase
80 {
81 public:
82   LrWpanErrorModelTestCase ();
83   virtual ~LrWpanErrorModelTestCase ();
84 
85 private:
86   virtual void DoRun (void);
87 };
88 
LrWpanErrorDistanceTestCase()89 LrWpanErrorDistanceTestCase::LrWpanErrorDistanceTestCase ()
90   : TestCase ("Test the 802.15.4 error model vs distance"),
91     m_received (0)
92 {
93 }
94 
~LrWpanErrorDistanceTestCase()95 LrWpanErrorDistanceTestCase::~LrWpanErrorDistanceTestCase ()
96 {
97 }
98 
99 void
Callback(McpsDataIndicationParams params,Ptr<Packet> p)100 LrWpanErrorDistanceTestCase::Callback (McpsDataIndicationParams params, Ptr<Packet> p)
101 {
102   m_received++;
103 }
104 
105 void
DoRun(void)106 LrWpanErrorDistanceTestCase::DoRun (void)
107 {
108   // Set the random seed and run number for this test
109   RngSeedManager::SetSeed (1);
110   RngSeedManager::SetRun (6);
111 
112   Ptr<Node> n0 = CreateObject <Node> ();
113   Ptr<Node> n1 = CreateObject <Node> ();
114   Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice> ();
115   Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice> ();
116 
117   // Make random variable stream assignment deterministic
118   dev0->AssignStreams (0);
119   dev1->AssignStreams (10);
120 
121   dev0->SetAddress (Mac16Address ("00:01"));
122   dev1->SetAddress (Mac16Address ("00:02"));
123   Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel> ();
124   Ptr<LogDistancePropagationLossModel> model = CreateObject<LogDistancePropagationLossModel> ();
125   channel->AddPropagationLossModel (model);
126   dev0->SetChannel (channel);
127   dev1->SetChannel (channel);
128   n0->AddDevice (dev0);
129   n1->AddDevice (dev1);
130   Ptr<ConstantPositionMobilityModel> mob0 = CreateObject<ConstantPositionMobilityModel> ();
131   dev0->GetPhy ()->SetMobility (mob0);
132   Ptr<ConstantPositionMobilityModel> mob1 = CreateObject<ConstantPositionMobilityModel> ();
133   dev1->GetPhy ()->SetMobility (mob1);
134 
135   McpsDataIndicationCallback cb0;
136   cb0 = MakeCallback (&LrWpanErrorDistanceTestCase::Callback, this);
137   dev1->GetMac ()->SetMcpsDataIndicationCallback (cb0);
138 
139   McpsDataRequestParams params;
140   params.m_srcAddrMode = SHORT_ADDR;
141   params.m_dstAddrMode = SHORT_ADDR;
142   params.m_dstPanId = 0;
143   params.m_dstAddr = Mac16Address ("00:02");
144   params.m_msduHandle = 0;
145   params.m_txOptions = 0;
146 
147   Ptr<Packet> p;
148   mob0->SetPosition (Vector (0,0,0));
149   mob1->SetPosition (Vector (100,0,0));
150   for (int i = 0; i < 1000; i++)
151     {
152       p = Create<Packet> (20);
153       Simulator::Schedule (Seconds (i),
154                            &LrWpanMac::McpsDataRequest,
155                            dev0->GetMac (), params, p);
156     }
157 
158   Simulator::Run ();
159 
160   // Test that we received 977 packets out of 1000, at distance of 100 m
161   // with default power of 0
162   NS_TEST_ASSERT_MSG_EQ (GetReceived (), 977, "Model fails");
163 
164   Simulator::Destroy ();
165 }
166 
167 // ==============================================================================
LrWpanErrorModelTestCase()168 LrWpanErrorModelTestCase::LrWpanErrorModelTestCase ()
169   : TestCase ("Test the 802.15.4 error model")
170 {
171 }
172 
~LrWpanErrorModelTestCase()173 LrWpanErrorModelTestCase::~LrWpanErrorModelTestCase ()
174 {
175 }
176 
177 void
DoRun(void)178 LrWpanErrorModelTestCase::DoRun (void)
179 {
180 
181   Ptr<LrWpanErrorModel> model = CreateObject<LrWpanErrorModel> ();
182 
183   // Test a few values
184   double snr = 5;
185   double ber = 1.0 - model->GetChunkSuccessRate (pow (10.0, snr / 10.0), 1);
186   NS_TEST_ASSERT_MSG_EQ_TOL (ber, 7.38e-14, 0.01e-14, "Model fails for SNR = " << snr);
187   snr = 2;
188   ber = 1.0 - model->GetChunkSuccessRate (pow (10.0, snr / 10.0), 1);
189   NS_TEST_ASSERT_MSG_EQ_TOL (ber, 5.13e-7, 0.01e-7, "Model fails for SNR = " << snr);
190   snr = -1;
191   ber = 1.0 - model->GetChunkSuccessRate (pow (10.0, snr / 10.0), 1);
192   NS_TEST_ASSERT_MSG_EQ_TOL (ber, 0.00114, 0.00001, "Model fails for SNR = " << snr);
193   snr = -4;
194   ber = 1.0 - model->GetChunkSuccessRate (pow (10.0, snr / 10.0), 1);
195   NS_TEST_ASSERT_MSG_EQ_TOL (ber, 0.0391, 0.0001, "Model fails for SNR = " << snr);
196   snr = -7;
197   ber = 1.0 - model->GetChunkSuccessRate (pow (10.0, snr / 10.0), 1);
198   NS_TEST_ASSERT_MSG_EQ_TOL (ber, 0.175, 0.001, "Model fails for SNR = " << snr);
199 }
200 
201 /**
202  * \ingroup lr-wpan-test
203  * \ingroup tests
204  *
205  * \brief LrWpan Error model TestSuite
206  */
207 class LrWpanErrorModelTestSuite : public TestSuite
208 {
209 public:
210   LrWpanErrorModelTestSuite ();
211 };
212 
LrWpanErrorModelTestSuite()213 LrWpanErrorModelTestSuite::LrWpanErrorModelTestSuite ()
214   : TestSuite ("lr-wpan-error-model", UNIT)
215 {
216   AddTestCase (new LrWpanErrorModelTestCase, TestCase::QUICK);
217   AddTestCase (new LrWpanErrorDistanceTestCase, TestCase::QUICK);
218 }
219 
220 static LrWpanErrorModelTestSuite g_lrWpanErrorModelTestSuite; //!< Static variable for test initialization
221