Bug fixes and test for energy detection code.

This commit is contained in:
Sascha Jopen
2014-04-25 12:51:56 +02:00
parent bdbf0fd6e7
commit 6ded61e205
4 changed files with 287 additions and 5 deletions

View File

@@ -262,7 +262,9 @@ LrWpanPhy::StartRx (Ptr<SpectrumSignalParameters> spectrumRxParams)
if (!m_edRequest.IsExpired ())
{
// Update the average receive power during ED.
m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ()) * (Simulator::Now () - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
Time now = Simulator::Now ();
m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ()) * (now - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
m_edPower.lastUpdate = now;
}
// Prevent PHY from receiving another packet while switching the transceiver state.
@@ -400,7 +402,9 @@ LrWpanPhy::EndRx (Ptr<LrWpanSpectrumSignalParameters> params)
if (!m_edRequest.IsExpired ())
{
// Update the average receive power during ED.
m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ()) * (Simulator::Now () - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
Time now = Simulator::Now ();
m_edPower.averagePower += LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ()) * (now - m_edPower.lastUpdate).GetTimeStep () / m_edPower.measurementLength.GetTimeStep ();
m_edPower.lastUpdate = now;
}
CheckInterference ();
@@ -564,7 +568,7 @@ void
LrWpanPhy::PlmeEdRequest (void)
{
NS_LOG_FUNCTION (this);
if (m_trxState == IEEE_802_15_4_PHY_RX_ON)
if (m_trxState == IEEE_802_15_4_PHY_RX_ON || m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
{
// Average over the powers of all signals received until EndEd()
m_edPower.averagePower = 0;
@@ -574,9 +578,15 @@ LrWpanPhy::PlmeEdRequest (void)
}
else
{
LrWpanPhyEnumeration result = m_trxState;
if (m_trxState == IEEE_802_15_4_PHY_BUSY_TX)
{
result = IEEE_802_15_4_PHY_TX_ON;
}
if (!m_plmeEdConfirmCallback.IsNull ())
{
m_plmeEdConfirmCallback (m_trxState, 0);
m_plmeEdConfirmCallback (result, 0);
}
}
}
@@ -672,6 +682,8 @@ LrWpanPhy::PlmeSetTRXStateRequest (LrWpanPhyEnumeration state)
// a packet being actively received)
if (state == IEEE_802_15_4_PHY_TRX_OFF)
{
CancelEd (state);
if ((m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
&& (m_currentRxPacket.first) && (!m_currentRxPacket.second))
{
@@ -692,6 +704,8 @@ LrWpanPhy::PlmeSetTRXStateRequest (LrWpanPhyEnumeration state)
if (state == IEEE_802_15_4_PHY_TX_ON)
{
CancelEd (state);
NS_LOG_DEBUG ("turn on PHY_TX_ON");
if ((m_trxState == IEEE_802_15_4_PHY_BUSY_RX) || (m_trxState == IEEE_802_15_4_PHY_RX_ON))
{
@@ -986,6 +1000,22 @@ LrWpanPhy::PhyIsBusy (void) const
|| (m_trxState == IEEE_802_15_4_PHY_BUSY));
}
void
LrWpanPhy::CancelEd (LrWpanPhyEnumeration state)
{
NS_LOG_FUNCTION (this);
NS_ASSERT (state == IEEE_802_15_4_PHY_TRX_OFF || state == IEEE_802_15_4_PHY_TX_ON);
if (!m_edRequest.IsExpired ())
{
m_edRequest.Cancel ();
if (!m_plmeEdConfirmCallback.IsNull ())
{
m_plmeEdConfirmCallback (state, 0);
}
}
}
void
LrWpanPhy::EndEd ()
{
@@ -1009,7 +1039,7 @@ LrWpanPhy::EndEd ()
else
{
// in-between with linear increase per sec 6.9.7
energyLevel = (uint8_t)((ratio / 10.0 - 1.0) * (255.0 / 3.0));
energyLevel = static_cast<uint8_t> (((ratio - 10.0) / 30.0) * 255.0);
}
if (!m_plmeEdConfirmCallback.IsNull ())

View File

@@ -396,6 +396,8 @@ private:
void CheckInterference ();
void EndRx (Ptr<LrWpanSpectrumSignalParameters> params);
void CancelEd (LrWpanPhyEnumeration state);
void EndEd ();
void EndCca ();
void EndSetTRXState ();

View File

@@ -0,0 +1,249 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 Fraunhofer FKIE
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author:
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
*/
#include <ns3/log.h>
#include <ns3/core-module.h>
#include <ns3/lr-wpan-module.h>
#include <ns3/propagation-loss-model.h>
#include <ns3/propagation-delay-model.h>
#include <ns3/simulator.h>
#include <ns3/single-model-spectrum-channel.h>
#include <ns3/constant-position-mobility-model.h>
#include <ns3/packet.h>
#include <iostream>
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("lr-wpan-ed-test");
using namespace ns3;
class LrWpanEdTestCase : public TestCase
{
public:
LrWpanEdTestCase ();
private:
virtual void DoRun (void);
void PlmeEdConfirm (LrWpanPhyEnumeration status, uint8_t level);
LrWpanPhyEnumeration m_status;
uint8_t m_level;
};
LrWpanEdTestCase::LrWpanEdTestCase ()
: TestCase ("Test the 802.15.4 energie detection")
{
m_status = IEEE_802_15_4_PHY_UNSPECIFIED;
m_level = 0;
}
void
LrWpanEdTestCase::PlmeEdConfirm (LrWpanPhyEnumeration status, uint8_t level)
{
NS_LOG_UNCOND ("ED completed with status " << LrWpanHelper::LrWpanPhyEnumerationPrinter(status) << " and energy level " << static_cast<uint32_t> (level));
m_status = status;
m_level = level;
}
void
LrWpanEdTestCase::DoRun (void)
{
// Tx Power: 0 dBm
// Receiver Sensitivity: -106.58 dBm
// Do energy detection for a single packet, arriving with 5 dB, 10 dB, 25 dB,
// 40 dB, relative to RX Power / Sensitivity. This should yield 0, 0, 127,
// and 255 as the reported energy levels.
// TODO: Maybe there should be a test for several interfering packets.
// TODO: There should be tests for signals not originating from 802.15.4
// devices.
// Test setup:
// Two nodes in communication range. The propagation model is adjusted to
// give us the above mentioned RX powers.
// Node 1 sends a packet to node 2. Node 2 starts energy detection, while the
// packet reception is in progress. The detected energy level is compared to
// the expected values.
// Enable calculation of FCS in the trailers. Only necessary when interacting with real devices or wireshark.
// GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
// Create 2 nodes, and a NetDevice for each one
Ptr<Node> n0 = CreateObject <Node> ();
Ptr<Node> n1 = CreateObject <Node> ();
Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice> ();
Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice> ();
dev0->SetAddress (Mac16Address ("00:01"));
dev1->SetAddress (Mac16Address ("00:02"));
// Each device must be attached to the same channel
Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel> ();
Ptr<FixedRssLossModel> propModel = CreateObject<FixedRssLossModel> ();
Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
channel->AddPropagationLossModel (propModel);
channel->SetPropagationDelayModel (delayModel);
dev0->SetChannel (channel);
dev1->SetChannel (channel);
// To complete configuration, a LrWpanNetDevice must be added to a node
n0->AddDevice (dev0);
n1->AddDevice (dev1);
Ptr<ConstantPositionMobilityModel> sender0Mobility = CreateObject<ConstantPositionMobilityModel> ();
sender0Mobility->SetPosition (Vector (0, 0, 0));
dev0->GetPhy ()->SetMobility (sender0Mobility);
Ptr<ConstantPositionMobilityModel> sender1Mobility = CreateObject<ConstantPositionMobilityModel> ();
// Configure position 10 m distance
sender1Mobility->SetPosition (Vector (0, 10, 0));
dev1->GetPhy ()->SetMobility (sender1Mobility);
// Set the ED confirm callback.
dev0->GetPhy ()->SetPlmeEdConfirmCallback (MakeCallback (&LrWpanEdTestCase::PlmeEdConfirm, this));
dev1->GetPhy ()->SetPlmeEdConfirmCallback (MakeCallback (&LrWpanEdTestCase::PlmeEdConfirm, this));
// Configure the RX Power to be -107.58 dBm, i.e. 1 dB below receiver sensitivity.
propModel->SetRss (-107.58);
m_status = IEEE_802_15_4_PHY_UNSPECIFIED;
m_level = 0;
Ptr<Packet> p0 = Create<Packet> (100); // 100 bytes of dummy data
McpsDataRequestParams params;
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstPanId = 0;
params.m_dstAddr = Mac16Address ("00:02");
params.m_msduHandle = 0;
params.m_txOptions = TX_OPTION_NONE;
Simulator::ScheduleNow (&LrWpanMac::McpsDataRequest, dev0->GetMac (), params, p0);
Simulator::Schedule (Seconds (0.0025), &LrWpanPhy::PlmeEdRequest, dev1->GetPhy ());
Simulator::Run ();
NS_TEST_EXPECT_MSG_EQ (m_status, IEEE_802_15_4_PHY_SUCCESS, "ED status SUCCESS (as expected)");
NS_TEST_EXPECT_MSG_EQ (m_level, 0, "ED reported signal level 0 (as expected)");
// Configure the RX Power to be -106.58 dBm, i.e. exectly to receiver sensitivity.
propModel->SetRss (-106.58);
m_status = IEEE_802_15_4_PHY_UNSPECIFIED;
m_level = 0;
Ptr<Packet> p1 = Create<Packet> (100); // 100 bytes of dummy data
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstPanId = 0;
params.m_dstAddr = Mac16Address ("00:02");
params.m_msduHandle = 0;
params.m_txOptions = TX_OPTION_NONE;
Simulator::ScheduleNow (&LrWpanMac::McpsDataRequest, dev0->GetMac (), params, p1);
Simulator::Schedule (Seconds (0.0025), &LrWpanPhy::PlmeEdRequest, dev1->GetPhy ());
Simulator::Run ();
NS_TEST_EXPECT_MSG_EQ (m_status, IEEE_802_15_4_PHY_SUCCESS, "ED status SUCCESS (as expected)");
NS_TEST_EXPECT_MSG_EQ (m_level, 0, "ED reported signal level 0 (as expected)");
// Configure the RX Power to be -81.58 dBm, i.e. 25 dB above receiver sensitivity.
propModel->SetRss (-81.58);
m_status = IEEE_802_15_4_PHY_UNSPECIFIED;
m_level = 0;
Ptr<Packet> p2 = Create<Packet> (100); // 100 bytes of dummy data
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstPanId = 0;
params.m_dstAddr = Mac16Address ("00:02");
params.m_msduHandle = 0;
params.m_txOptions = TX_OPTION_NONE;
Simulator::ScheduleNow (&LrWpanMac::McpsDataRequest, dev0->GetMac (), params, p2);
Simulator::Schedule (Seconds (0.0025), &LrWpanPhy::PlmeEdRequest, dev1->GetPhy ());
Simulator::Run ();
NS_TEST_EXPECT_MSG_EQ (m_status, IEEE_802_15_4_PHY_SUCCESS, "ED status SUCCESS (as expected)");
NS_TEST_EXPECT_MSG_EQ (m_level, 127, "ED reported signal level 127 (as expected)");
// Configure the RX Power to be -66.58 dBm, i.e. 40 dB above receiver sensitivity.
propModel->SetRss (-66.58);
m_status = IEEE_802_15_4_PHY_UNSPECIFIED;
m_level = 0;
Ptr<Packet> p3 = Create<Packet> (100); // 100 bytes of dummy data
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstPanId = 0;
params.m_dstAddr = Mac16Address ("00:02");
params.m_msduHandle = 0;
params.m_txOptions = TX_OPTION_NONE;
Simulator::ScheduleNow (&LrWpanMac::McpsDataRequest, dev0->GetMac (), params, p3);
Simulator::Schedule (Seconds (0.0025), &LrWpanPhy::PlmeEdRequest, dev1->GetPhy ());
Simulator::Run ();
NS_TEST_EXPECT_MSG_EQ (m_status, IEEE_802_15_4_PHY_SUCCESS, "ED status SUCCESS (as expected)");
NS_TEST_EXPECT_MSG_EQ (m_level, 255, "ED reported signal level 255 (as expected)");
// Test ED at sender.
m_status = IEEE_802_15_4_PHY_UNSPECIFIED;
m_level = 0;
Ptr<Packet> p4 = Create<Packet> (100); // 100 bytes of dummy data
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstPanId = 0;
params.m_dstAddr = Mac16Address ("00:02");
params.m_msduHandle = 0;
params.m_txOptions = TX_OPTION_NONE;
Simulator::ScheduleNow (&LrWpanMac::McpsDataRequest, dev0->GetMac (), params, p4);
Simulator::Schedule (Seconds (0.0025), &LrWpanPhy::PlmeEdRequest, dev0->GetPhy ());
Simulator::Run ();
NS_TEST_EXPECT_MSG_EQ (m_status, IEEE_802_15_4_PHY_TX_ON, "ED status TX_ON (as expected)");
NS_TEST_EXPECT_MSG_EQ (m_level, 0, "ED reported signal level 0 (as expected)");
Simulator::Destroy ();
}
class LrWpanEdTestSuite : public TestSuite
{
public:
LrWpanEdTestSuite ();
};
LrWpanEdTestSuite::LrWpanEdTestSuite ()
: TestSuite ("lr-wpan-ed", UNIT)
{
AddTestCase (new LrWpanEdTestCase, TestCase::QUICK);
}
static LrWpanEdTestSuite g_lrWpanEdTestSuite;

View File

@@ -21,6 +21,7 @@ def build(bld):
module_test.source = [
'test/lr-wpan-ack-test.cc',
'test/lr-wpan-collision-test.cc',
'test/lr-wpan-ed-test.cc',
'test/lr-wpan-error-model-test.cc',
'test/lr-wpan-packet-test.cc',
'test/lr-wpan-pd-plme-sap-test.cc',