diff -r 8359b3ac1ab0 src/netanim/helper/animation-interface-helper.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/netanim/helper/animation-interface-helper.cc Wed Jun 22 07:51:42 2011 -0700 @@ -0,0 +1,67 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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: John Abraham + */ + +// Animation Interface helpers + +#include "ns3/animation-interface-helper.h" +namespace ns3 { +AnimPacketInfo::AnimPacketInfo() + : m_nd (0), m_nRx (0), m_nDrop (0), m_nRxEnd (0), m_fbTx (0), m_lbTx (0) +{ +} + +AnimPacketInfo::AnimPacketInfo(Ptr nd, uint32_t nRx, + const Time& fbTx, const Time& lbTx) + : m_nd (nd), m_nRx (nRx), m_nDrop (0), m_nRxEnd (0), + m_fbTx (fbTx.GetSeconds ()), m_lbTx (lbTx.GetSeconds ()) +{ +} + +void AnimPacketInfo::AddRxBegin (Ptr nd, const Time& fbRx) +{ + m_rx.push_back (AnimRxInfo (nd, fbRx)); +} + +bool AnimPacketInfo::AddRxEnd (Ptr nd, const Time& lbRx) + +{ + // Find the RxInfo + for (uint32_t i = 0; i < m_rx.size (); ++i) + { + if (m_rx[i].m_nd == nd) + { // Found it + m_rx[i].m_lbRx = lbRx.GetSeconds (); + m_nRxEnd++; + if ((m_nRxEnd + m_nDrop) == m_nRx) return true; // Got them all + return false; // Still more rxEnd expected + } + } + // This should not happen, but if so we just bump the drop count + m_nDrop++; + if ((m_nRxEnd + m_nDrop) == m_nRx) return true; // Got them all + return false; // Still more rxEnd expected + +} + +void AnimPacketInfo::AddRxDrop () +{ + m_nDrop++; +} + + +} // namespace ns3 diff -r 8359b3ac1ab0 src/netanim/helper/animation-interface-helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/netanim/helper/animation-interface-helper.h Wed Jun 22 07:51:42 2011 -0700 @@ -0,0 +1,64 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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: John Abraham + */ + +// Animation Interface helpers + +#ifndef _ANIMATION_INTERFACE_HELPER_H_ +#define _ANIMATION_INTERFACE_HELPER_H_ + +#include "ns3/node.h" +#include "ns3/mobility-model.h" +#include "ns3/packet.h" +#include "ns3/simulator.h" +#include + + +namespace ns3 { +// We use a PacketInfo structure for wireless traces to keep up +// when each receiver has received packets. Also a PacketRxInfo +// to keep up with each receiver and the time it received the packet +struct AnimRxInfo + +{ + AnimRxInfo(Ptr nd, const Time& fbRx) + : m_nd (nd), m_fbRx (fbRx.GetSeconds ()), m_lbRx (0) {} + Ptr m_nd; // The receiving net device + double m_fbRx; // First bit rx time + double m_lbRx; // Last bit rx time +}; + +struct AnimPacketInfo + +{ + AnimPacketInfo (); + AnimPacketInfo(Ptr nd, uint32_t nRx, + const Time& fbTx, const Time& lbTx); + void AddRxBegin (Ptr nd, const Time& fbRx); + bool AddRxEnd (Ptr nd, const Time& fbRx); + void AddRxDrop (); + Ptr m_nd; + uint32_t m_nRx; // Number of receivers expected + uint32_t m_nDrop; // Number of drops + uint32_t m_nRxEnd; // Number of rxEnd callbacks + double m_fbTx; // Time of first bit tx + double m_lbTx; // Time of last bit tx + std::vector m_rx; +}; +} // namespace ns3 + +#endif diff -r 8359b3ac1ab0 src/netanim/model/animation-interface.cc --- a/src/netanim/model/animation-interface.cc Fri Jun 03 10:54:07 2011 -0700 +++ b/src/netanim/model/animation-interface.cc Wed Jun 22 07:51:42 2011 -0700 @@ -20,6 +20,9 @@ #include #include +#include +#include +#include // Socket related includes #if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H) @@ -37,6 +40,7 @@ #include "ns3/mobility-model.h" #include "ns3/packet.h" #include "ns3/simulator.h" +#include "ns3/animation-interface-helper.h" using namespace std; @@ -45,12 +49,18 @@ namespace ns3 { AnimationInterface::AnimationInterface () - : m_fHandle (STDOUT_FILENO), m_model (0) + : m_fHandle (STDOUT_FILENO), m_xml (false), m_model (0), mobilitypollinterval (Seconds(0.25)) { } AnimationInterface::~AnimationInterface () { + StopAnimation (); +} + +void AnimationInterface::SetXMLOutput () +{ + m_xml = true; } bool AnimationInterface::SetOutputFile (const std::string& fn) @@ -93,20 +103,74 @@ void AnimationInterface::StartAnimation () { + // Find the min/max x/y for the xml topology element + topo_minX = 0; + topo_minY = 0; + topo_maxX = 0; + topo_maxY = 0; + bool first = true; + for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) + { + Ptr n = *i; + Ptr loc = n->GetObject (); + Vector v; + if (!loc) continue; + if (loc) + { + v = loc->GetPosition (); + } + if (first) + { + topo_minX = v.x; + topo_minY = v.y; + topo_maxX = v.x; + topo_maxY = v.y; + first = false; + } + else + { + topo_minX = min (topo_minX, v.x); + topo_minY = min (topo_minY, v.y); + topo_maxX = max (topo_maxX, v.x); + topo_maxY = max (topo_maxY, v.y); + } + } + + if (m_xml) + { // output the xml headers + // Compute width/height, and add a small margin + double w = topo_maxX - topo_minX; + double h = topo_maxY - topo_minY; + topo_minX -= w * 0.05; + topo_minY -= h * 0.05; + topo_maxX = topo_minX + w * 1.10; + topo_maxY = topo_minY + h * 1.10; + ostringstream oss; + oss << GetXMLOpen_anim (0); + oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY); + WriteN (m_fHandle, oss.str ()); + } // Dump the topology for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) { Ptr n = *i; Ptr loc = n->GetObject (); - if (loc) + if (!loc) continue; // Can't find a position + ostringstream oss; + if (m_xml) + { + Vector v = loc->GetPosition (); + oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y); + } + else { // Location exists, dump it Vector v = loc->GetPosition (); - ostringstream oss; oss << "0.0 N " << n->GetId () << " " << v.x << " " << v.y << endl; - WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ()); } + + WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ()); } // Now dump the p2p links for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) @@ -134,32 +198,70 @@ if (n1Id < n2Id) { // ouptut the p2p link ostringstream oss; - oss << "0.0 L " << n1Id << " " << n2Id << endl; - WriteN (m_fHandle, oss.str ().c_str (), - oss.str ().length ()); + if (m_xml) + { + oss << GetXMLOpenClose_link (0,n1Id,0,n2Id); + } + else + { + oss << "0.0 L " << n1Id << " " << n2Id << endl; + } + WriteN (m_fHandle, oss.str ()); + } } } else { - NS_FATAL_ERROR ("Net animation currently only supports point-to-point links."); + //NS_FATAL_ERROR ("Net animation currently only supports point-to-point links."); } } } + if (m_xml) + { + WriteN (m_fHandle, GetXMLClose ("topology")); + Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this); + } // Connect the callback for packet tx events Config::Connect ("/ChannelList/*/TxRxPointToPoint", MakeCallback (&AnimationInterface::DevTxTrace, this)); +//#if 0 // To be implemented after trace sources are installed + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin", + MakeCallback (&AnimationInterface::PhyTxBeginTrace, this)); + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxEnd", + MakeCallback (&AnimationInterface::PhyTxEndTrace, this)); + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin", + MakeCallback (&AnimationInterface::PhyRxBeginTrace, this)); + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxEnd", + MakeCallback (&AnimationInterface::PhyRxEndTrace, this)); + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop", + MakeCallback (&AnimationInterface::PhyRxDropTrace, this)); + Config::ConnectWithoutContext ("/NodeList/1/$ns3::MobilityModel/CourseChange", + MakeCallback (&AnimationInterface::MobilityCourseChangeTrace, this)); + +//#endif + } void AnimationInterface::StopAnimation () { if (m_fHandle > 0) { + if (m_xml) + { // Terminate the anim element + WriteN (m_fHandle, GetXMLClose ("anim")); + } close (m_fHandle); + m_fHandle = 0; } } +int AnimationInterface::WriteN (int h, const string& st) +{ + return WriteN (h, st.c_str (), st.length ()); +} + // Private methods int AnimationInterface::WriteN (int h, const char* data, uint32_t count) @@ -167,7 +269,6 @@ uint32_t nLeft = count; const char* p = data; uint32_t written = 0; - while (nLeft) { int n = write (h, p, nLeft); @@ -188,13 +289,232 @@ { Time now = Simulator::Now (); ostringstream oss; - oss << now.GetSeconds () << " P " - << tx->GetNode ()->GetId () << " " - << rx->GetNode ()->GetId () << " " - << (now + txTime).GetSeconds () << " " // last bit tx time - << (now + rxTime - txTime).GetSeconds () << " " // first bit rx time - << (now + rxTime).GetSeconds () << endl; // last bit rx time - WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ()); + double fbTx = now.GetSeconds (); + double lbTx = (now + txTime).GetSeconds (); + double fbRx = (now + rxTime - txTime).GetSeconds (); + double lbRx = (now + rxTime).GetSeconds (); + if (m_xml) + { + oss << GetXMLOpen_packet (0,tx->GetNode ()->GetId (),fbTx,lbTx); + oss << GetXMLOpenClose_rx (0,rx->GetNode ()->GetId (),fbRx,lbRx); + oss << GetXMLClose ("packet"); + } + else + { + oss << setprecision (10); + oss << now.GetSeconds () << " P " + << tx->GetNode ()->GetId () << " " + << rx->GetNode ()->GetId () << " " + << (now + txTime).GetSeconds () << " " // last bit tx time + << (now + rxTime - txTime).GetSeconds () << " " // first bit rx time + << (now + rxTime).GetSeconds () << endl; // last bit rx time + } + WriteN (m_fHandle, oss.str ()); } + +void AnimationInterface::PhyTxBeginTrace (std::string context, + Ptr p, + Ptr nd, + const Time& txTime, + uint32_t nReceivers) +{ + // Add a new pending wireless + Ptr ndev = DynamicCast(nd); + NS_ASSERT (ndev); + pendingWirelessPackets[p->GetUid ()] = + AnimPacketInfo (ndev, nReceivers, Simulator::Now (), Simulator::Now () + txTime); +} + + +void AnimationInterface::PhyTxEndTrace (std::string context, + Ptr p, + Ptr nd) +{ +} + + +void AnimationInterface::PhyRxBeginTrace (std::string context, + Ptr p, + Ptr nd) +{ + Ptr ndev = DynamicCast(nd); + NS_ASSERT (ndev); + pendingWirelessPackets[p->GetUid ()].AddRxBegin (ndev, Simulator::Now ()); +} + + +void AnimationInterface::PhyRxEndTrace (std::string context, + Ptr p, + Ptr nd) +{ + Ptr ndev = DynamicCast(nd); + NS_ASSERT (ndev); + uint32_t uid = p->GetUid (); + AnimPacketInfo& pkt = pendingWirelessPackets[uid]; + if (pkt.AddRxEnd (ndev, Simulator::Now ())) + { + //cout << "Packet " << uid << " complete" << endl; + OutputWirelessPacket (uid, pkt); + pendingWirelessPackets.erase (pendingWirelessPackets.find (uid));; + } +} + + +void AnimationInterface::PhyRxDropTrace (std::string context, + Ptr p, + Ptr nd) +{ + pendingWirelessPackets[p->GetUid ()].AddRxDrop (); +} + + +void AnimationInterface::MobilityCourseChangeTrace (Ptr mobility) + +{ + Ptr n = mobility->GetObject (); + if (!n) return; + if (!mobility) return; + Vector v ; + v = mobility->GetPosition (); + ostringstream oss; + oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY); + oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y); + oss << GetXMLClose ("topology"); + WriteN (m_fHandle, oss.str ()); +} + +void AnimationInterface::MobilityAutoCheck () +{ + Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this); + for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) + { + Ptr n = *i; + if (!n) continue; + Ptr mobility = n->GetObject (); + if (!mobility) continue; + Vector v ; + v = mobility->GetPosition (); + ostringstream oss; + oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY); + oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y); + oss << GetXMLClose ("topology"); + WriteN (m_fHandle, oss.str ()); + } +} + + +// Helper to output a wireless packet. +// For now, only the XML interface is supported + +void AnimationInterface::OutputWirelessPacket (uint32_t uid, AnimPacketInfo& pktInfo) + +{ + if (!m_xml) return; + ostringstream oss; + uint32_t nodeId = pktInfo.m_nd->GetNode ()->GetId (); + double lbTx = pktInfo.m_lbTx; + +#if 0 // To be tested + + // This is a hack until the notify tx end is working + if (lbTx == 0) + { + if (pktInfo.m_rx.empty ()) + { + lbTx = pktInfo.m_fbTx + 100E-6; // 100 microsec + } + else + { + lbTx = pktInfo.m_fbTx + + pktInfo.m_rx[0].m_lbRx - pktInfo.m_rx[0].m_fbRx; + } + } + +#endif + + // Oops, need to figure out about range + oss << GetXMLOpen_wpacket (0,nodeId,pktInfo.m_fbTx,lbTx,500); + // Now add each rx + for (uint32_t i = 0; i < pktInfo.m_rx.size (); ++i) + { + AnimRxInfo& rx = pktInfo.m_rx[i]; + uint32_t rxId = rx.m_nd->GetNode ()->GetId (); + oss << GetXMLOpenClose_rx (0,rxId,rx.m_fbRx,rx.m_lbRx); + } + oss << GetXMLClose ("wpacket"); + WriteN (m_fHandle, oss.str ()); +} + + +// XML Private Helpers + +std::string AnimationInterface::GetXMLOpen_anim (uint32_t lp) +{ + ostringstream oss; + oss <<"\n"; + return oss.str (); +} +std::string AnimationInterface::GetXMLOpen_topology (double minX,double minY,double maxX,double maxY) +{ + ostringstream oss; + oss <<"" << endl; + return oss.str (); + +} + +std::string AnimationInterface::GetXMLOpenClose_node (uint32_t lp,uint32_t id,double locX,double locY) +{ + ostringstream oss; + oss <<"\n"; + return oss.str (); +} +std::string AnimationInterface::GetXMLOpenClose_link (uint32_t fromLp,uint32_t fromId, uint32_t toLp, uint32_t toId) +{ + ostringstream oss; + oss << "" << endl; + return oss.str (); +} + + +std::string AnimationInterface::GetXMLOpen_packet (uint32_t fromLp,uint32_t fromId, double fbTx, double lbTx) +{ + ostringstream oss; + oss << setprecision (10); + oss << "" << endl; + return oss.str (); +} + +std::string AnimationInterface::GetXMLOpen_wpacket (uint32_t fromLp,uint32_t fromId, double fbTx, double lbTx, double range) +{ + ostringstream oss; + oss << setprecision (10); + oss << "" << endl; + return oss.str (); + +} + +std::string AnimationInterface::GetXMLOpenClose_rx (uint32_t toLp, uint32_t toId, double fbRx, double lbRx) +{ + ostringstream oss; + oss << setprecision (10); + oss << "" << endl; + return oss.str (); +} + + } // namespace ns3 diff -r 8359b3ac1ab0 src/netanim/model/animation-interface.h --- a/src/netanim/model/animation-interface.h Fri Jun 03 10:54:07 2011 -0700 +++ b/src/netanim/model/animation-interface.h Wed Jun 22 07:51:42 2011 -0700 @@ -22,18 +22,21 @@ #define ANIMATION_INTERFACE__H #include - +#include +#include #include "ns3/ptr.h" #include "ns3/net-device.h" #include "ns3/nstime.h" #include "ns3/log.h" #include "ns3/node-list.h" - +#include "ns3/simulator.h" +#include "ns3/config.h" +#include "ns3/animation-interface-helper.h" namespace ns3 { class NetModel; - +//class AnimPacketInfo; /** * \defgroup netanim Netanim * @@ -72,6 +75,15 @@ bool SetOutputFile (const std::string& fn); /** + * @brief Specify that animation commands are to be written + * in XML format. + * + * @returns none + */ + + void SetXMLOutput (); + +/** * @brief Specify that animation commands are to be written to * a socket. * @@ -103,18 +115,66 @@ */ void StopAnimation (); - private: // Packet tx animation callback - void DevTxTrace (std::string context, Ptr p, - Ptr tx, Ptr rx, - Time txTime, Time rxTime); + void DevTxTrace (std::string context, + Ptr p, + Ptr tx, + Ptr rx, + Time txTime, + Time rxTime); + void PhyTxBeginTrace (std::string context, + Ptr p, + Ptr nd, + const Time& txTime, + uint32_t nReceivers); + void PhyTxEndTrace (std::string context, + Ptr p, + Ptr nd); + void PhyRxBeginTrace (std::string context, + Ptr p, + Ptr nd); + void PhyRxEndTrace (std::string context, + Ptr p, + Ptr nd); + void PhyRxDropTrace (std::string context, + Ptr p, + Ptr nd); + void MobilityCourseChangeTrace (Ptr mob); + // Write specified amount of data to the specified handle int WriteN (int, const char*, uint32_t); + // Write a string to the specified handle; + int WriteN (int, const std::string&); + //Helper to output xml wireless packet + void OutputWirelessPacket (uint32_t, AnimPacketInfo&); + void MobilityAutoCheck (); + void SetMobilityPollInterval (Time t) {mobilitypollinterval = t;} private: int m_fHandle; // File handle for output (-1 if none) + bool m_xml; // True if xml format desired NetModel* m_model; // If non nil, points to the internal network model // for the interlan animator + std::map pendingWirelessPackets; + +// XML helpers + + // Topology element dimensions + double topo_minX; + double topo_minY; + double topo_maxX; + double topo_maxY; + + std::string GetXMLOpen_anim (uint32_t lp); + std::string GetXMLOpen_topology (double minX,double minY,double maxX,double maxY); + std::string GetXMLOpenClose_node (uint32_t lp,uint32_t id,double locX,double locY); + std::string GetXMLOpenClose_link (uint32_t fromLp,uint32_t fromId, uint32_t toLp, uint32_t toId); + std::string GetXMLOpen_packet (uint32_t fromLp,uint32_t fromId, double fbTx, double lbTx); + std::string GetXMLOpenClose_rx (uint32_t toLp, uint32_t toId, double fbRx, double lbRx); + std::string GetXMLOpen_wpacket (uint32_t fromLp,uint32_t fromId, double fbTx, double lbTx, double range); + std::string GetXMLClose (std::string name) {return "\n"; } + Time mobilitypollinterval; + }; } #endif diff -r 8359b3ac1ab0 src/wifi/model/wifi-phy.cc --- a/src/wifi/model/wifi-phy.cc Fri Jun 03 10:54:07 2011 -0700 +++ b/src/wifi/model/wifi-phy.cc Wed Jun 22 07:51:42 2011 -0700 @@ -300,41 +300,48 @@ return MicroSeconds (duration); } - void -WifiPhy::NotifyTxBegin (Ptr packet) +WifiPhy::NotifyTxBegin (Ptr packet, + Ptr nd, + const Time& duration, + uint32_t nReceivers) { - m_phyTxBeginTrace (packet); + m_phyTxBeginTrace (packet, nd, duration, nReceivers); } -void -WifiPhy::NotifyTxEnd (Ptr packet) +void +WifiPhy::NotifyTxEnd (Ptr packet, + Ptr nd) { - m_phyTxEndTrace (packet); + m_phyTxEndTrace (packet, nd); } -void -WifiPhy::NotifyTxDrop (Ptr packet) +void +WifiPhy::NotifyTxDrop (Ptr packet, + Ptr nd) { - m_phyTxDropTrace (packet); + m_phyTxDropTrace (packet, nd); } -void -WifiPhy::NotifyRxBegin (Ptr packet) +void +WifiPhy::NotifyRxBegin (Ptr packet, + Ptr nd) { - m_phyRxBeginTrace (packet); + m_phyRxBeginTrace (packet, nd); } -void -WifiPhy::NotifyRxEnd (Ptr packet) +void +WifiPhy::NotifyRxEnd (Ptr packet, + Ptr nd) { - m_phyRxEndTrace (packet); + m_phyRxEndTrace (packet, nd); } -void -WifiPhy::NotifyRxDrop (Ptr packet) +void +WifiPhy::NotifyRxDrop (Ptr packet, + Ptr nd) { - m_phyRxDropTrace (packet); + m_phyRxDropTrace (packet, nd); } void diff -r 8359b3ac1ab0 src/wifi/model/wifi-phy.h --- a/src/wifi/model/wifi-phy.h Fri Jun 03 10:54:07 2011 -0700 +++ b/src/wifi/model/wifi-phy.h Wed Jun 22 07:51:42 2011 -0700 @@ -380,39 +380,50 @@ /** * Public method used to fire a PhyTxBegin trace. Implemented for encapsulation * purposes. + * \param Ptr to packet to be transmitted + * \param Ptr to device used to transmit + * \param Duration for Transmission + * \param Number of reeivers for the transmission */ - void NotifyTxBegin (Ptr packet); - + void NotifyTxBegin (Ptr packet, + Ptr nd, + const Time& duration, + uint32_t nReceivers); /** * Public method used to fire a PhyTxEnd trace. Implemented for encapsulation * purposes. + * \param Ptr to packet transmitted + * \param Ptr to device used to transmit */ - void NotifyTxEnd (Ptr packet); - + void NotifyTxEnd (Ptr packet, Ptr nd); /** * Public method used to fire a PhyTxDrop trace. Implemented for encapsulation * purposes. + * \param Ptr to packet to be dropped before transmission + * \param Ptr to device used to transmit */ - void NotifyTxDrop (Ptr packet); - + void NotifyTxDrop (Ptr packet, Ptr nd); /** * Public method used to fire a PhyRxBegin trace. Implemented for encapsulation * purposes. + * \param Ptr to packet to be received + * \param Ptr to device used to receive */ - void NotifyRxBegin (Ptr packet); - + void NotifyRxBegin (Ptr packet, Ptr nd); /** * Public method used to fire a PhyRxEnd trace. Implemented for encapsulation * purposes. + * \param Ptr to packet received + * \param Ptr to device used to receive */ - void NotifyRxEnd (Ptr packet); - + void NotifyRxEnd (Ptr packet, Ptr nd); /** * Public method used to fire a PhyRxDrop trace. Implemented for encapsulation * purposes. + * \param Ptr to packet to be dropped on reception + * \param Ptr to device used to receive */ - void NotifyRxDrop (Ptr packet); - + void NotifyRxDrop (Ptr packet, Ptr nd); /** * * Public method used to fire a PromiscSniffer trace for a wifi packet being received. Implemented for encapsulation @@ -456,50 +467,60 @@ /** * The trace source fired when a packet begins the transmission process on * the medium. - * + * \param Ptr to packet to be transmitted + * \param Ptr to device used to transmit + * \param Duration for Transmission + * \param Number of reeivers for the transmission + * * \see class CallBackTraceSource */ - TracedCallback > m_phyTxBeginTrace; + TracedCallback, Ptr, const Time&, uint32_t> m_phyTxBeginTrace; /** * The trace source fired when a packet ends the transmission process on * the medium. + * \param Ptr to packet transmitted + * \param Ptr to device used to transmit * * \see class CallBackTraceSource */ - TracedCallback > m_phyTxEndTrace; + TracedCallback, Ptr > m_phyTxEndTrace; /** * The trace source fired when the phy layer drops a packet as it tries * to transmit it. + * \param Ptr to packet to be dropped before transmission + * \param Ptr to device used to transmit * * \see class CallBackTraceSource */ - TracedCallback > m_phyTxDropTrace; - + TracedCallback, Ptr > m_phyTxDropTrace; /** * The trace source fired when a packet begins the reception process from * the medium. + * \param Ptr to packet to be received + * \param Ptr to device used to receive * * \see class CallBackTraceSource */ - TracedCallback > m_phyRxBeginTrace; - + TracedCallback, Ptr > m_phyRxBeginTrace; /** * The trace source fired when a packet ends the reception process from * the medium. + * \param Ptr to packet received + * \param Ptr to device used to receive * * \see class CallBackTraceSource */ - TracedCallback > m_phyRxEndTrace; - + TracedCallback , Ptr > m_phyRxEndTrace; /** * The trace source fired when the phy layer drops a packet it has received. + * \param Ptr to packet to be dropped on reception + * \param Ptr to device used to receive * * \see class CallBackTraceSource */ - TracedCallback > m_phyRxDropTrace; - + TracedCallback , Ptr > m_phyRxDropTrace; /** * A trace source that emulates a wifi device in monitor mode * sniffing a packet being received. diff -r 8359b3ac1ab0 src/wifi/model/yans-wifi-channel.cc --- a/src/wifi/model/yans-wifi-channel.cc Fri Jun 03 10:54:07 2011 -0700 +++ b/src/wifi/model/yans-wifi-channel.cc Wed Jun 22 07:51:42 2011 -0700 @@ -74,13 +74,14 @@ m_delay = delay; } -void +uint32_t YansWifiChannel::Send (Ptr sender, Ptr packet, double txPowerDbm, WifiMode wifiMode, WifiPreamble preamble) const { Ptr senderMobility = sender->GetMobility ()->GetObject (); NS_ASSERT (senderMobility != 0); uint32_t j = 0; + uint32_t nReceivers = 0; for (PhyList::const_iterator i = m_phyList.begin (); i != m_phyList.end (); i++, j++) { if (sender != (*i)) @@ -107,11 +108,13 @@ { dstNode = dstNetDevice->GetObject ()->GetNode ()->GetId (); } + nReceivers++; Simulator::ScheduleWithContext (dstNode, delay, &YansWifiChannel::Receive, this, j, copy, rxPowerDbm, wifiMode, preamble); } } + return nReceivers; } void diff -r 8359b3ac1ab0 src/wifi/model/yans-wifi-channel.h --- a/src/wifi/model/yans-wifi-channel.h Fri Jun 03 10:54:07 2011 -0700 +++ b/src/wifi/model/yans-wifi-channel.h Wed Jun 22 07:51:42 2011 -0700 @@ -76,14 +76,23 @@ * \param wifiMode the tx mode associated to the packet * \param preamble the preamble associated to the packet * + * returns the number of receivers that will receive the packet * This method should not be invoked by normal users. It is * currently invoked only from WifiPhy::Send. YansWifiChannel * delivers packets only between PHYs with the same m_channelNumber, * e.g. PHYs that are operating on the same channel. */ - void Send (Ptr sender, Ptr packet, double txPowerDbm, + uint32_t Send (Ptr sender, Ptr packet, double txPowerDbm, WifiMode wifiMode, WifiPreamble preamble) const; + /** + * returns the size of m_phyList (number of nodes in range in this channel) + * + */ + uint32_t GetPhyListCount () + { + return m_phyList.size (); + } private: YansWifiChannel& operator = (const YansWifiChannel &); YansWifiChannel (const YansWifiChannel &); diff -r 8359b3ac1ab0 src/wifi/model/yans-wifi-phy.cc --- a/src/wifi/model/yans-wifi-phy.cc Fri Jun 03 10:54:07 2011 -0700 +++ b/src/wifi/model/yans-wifi-phy.cc Wed Jun 22 07:51:42 2011 -0700 @@ -418,7 +418,7 @@ { case YansWifiPhy::SWITCHING: NS_LOG_DEBUG ("drop packet because of channel switching"); - NotifyRxDrop (packet); + NotifyRxDrop (packet, GetDevice ()); /* * Packets received on the upcoming channel are added to the event list * during the switching state. This way the medium can be correctly sensed @@ -437,7 +437,7 @@ case YansWifiPhy::RX: NS_LOG_DEBUG ("drop packet because already in Rx (power=" << rxPowerW << "W)"); - NotifyRxDrop (packet); + NotifyRxDrop (packet, GetDevice ()); if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) { // that packet will be noise _after_ the reception of the @@ -448,7 +448,7 @@ case YansWifiPhy::TX: NS_LOG_DEBUG ("drop packet because already in Tx (power=" << rxPowerW << "W)"); - NotifyRxDrop (packet); + NotifyRxDrop (packet, GetDevice ()); if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) { // that packet will be noise _after_ the transmission of the @@ -464,7 +464,7 @@ // sync to signal m_state->SwitchToRx (rxDuration); NS_ASSERT (m_endRxEvent.IsExpired ()); - NotifyRxBegin (packet); + NotifyRxBegin (packet, GetDevice ()); m_interference.NotifyRxStart (); m_endRxEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndReceive, this, packet, @@ -474,7 +474,7 @@ { NS_LOG_DEBUG ("drop packet because signal power too Small (" << rxPowerW << "<" << m_edThresholdW << ")"); - NotifyRxDrop (packet); + NotifyRxDrop (packet, GetDevice ()); goto maybeCcaBusy; } break; @@ -513,12 +513,12 @@ m_endRxEvent.Cancel (); m_interference.NotifyRxEnd (); } - NotifyTxBegin (packet); uint32_t dataRate500KbpsUnits = txMode.GetDataRate () / 500000; bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble); NotifyPromiscSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble); m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower); - m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble); + uint32_t nReceivers = m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble); + NotifyTxBegin (packet, GetDevice (), txDuration, nReceivers); } uint32_t @@ -782,7 +782,7 @@ ", snr=" << snrPer.snr << ", per=" << snrPer.per << ", size=" << packet->GetSize ()); if (m_random.GetValue () > snrPer.per) { - NotifyRxEnd (packet); + NotifyRxEnd (packet, GetDevice ()); uint32_t dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () / 500000; bool isShortPreamble = (WIFI_PREAMBLE_SHORT == event->GetPreambleType ()); double signalDbm = RatioToDb (event->GetRxPowerW ()) + 30; @@ -793,7 +793,7 @@ else { /* failure. */ - NotifyRxDrop (packet); + NotifyRxDrop (packet, GetDevice ()); m_state->SwitchFromRxEndError (packet, snrPer.snr); } }