1.1 --- a/examples/mixed-wireless.cc Sun May 31 22:11:52 2009 -0700
1.2 +++ b/examples/mixed-wireless.cc Tue Jun 02 10:52:56 2009 +0200
1.3 @@ -392,9 +392,9 @@
1.4 // Let's do a pcap trace on the application source and sink, ifIndex 0
1.5 // Csma captures in non-promiscuous mode
1.6 CsmaHelper::EnablePcap ("mixed-wireless", appSource->GetId (), 0, false);
1.7 - YansWifiPhyHelper::EnablePcap ("mixed-wireless", appSink->GetId (), 0);
1.8 - YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 2);
1.9 - YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 0);
1.10 + wifiPhy.EnablePcap ("mixed-wireless", appSink->GetId (), 0);
1.11 + wifiPhy.EnablePcap ("mixed-wireless", 9, 2);
1.12 + wifiPhy.EnablePcap ("mixed-wireless", 9, 0);
1.13 }
1.14
1.15 if (useCourseChangeCallback == true)
2.1 --- a/examples/simple-wifi-frame-aggregation.cc Sun May 31 22:11:52 2009 -0700
2.2 +++ b/examples/simple-wifi-frame-aggregation.cc Tue Jun 02 10:52:56 2009 +0200
2.3 @@ -141,7 +141,7 @@
2.4
2.5 Simulator::Stop (Seconds (10.0));
2.6
2.7 - YansWifiPhyHelper::EnablePcap ("test-802.11n",
2.8 + phy.EnablePcap ("test-802.11n",
2.9 wifiNodes.Get (nWifi - 1)->GetId (), 0);
2.10
2.11 Simulator::Run ();
3.1 --- a/examples/third.cc Sun May 31 22:11:52 2009 -0700
3.2 +++ b/examples/third.cc Tue Jun 02 10:52:56 2009 +0200
3.3 @@ -164,7 +164,7 @@
3.4 Simulator::Stop (Seconds (10.0));
3.5
3.6 PointToPointHelper::EnablePcapAll ("third");
3.7 - YansWifiPhyHelper::EnablePcap ("third", apDevices.Get (0));
3.8 + phy.EnablePcap ("third", apDevices.Get (0));
3.9 CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
3.10
3.11 Simulator::Run ();
4.1 --- a/examples/wifi-wired-bridging.cc Sun May 31 22:11:52 2009 -0700
4.2 +++ b/examples/wifi-wired-bridging.cc Tue Jun 02 10:52:56 2009 +0200
4.3 @@ -89,6 +89,10 @@
4.4 backboneDevices = csma.Install (backboneNodes);
4.5
4.6 double wifiX = 0.0;
4.7 +
4.8 + YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
4.9 + wifiPhy.SetPcapFormat(YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP);
4.10 +
4.11 for (uint32_t i = 0; i < nWifis; ++i)
4.12 {
4.13 // calculate ssid for wifi subnetwork
4.14 @@ -105,7 +109,6 @@
4.15 BridgeHelper bridge;
4.16 WifiHelper wifi = WifiHelper::Default ();
4.17 NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
4.18 - YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
4.19 YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
4.20 wifiPhy.SetChannel (wifiChannel.Create ());
4.21
4.22 @@ -182,8 +185,8 @@
4.23 apps.Start (Seconds (0.5));
4.24 apps.Stop (Seconds (3.0));
4.25
4.26 - YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[0]);
4.27 - YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[1]);
4.28 + wifiPhy.EnablePcap ("wifi-wired-bridging", apDevices[0]);
4.29 + wifiPhy.EnablePcap ("wifi-wired-bridging", apDevices[1]);
4.30
4.31 std::ofstream os;
4.32 os.open ("wifi-wired-bridging.mob");
5.1 --- a/src/common/pcap-writer.cc Sun May 31 22:11:52 2009 -0700
5.2 +++ b/src/common/pcap-writer.cc Tue Jun 02 10:52:56 2009 +0200
5.3 @@ -41,6 +41,8 @@
5.4 PCAP_PPP = 9,
5.5 PCAP_RAW_IP = 101,
5.6 PCAP_80211 = 105,
5.7 + PCAP_80211_PRISM = 119,
5.8 + PCAP_80211_RADIOTAP = 127,
5.9 };
5.10
5.11 PcapWriter::PcapWriter ()
5.12 @@ -115,6 +117,20 @@
5.13 WriteHeader (PCAP_80211);
5.14 }
5.15
5.16 +void
5.17 +PcapWriter::WriteWifiRadiotapHeader (void)
5.18 +{
5.19 + NS_LOG_FUNCTION_NOARGS ();
5.20 + WriteHeader (PCAP_80211_RADIOTAP);
5.21 +}
5.22 +
5.23 +void
5.24 +PcapWriter::WriteWifiPrismHeader (void)
5.25 +{
5.26 + NS_LOG_FUNCTION_NOARGS ();
5.27 + WriteHeader (PCAP_80211_PRISM);
5.28 +}
5.29 +
5.30 void
5.31 PcapWriter::WritePppHeader (void)
5.32 {
5.33 @@ -133,6 +149,7 @@
5.34 Write32 (0);
5.35 Write32 (0xffff);
5.36 Write32 (network);
5.37 + m_pcapMode = network;
5.38 }
5.39
5.40 void
5.41 @@ -151,12 +168,296 @@
5.42 }
5.43 }
5.44
5.45 +
5.46 +void PcapWriter::WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm)
5.47 +{
5.48 + NS_LOG_FUNCTION (this << packet->GetSize() << channelFreqMhz << rate << isShortPreamble << isTx << signalDbm << noiseDbm);
5.49 +
5.50 + if (m_writer == 0)
5.51 + {
5.52 + return;
5.53 + }
5.54 +
5.55 + if (m_pcapMode == PCAP_80211)
5.56 + {
5.57 + WritePacket (packet);
5.58 + return;
5.59 + }
5.60 +
5.61 + /* the following is common between PRISM and RADIOTAP */
5.62 +
5.63 + uint64_t current = Simulator::Now ().GetMicroSeconds ();
5.64 + uint64_t s = current / 1000000;
5.65 + uint64_t us = current % 1000000;
5.66 + Write32 (s & 0xffffffff);
5.67 + Write32 (us & 0xffffffff);
5.68 +
5.69 +
5.70 + // MAC timestamp. Actually according to radiotap specifications
5.71 + // (http://www.radiotap.org/defined-fields/TSFT) this should be
5.72 + // the time "when the first bit of the MPDU arrived at the
5.73 + // MAC". This is not exactly what we're doing here, but to handle
5.74 + // this properly we would need to first of all investigate how
5.75 + // real devices (e.g. madwifi) handle this case, especially for TX
5.76 + // packets (radiotap specs says TSFT is not used for TX packets,
5.77 + // but madwifi actually uses it).
5.78 + uint64_t tsft = current;
5.79 +
5.80 + if (m_pcapMode == PCAP_80211_PRISM)
5.81 + {
5.82 +
5.83 +#define PRISM_MSG_CODE 0x00000044
5.84 +#define PRISM_MSG_LENGTH 144
5.85 +#define PRISM_DID_HOSTTIME 0x00010044
5.86 +#define PRISM_DID_MACTIME 0x00020044
5.87 +#define PRISM_DID_CHANNEL 0x00030044
5.88 +#define PRISM_DID_RSSI 0x00040044
5.89 +#define PRISM_DID_SQ 0x00050044
5.90 +#define PRISM_DID_SIGNAL 0x00060044
5.91 +#define PRISM_DID_NOISE 0x00070044
5.92 +#define PRISM_DID_RATE 0x00080044
5.93 +#define PRISM_DID_ISTX 0x00090044
5.94 +#define PRISM_DID_FRMLEN 0x000A0044
5.95 +
5.96 +#define PRISM_STATUS_PRESENT 0
5.97 +#define PRISM_STATUS_ABSENT 1
5.98 +#define PRISM_ITEM_LENGTH 4
5.99 +
5.100 +
5.101 +
5.102 + uint32_t size = packet->GetSize () + PRISM_MSG_LENGTH;
5.103 + Write32 (size); // total packet size
5.104 + Write32 (size); // captured size
5.105 +
5.106 + Write32(PRISM_MSG_CODE);
5.107 + Write32(PRISM_MSG_LENGTH);
5.108 + WriteData((const uint8_t *)"unknown wifi device!!!!!!!!", 16);
5.109 +
5.110 + Write32(PRISM_DID_HOSTTIME);
5.111 + Write16(PRISM_STATUS_PRESENT);
5.112 + Write16(PRISM_ITEM_LENGTH);
5.113 + // madwifi reports hosttime in jiffies.
5.114 + // We calculate jiffies assuming HZ = 10
5.115 + Write32((uint32_t) (Now ().GetMilliSeconds () / 10 ) );
5.116 +
5.117 + Write32(PRISM_DID_MACTIME);
5.118 + Write16(PRISM_STATUS_PRESENT);
5.119 + Write16(PRISM_ITEM_LENGTH);
5.120 + // This looses precision, which is a well-known issue of the prism
5.121 + // header format.
5.122 + Write32((uint32_t) tsft);
5.123 +
5.124 + Write32(PRISM_DID_CHANNEL);
5.125 + Write16(PRISM_STATUS_PRESENT);
5.126 + Write16(PRISM_ITEM_LENGTH);
5.127 + // convert from frequency to channel number. This conversion is
5.128 + // correct only for IEEE 802.11b/g channels 1-13.
5.129 + Write32((channelFreqMhz - 2407) / 5);
5.130 +
5.131 + Write32(PRISM_DID_RSSI);
5.132 + Write16(PRISM_STATUS_PRESENT);
5.133 + Write16(PRISM_ITEM_LENGTH);
5.134 + // madwifi here reports a value which is said to be "the value in
5.135 + // dBm above noise". Apart from the fact that this is incorrect
5.136 + // (if it is relative to a value in dBm, then it must be in dB,
5.137 + // not in dBm again), this means that in fact it is not a RSSI
5.138 + // (which stands for Received Signal Strength Indicator) but it is
5.139 + // rather a Signal to Noise Ratio (SNR), of course in dB.
5.140 + // Anyway, in the end we calculate the value exactly as madwifi does.
5.141 + Write32(round(signalDbm - noiseDbm));
5.142 +
5.143 + // SQ field not used. I would expect a PRISM_STATUS_ABSENT to be
5.144 + // needed here, but if you look at the prism header that madwifi
5.145 + // produces you'll just see that the whole field structure is
5.146 + // zeroed.
5.147 + Write32(0);
5.148 + Write16(0);
5.149 + Write16(0);
5.150 + Write32(0);
5.151 +
5.152 + Write32(PRISM_DID_SIGNAL);
5.153 + Write16(PRISM_STATUS_PRESENT);
5.154 + Write16(PRISM_ITEM_LENGTH);
5.155 + Write32(round(signalDbm));
5.156 +
5.157 + Write32(PRISM_DID_NOISE);
5.158 + Write16(PRISM_STATUS_PRESENT);
5.159 + Write16(PRISM_ITEM_LENGTH);
5.160 + Write32(round(noiseDbm));
5.161 +
5.162 + Write32(PRISM_DID_RATE);
5.163 + Write16(PRISM_STATUS_PRESENT);
5.164 + Write16(PRISM_ITEM_LENGTH);
5.165 + Write32(rate);
5.166 +
5.167 + Write32(PRISM_DID_ISTX);
5.168 + Write16(PRISM_STATUS_PRESENT);
5.169 + Write16(PRISM_ITEM_LENGTH);
5.170 + Write32(isTx ? 1 : 0);
5.171 +
5.172 + Write32(PRISM_DID_FRMLEN);
5.173 + Write16(PRISM_STATUS_ABSENT);
5.174 + Write16(PRISM_ITEM_LENGTH);
5.175 + Write32(packet->GetSize ());
5.176 +
5.177 +
5.178 +
5.179 + } // PCAP_80211_PRISM
5.180 +
5.181 + else if (m_pcapMode == PCAP_80211_RADIOTAP)
5.182 + {
5.183 + NS_LOG_LOGIC("writing radiotap packet");
5.184 +
5.185 +#define RADIOTAP_TSFT 0x00000001
5.186 +#define RADIOTAP_FLAGS 0x00000002
5.187 +#define RADIOTAP_RATE 0x00000004
5.188 +#define RADIOTAP_CHANNEL 0x00000008
5.189 +#define RADIOTAP_FHSS 0x00000010
5.190 +#define RADIOTAP_DBM_ANTSIGNAL 0x00000020
5.191 +#define RADIOTAP_DBM_ANTNOISE 0x00000040
5.192 +#define RADIOTAP_LOCK_QUALITY 0x00000080
5.193 +#define RADIOTAP_TX_ATTENUATION 0x00000100
5.194 +#define RADIOTAP_DB_TX_ATTENUATION 0x00000200
5.195 +#define RADIOTAP_DBM_TX_POWER 0x00000200
5.196 +#define RADIOTAP_ANTENNA 0x00000400
5.197 +#define RADIOTAP_DB_ANTSIGNAL 0x00000800
5.198 +#define RADIOTAP_DB_ANTNOISE 0x00001000
5.199 +#define RADIOTAP_EXT 0x10000000
5.200 +
5.201 +#define RADIOTAP_FLAG_NONE 0x00
5.202 +#define RADIOTAP_FLAG_CFP 0x01
5.203 +#define RADIOTAP_FLAG_SHORTPRE 0x02
5.204 +#define RADIOTAP_FLAG_WEP 0x04
5.205 +#define RADIOTAP_FLAG_FRAG 0x08
5.206 +#define RADIOTAP_FLAG_FCS 0x10
5.207 +#define RADIOTAP_FLAG_DATAPAD 0x20
5.208 +#define RADIOTAP_FLAG_BADFCS 0x40
5.209 +
5.210 +#define RADIOTAP_CHANNEL_TURBO 0x0010
5.211 +#define RADIOTAP_CHANNEL_CCK 0x0020
5.212 +#define RADIOTAP_CHANNEL_OFDM 0x0040
5.213 +#define RADIOTAP_CHANNEL_2GHZ 0x0080
5.214 +#define RADIOTAP_CHANNEL_5GHZ 0x0100
5.215 +#define RADIOTAP_CHANNEL_PASSIVE 0x0200
5.216 +#define RADIOTAP_CHANNEL_DYN 0x0400
5.217 +#define RADIOTAP_CHANNEL_GFSK 0x0800
5.218 +
5.219 +#define RADIOTAP_RX_PRESENT (RADIOTAP_TSFT | RADIOTAP_FLAGS | RADIOTAP_RATE | RADIOTAP_CHANNEL | RADIOTAP_DBM_ANTSIGNAL | RADIOTAP_DBM_ANTNOISE)
5.220 +#define RADIOTAP_RX_LENGTH (8+8+1+1+2+2+1+1)
5.221 +
5.222 +#define RADIOTAP_TX_PRESENT (RADIOTAP_TSFT | RADIOTAP_FLAGS | RADIOTAP_RATE | RADIOTAP_CHANNEL)
5.223 +#define RADIOTAP_TX_LENGTH (8+8+1+1+2+2)
5.224 +
5.225 + uint32_t size;
5.226 + if (isTx)
5.227 + {
5.228 + size = packet->GetSize () + RADIOTAP_TX_LENGTH;
5.229 + }
5.230 + else
5.231 + {
5.232 + size = packet->GetSize () + RADIOTAP_RX_LENGTH;
5.233 + }
5.234 + Write32 (size); // total packet size
5.235 + Write32 (size); // captured size
5.236 +
5.237 + Write8(0); // radiotap version
5.238 + Write8(0); // padding
5.239 +
5.240 + if (isTx)
5.241 + {
5.242 + Write16(RADIOTAP_TX_LENGTH);
5.243 + Write32(RADIOTAP_TX_PRESENT);
5.244 + }
5.245 + else
5.246 + {
5.247 + Write16(RADIOTAP_RX_LENGTH);
5.248 + Write32(RADIOTAP_RX_PRESENT);
5.249 + }
5.250 +
5.251 + Write64(tsft);
5.252 +
5.253 + uint8_t flags = RADIOTAP_FLAG_NONE;
5.254 + if (isShortPreamble)
5.255 + {
5.256 + flags |= RADIOTAP_FLAG_SHORTPRE;
5.257 + }
5.258 + Write8(flags);
5.259 +
5.260 +
5.261 + Write8(rate);
5.262 +
5.263 + Write16((uint16_t) channelFreqMhz);
5.264 +
5.265 + // we might want to make this setting depend on the WifiMode and
5.266 + // on the ChannelFrequency at some time in the future. But for now
5.267 + // I think a fixed setting is more than enough for most purposes.
5.268 + Write16(RADIOTAP_CHANNEL_OFDM | RADIOTAP_CHANNEL_2GHZ);
5.269 +
5.270 + if (!isTx)
5.271 + {
5.272 +
5.273 + Write8 (RoundToInt8 (signalDbm));
5.274 + Write8 (RoundToInt8 (noiseDbm));
5.275 + }
5.276 +
5.277 + } // PCAP_80211_RADIOTAP
5.278 +
5.279 +
5.280 + else
5.281 + {
5.282 + NS_LOG_ERROR("unknown PCAP mode");
5.283 + return;
5.284 + }
5.285 +
5.286 + // finally, write rest of packet
5.287 + WriteData (packet->PeekData (), packet->GetSize ());
5.288 +}
5.289 +
5.290 +
5.291 +
5.292 +
5.293 +int8_t
5.294 +PcapWriter::RoundToInt8 (double value)
5.295 +{
5.296 + if (value < -128)
5.297 + {
5.298 + return -128;
5.299 + }
5.300 + if (value > 127)
5.301 + {
5.302 + return 127;
5.303 + }
5.304 + return ((int8_t) round(value));
5.305 +}
5.306 +
5.307 +
5.308 +
5.309 +
5.310 +
5.311 +
5.312 void
5.313 PcapWriter::WriteData (uint8_t const*buffer, uint32_t size)
5.314 {
5.315 + NS_LOG_FUNCTION(this << size);
5.316 m_writer->write ((char const *)buffer, size);
5.317 }
5.318
5.319 +
5.320 +void
5.321 +PcapWriter::Write64 (uint64_t data)
5.322 +{
5.323 + uint8_t buffer[8];
5.324 + buffer[0] = (data >> 0) & 0xff;
5.325 + buffer[1] = (data >> 8) & 0xff;
5.326 + buffer[2] = (data >> 16) & 0xff;
5.327 + buffer[3] = (data >> 24) & 0xff;
5.328 + buffer[4] = (data >> 32) & 0xff;
5.329 + buffer[5] = (data >> 40) & 0xff;
5.330 + buffer[6] = (data >> 48) & 0xff;
5.331 + buffer[7] = (data >> 56) & 0xff;
5.332 + WriteData (buffer, 8);
5.333 +}
5.334 +
5.335 void
5.336 PcapWriter::Write32 (uint32_t data)
5.337 {
5.338 @@ -177,4 +478,12 @@
5.339 WriteData (buffer, 2);
5.340 }
5.341
5.342 +void
5.343 +PcapWriter::Write8 (uint8_t data)
5.344 +{
5.345 + WriteData (&data, 1);
5.346 +}
5.347 +
5.348 +
5.349 +
5.350 } // namespace ns3
6.1 --- a/src/common/pcap-writer.h Sun May 31 22:11:52 2009 -0700
6.2 +++ b/src/common/pcap-writer.h Tue Jun 02 10:52:56 2009 +0200
6.3 @@ -76,6 +76,24 @@
6.4
6.5 /**
6.6 * Write a pcap header in the output file which specifies
6.7 + * that the content of the file will be 802.11 Packets preceded by a
6.8 + * radiotap header providing PHY layer info. This method should be
6.9 + * invoked before ns3::PcapWriter::WritePacket and after
6.10 + * ns3::PcapWriter::Open.
6.11 + */
6.12 + void WriteWifiRadiotapHeader (void);
6.13 +
6.14 + /**
6.15 + * Write a pcap header in the output file which specifies
6.16 + * that the content of the file will be 802.11 Packets preceded by a
6.17 + * prism header providing PHY layer info. This method should be
6.18 + * invoked before ns3::PcapWriter::WritePacket and after
6.19 + * ns3::PcapWriter::Open.
6.20 + */
6.21 + void WriteWifiPrismHeader (void);
6.22 +
6.23 + /**
6.24 + * Write a pcap header in the output file which specifies
6.25 * that the content of the file will be ppp Packets. This
6.26 * method should be invoked before ns3::PcapWriter::WritePacket
6.27 * and after ns3::PcapWriter::Open.
6.28 @@ -87,12 +105,40 @@
6.29 */
6.30 void WritePacket (Ptr<const Packet> packet);
6.31
6.32 + /**
6.33 + * Write a Packet, possibly adding wifi PHY layer information to it
6.34 + *
6.35 + * @param packet the packet being received
6.36 + * @param channelFreqMhz the frequency in MHz at which the packet is
6.37 + * received. Note that in real devices this is normally the
6.38 + * frequency to which the receiver is tuned, and this can be
6.39 + * different than the frequency at which the packet was originally
6.40 + * transmitted. This is because it is possible to have the receiver
6.41 + * tuned on a given channel and still to be able to receive packets
6.42 + * on a nearby channel.
6.43 + * @param rate the PHY data rate in units of 500kbps (i.e., the same
6.44 + * units used both for the radiotap and for the prism header)
6.45 + * @param isPreambleShort true if short preamble is used, false otherwise
6.46 + * @param isTx true if packet is being transmitted, false when
6.47 + * packet is being received
6.48 + * @param signalDbm signal power in dBm
6.49 + * @param noiseDbm noise power in dBm
6.50 + */
6.51 + void WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm);
6.52 +
6.53 +
6.54 +
6.55 +
6.56 private:
6.57 void WriteData (uint8_t const*buffer, uint32_t size);
6.58 + void Write64 (uint64_t data);
6.59 void Write32 (uint32_t data);
6.60 void Write16 (uint16_t data);
6.61 + void Write8 (uint8_t data);
6.62 void WriteHeader (uint32_t network);
6.63 + int8_t RoundToInt8 (double value);
6.64 std::ofstream *m_writer;
6.65 + uint32_t m_pcapMode;
6.66 };
6.67
6.68 } // namespace ns3
7.1 --- a/src/devices/wifi/wifi-phy.cc Sun May 31 22:11:52 2009 -0700
7.2 +++ b/src/devices/wifi/wifi-phy.cc Tue Jun 02 10:52:56 2009 +0200
7.3 @@ -73,9 +73,12 @@
7.4 .AddTraceSource ("PhyRxDrop",
7.5 "Trace source indicating a packet has been dropped by the device during reception",
7.6 MakeTraceSourceAccessor (&WifiPhy::m_phyRxDropTrace))
7.7 - .AddTraceSource ("PromiscSniffer",
7.8 - "Trace source simulating a promiscuous packet sniffer attached to the device",
7.9 - MakeTraceSourceAccessor (&WifiPhy::m_phyPromiscSnifferTrace))
7.10 + .AddTraceSource ("PromiscSnifferRx",
7.11 + "Trace source simulating a wifi device in monitor mode sniffing all received frames",
7.12 + MakeTraceSourceAccessor (&WifiPhy::m_phyPromiscSniffRxTrace))
7.13 + .AddTraceSource ("PromiscSnifferTx",
7.14 + "Trace source simulating the capability of a wifi device in monitor mode to sniff all frames being transmitted",
7.15 + MakeTraceSourceAccessor (&WifiPhy::m_phyPromiscSniffTxTrace))
7.16 ;
7.17 return tid;
7.18 }
7.19 @@ -194,9 +197,15 @@
7.20 }
7.21
7.22 void
7.23 -WifiPhy::NotifyPromiscSniff (Ptr<const Packet> packet)
7.24 +WifiPhy::NotifyPromiscSniffRx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm)
7.25 {
7.26 - m_phyPromiscSnifferTrace (packet);
7.27 + m_phyPromiscSniffRxTrace (packet, channelFreqMhz, rate, isShortPreamble, signalDbm, noiseDbm);
7.28 +}
7.29 +
7.30 +void
7.31 +WifiPhy::NotifyPromiscSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble)
7.32 +{
7.33 + m_phyPromiscSniffTxTrace (packet, channelFreqMhz, rate, isShortPreamble);
7.34 }
7.35
7.36 WifiMode
8.1 --- a/src/devices/wifi/wifi-phy.h Sun May 31 22:11:52 2009 -0700
8.2 +++ b/src/devices/wifi/wifi-phy.h Tue Jun 02 10:52:56 2009 +0200
8.3 @@ -294,11 +294,46 @@
8.4 */
8.5 void NotifyRxDrop (Ptr<const Packet> packet);
8.6
8.7 - /**
8.8 - * Public method used to fire a PromiscSniffer trace. Implemented for encapsulation
8.9 + /**
8.10 + *
8.11 + * Public method used to fire a PromiscSniffer trace for a wifi packet being received. Implemented for encapsulation
8.12 * purposes.
8.13 + *
8.14 + * @param packet the packet being received
8.15 + * @param channelFreqMhz the frequency in MHz at which the packet is
8.16 + * received. Note that in real devices this is normally the
8.17 + * frequency to which the receiver is tuned, and this can be
8.18 + * different than the frequency at which the packet was originally
8.19 + * transmitted. This is because it is possible to have the receiver
8.20 + * tuned on a given channel and still to be able to receive packets
8.21 + * on a nearby channel.
8.22 + * @param rate the PHY data rate in units of 500kbps (i.e., the same
8.23 + * units used both for the radiotap and for the prism header)
8.24 + * @param isPreambleShort true if short preamble is used, false otherwise
8.25 + * @param signalDbm signal power in dBm
8.26 + * @param noiseDbm noise power in dBm
8.27 */
8.28 - void NotifyPromiscSniff (Ptr<const Packet> packet);
8.29 + void NotifyPromiscSniffRx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm);
8.30 +
8.31 + /**
8.32 + *
8.33 + * Public method used to fire a PromiscSniffer trace for a wifi packet being transmitted. Implemented for encapsulation
8.34 + * purposes.
8.35 + *
8.36 + * @param packet the packet being received
8.37 + * @param channelFreqMhz the frequency in MHz at which the packet is
8.38 + * received. Note that in real devices this is normally the
8.39 + * frequency to which the receiver is tuned, and this can be
8.40 + * different than the frequency at which the packet was originally
8.41 + * transmitted. This is because it is possible to have the receiver
8.42 + * tuned on a given channel and still to be able to receive packets
8.43 + * on a nearby channel.
8.44 + * @param rate the PHY data rate in units of 500kbps (i.e., the same
8.45 + * units used both for the radiotap and for the prism header)
8.46 + * @param isPreambleShort true if short preamble is used, false otherwise
8.47 + */
8.48 + void NotifyPromiscSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble);
8.49 +
8.50
8.51 private:
8.52 /**
8.53 @@ -349,24 +384,29 @@
8.54 TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
8.55
8.56 /**
8.57 - * A trace source that emulates a promiscuous mode protocol sniffer connected
8.58 - * to the device. This trace source fire on packets destined for any host
8.59 - * just like your average everyday packet sniffer.
8.60 - *
8.61 - * On the transmit size, this trace hook will fire after a packet is dequeued
8.62 - * from the device queue for transmission. In Linux, for example, this would
8.63 - * correspond to the point just before a device hard_start_xmit where
8.64 - * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET
8.65 - * ETH_P_ALL handlers.
8.66 - *
8.67 - * On the receive side, this trace hook will fire when a packet is received,
8.68 - * just before the receive callback is executed. In Linux, for example,
8.69 - * this would correspond to the point at which the packet is dispatched to
8.70 - * packet sniffers in netif_receive_skb.
8.71 + * A trace source that emulates a wifi device in monitor mode
8.72 + * sniffing a packet being received.
8.73 + *
8.74 + * As a reference with the real world, firing this trace
8.75 + * corresponds in the madwifi driver to calling the function
8.76 + * ieee80211_input_monitor()
8.77 *
8.78 * \see class CallBackTraceSource
8.79 */
8.80 - TracedCallback<Ptr<const Packet> > m_phyPromiscSnifferTrace;
8.81 + TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool, double, double> m_phyPromiscSniffRxTrace;
8.82 +
8.83 + /**
8.84 + * A trace source that emulates a wifi device in monitor mode
8.85 + * sniffing a packet being transmitted.
8.86 + *
8.87 + * As a reference with the real world, firing this trace
8.88 + * corresponds in the madwifi driver to calling the function
8.89 + * ieee80211_input_monitor()
8.90 + *
8.91 + * \see class CallBackTraceSource
8.92 + */
8.93 + TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool> m_phyPromiscSniffTxTrace;
8.94 +
8.95 };
8.96
8.97 } // namespace ns3
9.1 --- a/src/devices/wifi/yans-wifi-phy.cc Sun May 31 22:11:52 2009 -0700
9.2 +++ b/src/devices/wifi/yans-wifi-phy.cc Tue Jun 02 10:52:56 2009 +0200
9.3 @@ -121,8 +121,10 @@
9.4 }
9.5
9.6 YansWifiPhy::YansWifiPhy ()
9.7 - : m_endSyncEvent (),
9.8 - m_random (0.0, 1.0)
9.9 + : m_channelFreqMhz(2437),
9.10 + m_endSyncEvent (),
9.11 + m_random (0.0, 1.0)
9.12 +
9.13 {
9.14 NS_LOG_FUNCTION (this);
9.15 m_state = CreateObject<WifiPhyStateHelper> ();
9.16 @@ -408,7 +410,9 @@
9.17 m_endSyncEvent.Cancel ();
9.18 }
9.19 NotifyTxBegin (packet);
9.20 - NotifyPromiscSniff (packet);
9.21 + uint32_t dataRate500KbpsUnits = txMode.GetDataRate () / 500000;
9.22 + bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble);
9.23 + NotifyPromiscSniffTx (packet, m_channelFreqMhz, dataRate500KbpsUnits, isShortPreamble);
9.24 m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower);
9.25 m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
9.26 }
9.27 @@ -577,11 +581,14 @@
9.28
9.29 NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<<
9.30 ", snr="<<snrPer.snr<<", per="<<snrPer.per<<", size="<<packet->GetSize ());
9.31 -
9.32 if (m_random.GetValue () > snrPer.per)
9.33 {
9.34 - NotifyRxEnd (packet);
9.35 - NotifyPromiscSniff (packet);
9.36 + NotifyRxEnd (packet);
9.37 + uint32_t dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () / 500000;
9.38 + bool isShortPreamble = (WIFI_PREAMBLE_SHORT == event->GetPreambleType ());
9.39 + double signalDbm = RatioToDb (event->GetRxPowerW ()) + 30;
9.40 + double noiseDbm = RatioToDb(event->GetRxPowerW() / snrPer.snr) - GetRxNoiseFigure() + 30 ;
9.41 + NotifyPromiscSniffRx (packet, m_channelFreqMhz, dataRate500KbpsUnits, isShortPreamble, signalDbm, noiseDbm);
9.42 m_state->SwitchFromSyncEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ());
9.43 }
9.44 else
9.45 @@ -591,5 +598,4 @@
9.46 m_state->SwitchFromSyncEndError (packet, snrPer.snr);
9.47 }
9.48 }
9.49 -
9.50 } // namespace ns3
10.1 --- a/src/devices/wifi/yans-wifi-phy.h Sun May 31 22:11:52 2009 -0700
10.2 +++ b/src/devices/wifi/yans-wifi-phy.h Tue Jun 02 10:52:56 2009 +0200
10.3 @@ -142,6 +142,7 @@
10.4 double m_txPowerBaseDbm;
10.5 double m_txPowerEndDbm;
10.6 uint32_t m_nTxPower;
10.7 + uint16_t m_channelFreqMhz;
10.8
10.9 Ptr<YansWifiChannel> m_channel;
10.10 Ptr<Object> m_device;
11.1 --- a/src/helper/yans-wifi-helper.cc Sun May 31 22:11:52 2009 -0700
11.2 +++ b/src/helper/yans-wifi-helper.cc Tue Jun 02 10:52:56 2009 +0200
11.3 @@ -31,11 +31,19 @@
11.4
11.5 namespace ns3 {
11.6
11.7 -static void PcapSnifferEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
11.8 +static void PcapSniffTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble)
11.9 {
11.10 - writer->WritePacket (packet);
11.11 + const double unusedValue = 0;
11.12 + writer->WriteWifiMonitorPacket(packet, channelFreqMhz, rate, isShortPreamble, true, unusedValue, unusedValue);
11.13 }
11.14
11.15 +
11.16 +static void PcapSniffRxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm)
11.17 +{
11.18 + writer->WriteWifiMonitorPacket(packet, channelFreqMhz, rate, isShortPreamble, false, signalDbm, noiseDbm);
11.19 +}
11.20 +
11.21 +
11.22 static void AsciiPhyTxEvent (std::ostream *os, std::string context,
11.23 Ptr<const Packet> packet,
11.24 WifiMode mode, WifiPreamble preamble,
11.25 @@ -137,7 +145,9 @@
11.26
11.27
11.28 YansWifiPhyHelper::YansWifiPhyHelper ()
11.29 - : m_channel (0)
11.30 + : m_channel (0),
11.31 + m_pcapFormat(PCAP_FORMAT_80211)
11.32 +
11.33 {
11.34 m_phy.SetTypeId ("ns3::YansWifiPhy");
11.35 }
11.36 @@ -202,6 +212,14 @@
11.37 return phy;
11.38 }
11.39
11.40 +
11.41 +void
11.42 +YansWifiPhyHelper::SetPcapFormat (enum PcapFormat format)
11.43 +{
11.44 + m_pcapFormat = format;
11.45 +}
11.46 +
11.47 +
11.48 void
11.49 YansWifiPhyHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
11.50 {
11.51 @@ -218,11 +236,28 @@
11.52 // with the locally-defined WifiPhyHelper::Create method.
11.53 Ptr<PcapWriter> pcap = ::ns3::Create<PcapWriter> ();
11.54 pcap->Open (oss.str ());
11.55 - pcap->WriteWifiHeader ();
11.56 +
11.57 + switch (m_pcapFormat) {
11.58 + case PCAP_FORMAT_80211:
11.59 + pcap->WriteWifiHeader ();
11.60 + break;
11.61 + case PCAP_FORMAT_80211_RADIOTAP:
11.62 + pcap->WriteWifiRadiotapHeader ();
11.63 + break;
11.64 + case PCAP_FORMAT_80211_PRISM:
11.65 + pcap->WriteWifiPrismHeader ();
11.66 + break;
11.67 + }
11.68 +
11.69 oss.str ("");
11.70 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
11.71 - oss << "/$ns3::WifiNetDevice/Phy/PromiscSniffer";
11.72 - Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSnifferEvent, pcap));
11.73 + oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferTx";
11.74 + Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffTxEvent, pcap));
11.75 +
11.76 + oss.str ("");
11.77 + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
11.78 + oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferRx";
11.79 + Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffRxEvent, pcap));
11.80 }
11.81
11.82 void
12.1 --- a/src/helper/yans-wifi-helper.h Sun May 31 22:11:52 2009 -0700
12.2 +++ b/src/helper/yans-wifi-helper.h Tue Jun 02 10:52:56 2009 +0200
12.3 @@ -198,18 +198,45 @@
12.4 std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
12.5
12.6 /**
12.7 + * PCAP formats
12.8 + *
12.9 + */
12.10 + enum PcapFormat {
12.11 + PCAP_FORMAT_80211 = 1,
12.12 + PCAP_FORMAT_80211_PRISM = 2,
12.13 + PCAP_FORMAT_80211_RADIOTAP = 3,
12.14 + };
12.15 +
12.16 + /**
12.17 + * Set the format of PCAP traces to be used. This function has to be
12.18 + * called before EnablePcap(), so that the header of the pcap file
12.19 + * can be written correctly.
12.20 + *
12.21 + * In madwifi, this corresponds to setting
12.22 + * /proc/sys/net/ath0/dev_type to a particular value. See
12.23 + * http://madwifi-project.org/wiki/UserDocs/MonitorModeInterface for
12.24 + * more information.
12.25 + *
12.26 + * @param format the PcapFormat to be used
12.27 + */
12.28 + void SetPcapFormat (enum PcapFormat format);
12.29 +
12.30 + /**
12.31 * \param filename filename prefix to use for pcap files.
12.32 * \param nodeid the id of the node to generate pcap output for.
12.33 * \param deviceid the id of the device to generate pcap output for.
12.34 *
12.35 * Generate a pcap file which contains the link-level data observed
12.36 * by the specified deviceid within the specified nodeid. The pcap
12.37 - * data is stored in the file prefix-nodeid-deviceid.pcap.
12.38 + * data is stored in the file prefix-nodeid-deviceid.pcap. By
12.39 + * default, no PHY layer information is provided. An optional header
12.40 + * with PHY layer information, such as the radiotap or the prism
12.41 + * header, can be used by invoking SetPcapFormat().
12.42 *
12.43 * This method should be invoked after the network topology has
12.44 * been fully constructed.
12.45 */
12.46 - static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
12.47 + void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
12.48
12.49 /**
12.50 * \param filename filename prefix to use for pcap files.
12.51 @@ -218,7 +245,7 @@
12.52 * Enable pcap output on each input device which is of the
12.53 * ns3::WifiNetDevice type.
12.54 */
12.55 - static void EnablePcap (std::string filename, Ptr<NetDevice> nd);
12.56 + void EnablePcap (std::string filename, Ptr<NetDevice> nd);
12.57
12.58 /**
12.59 * \param filename filename prefix to use for pcap files.
12.60 @@ -227,7 +254,7 @@
12.61 * Enable pcap output on each input device which is of the
12.62 * ns3::WifiNetDevice type.
12.63 */
12.64 - static void EnablePcap (std::string filename, std::string ndName);
12.65 + void EnablePcap (std::string filename, std::string ndName);
12.66
12.67 /**
12.68 * \param filename filename prefix to use for pcap files.
12.69 @@ -236,7 +263,7 @@
12.70 * Enable pcap output on each input device which is of the
12.71 * ns3::WifiNetDevice type.
12.72 */
12.73 - static void EnablePcap (std::string filename, NetDeviceContainer d);
12.74 + void EnablePcap (std::string filename, NetDeviceContainer d);
12.75
12.76 /**
12.77 * \param filename filename prefix to use for pcap files.
12.78 @@ -246,7 +273,7 @@
12.79 * ns3::WifiNetDevice type and which is located in one of the
12.80 * input nodes.
12.81 */
12.82 - static void EnablePcap (std::string filename, NodeContainer n);
12.83 + void EnablePcap (std::string filename, NodeContainer n);
12.84
12.85 /**
12.86 * \param filename filename prefix to use for pcap files.
12.87 @@ -254,7 +281,7 @@
12.88 * Enable pcap output on each device which is of the
12.89 * ns3::WifiNetDevice type
12.90 */
12.91 - static void EnablePcapAll (std::string filename);
12.92 + void EnablePcapAll (std::string filename);
12.93
12.94 /**
12.95 * \param os output stream
12.96 @@ -311,6 +338,7 @@
12.97 ObjectFactory m_phy;
12.98 ObjectFactory m_errorRateModel;
12.99 Ptr<YansWifiChannel> m_channel;
12.100 + enum PcapFormat m_pcapFormat;
12.101 };
12.102
12.103 } // namespace ns3