Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/inet/linklayer/ieee80211/mac/Ieee80211Frame.msg
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ class Ieee80211AddbaResponse extends Ieee80211ActionFrame
//
class Ieee80211Delba extends Ieee80211ActionFrame
{
chunkLength = LENGTH_DELBA;
chunkLength = LENGTH_DELBA - B(4); // FCS is carried by Ieee80211MacTrailer
category = 3; // Category field is set to 3 (representing DELBA). (1 byte)
blockAckAction = 2; // Block Ack Action field is set to 2 (representing DELBA). (1 byte)

Expand Down
108 changes: 62 additions & 46 deletions src/inet/linklayer/ieee80211/mac/Ieee80211MacHeaderSerializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "inet/linklayer/ieee80211/mac/Ieee80211MacHeaderSerializer.h"

#include "inet/common/checksum/Checksum.h"
#include "inet/common/packet/serializer/ChunkSerializerRegistry.h"

namespace inet {
Expand Down Expand Up @@ -64,6 +65,19 @@ uint16_t packSequenceControl(uint8_t fragmentNumber, uint16_t sequenceNumber)
return (fragmentNumber & 0xF) | ((sequenceNumber & 0xFFF) << 4);
}

uint16_t packBlockAckParameters(bool aMsduSupported, bool blockAckPolicy, uint8_t tid, uint16_t bufferSize)
{
// IEEE Std 802.11-2024, 9.4.1.13, Figure 9-151.
return aMsduSupported | (blockAckPolicy << 1) | ((tid & 0xF) << 2) | ((bufferSize & 0x3FF) << 6);
}

uint8_t computeMpduDelimiterCrc(uint16_t delimiter)
{
// IEEE Std 802.11-2024, 9.7.2: x^8 + x^2 + x + 1, complemented remainder.
const uint8_t bytes[] = {uint8_t(delimiter), uint8_t(delimiter >> 8)};
return generic_crc8(bytes, sizeof(bytes), 0x07, 0xFF, true, true, 0xFF);
}

void writeSequenceControl(MemoryOutputStream& stream, uint8_t fragmentNumber, uint16_t sequenceNumber)
{
stream.writeUint16Le(packSequenceControl(fragmentNumber, sequenceNumber));
Expand Down Expand Up @@ -126,24 +140,25 @@ const Ptr<Chunk> Ieee80211MsduSubframeHeaderSerializer::deserializeFields(Memory
void Ieee80211MpduSubframeHeaderSerializer::serializeFields(MemoryOutputStream& stream, const Ptr<const Chunk>& chunk) const
{
auto mpduSubframe = dynamicPtrCast<const Ieee80211MpduSubframeHeader>(chunk);
stream.writeUint4(0);
stream.writeUint4(mpduSubframe->getLength() >> 8);
stream.writeUint8(mpduSubframe->getLength() & 0xFF);
stream.writeByte(0);
// IEEE Std 802.11-2024, 9.7.1, Figures 9-1329/9-1330: HT length occupies B4-B15.
int length = mpduSubframe->getLength();
if (length < 0 || length > 0xFFF)
throw cRuntimeError("HT MPDU delimiter length is outside the 12-bit range: %d", length);
uint16_t delimiter = length << 4;
stream.writeUint16Le(delimiter);
stream.writeByte(computeMpduDelimiterCrc(delimiter));
stream.writeByte(0x4E);
}

const Ptr<Chunk> Ieee80211MpduSubframeHeaderSerializer::deserializeFields(MemoryInputStream& stream, const std::type_info&) const
{
auto mpduSubframe = makeShared<Ieee80211MpduSubframeHeader>();
stream.readUint4();
// IEEE Std 802.11-2024, 9.7.1, Table 9-659 and Figure 9-1330:
// in an HT PPDU, MPDU Length Low is 12 bits and MPDU Length High is reserved.
int length = stream.readUint4() << 8;
length |= stream.readUint8();
mpduSubframe->setLength(length);
stream.readByte();
stream.readByte();
auto delimiter = stream.readUint16Le();
mpduSubframe->setLength(delimiter >> 4);
auto crc = stream.readByte();
auto signature = stream.readByte();
if (crc != computeMpduDelimiterCrc(delimiter) || signature != 0x4E)
mpduSubframe->markIncorrect();
return mpduSubframe;
}

Expand Down Expand Up @@ -195,36 +210,32 @@ void Ieee80211MacHeaderSerializer::serializeFields(MemoryOutputStream& stream, c
auto addbaRequest = dynamicPtrCast<const Ieee80211AddbaRequest>(chunk);
stream.writeByte(addbaRequest->getBlockAckAction());
stream.writeByte(addbaRequest->getDialogToken());
stream.writeBit(addbaRequest->getAMsduSupported());
stream.writeBit(addbaRequest->getBlockAckPolicy());
stream.writeUint4(addbaRequest->getTid());
stream.writeNBitsOfUint64Be(addbaRequest->getBufferSize(), 10);
stream.writeUint16Be(addbaRequest->getBlockAckTimeoutValue().inUnit(SIMTIME_US) / 1024);
stream.writeUint4(addbaRequest->get_fragmentNumber());
stream.writeNBitsOfUint64Be(addbaRequest->getStartingSequenceNumber().get(), 12);
stream.writeUint16Le(packBlockAckParameters(addbaRequest->getAMsduSupported(),
addbaRequest->getBlockAckPolicy(), addbaRequest->getTid(), addbaRequest->getBufferSize()));
stream.writeUint16Le(addbaRequest->getBlockAckTimeoutValue().inUnit(SIMTIME_US) / 1024);
// IEEE Std 802.11-2024, 9.6.4.2: Fragment Number is zero.
writeSequenceControl(stream, 0, addbaRequest->getStartingSequenceNumber().get());
ASSERT(stream.getLength() - startPos == addbaRequest->getChunkLength());
break;
}
case 1: {
auto addbaResponse = dynamicPtrCast<const Ieee80211AddbaResponse>(chunk);
stream.writeByte(addbaResponse->getBlockAckAction());
stream.writeByte(addbaResponse->getDialogToken());
stream.writeUint16Be(addbaResponse->getStatusCode());
stream.writeBit(addbaResponse->getAMsduSupported());
stream.writeBit(addbaResponse->getBlockAckPolicy());
stream.writeUint4(addbaResponse->getTid());
stream.writeNBitsOfUint64Be(addbaResponse->getBufferSize(), 10);
stream.writeUint16Be(addbaResponse->getBlockAckTimeoutValue().inUnit(SIMTIME_US) / 1024);
stream.writeUint16Le(addbaResponse->getStatusCode());
stream.writeUint16Le(packBlockAckParameters(addbaResponse->getAMsduSupported(),
addbaResponse->getBlockAckPolicy(), addbaResponse->getTid(), addbaResponse->getBufferSize()));
stream.writeUint16Le(addbaResponse->getBlockAckTimeoutValue().inUnit(SIMTIME_US) / 1024);
ASSERT(stream.getLength() - startPos == addbaResponse->getChunkLength());
break;
}
case 2: {
auto delba = dynamicPtrCast<const Ieee80211Delba>(chunk);
stream.writeByte(delba->getBlockAckAction());
stream.writeNBitsOfUint64Be(delba->getReserved(), 11);
stream.writeBit(delba->getInitiator());
stream.writeUint4(delba->getTid());
stream.writeUint16Be(delba->getReasonCode());
// IEEE Std 802.11-2024, 9.4.1.16, Figure 9-154.
stream.writeUint16Le((delba->getReserved() & 0x7FF) |
(delba->getInitiator() << 11) | ((delba->getTid() & 0xF) << 12));
stream.writeUint16Le(delba->getReasonCode());
ASSERT(stream.getLength() - startPos == delba->getChunkLength());
break;
}
Expand Down Expand Up @@ -437,13 +448,15 @@ const Ptr<Chunk> Ieee80211MacHeaderSerializer::deserializeFields(MemoryInputStre
copyActionFrameFields(addbaRequest, actionFrame);
addbaRequest->setBlockAckAction(blockAckAction);
addbaRequest->setDialogToken(stream.readByte());
addbaRequest->setAMsduSupported(stream.readBit());
addbaRequest->setBlockAckPolicy(stream.readBit());
addbaRequest->setTid(stream.readUint4());
addbaRequest->setBufferSize(stream.readNBitsToUint64Be(10));
addbaRequest->setBlockAckTimeoutValue(SimTime(stream.readUint16Be() * 1024, SIMTIME_US));
addbaRequest->set_fragmentNumber(stream.readUint4());
addbaRequest->setStartingSequenceNumber(SequenceNumberCyclic(stream.readNBitsToUint64Be(12)));
auto parameters = stream.readUint16Le();
addbaRequest->setAMsduSupported(parameters & 1);
addbaRequest->setBlockAckPolicy(parameters & 2);
addbaRequest->setTid((parameters >> 2) & 0xF);
addbaRequest->setBufferSize(parameters >> 6);
addbaRequest->setBlockAckTimeoutValue(SimTime(stream.readUint16Le() * 1024, SIMTIME_US));
readSequenceControl(stream, fragmentNumber, sequenceNumber);
addbaRequest->set_fragmentNumber(fragmentNumber);
addbaRequest->setStartingSequenceNumber(sequenceNumber);
return addbaRequest;
}
case 1: {
Expand All @@ -452,22 +465,25 @@ const Ptr<Chunk> Ieee80211MacHeaderSerializer::deserializeFields(MemoryInputStre
copyActionFrameFields(addbaResponse, actionFrame);
addbaResponse->setBlockAckAction(blockAckAction);
addbaResponse->setDialogToken(stream.readByte());
addbaResponse->setStatusCode(stream.readUint16Be());
addbaResponse->setAMsduSupported(stream.readBit());
addbaResponse->setBlockAckPolicy(stream.readBit());
addbaResponse->setTid(stream.readUint4());
addbaResponse->setBufferSize(stream.readNBitsToUint64Be(10));
addbaResponse->setBlockAckTimeoutValue(SimTime(stream.readUint16Be() * 1024, SIMTIME_US));
addbaResponse->setStatusCode(stream.readUint16Le());
auto parameters = stream.readUint16Le();
addbaResponse->setAMsduSupported(parameters & 1);
addbaResponse->setBlockAckPolicy(parameters & 2);
addbaResponse->setTid((parameters >> 2) & 0xF);
addbaResponse->setBufferSize(parameters >> 6);
addbaResponse->setBlockAckTimeoutValue(SimTime(stream.readUint16Le() * 1024, SIMTIME_US));
return addbaResponse;
}
case 2: {
auto delba = makeShared<Ieee80211Delba>();
copyBasicFields(delba, macHeader);
copyActionFrameFields(delba, actionFrame);
delba->setBlockAckAction(blockAckAction);
delba->setReserved(stream.readNBitsToUint64Be(11));
delba->setInitiator(stream.readBit());
delba->setTid(stream.readUint4());
delba->setReasonCode(stream.readUint16Be());
auto parameters = stream.readUint16Le();
delba->setReserved(parameters & 0x7FF);
delba->setInitiator(parameters & 0x800);
delba->setTid(parameters >> 12);
delba->setReasonCode(stream.readUint16Le());
return delba;
}
default:
Expand Down
17 changes: 16 additions & 1 deletion src/inet/linklayer/ieee80211/mac/aggregation/MsduAggregation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,24 @@ Packet *MsduAggregation::aggregateFrames(std::vector<Packet *> *frames)
amsduHeader->setFromDS(fromDS);
amsduHeader->setAMsduPresent(true);
amsduHeader->setReceiverAddress(ra);
// IEEE Std 802.11-2024, 9.3.2.2.1: aggregation preserves the common RA and TA.
amsduHeader->setTransmitterAddress(firstHeader->getTransmitterAddress());
amsduHeader->setTid(tid);
amsduHeader->addChunkLength(QOSCONTROL_PART_LENGTH);
// TODO set addr3 and addr4 according to fromDS and toDS.
// IEEE Std 802.11-2024, 9.3.2.1.1, Figure 9-119.
if (toDS && fromDS)
amsduHeader->addChunkLength(B(6));
// IEEE Std 802.11-2024, 9.3.2.1.2, Table 9-60: Basic A-MSDUs carry the
// BSSID in Address3 and, when present, Address4. In the AP-to-AP case,
// the BSSID is the address of the transmitting AP.
if (fromDS)
amsduHeader->setAddress3(firstHeader->getTransmitterAddress());
else if (toDS)
amsduHeader->setAddress3(ra);
else
amsduHeader->setAddress3(firstHeader->getAddress3());
if (toDS && fromDS)
amsduHeader->setAddress4(firstHeader->getTransmitterAddress());
aggregatedFrame->insertAtFront(amsduHeader);
aggregatedFrame->insertAtBack(makeShared<Ieee80211MacTrailer>());
aggregatedFrame->setName(aggregatedName.c_str());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ void MsduDeaggregation::setExplodedFrameAddress(const Ptr<Ieee80211DataHeader>&
if (fromDS == 0 && toDS == 0) { // STA to STA
header->setTransmitterAddress(aMsduHeader->getTransmitterAddress());
header->setReceiverAddress(aMsduHeader->getReceiverAddress());
header->setAddress3(aMsduHeader->getAddress3());
}
else if (fromDS == 1 && toDS == 0) { // AP to STA
header->setTransmitterAddress(aMsduHeader->getTransmitterAddress());
Expand Down Expand Up @@ -64,6 +65,9 @@ std::vector<Packet *> *MsduDeaggregation::deaggregateFrame(Packet *aggregatedFra
header->addChunkLength(QOSCONTROL_PART_LENGTH);
header->setToDS(amsduHeader->getToDS());
header->setFromDS(amsduHeader->getFromDS());
// IEEE Std 802.11-2024, 9.3.2.1.1, Figure 9-119: Address4 adds six octets.
if (header->getToDS() && header->getFromDS())
header->addChunkLength(B(6));
header->setTid(tid);
header->setSequenceNumber(SequenceNumberCyclic(0));
setExplodedFrameAddress(header, msduSubframeHeader, amsduHeader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -758,8 +758,9 @@ const Ptr<Chunk> Ieee80211MgmtFrameSerializer::deserializeFields(MemoryInputStre
else if (typeInfo == typeid(Ieee80211BeaconFrame)) {
auto frame = makeShared<Ieee80211BeaconFrame>();

simtime_t timetstamp;
timetstamp.setRaw(stream.readUint64Le()); // TODO store timestamp
// IEEE Std 802.11-2024, 9.4.1.10 and 11.1.3.1: unsigned TSF counter in microseconds.
// The model does not retain TSF; no conversion to simulation-resolution ticks is needed.
stream.readUint64Le();

frame->setBeaconInterval(SimTime((int64_t)stream.readUint16Le() * 1024, SIMTIME_US));
stream.readUint16Le(); // Capability
Expand All @@ -775,8 +776,9 @@ const Ptr<Chunk> Ieee80211MgmtFrameSerializer::deserializeFields(MemoryInputStre
else if (typeInfo == typeid(Ieee80211ProbeResponseFrame)) {
auto frame = makeShared<Ieee80211ProbeResponseFrame>();

simtime_t timestamp;
timestamp.setRaw(stream.readUint64Le()); // TODO store timestamp
// IEEE Std 802.11-2024, 9.4.1.10 and 11.1.3.1: unsigned TSF counter in microseconds.
// The model does not retain TSF; no conversion to simulation-resolution ticks is needed.
stream.readUint64Le();

frame->setBeaconInterval(SimTime((int64_t)stream.readUint16Le() * 1024, SIMTIME_US));
stream.readUint16Le();
Expand Down
8 changes: 4 additions & 4 deletions tests/fingerprint/examples.csv
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# /examples/adhoc/ieee80211/, -f omnetpp.ini -c Ping2 -r 0, 100s, 0000-0000/tplx;0000-0000/~tNl;0000-0000/~tND, ERROR, wireless adhoc # [Config Ping2] # interactive config, needed a *.numHosts parameter
/examples/adhoc/qos/, -f omnetpp.ini -c MacNonQos -r 0, 10s, 5749-0281/tplx;f38a-cb93/~tNl;fd9b-683f/~tND;0eb8-3e3b/tyf, PASS, wireless adhoc Ipv4
/examples/adhoc/qos/, -f omnetpp.ini -c MacQos -r 0, 10s, 1486-cbae/tplx;521b-977a/~tNl;91c2-9aa9/~tND;2c1e-66e5/tyf, PASS, wireless adhoc Ipv4
/examples/adhoc/qos/, -f omnetpp.ini -c MacQos -r 1, 10s, 783f-d09a/tplx;13d1-ec15/~tNl;5aaf-cc7c/~tND;a587-3a4d/tyf, PASS, wireless adhoc Ipv4
/examples/adhoc/qos/, -f omnetpp.ini -c MacQos -r 1, 10s, 783f-d09a/tplx;13d1-ec15/~tNl;a50d-9ad8/~tND;a587-3a4d/tyf, PASS, wireless adhoc Ipv4
/examples/adhoc/qos/, -f omnetpp.ini -c Fragmentation, 10s, 9c66-e6f0/tplx;cc9e-d1a6/~tNl;53c8-e1b0/~tND;33b7-00f9/tyf, PASS, wireless adhoc Ipv4
/examples/adhoc/qos/, -f omnetpp.ini -c MsduAggregation, 10s, 85bd-85c6/tplx;22f6-085d/~tNl;dc0d-4e19/~tND;df04-18f7/tyf, PASS, wireless adhoc Ipv4

Expand Down Expand Up @@ -655,10 +655,10 @@
/examples/wireless/power/, -f omnetpp.ini -c General -r 0, 100s, 6fae-d558/tplx;b8ea-b2fc/~tNl;5ea8-2cea/~tND, PASS, wireless Ipv4

/examples/wireless/qos/, -f omnetpp.ini -c MacNonQos -r 0, 10s, f252-8a4b/tplx;481d-4747/~tNl;5962-e45d/~tND;6097-a429/tyf, PASS, wireless Ipv4
/examples/wireless/qos/, -f omnetpp.ini -c MacQos -r 0, 10s, 31b0-6212/tplx;82ec-9fde/~tNl;540d-c0a4/~tND;9f3c-4512/tyf, PASS, wireless Ipv4
/examples/wireless/qos/, -f omnetpp.ini -c MacQos -r 0, 10s, 31b0-6212/tplx;82ec-9fde/~tNl;9839-8fb0/~tND;9f3c-4512/tyf, PASS, wireless Ipv4
/examples/wireless/qos/, -f omnetpp.ini -c MacQosWithoutAggregation -r 0, 10s, acd6-0108/tplx;b339-294a/~tNl;75d4-11f9/~tND;a4c3-19bf/tyf, PASS, wireless Ipv4
/examples/wireless/qos/, -f omnetpp.ini -c MacQosWithRtsCts -r 0, 10s, 9ece-fbfb/tplx;c1af-29ff/~tNl;8fe3-d7a6/~tND;b2d6-1329/tyf, PASS, wireless Ipv4
/examples/wireless/qos/, -f omnetpp.ini -c MacQosWithBlockAck -r 0, 10s, d094-b008/tplx;173a-e3fb/~tNl;7147-4f5b/~tND;08b5-d005/tyf, PASS, wireless Ipv4
/examples/wireless/qos/, -f omnetpp.ini -c MacQosWithRtsCts -r 0, 10s, 9ece-fbfb/tplx;c1af-29ff/~tNl;4757-c17b/~tND;b2d6-1329/tyf, PASS, wireless Ipv4
/examples/wireless/qos/, -f omnetpp.ini -c MacQosWithBlockAck -r 0, 10s, d094-b008/tplx;173a-e3fb/~tNl;6541-bd60/~tND;08b5-d005/tyf, PASS, wireless Ipv4

/examples/wireless/ratecontrol/, -f omnetpp.ini -c Mac -r 0, 100s, bf30-2f13/tplx;7b2f-653d/~tNl;6e1e-3b7b/~tND;19fe-8b0e/tyf, PASS, wireless

Expand Down
Loading