EMANE  1.2.1
tdmascheduleevent.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-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 
34 #include "tdmascheduleevent.pb.h"
35 
36 #include <cstdint>
37 #include <tuple>
38 
39 class EMANE::Events::TDMAScheduleEvent::Implementation
40 {
41 public:
42  Implementation(const Serialization & serialization):
43  bHasStructure_{}
44  {
46 
47  if(!msg.ParseFromString(serialization))
48  {
49  throw SerializationException("unable to deserialize : TDMAScheduleEvent");
50  }
51 
52  std::uint32_t u32FramesPerMultiFrame{};
53  std::uint32_t u32SlotsPerFrame{};
54 
55  if(msg.has_structure())
56  {
57  const auto & structure = msg.structure();
58 
59  u32FramesPerMultiFrame = structure.framespermultiframe();
60  u32SlotsPerFrame = structure.slotsperframe();
61 
62  structure_ = SlotStructure{structure.bandwidthhz(),
63  u32FramesPerMultiFrame,
64  u32SlotsPerFrame,
65  Microseconds{structure.slotdurationmicroseconds()},
66  Microseconds{structure.slotoverheadmicroseconds()}};
67 
68  bHasStructure_ = true;
69 
70  slotInfos_.reserve(u32FramesPerMultiFrame * u32SlotsPerFrame);
71  }
72 
73  if(bHasStructure_)
74  {
75  // pre-built a complete schedule defaulting all slots to idle
76  for(unsigned i = 0; i < u32FramesPerMultiFrame; ++i)
77  {
78  for(unsigned j = 0; j < u32SlotsPerFrame; ++j)
79  {
80  slotInfos_.push_back({SlotInfo::Type::IDLE,i,j});
81  }
82  }
83  }
84 
85  for(const auto & frame :msg.frames())
86  {
87  std::uint32_t u32FrameIndex = frame.index();
88 
89  if(bHasStructure_ && u32FrameIndex >= u32FramesPerMultiFrame)
90  {
91  throw makeException<SerializationException>("TDMAScheduleEvent : Frame %lu index out of range",
92  u32FrameIndex);
93  }
94 
95  std::set<std::uint32_t> presentSlots{};
96 
97  for(const auto & slot : frame.slots())
98  {
100  std::uint64_t u64FrequencyHz{};
101  std::uint64_t u64DataRatebps{};
102  std::uint8_t u8ServiceClass{};
103  double dPowerdBm{};
104  NEMId destination{};
105 
106  std::uint32_t u32SlotIndex = slot.index();
107 
108  if(bHasStructure_ && u32SlotIndex >= u32SlotsPerFrame)
109  {
110  throw makeException<SerializationException>("TDMAScheduleEvent : Frame %lu Slot %lu slot index out of range",
111  u32FrameIndex,
112  u32SlotIndex);
113  }
114 
115  presentSlots.insert(u32SlotIndex);
116 
117  switch(slot.type())
118  {
119  case EMANEMessage::TDMAScheduleEvent::Frame::Slot::SLOT_TX:
120  {
121  const auto & tx = slot.tx();
122 
123  type = SlotInfo::Type::TX;
124 
125  if(tx.has_frequencyhz())
126  {
127  u64FrequencyHz = tx.frequencyhz();
128  }
129  else if(frame.has_frequencyhz())
130  {
131  u64FrequencyHz = frame.frequencyhz();
132  }
133  else if(msg.has_frequencyhz())
134  {
135  u64FrequencyHz = msg.frequencyhz();
136  }
137  else
138  {
139  throw makeException<SerializationException>("TDMAScheduleEvent : Frame %lu Slot %lu has undeterminable frequency",
140  u32FrameIndex,
141  u32SlotIndex);
142  }
143 
144  if(tx.has_dataratebps())
145  {
146  u64DataRatebps = tx.dataratebps();
147  }
148  else if(frame.has_dataratebps())
149  {
150  u64DataRatebps = frame.dataratebps();
151  }
152  else if(msg.has_dataratebps())
153  {
154  u64DataRatebps = msg.dataratebps();
155  }
156  else
157  {
158  throw makeException<SerializationException>("TDMAScheduleEvent : Frame %lu Slot %lu has undeterminable datarate",
159  u32FrameIndex,
160  u32SlotIndex);
161  }
162 
163 
164  if(tx.has_serviceclass())
165  {
166  u8ServiceClass = tx.serviceclass();
167  }
168  else if(frame.has_serviceclass())
169  {
170  u8ServiceClass = frame.serviceclass();
171  }
172  else if(msg.has_serviceclass())
173  {
174  u8ServiceClass = msg.serviceclass();
175  }
176  else
177  {
178  throw makeException<SerializationException>("TDMAScheduleEvent : Frame %lu Slot %lu has undeterminable class",
179  u32FrameIndex,
180  u32SlotIndex);
181  }
182 
183 
184  if(tx.has_powerdbm())
185  {
186  dPowerdBm = tx.powerdbm();
187  }
188  else if(frame.has_powerdbm())
189  {
190  dPowerdBm = frame.powerdbm();
191  }
192  else if(msg.has_powerdbm())
193  {
194  dPowerdBm = msg.powerdbm();
195  }
196  else
197  {
198  throw makeException<SerializationException>("TDMAScheduleEvent : Frame %lu Slot %lu has undeterminable power",
199  u32FrameIndex,
200  u32SlotIndex);
201  }
202 
203 
204  if(tx.has_destination())
205  {
206  destination = tx.destination();
207  }
208  }
209  break;
210 
211  case EMANEMessage::TDMAScheduleEvent::Frame::Slot::SLOT_RX:
212  {
213  const auto & rx = slot.rx();
214 
215  type = SlotInfo::Type::RX;
216 
217  if(rx.has_frequencyhz())
218  {
219  u64FrequencyHz = rx.frequencyhz();
220  }
221  else if(frame.has_frequencyhz())
222  {
223  u64FrequencyHz = frame.frequencyhz();
224  }
225  else if(msg.has_frequencyhz())
226  {
227  u64FrequencyHz = msg.frequencyhz();
228  }
229  else
230  {
231  throw makeException<SerializationException>("TDMAScheduleEvent : Frame %lu Slot %lu has undeterminable frequency",
232  u32FrameIndex,
233  u32SlotIndex);
234  }
235  }
236  break;
237 
238  case EMANEMessage::TDMAScheduleEvent::Frame::Slot::SLOT_IDLE:
239  type = SlotInfo::Type::IDLE;
240  break;
241  }
242 
243 
244  frequencies_.insert(u64FrequencyHz);
245 
246  if(bHasStructure_)
247  {
248  slotInfos_[u32FrameIndex * u32SlotsPerFrame + u32SlotIndex] =
249  {type,
250  u32FrameIndex,
251  u32SlotIndex,
252  u64FrequencyHz,
253  u64DataRatebps,
254  u8ServiceClass,
255  dPowerdBm,
256  destination};
257  }
258  else
259  {
260  slotInfos_.push_back({type,
261  u32FrameIndex,
262  u32SlotIndex,
263  u64FrequencyHz,
264  u64DataRatebps,
265  u8ServiceClass,
266  dPowerdBm,
267  destination});
268  }
269  }
270 
271  if(bHasStructure_)
272  {
273  // add RX slot info for any missing slot
274  for(unsigned i = 0; i < u32SlotsPerFrame; ++i)
275  {
276  if(!presentSlots.count(i))
277  {
278  std::uint64_t u64FrequencyHz{};
279 
280  if(frame.has_frequencyhz())
281  {
282  u64FrequencyHz = frame.frequencyhz();
283  }
284  else if(msg.has_frequencyhz())
285  {
286  u64FrequencyHz = msg.frequencyhz();
287  }
288  else
289  {
290  throw makeException<SerializationException>("TDMAScheduleEvent : Frame %lu Slot %lu has undeterminable frequency",
291  u32FrameIndex,
292  i);
293  }
294 
295  frequencies_.insert(u64FrequencyHz);
296 
297  slotInfos_[u32FrameIndex * u32SlotsPerFrame + i] = {SlotInfo::Type::RX,
298  u32FrameIndex,
299  i,
300  u64FrequencyHz};
301  }
302  }
303  }
304  }
305  }
306 
307  const SlotInfos & getSlotInfos() const
308  {
309  return slotInfos_;
310  }
311 
312  const Frequencies & getFrequencies() const
313  {
314  return frequencies_;
315  }
316 
317  std::pair<const SlotStructure &,bool> getSlotStructure() const
318  {
319  return {structure_,bHasStructure_};
320  }
321 
322 private:
323  SlotInfos slotInfos_;
324  Frequencies frequencies_;
325  SlotStructure structure_;
326  bool bHasStructure_;
327 };
328 
329 
331  Event{IDENTIFIER},
332  pImpl_{new Implementation{serialization}}{}
333 
335 
337 {
338  return pImpl_->getSlotInfos();
339 }
340 
341 
344 {
345  return pImpl_->getFrequencies();
346 }
347 
348 std::pair<const EMANE::Events::SlotStructure &,bool>
350 {
351  return pImpl_->getSlotStructure();
352 }
std::string Serialization
Definition: serializable.h:42
Event interface is the base for all events.
Definition: event.h:46
const Frequencies & getFrequencies() const
std::pair< const SlotStructure &, bool > getSlotStructure() const
std::chrono::microseconds Microseconds
Definition: types.h:45
std::uint16_t NEMId
Definition: types.h:52
std::vector< SlotInfo > SlotInfos
Definition: slotinfo.h:85
TDMAScheduleEvent(const Serialization &serialization)
const SlotInfos & getSlotInfos() const