INET Framework for OMNeT++/OMNEST
inet::ieee80211::Ieee80211MacHeaderSerializer Class Reference

Converts between Ieee80211MacHeader and binary network byte order IEEE 802.11 mac header. More...

#include <Ieee80211MacHeaderSerializer.h>

Inheritance diagram for inet::ieee80211::Ieee80211MacHeaderSerializer:
inet::FieldsChunkSerializer inet::ChunkSerializer

Public Member Functions

 Ieee80211MacHeaderSerializer ()
 
- Public Member Functions inherited from inet::FieldsChunkSerializer
virtual void serialize (MemoryOutputStream &stream, const Ptr< const Chunk > &chunk, b offset, b length) const override
 Serializes a chunk into a stream by writing the bytes representing the chunk at the end of the stream. More...
 
virtual const Ptr< Chunkdeserialize (MemoryInputStream &stream, const std::type_info &typeInfo) const override
 Deserializes a chunk from a stream by reading the bytes at the current position of the stream. More...
 

Protected Member Functions

virtual void serialize (MemoryOutputStream &stream, const Ptr< const Chunk > &chunk) const override
 Serializes a chunk into a stream by writing all bytes representing the chunk at the end of the stream. More...
 
virtual const Ptr< Chunkdeserialize (MemoryInputStream &stream) const override
 Deserializes a chunk from a stream by reading the bytes at the current position of the stream. More...
 

Additional Inherited Members

- Static Public Attributes inherited from inet::ChunkSerializer
static b totalSerializedLength = b(0)
 
static b totalDeserializedLength = b(0)
 

Detailed Description

Converts between Ieee80211MacHeader and binary network byte order IEEE 802.11 mac header.

Constructor & Destructor Documentation

◆ Ieee80211MacHeaderSerializer()

inet::ieee80211::Ieee80211MacHeaderSerializer::Ieee80211MacHeaderSerializer ( )
inline
28 : FieldsChunkSerializer() {}

Member Function Documentation

◆ deserialize()

const Ptr< Chunk > inet::ieee80211::Ieee80211MacHeaderSerializer::deserialize ( MemoryInputStream stream) const
overrideprotectedvirtual

Deserializes a chunk from a stream by reading the bytes at the current position of the stream.

The current stream position is updated according to the length of the returned chunk.

Implements inet::FieldsChunkSerializer.

