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