INET Framework for OMNeT++/OMNEST
inet::PimPacketSerializer Class Reference

Converts between PimPacket and binary (network byte order) PIM packets. More...

#include <PimPacketSerializer.h>

Inheritance diagram for inet::PimPacketSerializer:
inet::FieldsChunkSerializer inet::ChunkSerializer

Public Member Functions

 PimPacketSerializer ()
 
- 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 PimPacket and binary (network byte order) PIM packets.

Constructor & Destructor Documentation

◆ PimPacketSerializer()

inet::PimPacketSerializer::PimPacketSerializer ( )
inline
25 : FieldsChunkSerializer() {}

Member Function Documentation

◆ deserialize()

const Ptr< Chunk > inet::PimPacketSerializer::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.

218 {
219  auto pimPacket = makeShared<PimPacket>();
220  // PIM header common to all PIM messages:
221  // | PIM version (4 bits) | Type (4 bits) | Reserved (8 bits) | Checksum (16 bits) |
222  pimPacket->setVersion(stream.readNBitsToUint64Be(4));
223  pimPacket->setType(static_cast<PimPacketType>(stream.readNBitsToUint64Be(4)));
224  pimPacket->setReserved(stream.readByte());
225  pimPacket->setCrc(stream.readUint16Be());
226  pimPacket->setCrcMode(CRC_COMPUTED);
227  B length = B(4); // header length
228  switch (pimPacket->getType()) {
229  case Hello: {
230  auto pimHello = makeShared<PimHello>();
231  pimHello->setType(pimPacket->getType());
232  pimHello->setVersion(pimPacket->getVersion());
233  pimHello->setReserved(pimPacket->getReserved());
234  pimHello->setCrc(pimPacket->getCrc());
235  pimHello->setCrcMode(pimPacket->getCrcMode());
237  size_t i = 0;
238  while (stream.getRemainingLength().get() > 0) {
239  type = static_cast<PimHelloOptionType>(stream.readUint16Be());
240  switch (type) {
241  case Holdtime: {
242  uint16_t size = stream.readUint16Be();
243  if (size != 2)
244  pimHello->markIncorrect();
245  pimHello->setOptionsArraySize(++i);
246  HoldtimeOption *holdtimeOption = new HoldtimeOption();
247  holdtimeOption->setHoldTime(stream.readUint16Be());
248  pimHello->setOptions(i - 1, holdtimeOption);
249  length += B(6);
250  break;
251  }
252  case LANPruneDelay: {
253  uint16_t size = stream.readUint16Be();
254  bool T = stream.readBit(); // T bit
255  if (size != 4 || T)
256  pimHello->markIncorrect();
257  pimHello->setOptionsArraySize(++i);
258  LanPruneDelayOption *lanPruneDelayOption = new LanPruneDelayOption();
259  lanPruneDelayOption->setPropagationDelay(stream.readNBitsToUint64Be(15));
260  lanPruneDelayOption->setOverrideInterval(stream.readUint16Be());
261  pimHello->setOptions(i - 1, lanPruneDelayOption);
262  length += B(8);
263  break;
264  }
265  case DRPriority: {
266  uint16_t size = stream.readUint16Be();
267  if (size != 4)
268  pimHello->markIncorrect();
269  pimHello->setOptionsArraySize(++i);
270  DrPriorityOption *drPriorityOption = new DrPriorityOption();
271  drPriorityOption->setPriority(stream.readUint32Be());
272  pimHello->setOptions(i - 1, drPriorityOption);
273  length += B(8);
274  break;
275  }
276  case GenerationID: {
277  uint16_t size = stream.readUint16Be();
278  if (size != 4)
279  pimHello->markIncorrect();
280  pimHello->setOptionsArraySize(++i);
281  GenerationIdOption *generationIdOption = new GenerationIdOption();
282  generationIdOption->setGenerationID(stream.readUint32Be());
283  pimHello->setOptions(i - 1, generationIdOption);
284  length += B(8);
285  break;
286  }
287  default:
288  throw cRuntimeError("Cannot deserialize Hello options: type %d not supported.", type);
289  }
290  }
291  pimHello->setChunkLength(length);
292  return pimHello;
293  }
294  case Register: {
295  auto pimRegister = makeShared<PimRegister>();
296  pimRegister->setType(pimPacket->getType());
297  pimRegister->setVersion(pimPacket->getVersion());
298  pimRegister->setReserved(pimPacket->getReserved());
299  pimRegister->setCrc(pimPacket->getCrc());
300  pimRegister->setCrcMode(pimPacket->getCrcMode());
301  pimRegister->setB(stream.readBit());
302  pimRegister->setN(stream.readBit());
303  stream.readNBitsToUint64Be(30); // Reserved
304  length += B(4);
305  pimRegister->setChunkLength(length);
306  return pimRegister;
307  }
308  case RegisterStop: {
309  auto pimRegisterStop = makeShared<PimRegisterStop>();
310  pimRegisterStop->setType(pimPacket->getType());
311  pimRegisterStop->setVersion(pimPacket->getVersion());
312  pimRegisterStop->setReserved(pimPacket->getReserved());
313  pimRegisterStop->setCrc(pimPacket->getCrc());
314  pimRegisterStop->setCrcMode(pimPacket->getCrcMode());
315  deserializeEncodedGroupAddress(stream, pimRegisterStop, pimRegisterStop->getGroupAddressForUpdate());
317  deserializeEncodedUnicastAddress(stream, pimRegisterStop, pimRegisterStop->getSourceAddressForUpdate());
319  pimRegisterStop->setChunkLength(length);
320  return pimRegisterStop;
321  }
322  case GraftAck:
323  case Graft:
324  case JoinPrune: {
325  auto pimJoinPrune = makeShared<PimJoinPrune>();
326  if (pimPacket->getType() == Graft || pimPacket->getType() == GraftAck)
327  pimJoinPrune = makeShared<PimGraft>();
328  pimJoinPrune->setType(pimPacket->getType());
329  pimJoinPrune->setVersion(pimPacket->getVersion());
330  pimJoinPrune->setReserved(pimPacket->getReserved());
331  pimJoinPrune->setCrc(pimPacket->getCrc());
332  pimJoinPrune->setCrcMode(pimPacket->getCrcMode());
333  deserializeEncodedUnicastAddress(stream, pimJoinPrune, pimJoinPrune->getUpstreamNeighborAddressForUpdate());
335  pimJoinPrune->setReserved2(stream.readByte()); // Reserved
336  pimJoinPrune->setJoinPruneGroupsArraySize(stream.readByte());
337  pimJoinPrune->setHoldTime(stream.readUint16Be());
338  length += B(4);
339  if ((pimPacket->getType() == Graft || pimPacket->getType() == GraftAck) && pimJoinPrune->getHoldTime() != 0)
340  pimJoinPrune->markIncorrect();
341  for (size_t i = 0; i < pimJoinPrune->getJoinPruneGroupsArraySize(); ++i) {
342  deserializeEncodedGroupAddress(stream, pimJoinPrune, pimJoinPrune->getJoinPruneGroupsForUpdate(i).getGroupAddressForUpdate());
344  auto& joinPruneGroup = pimJoinPrune->getJoinPruneGroupsForUpdate(i);
345  joinPruneGroup.setJoinedSourceAddressArraySize(stream.readUint16Be());
346  joinPruneGroup.setPrunedSourceAddressArraySize(stream.readUint16Be());
347  length += B(4);
348  for (size_t k = 0; k < joinPruneGroup.getJoinedSourceAddressArraySize(); ++k) {
349  deserializeEncodedSourceAddress(stream, pimJoinPrune, joinPruneGroup.getJoinedSourceAddressForUpdate(k));
351  }
352  for (size_t k = 0; k < pimJoinPrune->getJoinPruneGroups(i).getPrunedSourceAddressArraySize(); ++k) {
353  deserializeEncodedSourceAddress(stream, pimJoinPrune, joinPruneGroup.getPrunedSourceAddressForUpdate(k));
355  }
356  }
357  pimJoinPrune->setChunkLength(length);
358  return pimJoinPrune;
359  }
360  case Assert: {
361  auto pimAssert = makeShared<PimAssert>();
362  pimAssert->setType(pimPacket->getType());
363  pimAssert->setVersion(pimPacket->getVersion());
364  pimAssert->setReserved(pimPacket->getReserved());
365  pimAssert->setCrc(pimPacket->getCrc());
366  pimAssert->setCrcMode(pimPacket->getCrcMode());
367  deserializeEncodedGroupAddress(stream, pimAssert, pimAssert->getGroupAddressForUpdate());
369  deserializeEncodedUnicastAddress(stream, pimAssert, pimAssert->getSourceAddressForUpdate());
371  pimAssert->setR(stream.readBit());
372  pimAssert->setMetricPreference(stream.readNBitsToUint64Be(31));
373  pimAssert->setMetric(stream.readUint32Be());
374  length += B(8);
375  return pimAssert;
376  }
377  case StateRefresh: {
378  auto pimStateRefresh = makeShared<PimStateRefresh>();
379  pimStateRefresh->setType(pimPacket->getType());
380  pimStateRefresh->setVersion(pimPacket->getVersion());
381  pimStateRefresh->setReserved(pimPacket->getReserved());
382  pimStateRefresh->setCrc(pimPacket->getCrc());
383  pimStateRefresh->setCrcMode(pimPacket->getCrcMode());
384  deserializeEncodedGroupAddress(stream, pimStateRefresh, pimStateRefresh->getGroupAddressForUpdate());
386  deserializeEncodedUnicastAddress(stream, pimStateRefresh, pimStateRefresh->getSourceAddressForUpdate());
388  deserializeEncodedUnicastAddress(stream, pimStateRefresh, pimStateRefresh->getOriginatorAddressForUpdate());
390  stream.readBit(); // R: The Rendezvous Point Tree bit. Set to 0 for PIM-DM. Ignored upon receipt.
391  pimStateRefresh->setMetricPreference(stream.readNBitsToUint64Be(31));
392  pimStateRefresh->setMetric(stream.readUint32Be());
393  pimStateRefresh->setMaskLen(stream.readByte());
394  pimStateRefresh->setTtl(stream.readByte());
395  pimStateRefresh->setP(stream.readBit());
396  pimStateRefresh->setN(stream.readBit());
397  pimStateRefresh->setO(stream.readBit());
398  pimStateRefresh->setReserved2(stream.readNBitsToUint64Be(5)); // Reserved
399  pimStateRefresh->setInterval(stream.readByte());
400  length += B(12);
401  return pimStateRefresh;
402  }
403  default:
404  throw cRuntimeError("Cannot serialize PIM packet: type %d not supported.", pimPacket->getType());
405  }
406 }

