From dbbaa67ade07b58f02f4369f61cb51473af5091a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Gonz=C3=A1lez=20L=C3=B3pez?= Date: Fri, 14 Aug 2026 23:06:31 +0200 Subject: [PATCH 1/2] Fix remaining TXOP duration calculation TxopProcedure::getRemaining() incorrectly returns the elapsed TXOP duration while the TXOP is active. This causes callers to treat spent time as the remaining transmission budget. Return the configured TXOP limit minus the elapsed duration while preserving the existing zero clamp after expiry. Add a focused unit test covering the inactive state, the full limit at startup, partial elapsed time, exact expiry, post-expiry clamping, and the state after ending the TXOP. --- .../ieee80211/mac/originator/TxopProcedure.cc | 2 +- tests/unit/Ieee80211TxopProcedure_1.test | 86 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 tests/unit/Ieee80211TxopProcedure_1.test diff --git a/src/inet/linklayer/ieee80211/mac/originator/TxopProcedure.cc b/src/inet/linklayer/ieee80211/mac/originator/TxopProcedure.cc index 0ec6898bd00..340270693a3 100644 --- a/src/inet/linklayer/ieee80211/mac/originator/TxopProcedure.cc +++ b/src/inet/linklayer/ieee80211/mac/originator/TxopProcedure.cc @@ -96,7 +96,7 @@ simtime_t TxopProcedure::getRemaining() const if (start == -1) throw cRuntimeError("Txop has not started yet"); auto now = simTime(); - return now > start + limit ? 0 : now - start; + return now > start + limit ? 0 : start + limit - now; } simtime_t TxopProcedure::getDuration() const diff --git a/tests/unit/Ieee80211TxopProcedure_1.test b/tests/unit/Ieee80211TxopProcedure_1.test new file mode 100644 index 00000000000..5f06b4e7ebe --- /dev/null +++ b/tests/unit/Ieee80211TxopProcedure_1.test @@ -0,0 +1,86 @@ +%description: +Tests that TxopProcedure reports the remaining time until the TXOP limit. + +%includes: +#include "inet/linklayer/ieee80211/mac/originator/TxopProcedure.h" + +using namespace omnetpp; +using namespace inet; +using namespace inet::ieee80211; + +namespace Ieee80211TxopProcedure_1 { + +class TestTxopProcedure : public TxopProcedure +{ + protected: + virtual void initialize(int stage) override + { + if (stage == INITSTAGE_LOCAL) + limit = par("txopLimit"); + } +}; + +Define_Module(TestTxopProcedure); + +} // namespace Ieee80211TxopProcedure_1 + +%file: TestNetwork.ned + +import inet.linklayer.ieee80211.mac.originator.TxopProcedure; + +simple TestTxopProcedure extends TxopProcedure +{ + parameters: + @class(TestTxopProcedure); +} + +network TestNetwork +{ + submodules: + test: Test; + txop: TestTxopProcedure { + parameters: + txopLimit = 10ms; + } +} + +%inifile: omnetpp.ini +[General] +ned-path = .;../../../../src;../../lib +network = TestNetwork + +%activity: + +auto txop = check_and_cast(cSimulation::getActiveSimulation()->getModuleByPath("txop")); + +auto getRemainingThrows = [txop]() { + try { + txop->getRemaining(); + return false; + } + catch (const cRuntimeError&) { + return true; + } +}; + +ASSERT(getRemainingThrows()); + +txop->startTxop(AC_VI); +ASSERT(txop->getRemaining() == SimTime(10, SIMTIME_MS)); + +wait(0.003); +ASSERT(txop->getRemaining() == SimTime(7, SIMTIME_MS)); + +wait(0.007); +ASSERT(txop->getRemaining() == SIMTIME_ZERO); + +wait(0.001); +ASSERT(txop->getRemaining() == SIMTIME_ZERO); + +txop->endTxop(); +ASSERT(getRemainingThrows()); + +EV << "TXOP remaining time is correct at all boundaries.\n"; + +%contains: stdout +TXOP remaining time is correct at all boundaries. From 9659beb85d339434f003bfbe49670b1a3b7e9bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Gonz=C3=A1lez=20L=C3=B3pez?= Date: Fri, 14 Aug 2026 23:33:52 +0200 Subject: [PATCH 2/2] tests(fingerprint): update MIPv6 roaming baseline The corrected TxopProcedure::getRemaining() now reports the remaining TXOP budget instead of elapsed duration. HcfFs::hasMoreTxOps() therefore makes different frame-continuation decisions in the MIPv6 roaming Wi-Fi scenario. Record the deterministic trajectory produced by the fix: 7ed8-bee3/~tNlb replaces c8dc-27c2/~tNlb in the focused regression baseline. The narrow fingerprint test passed after the update. --- tests/fingerprint/mipv6-refactoring.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fingerprint/mipv6-refactoring.csv b/tests/fingerprint/mipv6-refactoring.csv index e7a648648c0..4c2175bce5a 100644 --- a/tests/fingerprint/mipv6-refactoring.csv +++ b/tests/fingerprint/mipv6-refactoring.csv @@ -10,7 +10,7 @@ # MIPv6 example — the primary test /examples/ipv6/mipv6/, -f omnetpp.ini -c Handover -r 0, 70s, aa29-a8c5/~tNlb, PASS, wireless EthernetMac /examples/ipv6/mipv6/, -f omnetpp.ini -c RouteOptimizationTwoCNs -r 0, 60s, 068b-23aa/~tNlb, PASS, wireless EthernetMac -/examples/ipv6/mipv6roaming/, -f omnetpp.ini -c Roaming -r 0, 70s, c8dc-27c2/~tNlb, PASS, wireless EthernetMac +/examples/ipv6/mipv6roaming/, -f omnetpp.ini -c Roaming -r 0, 70s, 7ed8-bee3/~tNlb, PASS, wireless EthernetMac # IPv6 examples # MLD example — new PASS row; ~tNl locks the MLD Report/Query/Done/MAS-Query packet exchange (traffic+lengths);