353 {
354  auto macHeader = makeShared<Ieee80211MacHeader>();
355  uint8_t subType = stream.readUint4();
356  uint8_t frameType = stream.readNBitsToUint64Be(2);
357  uint8_t protocolVersion = stream.readNBitsToUint64Be(2);
358  macHeader->setType(protocolVersion, frameType, subType);
359  bool order = stream.readBit();
360  macHeader->setOrder(order);
361  macHeader->setProtectedFrame(stream.readBit());
362  macHeader->setMoreData(stream.readBit());
363  macHeader->setPowerMgmt(stream.readBit());
364  macHeader->setRetry(stream.readBit());
365  macHeader->setMoreFragments(stream.readBit());
366  macHeader->setFromDS(stream.readBit());
367  macHeader->setToDS(stream.readBit());
368  Ieee80211FrameType type = macHeader->getType();
369  switch (type) {
374  case ST_PROBEREQUEST:
375  case ST_PROBERESPONSE:
376  case ST_BEACON:
377  case ST_ATIM:
378  case ST_DISASSOCIATION:
379  case ST_AUTHENTICATION:
380  case ST_DEAUTHENTICATION:
381  case ST_NOACKACTION: {
382  auto mgmtHeader = makeShared<Ieee80211MgmtHeader>();
383  copyBasicFields(mgmtHeader, macHeader);
384  mgmtHeader->setDurationField(SimTime(stream.readUint16Le(), SIMTIME_US));
385  mgmtHeader->setReceiverAddress(stream.readMacAddress());
386  mgmtHeader->setTransmitterAddress(stream.readMacAddress());
387  mgmtHeader->setAddress3(stream.readMacAddress());
388  mgmtHeader->setFragmentNumber(stream.readUint4());
389  mgmtHeader->setSequenceNumber(SequenceNumberCyclic(stream.readNBitsToUint64Be(12)));
390  if (order)
391  stream.readUint32Be();
392  return mgmtHeader;
393  }
394  case ST_ACTION: {
395  auto actionFrame = makeShared<Ieee80211ActionFrame>();
396  copyBasicFields(actionFrame, macHeader);
397  actionFrame->setDurationField(SimTime(stream.readUint16Le(), SIMTIME_US));
398  actionFrame->setReceiverAddress(stream.readMacAddress());
399  actionFrame->setTransmitterAddress(stream.readMacAddress());
400  actionFrame->setAddress3(stream.readMacAddress());
401  actionFrame->setFragmentNumber(stream.readUint4());
402  actionFrame->setSequenceNumber(SequenceNumberCyclic(stream.readNBitsToUint64Be(12)));
403  if (order)
404  stream.readUint32Be();
405  actionFrame->setCategory(stream.readByte());
406  switch (actionFrame->getCategory()) {
407  case 3: {
408  uint8_t blockAckAction = stream.readByte();
409  switch (blockAckAction) {
410  case 0: {
411  auto addbaRequest = makeShared<Ieee80211AddbaRequest>();
412  copyBasicFields(addbaRequest, macHeader);
413  copyActionFrameFields(addbaRequest, actionFrame);
414  addbaRequest->setBlockAckAction(blockAckAction);
415  addbaRequest->setDialogToken(stream.readByte());
416  addbaRequest->setAMsduSupported(stream.readBit());
417  addbaRequest->setBlockAckPolicy(stream.readBit());
418  addbaRequest->setTid(stream.readUint4());
419  addbaRequest->setBufferSize(stream.readNBitsToUint64Be(10));
420  addbaRequest->setBlockAckTimeoutValue(SimTime(stream.readUint16Be() * 1024, SIMTIME_US));
421  addbaRequest->set_fragmentNumber(stream.readUint4());
422  addbaRequest->setStartingSequenceNumber(SequenceNumberCyclic(stream.readNBitsToUint64Be(12)));
423  return addbaRequest;
424  }
425  case 1: {
426  auto addbaResponse = makeShared<Ieee80211AddbaResponse>();
427  copyBasicFields(addbaResponse, macHeader);
428  copyActionFrameFields(addbaResponse, actionFrame);
429  addbaResponse->setBlockAckAction(blockAckAction);
430  addbaResponse->setDialogToken(stream.readByte());
431  addbaResponse->setStatusCode(stream.readUint16Be());
432  addbaResponse->setAMsduSupported(stream.readBit());
433  addbaResponse->setBlockAckPolicy(stream.readBit());
434  addbaResponse->setTid(stream.readUint4());
435  addbaResponse->setBufferSize(stream.readNBitsToUint64Be(10));
436  addbaResponse->setBlockAckTimeoutValue(SimTime(stream.readUint16Be() * 1024, SIMTIME_US));
437  return addbaResponse;
438  }
439  case 2: {
440  auto delba = makeShared<Ieee80211Delba>();
441  copyBasicFields(delba, macHeader);
442  delba->setBlockAckAction(blockAckAction);
443  delba->setReserved(stream.readNBitsToUint64Be(11));
444  delba->setInitiator(stream.readBit());
445  delba->setTid(stream.readUint4());
446  delba->setReasonCode(stream.readUint16Be());
447  return delba;
448  }
449  default:
450  actionFrame->markIncorrect();
451  return actionFrame;
452  }
453  break;
454  }
455  default: {
456  actionFrame->markIncorrect();
457  return actionFrame;
458  }
459  }
460  }
461  case ST_RTS: {
462  auto rtsFrame = makeShared<Ieee80211RtsFrame>();
463  copyBasicFields(rtsFrame, macHeader);
464  rtsFrame->setDurationField(SimTime(stream.readUint16Le(), SIMTIME_US));
465  rtsFrame->setReceiverAddress(stream.readMacAddress());
466  rtsFrame->setTransmitterAddress(stream.readMacAddress());
467  return rtsFrame;
468  }
469  case ST_CTS: {
470  auto ctsFrame = makeShared<Ieee80211CtsFrame>();
471  copyBasicFields(ctsFrame, macHeader);
472  ctsFrame->setDurationField(SimTime(stream.readUint16Le(), SIMTIME_US));
473  ctsFrame->setReceiverAddress(stream.readMacAddress());
474  return ctsFrame;
475  }
476  case ST_ACK: {
477  auto ackFrame = makeShared<Ieee80211AckFrame>();
478  copyBasicFields(ackFrame, macHeader);
479  ackFrame->setDurationField(SimTime(stream.readUint16Le(), SIMTIME_US));
480  ackFrame->setReceiverAddress(stream.readMacAddress());
481  return ackFrame;
482  }
483  case ST_BLOCKACK_REQ: {
484  auto blockAckReq = makeShared<Ieee80211BlockAckReq>();
485  copyBasicFields(blockAckReq, macHeader);
486  blockAckReq->setDurationField(SimTime(stream.readUint16Le(), SIMTIME_US));
487  blockAckReq->setReceiverAddress(stream.readMacAddress());
488  blockAckReq->setTransmitterAddress(stream.readMacAddress());
489  blockAckReq->setBarAckPolicy(stream.readBit());
490  bool multiTid = stream.readBit();
491  bool compressedBitmap = stream.readBit();
492  blockAckReq->setMultiTid(multiTid);
493  blockAckReq->setCompressedBitmap(compressedBitmap);
494  blockAckReq->setReserved(stream.readNBitsToUint64Be(9));
495  if (!multiTid && !compressedBitmap) {
496  auto basicBlockAckReq = makeShared<Ieee80211BasicBlockAckReq>();
497  copyBasicFields(basicBlockAckReq, macHeader);
498  copyBlockAckReqFrameFields(basicBlockAckReq, blockAckReq);
499  basicBlockAckReq->setTidInfo(stream.readUint4());
500  basicBlockAckReq->setFragmentNumber(stream.readUint32Be());
501  stream.readUint64Be();
502  basicBlockAckReq->setStartingSequenceNumber(SequenceNumberCyclic(stream.readUint64Be()));
503  return basicBlockAckReq;
504  }
505  else if (!multiTid && compressedBitmap) {
506  auto compressedBlockAckReq = makeShared<Ieee80211CompressedBlockAckReq>();
507  copyBasicFields(compressedBlockAckReq, macHeader);
508  copyBlockAckReqFrameFields(compressedBlockAckReq, blockAckReq);
509  compressedBlockAckReq->setTidInfo(stream.readUint4());
510  compressedBlockAckReq->setFragmentNumber(stream.readUint32Be());
511  stream.readUint64Be();
512  compressedBlockAckReq->setStartingSequenceNumber(SequenceNumberCyclic(stream.readUint64Be()));
513  return compressedBlockAckReq;
514  }
515  else
516  blockAckReq->markIncorrect();
517  return blockAckReq;
518  }
519  case ST_BLOCKACK: {
520  auto blockAck = makeShared<Ieee80211BlockAck>();
521  copyBasicFields(blockAck, macHeader);
522  blockAck->setDurationField(SimTime(stream.readUint16Le(), SIMTIME_US));
523  blockAck->setReceiverAddress(stream.readMacAddress());
524  blockAck->setTransmitterAddress(stream.readMacAddress());
525  blockAck->setBlockAckPolicy(stream.readBit());
526  bool multiTid = stream.readBit();
527  bool compressedBitmap = stream.readBit();
528  blockAck->setMultiTid(multiTid);
529  blockAck->setCompressedBitmap(compressedBitmap);
530  blockAck->setReserved(stream.readNBitsToUint64Be(9));
531  if (!multiTid && !compressedBitmap) {
532  auto basicBlockAck = makeShared<Ieee80211BasicBlockAck>();
533  copyBasicFields(basicBlockAck, macHeader);
534  copyBlockAckFrameFields(basicBlockAck, blockAck);
535  basicBlockAck->setTidInfo(stream.readUint4());
536  basicBlockAck->setStartingSequenceNumber(SequenceNumberCyclic(stream.readUint16Be()));
537  for (size_t i = 0; i < 64; ++i) {
538  std::vector<uint8_t> bytes;
539  bytes.push_back(stream.readByte());
540  bytes.push_back(stream.readByte());
541  BitVector *blockAckBitmap = new BitVector(bytes);
542  basicBlockAck->setBlockAckBitmap(i, *blockAckBitmap);
543  }
544  return basicBlockAck;
545  }
546  else if (!multiTid && compressedBitmap) {
547  auto compressedBlockAck = makeShared<Ieee80211CompressedBlockAck>();
548  copyBasicFields(compressedBlockAck, macHeader);
549  copyBlockAckFrameFields(compressedBlockAck, blockAck);
550 
551  compressedBlockAck->setTidInfo(stream.readUint4());
552  compressedBlockAck->setStartingSequenceNumber(SequenceNumberCyclic(stream.readUint16Be()));
553  std::vector<uint8_t> bytes;
554  for (size_t i = 0; i < 8; ++i) {
555  bytes.push_back(stream.readByte());
556  }
557  compressedBlockAck->setBlockAckBitmap(*(new BitVector(bytes)));
558  return compressedBlockAck;
559  }
560  else {
561  blockAck->markIncorrect();
562  return blockAck;
563  }
564  return blockAck;
565 
566  }
567  case ST_DATA_WITH_QOS:
568  case ST_DATA: {
569  auto dataHeader = makeShared<Ieee80211DataHeader>();
570  copyBasicFields(dataHeader, macHeader);
571  dataHeader->setDurationField(SimTime(stream.readUint16Le(), SIMTIME_US));
572  dataHeader->setReceiverAddress(stream.readMacAddress());
573  dataHeader->setTransmitterAddress(stream.readMacAddress());
574  dataHeader->setAddress3(stream.readMacAddress());
575  dataHeader->setFragmentNumber(stream.readUint4());
576  dataHeader->setSequenceNumber(SequenceNumberCyclic(stream.readNBitsToUint64Be(12)));
577  if (dataHeader->getFromDS() && dataHeader->getToDS())
578  dataHeader->setAddress4(stream.readMacAddress());
579  if (type == ST_DATA_WITH_QOS) {
580  dataHeader->setTid(stream.readUint4());
581  stream.readBit();
582  dataHeader->setAckPolicy(static_cast<AckPolicy>(stream.readNBitsToUint64Be(2)));
583  dataHeader->setAMsduPresent(stream.readBit());
584  stream.readByte();
585  }
586  return dataHeader;
587  }
588  case ST_PSPOLL:
589  case ST_LBMS_REQUEST:
590  case ST_LBMS_REPORT: {
591  return macHeader;
592  }
593  default: {
594  macHeader->markIncorrect();
595  return macHeader;
596  }
597  }
598 }