◆ serialize()

void inet::PimPacketSerializer::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.

102 {
103  const auto& pimPacket = staticPtrCast<const PimPacket>(chunk);
104  // PIM header common to all PIM messages:
105  // | PIM version (4 bits) | Type (4 bits) | Reserved (8 bits) | Checksum (16 bits) |
106  stream.writeNBitsOfUint64Be(pimPacket->getVersion(), 4);
107  stream.writeNBitsOfUint64Be(pimPacket->getType(), 4);
108  stream.writeByte(pimPacket->getReserved());
109  stream.writeUint16Be(pimPacket->getCrc());
110  switch (pimPacket->getType()) {
111  case Hello: {
112  const auto& pimHello = staticPtrCast<const PimHello>(chunk);
113  for (size_t i = 0; i < pimHello->getOptionsArraySize(); ++i) {
114  stream.writeUint16Be(pimHello->getOptions(i)->getType()); // type
115  switch (pimHello->getOptions(i)->getType()) {
116  case Holdtime: {
117  const HoldtimeOption *holdtimeOption = static_cast<const HoldtimeOption *>(pimHello->getOptions(i));
118  stream.writeUint16Be(2); // length
119  stream.writeUint16Be(holdtimeOption->getHoldTime());
120  break;
121  }
122  case LANPruneDelay: {
123  const LanPruneDelayOption *lanPruneDelayOption = static_cast<const LanPruneDelayOption *>(pimHello->getOptions(i));
124  stream.writeUint16Be(4); // length
125  stream.writeBit(0); // FIXME T bit missing
126  stream.writeNBitsOfUint64Be(lanPruneDelayOption->getPropagationDelay(), 15);
127  stream.writeUint16Be(lanPruneDelayOption->getOverrideInterval());
128  break;
129  }
130  case DRPriority: {
131  const DrPriorityOption *drPriorityOption = static_cast<const DrPriorityOption *>(pimHello->getOptions(i));
132  stream.writeUint16Be(4); // length
133  stream.writeUint32Be(drPriorityOption->getPriority());
134  break;
135  }
136  case GenerationID: {
137  const GenerationIdOption *generationIdOption = static_cast<const GenerationIdOption *>(pimHello->getOptions(i));
138  stream.writeUint16Be(4); // length
139  stream.writeUint32Be(generationIdOption->getGenerationID());
140  break;
141  }
142  default:
143  throw cRuntimeError("Cannot serialize Hello options: type %d not supported.", pimHello->getOptions(i)->getType());
144  }
145  }
146  break;
147  }
148  case Register: {
149  const auto& pimRegister = staticPtrCast<const PimRegister>(chunk);
150  stream.writeBit(pimRegister->getB());
151  stream.writeBit(pimRegister->getN());
152  stream.writeNBitsOfUint64Be(0, 30); // Reserved
153  break;
154  }
155  case RegisterStop: {
156  const auto& pimRegisterStop = staticPtrCast<const PimRegisterStop>(chunk);
157  serializeEncodedGroupAddress(stream, pimRegisterStop->getGroupAddress());
158  serializeEncodedUnicastAddress(stream, pimRegisterStop->getSourceAddress());
159  break;
160  }
161  case GraftAck:
162  case Graft:
163  case JoinPrune: {
164  const auto& pimJoinPrune = staticPtrCast<const PimJoinPrune>(chunk);
165  serializeEncodedUnicastAddress(stream, pimJoinPrune->getUpstreamNeighborAddress());
166  stream.writeByte(pimJoinPrune->getReserved2());
167  stream.writeByte(pimJoinPrune->getJoinPruneGroupsArraySize());
168  if (pimPacket->getType() == Graft || pimPacket->getType() == GraftAck)
169  stream.writeUint16Be(0);
170  else
171  stream.writeUint16Be(pimJoinPrune->getHoldTime());
172  for (size_t i = 0; i < pimJoinPrune->getJoinPruneGroupsArraySize(); ++i) {
173  auto& joinPruneGroups = pimJoinPrune->getJoinPruneGroups(i);
174  serializeEncodedGroupAddress(stream, joinPruneGroups.getGroupAddress());
175  stream.writeUint16Be(joinPruneGroups.getJoinedSourceAddressArraySize());
176  stream.writeUint16Be(joinPruneGroups.getPrunedSourceAddressArraySize());
177  for (size_t k = 0; k < joinPruneGroups.getJoinedSourceAddressArraySize(); ++k) {
178  serializeEncodedSourceAddress(stream, joinPruneGroups.getJoinedSourceAddress(k));
179  }
180  for (size_t k = 0; k < joinPruneGroups.getPrunedSourceAddressArraySize(); ++k) {
181  serializeEncodedSourceAddress(stream, joinPruneGroups.getPrunedSourceAddress(k));
182  }
183  }
184  break;
185  }
186  case Assert: {
187  const auto& pimAssert = staticPtrCast<const PimAssert>(chunk);
188  serializeEncodedGroupAddress(stream, pimAssert->getGroupAddress());
189  serializeEncodedUnicastAddress(stream, pimAssert->getSourceAddress());
190  stream.writeBit(pimAssert->getR());
191  stream.writeNBitsOfUint64Be(pimAssert->getMetricPreference(), 31);
192  stream.writeUint32Be(pimAssert->getMetric());
193  break;
194  }
195  case StateRefresh: {
196  const auto& pimStateRefresh = staticPtrCast<const PimStateRefresh>(chunk);
197  serializeEncodedGroupAddress(stream, pimStateRefresh->getGroupAddress());
198  serializeEncodedUnicastAddress(stream, pimStateRefresh->getSourceAddress());
199  serializeEncodedUnicastAddress(stream, pimStateRefresh->getOriginatorAddress());
200  stream.writeBit(pimStateRefresh->getR()); // R: The Rendezvous Point Tree bit. Set to 0 for PIM-DM. Ignored upon receipt.
201  stream.writeNBitsOfUint64Be(pimStateRefresh->getMetricPreference(), 31);
202  stream.writeUint32Be(pimStateRefresh->getMetric());
203  stream.writeByte(pimStateRefresh->getMaskLen());
204  stream.writeByte(pimStateRefresh->getTtl());
205  stream.writeBit(pimStateRefresh->getP());
206  stream.writeBit(pimStateRefresh->getN());
207  stream.writeBit(pimStateRefresh->getO());
208  stream.writeNBitsOfUint64Be(pimStateRefresh->getReserved2(), 5);
209  stream.writeByte(pimStateRefresh->getInterval());
210  break;
211  }
212  default:
213  throw cRuntimeError("Cannot serialize PIM packet: type %d not supported.", pimPacket->getType());
214  }
215 }

