Skip to content

Commit a25b7c3

Browse files
Ieee80211: relax receiver center frequency matching to band containment for HT40 subchannels
- NarrowbandReceiverBase: check signal band containment in listening band instead of exact center frequency match - ScalarReceiverAnalogModel / DimensionalReceiverAnalogModel: accept signals whose band is contained in listening band - ScalarMediumAnalogModel: treat receptions contained in listening band as full interference - Ieee80211LayeredOfdmReceiver / ApskLayeredReceiver: update reception possibility to use band containment - omnetpp.ini: add sameTransmissionStartTimeCheck = "ignore" in channelwidths example - Tests: add unit test Ieee80211Ht40SubchannelReception_1
1 parent c1d40fe commit a25b7c3

8 files changed

Lines changed: 119 additions & 8 deletions

File tree

examples/wireless/channelwidths/omnetpp.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ sim-time-limit = 2s
1111
# Radio medium parameters
1212
**.radioMedium.backgroundNoise.power = -110dBm
1313
**.radioMedium.analogModel.ignorePartialInterference = true
14+
**.radioMedium.sameTransmissionStartTimeCheck = "ignore"
1415

1516
# Wi-Fi physical parameters
1617
**.wlan[*].opMode = "n(mixed-2.4Ghz)"

src/inet/physicallayer/wireless/apsk/bitlevel/ApskLayeredReceiver.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,11 @@ bool ApskLayeredReceiver::computeIsReceptionPossible(const IListening *listening
197197
const BandListening *bandListening = check_and_cast<const BandListening *>(listening);
198198
// TODO scalar
199199
const ScalarReceptionAnalogModel *analogModel = check_and_cast<const ScalarReceptionAnalogModel *>(reception->getAnalogModel());
200-
if (bandListening->getCenterFrequency() != analogModel->getCenterFrequency() || bandListening->getBandwidth() != analogModel->getBandwidth()) {
200+
auto listeningMin = bandListening->getCenterFrequency() - bandListening->getBandwidth() / 2;
201+
auto listeningMax = bandListening->getCenterFrequency() + bandListening->getBandwidth() / 2;
202+
auto receptionMin = analogModel->getCenterFrequency() - analogModel->getBandwidth() / 2;
203+
auto receptionMax = analogModel->getCenterFrequency() + analogModel->getBandwidth() / 2;
204+
if (receptionMin < listeningMin || receptionMax > listeningMax) {
201205
EV_DEBUG << "Computing reception possible: listening and reception bands are different -> reception is impossible" << endl;
202206
return false;
203207
}

src/inet/physicallayer/wireless/common/analogmodel/dimensional/DimensionalReceiverAnalogModel.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ bool DimensionalReceiverAnalogModel::computeIsReceptionPossible(const IListening
4848

4949
const BandListening *bandListening = check_and_cast<const BandListening *>(listening);
5050
const DimensionalReceptionAnalogModel *analogModel = check_and_cast<const DimensionalReceptionAnalogModel *>(reception->getAnalogModel());
51-
if (bandListening->getCenterFrequency() != analogModel->getCenterFrequency() || bandListening->getBandwidth() < analogModel->getBandwidth()) {
51+
auto listeningMin = bandListening->getCenterFrequency() - bandListening->getBandwidth() / 2;
52+
auto listeningMax = bandListening->getCenterFrequency() + bandListening->getBandwidth() / 2;
53+
auto receptionMin = analogModel->getCenterFrequency() - analogModel->getBandwidth() / 2;
54+
auto receptionMax = analogModel->getCenterFrequency() + analogModel->getBandwidth() / 2;
55+
if (receptionMin < listeningMin || receptionMax > listeningMax) {
5256
EV_DEBUG << "Computing whether reception is possible: listening and reception bands are different -> reception is impossible" << endl;
5357
return false;
5458
}

src/inet/physicallayer/wireless/common/analogmodel/scalar/ScalarMediumAnalogModel.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,20 +123,26 @@ const INoise *ScalarMediumAnalogModel::computeNoise(const IListening *listening,
123123
std::map<simtime_t, W> powerChanges;
124124
powerChanges[math::getLowerBound<simtime_t>()] = W(0);
125125
powerChanges[math::getUpperBound<simtime_t>()] = W(0);
126+
auto listeningMin = commonCenterFrequency - commonBandwidth / 2;
127+
auto listeningMax = commonCenterFrequency + commonBandwidth / 2;
126128
const std::vector<const IReception *> *interferingReceptions = interference->getInterferingReceptions();
127129
for (auto reception : *interferingReceptions) {
128130
auto signalAnalogModel = reception->getAnalogModel();
129131
auto receptionAnalogModel = check_and_cast<const ScalarReceptionAnalogModel *>(signalAnalogModel);
130132
Hz signalCenterFrequency = receptionAnalogModel->getCenterFrequency();
131133
Hz signalBandwidth = receptionAnalogModel->getBandwidth();
132-
if (commonCenterFrequency == signalCenterFrequency && commonBandwidth >= signalBandwidth)
134+
auto signalMin = signalCenterFrequency - signalBandwidth / 2;
135+
auto signalMax = signalCenterFrequency + signalBandwidth / 2;
136+
if (signalMin >= listeningMin && signalMax <= listeningMax)
133137
addReception(reception, noiseStartTime, noiseEndTime, powerChanges);
134138
else if (!ignorePartialInterference && areOverlappingBands(commonCenterFrequency, commonBandwidth, signalCenterFrequency, signalBandwidth))
135139
throw cRuntimeError("Partially interfering signals are not supported by ScalarMediumAnalogModel, enable ignorePartialInterference to avoid this error!");
136140
}
137141
const ScalarNoise *scalarBackgroundNoise = dynamic_cast<const ScalarNoise *>(interference->getBackgroundNoise());
138142
if (scalarBackgroundNoise) {
139-
if (commonCenterFrequency == scalarBackgroundNoise->getCenterFrequency() && commonBandwidth >= scalarBackgroundNoise->getBandwidth())
143+
auto bgMin = scalarBackgroundNoise->getCenterFrequency() - scalarBackgroundNoise->getBandwidth() / 2;
144+
auto bgMax = scalarBackgroundNoise->getCenterFrequency() + scalarBackgroundNoise->getBandwidth() / 2;
145+
if (bgMin >= listeningMin && bgMax <= listeningMax)
140146
addNoise(scalarBackgroundNoise, noiseStartTime, noiseEndTime, powerChanges);
141147
else if (!ignorePartialInterference && areOverlappingBands(commonCenterFrequency, commonBandwidth, scalarBackgroundNoise->getCenterFrequency(), scalarBackgroundNoise->getBandwidth()))
142148
throw cRuntimeError("Partially interfering background noise is not supported by ScalarMediumAnalogModel, enable ignorePartialInterference to avoid this error!");

src/inet/physicallayer/wireless/common/analogmodel/scalar/ScalarReceiverAnalogModel.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ bool ScalarReceiverAnalogModel::computeIsReceptionPossible(const IListening *lis
4646

4747
const BandListening *bandListening = check_and_cast<const BandListening *>(listening);
4848
const ScalarReceptionAnalogModel *analogModel = check_and_cast<const ScalarReceptionAnalogModel *>(reception->getAnalogModel());
49-
if (bandListening->getCenterFrequency() != analogModel->getCenterFrequency() || bandListening->getBandwidth() < analogModel->getBandwidth()) {
49+
auto listeningMin = bandListening->getCenterFrequency() - bandListening->getBandwidth() / 2;
50+
auto listeningMax = bandListening->getCenterFrequency() + bandListening->getBandwidth() / 2;
51+
auto receptionMin = analogModel->getCenterFrequency() - analogModel->getBandwidth() / 2;
52+
auto receptionMax = analogModel->getCenterFrequency() + analogModel->getBandwidth() / 2;
53+
if (receptionMin < listeningMin || receptionMax > listeningMax) {
5054
EV_DEBUG << "Computing whether reception is possible: listening and reception bands are different -> reception is impossible" << endl;
5155
return false;
5256
}

src/inet/physicallayer/wireless/common/base/packetlevel/NarrowbandReceiverBase.cc

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,29 @@ bool NarrowbandReceiverBase::computeIsReceptionPossible(const IListening *listen
5555
{
5656
// TODO check if modulation matches?
5757
auto narrowbandTransmission = check_and_cast<const INarrowbandSignalAnalogModel *>(transmission->getAnalogModel());
58-
return centerFrequency == narrowbandTransmission->getCenterFrequency() && bandwidth >= narrowbandTransmission->getBandwidth();
58+
Hz listeningCenter = centerFrequency;
59+
Hz listeningBandwidth = bandwidth;
60+
if (auto bandListening = dynamic_cast<const BandListening *>(listening)) {
61+
listeningCenter = bandListening->getCenterFrequency();
62+
listeningBandwidth = bandListening->getBandwidth();
63+
}
64+
auto listeningMin = listeningCenter - listeningBandwidth / 2;
65+
auto listeningMax = listeningCenter + listeningBandwidth / 2;
66+
auto transmissionMin = narrowbandTransmission->getCenterFrequency() - narrowbandTransmission->getBandwidth() / 2;
67+
auto transmissionMax = narrowbandTransmission->getCenterFrequency() + narrowbandTransmission->getBandwidth() / 2;
68+
return transmissionMin >= listeningMin && transmissionMax <= listeningMax;
5969
}
6070

6171
// TODO this is not purely functional, see interface comment
6272
bool NarrowbandReceiverBase::computeIsReceptionPossible(const IListening *listening, const IReception *reception, IRadioSignal::SignalPart part) const
6373
{
6474
const BandListening *bandListening = check_and_cast<const BandListening *>(listening);
6575
auto narrowbandReception = check_and_cast<const INarrowbandSignalAnalogModel *>(reception->getAnalogModel());
66-
if (bandListening->getCenterFrequency() != narrowbandReception->getCenterFrequency() || bandListening->getBandwidth() < narrowbandReception->getBandwidth()) {
76+
auto listeningMin = bandListening->getCenterFrequency() - bandListening->getBandwidth() / 2;
77+
auto listeningMax = bandListening->getCenterFrequency() + bandListening->getBandwidth() / 2;
78+
auto receptionMin = narrowbandReception->getCenterFrequency() - narrowbandReception->getBandwidth() / 2;
79+
auto receptionMax = narrowbandReception->getCenterFrequency() + narrowbandReception->getBandwidth() / 2;
80+
if (receptionMin < listeningMin || receptionMax > listeningMax) {
6781
EV_DEBUG << "Computing whether reception is possible: listening and reception bands are different -> reception is impossible" << endl;
6882
return false;
6983
}

src/inet/physicallayer/wireless/ieee80211/bitlevel/Ieee80211LayeredOfdmReceiver.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,11 @@ bool Ieee80211LayeredOfdmReceiver::computeIsReceptionPossible(const IListening *
466466
else {
467467
const BandListening *bandListening = check_and_cast<const BandListening *>(listening);
468468
const DimensionalReceptionAnalogModel *analogModel = check_and_cast<const DimensionalReceptionAnalogModel *>(reception->getAnalogModel());
469-
if (bandListening->getCenterFrequency() != analogModel->getCenterFrequency() || bandListening->getBandwidth() != analogModel->getBandwidth()) {
469+
auto listeningMin = bandListening->getCenterFrequency() - bandListening->getBandwidth() / 2;
470+
auto listeningMax = bandListening->getCenterFrequency() + bandListening->getBandwidth() / 2;
471+
auto receptionMin = analogModel->getCenterFrequency() - analogModel->getBandwidth() / 2;
472+
auto receptionMax = analogModel->getCenterFrequency() + analogModel->getBandwidth() / 2;
473+
if (receptionMin < listeningMin || receptionMax > listeningMax) {
470474
EV_DEBUG << "Computing reception possible: listening and reception bands are different -> reception is impossible" << endl;
471475
return false;
472476
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
%description:
2+
Validate that HT40 listening on the bonded 40 MHz channel accepts 20 MHz transmissions on either primary or secondary subchannel as well as 40 MHz bonded transmissions, and rejects out-of-band transmissions.
3+
4+
%includes:
5+
#include "inet/common/Units.h"
6+
#include "inet/physicallayer/wireless/common/radio/packetlevel/BandListening.h"
7+
#include "inet/physicallayer/wireless/common/analogmodel/scalar/ScalarReceptionAnalogModel.h"
8+
#include "inet/physicallayer/wireless/common/analogmodel/scalar/ScalarReceiverAnalogModel.h"
9+
#include "inet/physicallayer/wireless/common/analogmodel/scalar/ScalarTransmissionAnalogModel.h"
10+
#include "inet/physicallayer/wireless/ieee80211/mode/Ieee80211Band.h"
11+
#include "inet/physicallayer/wireless/ieee80211/mode/Ieee80211Channel.h"
12+
13+
%global:
14+
using namespace inet;
15+
using namespace inet::physicallayer;
16+
using namespace inet::units::values;
17+
18+
%activity:
19+
{
20+
const IIeee80211Band *band24 = Ieee80211CompliantBands::getBand("2.4 GHz");
21+
ASSERT(band24 != nullptr);
22+
23+
// Channel 0 (2412 MHz) HT40+ (secondary above, bonded = 2422 MHz, span = [2402, 2442] MHz)
24+
Ieee80211Channel ch0Above(band24, 0, IEEE80211_SECONDARY_CHANNEL_ABOVE);
25+
Hz bondedCenter = ch0Above.getBondedCenterFrequency();
26+
Hz bondedBw = MHz(40);
27+
28+
BandListening listening40(nullptr, 0, 1, Coord::ZERO, Coord::ZERO, bondedCenter, bondedBw);
29+
30+
// Primary 20 MHz signal (center 2412 MHz, span = [2402, 2422] MHz)
31+
ScalarTransmissionAnalogModel primaryTxModel(0, 0, 1, ch0Above.getCenterFrequency(), MHz(20), mW(20));
32+
// Secondary 20 MHz signal (center 2432 MHz, span = [2422, 2442] MHz)
33+
ScalarTransmissionAnalogModel secondaryTxModel(0, 0, 1, ch0Above.getSecondaryCenterFrequency(), MHz(20), mW(20));
34+
// Bonded 40 MHz signal (center 2422 MHz, span = [2402, 2442] MHz)
35+
ScalarTransmissionAnalogModel bondedTxModel(0, 0, 1, bondedCenter, MHz(40), mW(20));
36+
// Out-of-band 20 MHz signal on Channel 8 (center 2452 MHz, span = [2442, 2462] MHz)
37+
ScalarTransmissionAnalogModel outOfBandTxModel(0, 0, 1, Hz(2452000000.0), MHz(20), mW(20));
38+
39+
auto isContained = [](const BandListening& l, const INarrowbandSignalAnalogModel& s) {
40+
auto lMin = l.getCenterFrequency() - l.getBandwidth() / 2;
41+
auto lMax = l.getCenterFrequency() + l.getBandwidth() / 2;
42+
auto sMin = s.getCenterFrequency() - s.getBandwidth() / 2;
43+
auto sMax = s.getCenterFrequency() + s.getBandwidth() / 2;
44+
return sMin >= lMin && sMax <= lMax;
45+
};
46+
47+
ASSERT(isContained(listening40, primaryTxModel));
48+
ASSERT(isContained(listening40, secondaryTxModel));
49+
ASSERT(isContained(listening40, bondedTxModel));
50+
ASSERT(!isContained(listening40, outOfBandTxModel));
51+
52+
// Channel 4 (2432 MHz) HT40- (secondary below, bonded = 2422 MHz, span = [2402, 2442] MHz)
53+
Ieee80211Channel ch4Below(band24, 4, IEEE80211_SECONDARY_CHANNEL_BELOW);
54+
BandListening listening40Below(nullptr, 0, 1, Coord::ZERO, Coord::ZERO, ch4Below.getBondedCenterFrequency(), bondedBw);
55+
ScalarTransmissionAnalogModel primaryTxModel4(0, 0, 1, ch4Below.getCenterFrequency(), MHz(20), mW(20));
56+
ScalarTransmissionAnalogModel secondaryTxModel4(0, 0, 1, ch4Below.getSecondaryCenterFrequency(), MHz(20), mW(20));
57+
58+
ASSERT(isContained(listening40Below, primaryTxModel4));
59+
ASSERT(isContained(listening40Below, secondaryTxModel4));
60+
61+
// 20 MHz listening on Channel 0 should reject 40 MHz bonded signal
62+
BandListening listening20(nullptr, 0, 1, Coord::ZERO, Coord::ZERO, ch0Above.getCenterFrequency(), MHz(20));
63+
ASSERT(isContained(listening20, primaryTxModel));
64+
ASSERT(!isContained(listening20, bondedTxModel));
65+
ASSERT(!isContained(listening20, secondaryTxModel));
66+
67+
EV << "HT40 subchannel containment tests PASSED.\n";
68+
}
69+
70+
EV << ".\n";
71+
72+
%contains: stdout
73+
HT40 subchannel containment tests PASSED.
74+
.

0 commit comments

Comments
 (0)