EMANE  1.0.1
downstreampacket.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014,2016 - Adjacent Link LLC, Bridgewater,
3  * New Jersey
4  * Copyright (c) 2008 - DRS CenGen, LLC, Columbia, Maryland
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  * * Neither the name of DRS CenGen, LLC nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "emane/downstreampacket.h"
36 #include "emane/utils/vectorio.h"
37 #include "emane/net.h"
38 #include "emane/event.h"
39 
40 #include <string>
41 #include <deque>
42 #include <list>
43 
44 class EMANE::DownstreamPacket::Implementation
45 {
46 public:
47  Implementation():
48  pShared_{std::make_shared<Shared>()}{}
49 
50  Implementation(const PacketInfo & info, const void * buf, size_t size):
51  pShared_{std::make_shared<Shared>()}
52  {
53  const unsigned char * c = static_cast<const unsigned char *>(buf);
54  pShared_->segment_ = PacketSegment(&c[0],&c[size]);
55  pShared_->info_ = info;
56  totalLengthBytes_ += size;
57  }
58 
59  void prepend(const void * buf, size_t size)
60  {
61  const unsigned char * c = static_cast<const unsigned char *>(buf);
62 
63  segments_.emplace_front(&c[0],&c[size]);
64 
65  totalLengthBytes_ += size;
66  }
67 
68  void prependLengthPrefixFraming(std::uint16_t u16Length)
69  {
70  std::uint16_t u16LengthNet{HTONS(u16Length)};
71 
72  auto c = reinterpret_cast<const std::uint8_t *>(&u16LengthNet);
73 
74  segments_.emplace_front(&c[0],&c[sizeof(u16Length)]);
75 
76  totalLengthBytes_ += sizeof(u16Length);
77  }
78 
79  size_t length() const
80  {
81  return totalLengthBytes_;
82  }
83 
84  const PacketInfo & getPacketInfo() const
85  {
86  return pShared_->info_;
87  }
88 
90  {
91  Utils::VectorIO vectorIO{};
92 
93  vectorIO.reserve(segments_.size() + 1);
94 
95  for(const auto & segment : segments_)
96  {
97  vectorIO.push_back({reinterpret_cast<std::uint8_t *>(const_cast<char *>(segment.c_str())),
98  segment.size()});
99  }
100 
101  vectorIO.push_back({reinterpret_cast<std::uint8_t *>(const_cast<char *>(pShared_->segment_.c_str())),
102  pShared_->segment_.size()});
103 
104  return vectorIO;
105  }
106 
107  void attachEvent(NEMId nemId, const Event & event)
108  {
109  attachedEvents_.push_back(std::make_tuple(nemId,
110  event.getEventId(),
111  event.serialize()));
112  }
113 
115  {
116  return attachedEvents_;
117  }
118 
119 private:
120  using PacketSegment = std::string;
121  using Segments = std::deque<PacketSegment>;
122  using AttachedEvents = std::list<std::tuple<NEMId,EventId,std::string>>;
123 
124  class Shared
125  {
126  public:
127  PacketSegment segment_{};
128  PacketInfo info_{0,0,0,{}};
129  };
130 
131  Segments segments_{};
132  PacketSegment::size_type totalLengthBytes_{};
133  AttachedEvents attachedEvents_{};
134  std::shared_ptr<Shared> pShared_;
135 };
136 
138  const void * buf,
139  size_t size):
140  pImpl_{new Implementation{info,buf,size}}{}
141 
142 
144  pImpl_{new Implementation{*pkt.pImpl_}}{}
145 
147  pImpl_{std::move(pkt.pImpl_)}{}
148 
150 
152 {
153  pImpl_.reset(new Implementation{*pkt.pImpl_});
154  return *this;
155 }
156 
158 {
159  pImpl_ = std::move(pkt.pImpl_);
160  return *this;
161 }
162 
163 void EMANE::DownstreamPacket::prepend(const void * buf, size_t size)
164 {
165  pImpl_->prepend(buf,size);
166 }
167 
169 {
170  pImpl_->prependLengthPrefixFraming(u16Length);
171 }
172 
173 
175 {
176  return pImpl_->getVectorIO();
177 }
178 
180 {
181  return pImpl_->length();
182 }
183 
185 {
186  return pImpl_->getPacketInfo();
187 }
188 
190 {
191  pImpl_->attachEvent(nemId,event);
192 }
193 
196 {
197  return pImpl_->getEventSerializations();
198 }
const PacketInfo & getPacketInfo() const
void attachEvent(NEMId nemId, const Event &event)
Event interface is the base for all events.
Definition: event.h:46
void prepend(const void *buf, size_t size)
std::vector< iovec > VectorIO
Definition: vectorio.h:43
Store source, destination, creation time and priority information for a packet.
Definition: packetinfo.h:50
DownstreamPacket & operator=(const DownstreamPacket &pkt)
Specialized packet the allows downstream processing to add layer specific headers as the packet trave...
std::list< std::tuple< EMANE::NEMId, EMANE::EventId, Serialization > > EventSerializations
std::uint16_t NEMId
Definition: types.h:52
constexpr std::uint16_t HTONS(std::uint16_t x)
Definition: net.h:125
DownstreamPacket(const PacketInfo &info, const void *buf, size_t size)
const EventSerializations & getEventSerializations() const
Utils::VectorIO getVectorIO() const
void prependLengthPrefixFraming(std::uint16_t u16Length)