Skip to content

Commit fa2bc31

Browse files
committed
ieee80211: tag datarateSelected with the receiving station
datarateSelected reports the rate chosen for every transmitted frame, so unlike datarateChanged it also covers interface-wide fixed rates and per-receiver configured rates, not just adaptive rate control. It was emitted with the packet as details, which identifies the frame but not the peer, so the values of several stations arrived interleaved with no way to separate them. ~IRateSelection::emitDatarateSelected() now emits unicast data frames with the receiver's station label as a named details object, so a demux(datarateSelected) result filter can key a per-station series on it. The condition matches the one under which ~RateSelection applies a per-receiver configured rate, so the label always names the station whose rate is being reported. Control, management and group-addressed frames have no per-station rate and are emitted without details: they still reach the aggregate statistic. Both coordination functions emit through the shared helper rather than each formatting the signal themselves. Unlike datarateChanged, this signal fires for every transmitted frame, and resolving a station label sweeps the network's interface tables -- so the label is only computed when the signal has listeners: with result recording off, transmitting costs nothing extra.
1 parent 1acce62 commit fa2bc31

4 files changed

Lines changed: 31 additions & 5 deletions

File tree

src/inet/linklayer/ieee80211/mac/contract/IRateSelection.cc

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,27 @@
77

88
#include "inet/linklayer/ieee80211/mac/contract/IRateSelection.h"
99

10+
#include "inet/networklayer/common/L3AddressResolver.h"
11+
1012
namespace inet {
1113
namespace ieee80211 {
1214

15+
using namespace inet::physicallayer;
16+
1317
simsignal_t IRateSelection::datarateSelectedSignal = cComponent::registerSignal("datarateSelected");
1418

19+
void IRateSelection::emitDatarateSelected(cComponent *emitter, const Ptr<const Ieee80211MacHeader>& header, const IIeee80211Mode *mode)
20+
{
21+
double rate = mode->getDataMode()->getNetBitrate().get<bps>();
22+
auto dataHeader = dynamicPtrCast<const Ieee80211DataHeader>(header);
23+
// naming the station sweeps the network, so skip it if nothing listens anyway
24+
if (dataHeader != nullptr && !dataHeader->getReceiverAddress().isMulticast() && emitter->mayHaveListeners(datarateSelectedSignal)) {
25+
cNamedObject details(L3AddressResolver().getHostNameWithMacAddress(dataHeader->getReceiverAddress()).c_str());
26+
emitter->emit(datarateSelectedSignal, rate, &details);
27+
}
28+
else
29+
emitter->emit(datarateSelectedSignal, rate);
30+
}
31+
1532
} // namespace ieee80211
1633
} // namespace inet
17-

src/inet/linklayer/ieee80211/mac/contract/IRateSelection.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ class INET_API IRateSelection
2626
public:
2727
static simsignal_t datarateSelectedSignal;
2828

29+
// Emits datarateSelected on behalf of a coordination function. Unicast data frames are tagged
30+
// with the name of the receiving station as a named details object, so that a
31+
// demux(datarateSelected) result filter or a statistic visualizer can key a separate
32+
// per-station series on it; this mirrors the condition under which ~RateSelection applies a
33+
// per-receiver configured rate, so the details always name the station whose rate is
34+
// reported. Control, management and group-addressed frames carry no per-station data rate and
35+
// are emitted without details: the aggregate datarateSelected statistic still records them, a
36+
// bar chart ignores them.
37+
static void emitDatarateSelected(cComponent *emitter, const Ptr<const Ieee80211MacHeader>& header, const physicallayer::IIeee80211Mode *mode);
38+
2939
public:
3040
virtual ~IRateSelection() {}
3141

src/inet/linklayer/ieee80211/mac/coordinationfunction/Dcf.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void Dcf::transmitControlResponseFrame(Packet *responsePacket, const Ptr<const I
102102
else
103103
throw cRuntimeError("Unknown received frame type");
104104
RateSelection::setFrameMode(responsePacket, responseHeader, responseMode);
105-
emit(IRateSelection::datarateSelectedSignal, responseMode->getDataMode()->getNetBitrate().get<bps>(), responsePacket);
105+
IRateSelection::emitDatarateSelected(this, responseHeader, responseMode);
106106
EV_DEBUG << "Datarate for " << responsePacket->getName() << " is set to " << responseMode->getDataMode()->getNetBitrate() << ".\n";
107107
tx->transmitFrame(responsePacket, responseHeader, modeSet->getSifsTime(), this);
108108
delete responsePacket;
@@ -166,7 +166,7 @@ void Dcf::transmitFrame(Packet *packet, simtime_t ifs)
166166
const auto& header = packet->peekAtFront<Ieee80211MacHeader>();
167167
auto mode = rateSelection->computeMode(packet, header);
168168
RateSelection::setFrameMode(packet, header, mode);
169-
emit(IRateSelection::datarateSelectedSignal, mode->getDataMode()->getNetBitrate().get<bps>(), packet);
169+
IRateSelection::emitDatarateSelected(this, header, mode);
170170
EV_DEBUG << "Datarate for " << packet->getName() << " is set to " << mode->getDataMode()->getNetBitrate() << ".\n";
171171
auto pendingPacket = channelAccess->getInProgressFrames()->getPendingFrameFor(packet);
172172
auto duration = originatorProtectionMechanism->computeDurationField(packet, header, pendingPacket, pendingPacket == nullptr ? nullptr : pendingPacket->peekAtFront<Ieee80211DataOrMgmtHeader>());

src/inet/linklayer/ieee80211/mac/coordinationfunction/Hcf.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ void Hcf::transmitFrame(Packet *packet, simtime_t ifs)
668668
}
669669
auto mode = rateSelection->computeMode(packet, header, txop);
670670
setFrameMode(packet, header, mode);
671-
emit(IRateSelection::datarateSelectedSignal, mode->getDataMode()->getNetBitrate().get<bps>(), packet);
671+
IRateSelection::emitDatarateSelected(this, header, mode);
672672
EV_DEBUG << "Datarate for " << packet->getName() << " is set to " << mode->getDataMode()->getNetBitrate() << ".\n";
673673
if (txop->getProtectionMechanism() == TxopProcedure::ProtectionMechanism::SINGLE_PROTECTION) {
674674
auto pendingPacket = channelOwner->getInProgressFrames()->getPendingFrameFor(packet);
@@ -703,7 +703,7 @@ void Hcf::transmitControlResponseFrame(Packet *responsePacket, const Ptr<const I
703703
else
704704
throw cRuntimeError("Unknown received frame type");
705705
setFrameMode(responsePacket, responseHeader, responseMode);
706-
emit(IRateSelection::datarateSelectedSignal, responseMode->getDataMode()->getNetBitrate().get<bps>(), responsePacket);
706+
IRateSelection::emitDatarateSelected(this, responseHeader, responseMode);
707707
EV_DEBUG << "Datarate for " << responsePacket->getName() << " is set to " << responseMode->getDataMode()->getNetBitrate() << ".\n";
708708
tx->transmitFrame(responsePacket, responseHeader, modeSet->getSifsTime(), this);
709709
delete responsePacket;

0 commit comments

Comments
 (0)