◆ serialize()

void inet::ieee80211::Ieee80211MacHeaderSerializer::serialize ( MemoryOutputStream stream,
const Ptr< const Chunk > &  chunk 
) const
overrideprotectedvirtual

Serializes a chunk into a stream by writing all bytes representing the chunk at the end of the stream.

Implements inet::FieldsChunkSerializer.

131 {
132  B startPos = stream.getLength();
133  auto macHeader = dynamicPtrCast<const Ieee80211MacHeader>(chunk);
134  stream.writeUint4(macHeader->getSubType());
135  stream.writeNBitsOfUint64Be(macHeader->getFrameType(), 2);
136  stream.writeNBitsOfUint64Be(macHeader->getProtocolVersion(), 2);
137  stream.writeBit(macHeader->getOrder());
138  stream.writeBit(macHeader->getProtectedFrame());
139  stream.writeBit(macHeader->getMoreData());
140  stream.writeBit(macHeader->getPowerMgmt());
141  stream.writeBit(macHeader->getRetry());
142  stream.writeBit(macHeader->getMoreFragments());
143  stream.writeBit(macHeader->getFromDS());
144  stream.writeBit(macHeader->getToDS());
145  Ieee80211FrameType type = macHeader->getType();
146  switch (type) {
151  case ST_PROBEREQUEST:
152  case ST_PROBERESPONSE:
153  case ST_BEACON:
154  case ST_ATIM:
155  case ST_DISASSOCIATION:
156  case ST_AUTHENTICATION:
157  case ST_DEAUTHENTICATION:
158  case ST_ACTION:
159  case ST_NOACKACTION: {
160  auto mgmtHeader = dynamicPtrCast<const Ieee80211MgmtHeader>(chunk);
161  stream.writeUint16Le(mgmtHeader->getDurationField().inUnit(SIMTIME_US));
162  stream.writeMacAddress(mgmtHeader->getReceiverAddress());
163  stream.writeMacAddress(mgmtHeader->getTransmitterAddress());
164  stream.writeMacAddress(mgmtHeader->getAddress3());
165  stream.writeUint4(mgmtHeader->getFragmentNumber());
166  stream.writeNBitsOfUint64Be(mgmtHeader->getSequenceNumber().get(), 12);
167  if (mgmtHeader->getOrder())
168  stream.writeUint32Be(0);
169  if (type == ST_ACTION) {
170  auto actionFrame = dynamicPtrCast<const Ieee80211ActionFrame>(chunk);
171  switch (actionFrame->getCategory()) {
172  case 3: {
173  stream.writeByte(actionFrame->getCategory());
174  switch (actionFrame->getBlockAckAction()) {
175  case 0: {
176  auto addbaRequest = dynamicPtrCast<const Ieee80211AddbaRequest>(chunk);
177  stream.writeByte(addbaRequest->getBlockAckAction());
178  stream.writeByte(addbaRequest->getDialogToken());
179  stream.writeBit(addbaRequest->getAMsduSupported());
180  stream.writeBit(addbaRequest->getBlockAckPolicy());
181  stream.writeUint4(addbaRequest->getTid());
182  stream.writeNBitsOfUint64Be(addbaRequest->getBufferSize(), 10);
183  stream.writeUint16Be(addbaRequest->getBlockAckTimeoutValue().inUnit(SIMTIME_US) / 1024);
184  stream.writeUint4(addbaRequest->get_fragmentNumber());
185  stream.writeNBitsOfUint64Be(addbaRequest->getStartingSequenceNumber().get(), 12);
186  ASSERT(stream.getLength() - startPos == addbaRequest->getChunkLength());
187  break;
188  }
189  case 1: {
190  auto addbaResponse = dynamicPtrCast<const Ieee80211AddbaResponse>(chunk);
191  stream.writeByte(addbaResponse->getBlockAckAction());
192  stream.writeByte(addbaResponse->getDialogToken());
193  stream.writeUint16Be(addbaResponse->getStatusCode());
194  stream.writeBit(addbaResponse->getAMsduSupported());
195  stream.writeBit(addbaResponse->getBlockAckPolicy());
196  stream.writeUint4(addbaResponse->getTid());
197  stream.writeNBitsOfUint64Be(addbaResponse->getBufferSize(), 10);
198  stream.writeUint16Be(addbaResponse->getBlockAckTimeoutValue().inUnit(SIMTIME_US) / 1024);
199  ASSERT(stream.getLength() - startPos == addbaResponse->getChunkLength());
200  break;
201  }
202  case 2: {
203  auto delba = dynamicPtrCast<const Ieee80211Delba>(chunk);
204  stream.writeByte(delba->getBlockAckAction());
205  stream.writeNBitsOfUint64Be(delba->getReserved(), 11);
206  stream.writeBit(delba->getInitiator());
207  stream.writeUint4(delba->getTid());
208  stream.writeUint16Be(delba->getReasonCode());
209  ASSERT(stream.getLength() - startPos == delba->getChunkLength());
210  break;
211  }
212  default:
213  throw cRuntimeError("Ieee80211MacHeaderSerializer: cannot serialize the Ieee80211ActionFrame frame, blockAckAction %d not supported.", actionFrame->getBlockAckAction());
214  }
215  break;
216  }
217  default:
218  throw cRuntimeError("Ieee80211MacHeaderSerializer: cannot serialize the Ieee80211ActionFrame frame, category %d not supported.", actionFrame->getCategory());
219  }
220  break;
221  }
222  else
223  ASSERT(stream.getLength() - startPos == mgmtHeader->getChunkLength());
224  break;
225  }
226  case ST_RTS: {
227  auto rtsFrame = dynamicPtrCast<const Ieee80211RtsFrame>(chunk);
228  stream.writeUint16Le(rtsFrame->getDurationField().inUnit(SIMTIME_US));
229  stream.writeMacAddress(rtsFrame->getReceiverAddress());
230  stream.writeMacAddress(rtsFrame->getTransmitterAddress());
231  ASSERT(stream.getLength() - startPos == rtsFrame->getChunkLength());
232  break;
233  }
234  case ST_CTS: {
235  auto ctsFrame = dynamicPtrCast<const Ieee80211CtsFrame>(chunk);
236  stream.writeUint16Le(ctsFrame->getDurationField().inUnit(SIMTIME_US));
237  stream.writeMacAddress(ctsFrame->getReceiverAddress());
238  ASSERT(stream.getLength() - startPos == ctsFrame->getChunkLength());
239  break;
240  }
241  case ST_ACK: {
242  auto ackFrame = dynamicPtrCast<const Ieee80211AckFrame>(chunk);
243  stream.writeUint16Le(ackFrame->getDurationField().inUnit(SIMTIME_US));
244  stream.writeMacAddress(ackFrame->getReceiverAddress());
245  ASSERT(stream.getLength() - startPos == ackFrame->getChunkLength());
246  break;
247  }
248  case ST_BLOCKACK_REQ: {
249  auto blockAckReq = dynamicPtrCast<const Ieee80211BlockAckReq>(chunk);
250  stream.writeUint16Le(blockAckReq->getDurationField().inUnit(SIMTIME_US));
251  stream.writeMacAddress(blockAckReq->getReceiverAddress());
252  stream.writeMacAddress(blockAckReq->getTransmitterAddress());
253  stream.writeBit(blockAckReq->getBarAckPolicy());
254  bool multiTid = blockAckReq->getMultiTid();
255  bool compressedBitmap = blockAckReq->getCompressedBitmap();
256  stream.writeBit(multiTid);
257  stream.writeBit(compressedBitmap);
258  stream.writeNBitsOfUint64Be(blockAckReq->getReserved(), 9);
259  if (!multiTid && !compressedBitmap) {
260  auto basicBlockAckReq = dynamicPtrCast<const Ieee80211BasicBlockAckReq>(chunk);
261  stream.writeUint4(basicBlockAckReq->getTidInfo());
262  stream.writeUint32Be(basicBlockAckReq->getFragmentNumber());
263  stream.writeUint64Be(0);
264  stream.writeUint64Be(basicBlockAckReq->getStartingSequenceNumber().get());
265  ASSERT(stream.getLength() - startPos == basicBlockAckReq->getChunkLength());
266  }
267  else if (!multiTid && compressedBitmap) {
268  auto compressedBlockAckReq = dynamicPtrCast<const Ieee80211CompressedBlockAckReq>(chunk);
269  stream.writeUint4(compressedBlockAckReq->getTidInfo());
270  stream.writeUint32Be(compressedBlockAckReq->getFragmentNumber());
271  stream.writeUint64Be(0);
272  stream.writeUint64Be(compressedBlockAckReq->getStartingSequenceNumber().get());
273  ASSERT(stream.getLength() - startPos == compressedBlockAckReq->getChunkLength());
274  }
275  else if (multiTid && compressedBitmap) {
276  throw cRuntimeError("Ieee80211MacHeaderSerializer: cannot serialize the frame, Ieee80211MultiTidBlockAckReq unimplemented.");
277  }
278  else
279  throw cRuntimeError("Ieee80211MacHeaderSerializer: cannot serialize the frame, multiTid = 1 && compressedBitmap = 0 is reserved.");
280  break;
281  }
282  case ST_BLOCKACK: {
283  auto blockAck = dynamicPtrCast<const Ieee80211BlockAck>(chunk);
284  stream.writeUint16Le(blockAck->getDurationField().inUnit(SIMTIME_US));
285  stream.writeMacAddress(blockAck->getReceiverAddress());
286  stream.writeMacAddress(blockAck->getTransmitterAddress());
287  stream.writeBit(blockAck->getBlockAckPolicy());
288  bool multiTid = blockAck->getMultiTid();
289  bool compressedBitmap = blockAck->getCompressedBitmap();
290  stream.writeBit(multiTid);
291  stream.writeBit(compressedBitmap);
292  stream.writeNBitsOfUint64Be(blockAck->getReserved(), 9);
293  if (!multiTid && !compressedBitmap) {
294  auto basicBlockAck = dynamicPtrCast<const Ieee80211BasicBlockAck>(chunk);
295  stream.writeUint4(basicBlockAck->getTidInfo());
296  stream.writeUint16Be(basicBlockAck->getStartingSequenceNumber().get());
297  for (size_t i = 0; i < 64; ++i) {
298  stream.writeByte(basicBlockAck->getBlockAckBitmap(i).getBytes()[0]);
299  stream.writeByte(basicBlockAck->getBlockAckBitmap(i).getBytes()[1]);
300  }
301  ASSERT(stream.getLength() - startPos == basicBlockAck->getChunkLength());
302  }
303  else if (!multiTid && compressedBitmap) {
304  auto compressedBlockAck = dynamicPtrCast<const Ieee80211CompressedBlockAck>(chunk);
305  stream.writeUint4(compressedBlockAck->getTidInfo());
306  stream.writeUint16Be(compressedBlockAck->getStartingSequenceNumber().get());
307  for (size_t i = 0; i < 8; ++i) {
308  stream.writeByte(compressedBlockAck->getBlockAckBitmap().getBytes()[i]);
309  }
310  ASSERT(stream.getLength() - startPos == compressedBlockAck->getChunkLength());
311  }
312  else if (multiTid && compressedBitmap) {
313  throw cRuntimeError("Ieee80211MacHeaderSerializer: cannot serialize the frame, Ieee80211MultiTidBlockAck unimplemented.");
314  }
315  else {
316  throw cRuntimeError("Ieee80211MacHeaderSerializer: cannot serialize the frame, multiTid = 1 && compressedBitmap = 0 is reserved.");
317  }
318  break;
319 
320  }
321  case ST_DATA_WITH_QOS:
322  case ST_DATA: {
323  auto dataHeader = dynamicPtrCast<const Ieee80211DataHeader>(chunk);
324  stream.writeUint16Le(dataHeader->getDurationField().inUnit(SIMTIME_US));
325  stream.writeMacAddress(dataHeader->getReceiverAddress());
326  stream.writeMacAddress(dataHeader->getTransmitterAddress());
327  stream.writeMacAddress(dataHeader->getAddress3());
328  stream.writeUint4(dataHeader->getFragmentNumber());
329  stream.writeNBitsOfUint64Be(dataHeader->getSequenceNumber().get(), 12);
330  if (dataHeader->getFromDS() && dataHeader->getToDS())
331  stream.writeMacAddress(dataHeader->getAddress4());
332  if (type == ST_DATA_WITH_QOS) {
333  stream.writeUint4(dataHeader->getTid());
334  stream.writeBit(true);
335  stream.writeNBitsOfUint64Be(dataHeader->getAckPolicy(), 2);
336  stream.writeBit(dataHeader->getAMsduPresent());
337  stream.writeByte(0);
338  }
339  ASSERT(stream.getLength() - startPos == dataHeader->getChunkLength());
340  break;
341  }
342  case ST_PSPOLL:
343  case ST_LBMS_REQUEST:
344  case ST_LBMS_REPORT: {
345  break;
346  }
347  default:
348  throw cRuntimeError("Ieee80211Serializer: cannot serialize the frame, type %d not supported.", type);
349  }
350 }