The documentation for this class was generated from the following files:
inet::GenerationID
@ GenerationID
Definition: PimPacket_m.h:126
inet::Register
@ Register
Definition: PimPacket_m.h:94
inet::PimHelloOptionType
PimHelloOptionType
Enum generated from inet/routing/pim/PimPacket.msg:41 by opp_msgtool.
Definition: PimPacket_m.h:122
inet::units::units::T
compose< Wb, pow< m, -2 > > T
Definition: Units.h:951
inet::Hello
@ Hello
Definition: PimPacket_m.h:93
inet::DRPriority
@ DRPriority
Definition: PimPacket_m.h:125
inet::ENCODED_GROUP_ADDRESS_LENGTH
const B ENCODED_GROUP_ADDRESS_LENGTH
Definition: PimPacket_m.h:70
inet::CRC_COMPUTED
@ CRC_COMPUTED
Definition: CrcMode_m.h:59
inet::LANPruneDelay
@ LANPruneDelay
Definition: PimPacket_m.h:124
inet::StateRefresh
@ StateRefresh
Definition: PimPacket_m.h:102
inet::RegisterStop
@ RegisterStop
Definition: PimPacket_m.h:95
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
type
removed type
Definition: IUdp-gates.txt:7
inet::Graft
@ Graft
Definition: PimPacket_m.h:99
inet::ENCODED_SOURCE_ADDRESS_LENGTH
const B ENCODED_SOURCE_ADDRESS_LENGTH
Definition: PimPacket_m.h:71
inet::physicallayer::k
const double k
Definition: Qam1024Modulation.cc:14
inet::PimPacketType
PimPacketType
Enum generated from inet/routing/pim/PimPacket.msg:27 by opp_msgtool.
Definition: PimPacket_m.h:92
inet::Assert
@ Assert
Definition: PimPacket_m.h:98
inet::ENCODED_UNICODE_ADDRESS_LENGTH
const B ENCODED_UNICODE_ADDRESS_LENGTH
Definition: PimPacket_m.h:69
inet::Holdtime
@ Holdtime
Definition: PimPacket_m.h:123
inet::GraftAck
@ GraftAck
Definition: PimPacket_m.h:100
inet::JoinPrune
@ JoinPrune
Definition: PimPacket_m.h:96