Skip to content

Commit 87e64f2

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 883e3d1 commit 87e64f2

4 files changed

Lines changed: 29 additions & 4 deletions

File tree

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,23 @@
1212
namespace inet {
1313
namespace ieee80211 {
1414

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

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+
// resolving the station label sweeps the network, so skip it if nothing listens anyway
24+
if (dataHeader != nullptr && !dataHeader->getReceiverAddress().isMulticast() && emitter->mayHaveListeners(datarateSelectedSignal)) {
25+
cNamedObject details(getStationLabel(dataHeader->getReceiverAddress()).c_str());
26+
emitter->emit(datarateSelectedSignal, rate, &details);
27+
}
28+
else
29+
emitter->emit(datarateSelectedSignal, rate);
30+
}
31+
1732
std::string IRateSelection::getStationLabel(const MacAddress& receiver)
1833
{
1934
// resolve the receiver MAC to the network node that owns it; fall back to the MAC
@@ -32,3 +47,4 @@ std::string IRateSelection::getStationLabel(const MacAddress& receiver)
3247

3348
} // namespace ieee80211
3449
} // namespace inet
50+

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ 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 receiver's station label as a named details object, so that a demux(datarateSelected)
31+
// result filter or the statistic bar chart visualizer can key a separate per-station series on
32+
// it; this mirrors the condition under which ~RateSelection applies a per-receiver configured
33+
// rate, so the label always names the station whose rate is reported. Control, management and
34+
// group-addressed frames carry no per-station data rate and are emitted without details: the
35+
// aggregate datarateSelected statistic still records them, a bar chart ignores them.
36+
static void emitDatarateSelected(cComponent *emitter, const Ptr<const Ieee80211MacHeader>& header, const physicallayer::IIeee80211Mode *mode);
37+
2938
// The label identifying a station in a per-station signal emission: it names the details
3039
// object emitted with the value, which a demux() result filter and the statistic bar chart
3140
// visualizer key their per-station series on. The receiver's network node path relative to

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)