The documentation for this class was generated from the following files:
inet::ieee80211::ST_NOACKACTION
@ ST_NOACKACTION
Definition: Ieee80211Frame_m.h:161
inet::ieee80211::ST_ATIM
@ ST_ATIM
Definition: Ieee80211Frame_m.h:156
inet::ieee80211::ST_DATA
@ ST_DATA
Definition: Ieee80211Frame_m.h:168
inet::ieee80211::ST_PSPOLL
@ ST_PSPOLL
Definition: Ieee80211Frame_m.h:162
inet::ieee80211::ST_PROBEREQUEST
@ ST_PROBEREQUEST
Definition: Ieee80211Frame_m.h:153
inet::ieee80211::ST_ACK
@ ST_ACK
Definition: Ieee80211Frame_m.h:165
inet::ieee80211::ST_ACTION
@ ST_ACTION
Definition: Ieee80211Frame_m.h:160
inet::ieee80211::ST_BLOCKACK
@ ST_BLOCKACK
Definition: Ieee80211Frame_m.h:167
inet::ieee80211::ST_LBMS_REPORT
@ ST_LBMS_REPORT
Definition: Ieee80211Frame_m.h:171
inet::ieee80211::ST_REASSOCIATIONRESPONSE
@ ST_REASSOCIATIONRESPONSE
Definition: Ieee80211Frame_m.h:152
inet::ieee80211::ST_ASSOCIATIONREQUEST
@ ST_ASSOCIATIONREQUEST
Definition: Ieee80211Frame_m.h:149
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::ieee80211::ST_AUTHENTICATION
@ ST_AUTHENTICATION
Definition: Ieee80211Frame_m.h:158
inet::ieee80211::ST_DEAUTHENTICATION
@ ST_DEAUTHENTICATION
Definition: Ieee80211Frame_m.h:159
type
removed type
Definition: IUdp-gates.txt:7
inet::ieee80211::ST_BEACON
@ ST_BEACON
Definition: Ieee80211Frame_m.h:155
inet::ieee80211::ST_PROBERESPONSE
@ ST_PROBERESPONSE
Definition: Ieee80211Frame_m.h:154
inet::ieee80211::ST_BLOCKACK_REQ
@ ST_BLOCKACK_REQ
Definition: Ieee80211Frame_m.h:166
inet::ieee80211::ST_DISASSOCIATION
@ ST_DISASSOCIATION
Definition: Ieee80211Frame_m.h:157
inet::ieee80211::ST_DATA_WITH_QOS
@ ST_DATA_WITH_QOS
Definition: Ieee80211Frame_m.h:169
inet::ieee80211::ST_REASSOCIATIONREQUEST
@ ST_REASSOCIATIONREQUEST
Definition: Ieee80211Frame_m.h:151
inet::ieee80211::ST_ASSOCIATIONRESPONSE
@ ST_ASSOCIATIONRESPONSE
Definition: Ieee80211Frame_m.h:150
inet::ieee80211::AckPolicy
AckPolicy
Enum generated from inet/linklayer/ieee80211/mac/Ieee80211Frame.msg:92 by opp_msgtool.
Definition: Ieee80211Frame_m.h:192
inet::ieee80211::ST_CTS
@ ST_CTS
Definition: Ieee80211Frame_m.h:164
inet::ieee80211::ST_LBMS_REQUEST
@ ST_LBMS_REQUEST
Definition: Ieee80211Frame_m.h:170
inet::ieee80211::Ieee80211FrameType
Ieee80211FrameType
Enum generated from inet/linklayer/ieee80211/mac/Ieee80211Frame.msg:56 by opp_msgtool.
Definition: Ieee80211Frame_m.h:148
inet::ieee80211::ST_RTS
@ ST_RTS
Definition: Ieee80211Frame_m.h:163