EMANE  1.2.1
commonphyheader.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013,2016 - Adjacent Link LLC, Bridgewater, New Jersey
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of Adjacent Link LLC nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "emane/commonphyheader.h"
34 #include "commonphyheader.pb.h"
35 
36 class EMANE::CommonPHYHeader::Implementation
37 {
38 public:
39  Implementation(RegistrationId registrationId,
40  std::uint16_t u16SubId,
41  std::uint16_t u16SequenceNumber,
42  std::uint64_t u64BandwidthHz,
43  const TimePoint & txTime,
44  const FrequencySegments & frequencySegments,
45  const Transmitters & transmitters,
46  const std::pair<double,bool> & optionalFixedAntennaGaindBi):
47  registrationId_{registrationId},
48  u16SubId_{u16SubId},
49  u16SequenceNumber_{u16SequenceNumber},
50  u64BandwidthHz_{u64BandwidthHz},
51  txTime_{txTime},
52  frequencySegments_{frequencySegments},
53  transmitters_{transmitters},
54  optionalFixedAntennaGaindBi_{optionalFixedAntennaGaindBi}{}
55 
57  {
58  return registrationId_;
59  }
60 
61  std::uint16_t getSubId() const
62  {
63  return u16SubId_;
64  }
65 
66  const std::pair<double,bool> & getOptionalFixedAntennaGaindBi() const
67  {
68  return optionalFixedAntennaGaindBi_;
69  }
70 
71  const TimePoint & getTxTime() const
72  {
73  return txTime_;
74  }
75 
76  std::uint64_t getBandwidthHz() const
77  {
78  return u64BandwidthHz_;
79  }
80 
81  std::uint16_t getSequenceNumber() const
82  {
83  return u16SequenceNumber_;
84  }
85 
87  {
88  return frequencySegments_;
89  }
90 
91  const Transmitters & getTransmitters() const
92  {
93  return transmitters_;
94  }
95 
96 private:
97  RegistrationId registrationId_;
98  std::uint16_t u16SubId_;
99  std::uint16_t u16SequenceNumber_;
100  std::uint64_t u64BandwidthHz_;
101  TimePoint txTime_;
102  FrequencySegments frequencySegments_;
103  Transmitters transmitters_;
104  std::pair<double,bool> optionalFixedAntennaGaindBi_;
105 };
106 
108 {
109  if(pkt.length() >= sizeof(decltype(pkt.stripLengthPrefixFraming())))
110  {
111  std::uint16_t u16HeaderLength{pkt.stripLengthPrefixFraming()};
112 
113  if(pkt.length() >= u16HeaderLength)
114  {
116 
117  if(!msg.ParseFromArray(pkt.get(),u16HeaderLength))
118  {
119  throw SerializationException("unable to deserialize CommonPHYHeader");
120  }
121 
122  Transmitters transmitters{};
123 
124  for(const auto & transmitter : msg.transmitters())
125  {
126  transmitters.push_back({static_cast<NEMId>(transmitter.nemid()),
127  transmitter.powerdbm()});
128  }
129 
130  FrequencySegments frequencySegments{};
131 
132  for(const auto & segment : msg.frequencysegments())
133  {
134  if(segment.has_powerdbm())
135  {
136  frequencySegments.push_back({segment.frequencyhz(),
137  segment.powerdbm(),
138  Microseconds(segment.durationmicroseconds()),
139  Microseconds(segment.offsetmicroseconds())});
140  }
141  else
142  {
143  frequencySegments.push_back({segment.frequencyhz(),
144  Microseconds(segment.durationmicroseconds()),
145  Microseconds(segment.offsetmicroseconds())});
146  }
147  }
148 
149  RegistrationId registrationId{static_cast<RegistrationId>(msg.registrationid())};
150  std::uint16_t u16SubId{static_cast<std::uint16_t>(msg.subid())};
151  std::uint16_t u16SequenceNumber{static_cast<std::uint16_t>(msg.sequencenumber())};
152  std::uint64_t u64BandwidthHz{msg.bandwidthhz()};
153  TimePoint txTime{static_cast<Microseconds>(msg.txtimemicroseconds())};
154  std::pair<double,bool> optionalFixedAntennaGaindBi{0,msg.has_fixedantennagain()};
155 
156  if(optionalFixedAntennaGaindBi.second)
157  {
158  optionalFixedAntennaGaindBi.first = msg.fixedantennagain();
159  }
160 
161  pImpl_.reset(new Implementation{registrationId,
162  u16SubId,
163  u16SequenceNumber,
164  u64BandwidthHz,
165  txTime,
166  frequencySegments,
167  transmitters,
168  optionalFixedAntennaGaindBi});
169 
170  }
171  else
172  {
173  throw SerializationException("CommonPHYHeader not large enough for header data");
174  }
175 
176  // strip common phy header from pkt
177  pkt.strip(u16HeaderLength);
178  }
179  else
180  {
181  throw SerializationException("CommonPHYHeader not large enough for header size data");
182  }
183 }
184 
185 
187  std::uint16_t u16SubId,
188  std::uint16_t u16SequenceNumber,
189  std::uint64_t u64BandwidthHz,
190  const TimePoint & txTime,
191  const FrequencySegments & frequencySegments,
192  const Transmitters & transmitters,
193  const std::pair<double,bool> & optionalFixedAntennaGaindBi):
194  pImpl_{new Implementation{registrationId,
195  u16SubId,
196  u16SequenceNumber,
197  u64BandwidthHz,
198  txTime,
199  frequencySegments,
200  transmitters,
201  optionalFixedAntennaGaindBi}}
202 {}
203 
204 
206  pImpl_(std::move(rvalue.pImpl_))
207 {}
208 
210 
212 {
213  return pImpl_->getRegistrationId();
214 }
215 
216 std::uint16_t EMANE::CommonPHYHeader::getSubId() const
217 {
218  return pImpl_->getSubId();
219 }
220 
221 const std::pair<double,bool> & EMANE::CommonPHYHeader::getOptionalFixedAntennaGaindBi() const
222 {
223  return pImpl_->getOptionalFixedAntennaGaindBi();
224 }
225 
226 
228 {
229  return pImpl_->getTxTime();
230 }
231 
232 
234 {
235  Microseconds start = Microseconds::zero();
236  Microseconds end = Microseconds::zero();
237 
238  for(const auto & segment: pImpl_->getFrequencySegments())
239  {
240  // the offset
241  const auto & offset = segment.getOffset();
242  const auto & duration = segment.getDuration();
243 
244  // duration position
245  const auto relative = offset + duration;
246 
247  // get the begin time
248  if(offset < start)
249  {
250  start = offset;
251  }
252 
253  // get the end time
254  if(relative > end)
255  {
256  end = relative;
257  }
258  }
259 
260  // the total duration with gaps/overlap
261  return end - start;
262 }
263 
264 
266 {
267  return pImpl_->getBandwidthHz();
268 }
269 
270 
272 {
273  return pImpl_->getSequenceNumber();
274 }
275 
276 
278 {
279  return pImpl_->getFrequencySegments();
280 }
281 
282 
284 {
285  return pImpl_->getTransmitters();
286 }
287 
289 {
291  msg.set_registrationid(pImpl_->getRegistrationId());
292  msg.set_subid(pImpl_->getSubId());
293  msg.set_sequencenumber(pImpl_->getSequenceNumber());
294  msg.set_bandwidthhz(pImpl_->getBandwidthHz());
295  msg.set_txtimemicroseconds(std::chrono::duration_cast<Microseconds>(pImpl_->getTxTime().time_since_epoch()).count());
296 
297  const auto & optionalFixedAntennaGaindBi = pImpl_->getOptionalFixedAntennaGaindBi();
298 
299  if(optionalFixedAntennaGaindBi.second)
300  {
301  msg.set_fixedantennagain(optionalFixedAntennaGaindBi.first);
302  }
303 
304  for(const auto & transmitter : pImpl_->getTransmitters())
305  {
306  auto pTransmitter = msg.add_transmitters();
307  pTransmitter->set_nemid(transmitter.getNEMId());
308  pTransmitter->set_powerdbm(transmitter.getPowerdBm());
309  }
310 
311  for(const auto & segment : pImpl_->getFrequencySegments())
312  {
313  auto pSegment = msg.add_frequencysegments();
314  pSegment->set_frequencyhz(segment.getFrequencyHz());
315  pSegment->set_offsetmicroseconds(segment.getOffset().count());
316  pSegment->set_durationmicroseconds(segment.getDuration().count());
317 
318  if(segment.getPowerdBm().second)
319  {
320  pSegment->set_powerdbm(segment.getPowerdBm().first);
321  }
322  }
323 
324  std::string sSerialization;
325 
326  if(!msg.SerializeToString(&sSerialization))
327  {
328  throw SerializationException("unable to serialize CommonPHYHeader");
329  }
330 
331  // prepend order is important
332  pkt.prepend(sSerialization.c_str(),sSerialization.size());
333 
334  pkt.prependLengthPrefixFraming(sSerialization.size());
335 }
336 
338 {
339  const auto & optionalFixedAntennaGaindBi =
340  pImpl_->getOptionalFixedAntennaGaindBi();
341 
342  Strings sFormat{{"regid: " + std::to_string( pImpl_->getRegistrationId())},
343  {"seq: " + std::to_string(pImpl_->getSequenceNumber())},
344  {"bandwidth: " + std::to_string(pImpl_->getBandwidthHz())},
345  {"fixed antenna gain: " + std::string(optionalFixedAntennaGaindBi.second ? "on" : "off")},
346  {"fixed antenna gain: " + std::to_string(optionalFixedAntennaGaindBi.first)},
347  {"tx time: " + std::to_string(std::chrono::duration_cast<DoubleSeconds>(pImpl_->getTxTime().time_since_epoch()).count())}};
348 
349  for(const auto & segment : pImpl_->getFrequencySegments())
350  {
351  sFormat.push_back("freq: " + std::to_string(segment.getFrequencyHz()));
352  sFormat.push_back("duration: " + std::to_string(segment.getDuration().count()));
353  sFormat.push_back("offset: " + std::to_string(segment.getOffset().count()));
354  if(segment.getPowerdBm().second)
355  {
356  sFormat.push_back("segment power: " + std::to_string(segment.getPowerdBm().first));
357  }
358  }
359 
360  for(const auto & transmitter : pImpl_->getTransmitters())
361  {
362  sFormat.push_back("src: " + std::to_string(transmitter.getNEMId()));
363  sFormat.push_back("transmitter power: " + std::to_string(transmitter.getPowerdBm()));
364  }
365 
366  return sFormat;
367 }
A Packet class that allows upstream processing to strip layer headers as the packet travels up the st...
SerializationException is thrown when an exception occurs during serialization or deserialization of ...
const std::pair< double, bool > & getOptionalFixedAntennaGaindBi() const
std::uint16_t stripLengthPrefixFraming()
size_t strip(size_t size)
CommonPHYHeader(RegistrationId registrationId, std::uint16_t subId, std::uint16_t u16SequenceNumber, std::uint64_t u64BandwidthHz, const TimePoint &txTime, const FrequencySegments &frequencySegments, const Transmitters &transmitters, const std::pair< double, bool > &optionalFixedAntennaGaindBi)
void prepend(const void *buf, size_t size)
std::uint64_t getBandwidthHz() const
void prependTo(DownstreamPacket &pkt) const
const TimePoint & getTxTime() const
The common physical layer header used to facilitate heterogeneous radio model experimentation.
Specialized packet the allows downstream processing to add layer specific headers as the packet trave...
std::uint16_t RegistrationId
Definition: types.h:59
const FrequencySegments & getFrequencySegments() const
std::chrono::microseconds Microseconds
Definition: types.h:45
std::uint16_t NEMId
Definition: types.h:52
std::list< std::string > Strings
Definition: types.h:66
std::uint16_t getSubId() const
const Transmitters & getTransmitters() const
const void * get() const
std::list< FrequencySegment > FrequencySegments
Microseconds getDuration() const
Clock::time_point TimePoint
Definition: types.h:50
std::list< Transmitter > Transmitters
Definition: transmitter.h:85
void prependLengthPrefixFraming(std::uint16_t u16Length)
RegistrationId getRegistrationId() const
std::uint16_t getSequenceNumber() const