lorawan-mac-command.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2017 University of Padova
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Davide Magrin <magrinda@dei.unipd.it>
19  *
20  * Modified by: Bastien Tauran <bastien.tauran@viveris.fr>
21  */
22 
23 #include "lorawan-mac-command.h"
24 
25 #include <ns3/log.h>
26 
27 #include <bitset>
28 #include <cmath>
29 
30 namespace ns3
31 {
32 
33 NS_LOG_COMPONENT_DEFINE("LorawanLorawanMacCommand");
34 
35 NS_OBJECT_ENSURE_REGISTERED(LorawanMacCommand);
36 
37 TypeId
39 {
40  static TypeId tid = TypeId("ns3::LorawanMacCommand").SetParent<Object>();
41  return tid;
42 }
43 
45 {
46  NS_LOG_FUNCTION(this);
47 }
48 
50 {
51  NS_LOG_FUNCTION(this);
52 }
53 
54 enum MacCommandType
56 {
57  NS_LOG_FUNCTION_NOARGS();
58 
59  return m_commandType;
60 }
61 
62 uint8_t
64 {
65  NS_LOG_FUNCTION_NOARGS();
66 
67  return m_serializedSize;
68 }
69 
70 uint8_t
72 {
73  NS_LOG_FUNCTION_NOARGS();
74 
75  switch (commandType)
76  {
77  case (INVALID): {
78  return 0x0;
79  }
80  case (LINK_CHECK_REQ):
81  case (LINK_CHECK_ANS): {
82  return 0x02;
83  }
84  case (LINK_ADR_REQ):
85  case (LINK_ADR_ANS): {
86  return 0x03;
87  }
88  case (DUTY_CYCLE_REQ):
89  case (DUTY_CYCLE_ANS): {
90  return 0x04;
91  }
92  case (RX_PARAM_SETUP_REQ):
93  case (RX_PARAM_SETUP_ANS): {
94  return 0x05;
95  }
96  case (DEV_STATUS_REQ):
97  case (DEV_STATUS_ANS): {
98  return 0x06;
99  }
100  case (NEW_CHANNEL_REQ):
101  case (NEW_CHANNEL_ANS): {
102  return 0x07;
103  }
104  case (RX_TIMING_SETUP_REQ):
105  case (RX_TIMING_SETUP_ANS): {
106  return 0x08;
107  }
108  case (TX_PARAM_SETUP_REQ):
109  case (TX_PARAM_SETUP_ANS): {
110  return 0x09;
111  }
112  case (DL_CHANNEL_REQ):
113  case (DL_CHANNEL_ANS): {
114  return 0x0A;
115  }
116  }
117  return 0;
118 }
119 
121 // LinkCheckReq //
123 
125 {
126  NS_LOG_FUNCTION_NOARGS();
128  m_serializedSize = 1;
129 }
130 
132 {
133  NS_LOG_FUNCTION_NOARGS();
134 }
135 
136 void
137 LinkCheckReq::Serialize(Buffer::Iterator& start) const
138 {
139  NS_LOG_FUNCTION_NOARGS();
140 
141  // Write the CID and we're done
143  start.WriteU8(cid);
144  NS_LOG_DEBUG("Serialized LinkCheckReq: " << unsigned(cid));
145 }
146 
147 uint8_t
148 LinkCheckReq::Deserialize(Buffer::Iterator& start)
149 {
150  NS_LOG_FUNCTION_NOARGS();
151 
152  // Read the CID
153  start.ReadU8();
154 
155  return m_serializedSize;
156 }
157 
158 void
159 LinkCheckReq::Print(std::ostream& os) const
160 {
161  NS_LOG_FUNCTION_NOARGS();
162 
163  os << "LinkCheckReq" << std::endl;
164 }
165 
167 // LinkCheckAns //
169 
171  : m_margin(0),
172  m_gwCnt(0)
173 {
174  NS_LOG_FUNCTION(this);
175 
177  m_serializedSize = 3;
178 }
179 
180 LinkCheckAns::LinkCheckAns(uint8_t margin, uint8_t gwCnt)
181  : m_margin(margin),
182  m_gwCnt(gwCnt)
183 {
184  NS_LOG_FUNCTION(this << unsigned(margin) << unsigned(gwCnt));
185 
187  m_serializedSize = 3;
188 }
189 
190 void
191 LinkCheckAns::Serialize(Buffer::Iterator& start) const
192 {
193  NS_LOG_FUNCTION_NOARGS();
194 
195  // Write the CID
197  // Write the margin
198  start.WriteU8(m_margin);
199  // Write the gwCnt
200  start.WriteU8(m_gwCnt);
201 }
202 
203 uint8_t
204 LinkCheckAns::Deserialize(Buffer::Iterator& start)
205 {
206  NS_LOG_FUNCTION_NOARGS();
207 
208  // Consume the CID
209  start.ReadU8();
210  m_margin = start.ReadU8();
211  m_gwCnt = start.ReadU8();
212  return m_serializedSize;
213 }
214 
215 void
216 LinkCheckAns::Print(std::ostream& os) const
217 {
218  NS_LOG_FUNCTION_NOARGS();
219 
220  os << "LinkCheckAns" << std::endl;
221  os << "margin: " << unsigned(m_margin) << std::endl;
222  os << "gwCnt: " << unsigned(m_gwCnt) << std::endl;
223 }
224 
225 void
226 LinkCheckAns::SetMargin(uint8_t margin)
227 {
228  NS_LOG_FUNCTION(this << unsigned(margin));
229 
230  m_margin = margin;
231 }
232 
233 uint8_t
235 {
236  NS_LOG_FUNCTION(this);
237 
238  return m_margin;
239 }
240 
241 void
243 {
244  NS_LOG_FUNCTION(this << unsigned(gwCnt));
245 
246  m_gwCnt = gwCnt;
247 }
248 
249 uint8_t
251 {
252  NS_LOG_FUNCTION(this);
253 
254  return m_gwCnt;
255 }
256 
257 void
259 {
260  NS_LOG_FUNCTION(this);
261 
262  m_gwCnt++;
263 }
264 
266 // LinkAdrReq //
268 
270 {
271  NS_LOG_FUNCTION(this);
272 
274  m_serializedSize = 5;
275 }
276 
277 LinkAdrReq::LinkAdrReq(uint8_t dataRate,
278  uint8_t txPower,
279  uint16_t channelMask,
280  uint8_t chMaskCntl,
281  uint8_t nbRep)
282  : m_dataRate(dataRate),
283  m_txPower(txPower),
284  m_channelMask(channelMask),
285  m_chMaskCntl(chMaskCntl),
286  m_nbRep(nbRep)
287 {
288  NS_LOG_FUNCTION(this);
289 
291  m_serializedSize = 5;
292 }
293 
294 void
295 LinkAdrReq::Serialize(Buffer::Iterator& start) const
296 {
297  NS_LOG_FUNCTION_NOARGS();
298 
299  // Write the CID
301  start.WriteU8(m_dataRate << 4 | (m_txPower & 0b1111));
302  start.WriteU16(m_channelMask);
303  start.WriteU8(m_chMaskCntl << 4 | (m_nbRep & 0b1111));
304 }
305 
306 uint8_t
307 LinkAdrReq::Deserialize(Buffer::Iterator& start)
308 {
309  NS_LOG_FUNCTION_NOARGS();
310 
311  // Consume the CID
312  start.ReadU8();
313  uint8_t firstByte = start.ReadU8();
314  m_dataRate = firstByte >> 4;
315  m_txPower = firstByte & 0b1111;
316  m_channelMask = start.ReadU16();
317  uint8_t fourthByte = start.ReadU8();
318  m_chMaskCntl = fourthByte >> 4;
319  m_nbRep = fourthByte & 0b1111;
320 
321  return m_serializedSize;
322 }
323 
324 void
325 LinkAdrReq::Print(std::ostream& os) const
326 {
327  NS_LOG_FUNCTION_NOARGS();
328 
329  os << "LinkAdrReq" << std::endl;
330  os << "dataRate: " << unsigned(m_dataRate) << std::endl;
331  os << "txPower: " << unsigned(m_txPower) << std::endl;
332  os << "channelMask: " << std::bitset<16>(m_channelMask) << std::endl;
333  os << "chMaskCntl: " << unsigned(m_chMaskCntl) << std::endl;
334  os << "nbRep: " << unsigned(m_nbRep) << std::endl;
335 }
336 
337 uint8_t
339 {
340  NS_LOG_FUNCTION(this);
341 
342  return m_dataRate;
343 }
344 
345 uint8_t
347 {
348  NS_LOG_FUNCTION(this);
349 
350  return m_txPower;
351 }
352 
353 std::list<int>
355 {
356  NS_LOG_FUNCTION(this);
357 
358  std::list<int> channelIndices;
359  for (int i = 0; i < 16; i++)
360  {
361  if (m_channelMask & (0b1 << i)) // Take channel mask's i-th bit
362  {
363  NS_LOG_DEBUG("Adding channel index " << i);
364  channelIndices.push_back(i);
365  }
366  }
367 
368  return channelIndices;
369 }
370 
371 int
373 {
374  NS_LOG_FUNCTION(this);
375 
376  return m_nbRep;
377 }
378 
380 // LinkAdrAns //
382 
384 {
385  NS_LOG_FUNCTION(this);
386 
388  m_serializedSize = 2;
389 }
390 
391 LinkAdrAns::LinkAdrAns(bool powerAck, bool dataRateAck, bool channelMaskAck)
392  : m_powerAck(powerAck),
393  m_dataRateAck(dataRateAck),
394  m_channelMaskAck(channelMaskAck)
395 {
396  NS_LOG_FUNCTION(this);
397 
399  m_serializedSize = 2;
400 }
401 
402 void
403 LinkAdrAns::Serialize(Buffer::Iterator& start) const
404 {
405  NS_LOG_FUNCTION_NOARGS();
406 
407  // Write the CID
409  // We can assume that true will be converted to 1 and that false will be
410  // converted to 0 on any C++ compiler
411  start.WriteU8((uint8_t(m_powerAck) << 2) | (uint8_t(m_dataRateAck) << 1) |
412  uint8_t(m_channelMaskAck));
413 }
414 
415 uint8_t
416 LinkAdrAns::Deserialize(Buffer::Iterator& start)
417 {
418  NS_LOG_FUNCTION_NOARGS();
419 
420  // Consume the CID
421  start.ReadU8();
422 
423  uint8_t byte = start.ReadU8();
424 
425  m_powerAck = byte & 0b100;
426  m_dataRateAck = byte & 0b10;
427  m_channelMaskAck = byte & 0b1;
428 
429  return m_serializedSize;
430 }
431 
432 void
433 LinkAdrAns::Print(std::ostream& os) const
434 {
435  NS_LOG_FUNCTION_NOARGS();
436 
437  os << "LinkAdrAns" << std::endl;
438 }
439 
441 // DutyCycleReq //
443 
445 {
446  NS_LOG_FUNCTION(this);
447 
449  m_serializedSize = 2;
450 }
451 
452 DutyCycleReq::DutyCycleReq(uint8_t dutyCycle)
453  : m_maxDCycle(dutyCycle)
454 {
455  NS_LOG_FUNCTION(this);
456 
458  m_serializedSize = 2;
459 }
460 
461 void
462 DutyCycleReq::Serialize(Buffer::Iterator& start) const
463 {
464  NS_LOG_FUNCTION_NOARGS();
465 
466  // Write the CID
468  start.WriteU8(m_maxDCycle);
469 }
470 
471 uint8_t
472 DutyCycleReq::Deserialize(Buffer::Iterator& start)
473 {
474  NS_LOG_FUNCTION_NOARGS();
475 
476  // Consume the CID
477  start.ReadU8();
478  m_maxDCycle = start.ReadU8();
479 
480  return m_serializedSize;
481 }
482 
483 void
484 DutyCycleReq::Print(std::ostream& os) const
485 {
486  NS_LOG_FUNCTION_NOARGS();
487 
488  os << "DutyCycleReq" << std::endl;
489  os << "maxDCycle: " << unsigned(m_maxDCycle) << std::endl;
490  os << "maxDCycle (fraction): " << GetMaximumAllowedDutyCycle() << std::endl;
491 }
492 
493 double
495 {
496  NS_LOG_FUNCTION(this);
497 
498  // Check if we need to turn off completely
499  if (m_maxDCycle == 255)
500  {
501  return 0;
502  }
503 
504  if (m_maxDCycle == 0)
505  {
506  return 1;
507  }
508 
509  return 1 / std::pow(2, double(m_maxDCycle));
510 }
511 
513 // DutyCycleAns //
515 
517 {
518  NS_LOG_FUNCTION(this);
519 
521  m_serializedSize = 1;
522 }
523 
524 void
525 DutyCycleAns::Serialize(Buffer::Iterator& start) const
526 {
527  NS_LOG_FUNCTION_NOARGS();
528 
529  // Write the CID
531 }
532 
533 uint8_t
534 DutyCycleAns::Deserialize(Buffer::Iterator& start)
535 {
536  NS_LOG_FUNCTION_NOARGS();
537 
538  // Consume the CID
539  start.ReadU8();
540  return m_serializedSize;
541 }
542 
543 void
544 DutyCycleAns::Print(std::ostream& os) const
545 {
546  NS_LOG_FUNCTION_NOARGS();
547 
548  os << "DutyCycleAns" << std::endl;
549 }
550 
552 // RxParamSetupReq //
554 
556 {
557  NS_LOG_FUNCTION(this);
558 
560  m_serializedSize = 5;
561 }
562 
563 RxParamSetupReq::RxParamSetupReq(uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequency)
564  : m_rx1DrOffset(rx1DrOffset),
565  m_rx2DataRate(rx2DataRate),
566  m_frequency(frequency)
567 {
568  NS_LOG_FUNCTION(this << unsigned(rx1DrOffset) << unsigned(rx2DataRate) << frequency);
569 
570  if ((rx1DrOffset & 0b11111000) != 0)
571  {
572  NS_LOG_WARN(
573  "Warning: received an rx1DrOffset greater than 7. Actual value will be different.");
574  }
575  if ((rx2DataRate & 0b11110000) != 0)
576  {
577  NS_LOG_WARN(
578  "Warning: received a rx2DataRate greater than 15. Actual value will be different.");
579  }
580 
582  m_serializedSize = 5;
583 }
584 
585 void
586 RxParamSetupReq::Serialize(Buffer::Iterator& start) const
587 {
588  NS_LOG_FUNCTION_NOARGS();
589 
590  // Write the CID
592  // Data serialization
593  start.WriteU8((m_rx1DrOffset & 0b111) << 4 | (m_rx2DataRate & 0b1111));
594  uint32_t encodedFrequency = uint32_t(m_frequency / 100);
595  NS_LOG_DEBUG(unsigned(encodedFrequency));
596  NS_LOG_DEBUG(std::bitset<32>(encodedFrequency));
597  start.WriteU8((encodedFrequency & 0xff0000) >> 16); // Most significant byte
598  start.WriteU8((encodedFrequency & 0xff00) >> 8); // Middle byte
599  start.WriteU8(encodedFrequency & 0xff); // Least significant byte
600 }
601 
602 uint8_t
603 RxParamSetupReq::Deserialize(Buffer::Iterator& start)
604 {
605  NS_LOG_FUNCTION_NOARGS();
606 
607  // Consume the CID
608  start.ReadU8();
609  // Data serialization
610  uint8_t firstByte = start.ReadU8();
611  m_rx1DrOffset = (firstByte & 0b1110000) >> 4;
612  m_rx2DataRate = firstByte & 0b1111;
613  uint32_t secondByte = start.ReadU8();
614  uint32_t thirdByte = start.ReadU8();
615  uint32_t fourthByte = start.ReadU8();
616  uint32_t encodedFrequency = (secondByte << 16) | (thirdByte << 8) | fourthByte;
617  NS_LOG_DEBUG(std::bitset<32>(encodedFrequency));
618  m_frequency = double(encodedFrequency) * 100;
619 
620  return m_serializedSize;
621 }
622 
623 void
624 RxParamSetupReq::Print(std::ostream& os) const
625 {
626  NS_LOG_FUNCTION_NOARGS();
627 
628  os << "RxParamSetupReq" << std::endl;
629  os << "rx1DrOffset: " << unsigned(m_rx1DrOffset) << std::endl;
630  os << "rx2DataRate: " << unsigned(m_rx2DataRate) << std::endl;
631  os << "frequency: " << m_frequency << std::endl;
632 }
633 
634 uint8_t
636 {
637  NS_LOG_FUNCTION(this);
638 
639  return m_rx1DrOffset;
640 }
641 
642 uint8_t
644 {
645  NS_LOG_FUNCTION(this);
646 
647  return m_rx2DataRate;
648 }
649 
650 double
652 {
653  NS_LOG_FUNCTION(this);
654 
655  return m_frequency;
656 }
657 
659 // RxParamSetupAns //
661 
663 {
664  NS_LOG_FUNCTION(this);
665 
667  m_serializedSize = 2;
668 }
669 
670 RxParamSetupAns::RxParamSetupAns(bool rx1DrOffsetAck, bool rx2DataRateAck, bool channelAck)
671  : m_rx1DrOffsetAck(rx1DrOffsetAck),
672  m_rx2DataRateAck(rx2DataRateAck),
673  m_channelAck(channelAck)
674 {
675  NS_LOG_FUNCTION(this << rx1DrOffsetAck << rx2DataRateAck << channelAck);
676 
678  m_serializedSize = 2;
679 }
680 
681 void
682 RxParamSetupAns::Serialize(Buffer::Iterator& start) const
683 {
684  NS_LOG_FUNCTION_NOARGS();
685 
686  // Write the CID
688  // Data serialization
689  start.WriteU8(uint8_t(m_rx1DrOffsetAck) << 2 | uint8_t(m_rx2DataRateAck) << 1 |
690  uint8_t(m_channelAck));
691 }
692 
693 uint8_t
694 RxParamSetupAns::Deserialize(Buffer::Iterator& start)
695 {
696  NS_LOG_FUNCTION_NOARGS();
697 
698  // Consume the CID
699  start.ReadU8();
700 
701  uint8_t byte = start.ReadU8();
702 
703  m_rx1DrOffsetAck = (byte & 0b100) >> 2;
704  m_rx2DataRateAck = (byte & 0b10) >> 1;
705  m_channelAck = byte & 0b1;
706 
707  return m_serializedSize;
708 }
709 
710 void
711 RxParamSetupAns::Print(std::ostream& os) const
712 {
713  NS_LOG_FUNCTION_NOARGS();
714 
715  os << "RxParamSetupAns" << std::endl;
716  os << "m_rx1DrOffsetAck: " << m_rx1DrOffsetAck << std::endl;
717  os << "m_rx2DataRateAck: " << m_rx2DataRateAck << std::endl;
718  os << "m_channelAck: " << m_channelAck << std::endl;
719 }
720 
722 // DevStatusReq //
724 
726 {
727  NS_LOG_FUNCTION(this);
728 
730  m_serializedSize = 1;
731 }
732 
733 void
734 DevStatusReq::Serialize(Buffer::Iterator& start) const
735 {
736  NS_LOG_FUNCTION_NOARGS();
737 
738  // Write the CID
740 }
741 
742 uint8_t
743 DevStatusReq::Deserialize(Buffer::Iterator& start)
744 {
745  NS_LOG_FUNCTION_NOARGS();
746 
747  // Consume the CID
748  start.ReadU8();
749 
750  return m_serializedSize;
751 }
752 
753 void
754 DevStatusReq::Print(std::ostream& os) const
755 {
756  NS_LOG_FUNCTION_NOARGS();
757 
758  os << "DevStatusReq" << std::endl;
759 }
760 
762 // DevStatusAns //
764 
766 {
767  NS_LOG_FUNCTION(this);
768 
770  m_serializedSize = 3;
771 }
772 
773 DevStatusAns::DevStatusAns(uint8_t battery, uint8_t margin)
774  : m_battery(battery),
775  m_margin(margin)
776 {
777  NS_LOG_FUNCTION(this << unsigned(battery) << unsigned(margin));
778 
780  m_serializedSize = 3;
781 }
782 
783 void
784 DevStatusAns::Serialize(Buffer::Iterator& start) const
785 {
786  NS_LOG_FUNCTION_NOARGS();
787 
788  // Write the CID
790  start.WriteU8(m_battery);
791  start.WriteU8(m_margin);
792 }
793 
794 uint8_t
795 DevStatusAns::Deserialize(Buffer::Iterator& start)
796 {
797  NS_LOG_FUNCTION_NOARGS();
798 
799  // Consume the CID
800  start.ReadU8();
801  m_battery = start.ReadU8();
802  m_margin = start.ReadU8() & 0b111111;
803 
804  return m_serializedSize;
805 }
806 
807 void
808 DevStatusAns::Print(std::ostream& os) const
809 {
810  NS_LOG_FUNCTION_NOARGS();
811 
812  os << "DevStatusAns" << std::endl;
813  os << "Battery: " << unsigned(m_battery) << std::endl;
814  os << "Margin: " << unsigned(m_margin) << std::endl;
815 }
816 
817 uint8_t
819 {
820  NS_LOG_FUNCTION_NOARGS();
821 
822  return m_battery;
823 }
824 
825 uint8_t
827 {
828  NS_LOG_FUNCTION_NOARGS();
829 
830  return m_margin;
831 }
832 
834 // NewChannelReq //
836 
838 {
839  NS_LOG_FUNCTION(this);
840 
842  m_serializedSize = 6;
843 }
844 
846  double frequency,
847  uint8_t minDataRate,
848  uint8_t maxDataRate)
849  : m_chIndex(chIndex),
850  m_frequency(frequency),
851  m_minDataRate(minDataRate),
852  m_maxDataRate(maxDataRate)
853 {
854  NS_LOG_FUNCTION(this);
855 
857  m_serializedSize = 6;
858 }
859 
860 void
861 NewChannelReq::Serialize(Buffer::Iterator& start) const
862 {
863  NS_LOG_FUNCTION_NOARGS();
864 
865  // Write the CID
867 
868  start.WriteU8(m_chIndex);
869  uint32_t encodedFrequency = uint32_t(m_frequency / 100);
870  start.WriteU8((encodedFrequency & 0xff0000) >> 16);
871  start.WriteU8((encodedFrequency & 0xff00) >> 8);
872  start.WriteU8(encodedFrequency & 0xff);
873  start.WriteU8((m_maxDataRate << 4) | (m_minDataRate & 0xf));
874 }
875 
876 uint8_t
877 NewChannelReq::Deserialize(Buffer::Iterator& start)
878 {
879  NS_LOG_FUNCTION_NOARGS();
880 
881  // Consume the CID
882  start.ReadU8();
883  // Read the data
884  m_chIndex = start.ReadU8();
885  uint32_t encodedFrequency = 0;
886  encodedFrequency |= uint32_t(start.ReadU16()) << 8;
887  encodedFrequency |= uint32_t(start.ReadU8());
888  m_frequency = double(encodedFrequency) * 100;
889  uint8_t dataRateByte = start.ReadU8();
890  m_maxDataRate = dataRateByte >> 4;
891  m_minDataRate = dataRateByte & 0xf;
892 
893  return m_serializedSize;
894 }
895 
896 void
897 NewChannelReq::Print(std::ostream& os) const
898 {
899  NS_LOG_FUNCTION_NOARGS();
900 
901  os << "NewChannelReq" << std::endl;
902 }
903 
904 uint8_t
906 {
907  NS_LOG_FUNCTION_NOARGS();
908 
909  return m_chIndex;
910 }
911 
912 double
914 {
915  NS_LOG_FUNCTION_NOARGS();
916 
917  return m_frequency;
918 }
919 
920 uint8_t
922 {
923  NS_LOG_FUNCTION_NOARGS();
924 
925  return m_minDataRate;
926 }
927 
928 uint8_t
930 {
931  NS_LOG_FUNCTION_NOARGS();
932 
933  return m_maxDataRate;
934 }
935 
937 // NewChannelAns //
939 
941 {
942  NS_LOG_FUNCTION(this);
943 
945  m_serializedSize = 2;
946 }
947 
948 NewChannelAns::NewChannelAns(bool dataRateRangeOk, bool channelFrequencyOk)
949  : m_dataRateRangeOk(dataRateRangeOk),
950  m_channelFrequencyOk(channelFrequencyOk)
951 {
952  NS_LOG_FUNCTION(this);
953 
955  m_serializedSize = 2;
956 }
957 
958 void
959 NewChannelAns::Serialize(Buffer::Iterator& start) const
960 {
961  NS_LOG_FUNCTION_NOARGS();
962 
963  // Write the CID
965 
966  start.WriteU8((uint8_t(m_dataRateRangeOk) << 1) | uint8_t(m_channelFrequencyOk));
967 }
968 
969 uint8_t
970 NewChannelAns::Deserialize(Buffer::Iterator& start)
971 {
972  NS_LOG_FUNCTION_NOARGS();
973 
974  // Consume the CID
975  start.ReadU8();
976  // Read the data
977  uint8_t byte = start.ReadU8();
978  m_dataRateRangeOk = (byte & 0b10) >> 1;
979  m_channelFrequencyOk = (byte & 0b1);
980 
981  return m_serializedSize;
982 }
983 
984 void
985 NewChannelAns::Print(std::ostream& os) const
986 {
987  NS_LOG_FUNCTION_NOARGS();
988 
989  os << "NewChannelAns" << std::endl;
990  os << "DataRateRangeOk: " << m_dataRateRangeOk << std::endl;
991  os << "ChannelFrequencyOk: " << m_channelFrequencyOk << std::endl;
992 }
993 
995 // RxTimingSetupReq //
997 
999 {
1000  NS_LOG_FUNCTION(this);
1001 
1003  m_serializedSize = 2;
1004 }
1005 
1007  : m_delay(delay)
1008 {
1009  NS_LOG_FUNCTION(this);
1010 
1012  m_serializedSize = 2;
1013 }
1014 
1015 void
1016 RxTimingSetupReq::Serialize(Buffer::Iterator& start) const
1017 {
1018  NS_LOG_FUNCTION_NOARGS();
1019 
1020  // Write the CID
1022  // Write the data
1023  start.WriteU8(m_delay & 0xf);
1024 }
1025 
1026 uint8_t
1027 RxTimingSetupReq::Deserialize(Buffer::Iterator& start)
1028 {
1029  NS_LOG_FUNCTION_NOARGS();
1030 
1031  // Consume the CID
1032  start.ReadU8();
1033  // Read the data
1034  m_delay = start.ReadU8() & 0xf;
1035 
1036  return m_serializedSize;
1037 }
1038 
1039 void
1040 RxTimingSetupReq::Print(std::ostream& os) const
1041 {
1042  NS_LOG_FUNCTION_NOARGS();
1043 
1044  os << "RxTimingSetupReq" << std::endl;
1045 }
1046 
1047 Time
1049 {
1050  NS_LOG_FUNCTION(this);
1051 
1052  if (m_delay == 0)
1053  {
1054  return Seconds(1);
1055  }
1056  return Seconds(m_delay);
1057 }
1058 
1060 // RxTimingSetupAns //
1062 
1064 {
1065  NS_LOG_FUNCTION(this);
1066 
1068  m_serializedSize = 1;
1069 }
1070 
1071 void
1072 RxTimingSetupAns::Serialize(Buffer::Iterator& start) const
1073 {
1074  NS_LOG_FUNCTION_NOARGS();
1075 
1076  // Write the CID
1078 }
1079 
1080 uint8_t
1081 RxTimingSetupAns::Deserialize(Buffer::Iterator& start)
1082 {
1083  NS_LOG_FUNCTION_NOARGS();
1084 
1085  // Consume the CID
1086  start.ReadU8();
1087 
1088  return m_serializedSize;
1089 }
1090 
1091 void
1092 RxTimingSetupAns::Print(std::ostream& os) const
1093 {
1094  NS_LOG_FUNCTION_NOARGS();
1095 
1096  os << "RxTimingSetupAns" << std::endl;
1097 }
1098 
1100 // DlChannelAns //
1102 
1104 {
1105  NS_LOG_FUNCTION(this);
1106 
1108  m_serializedSize = 1;
1109 }
1110 
1111 void
1112 DlChannelAns::Serialize(Buffer::Iterator& start) const
1113 {
1114  NS_LOG_FUNCTION_NOARGS();
1115 
1116  // Write the CID
1118 }
1119 
1120 uint8_t
1121 DlChannelAns::Deserialize(Buffer::Iterator& start)
1122 {
1123  NS_LOG_FUNCTION_NOARGS();
1124 
1125  // Consume the CID
1126  start.ReadU8();
1127 
1128  return m_serializedSize;
1129 }
1130 
1131 void
1132 DlChannelAns::Print(std::ostream& os) const
1133 {
1134  NS_LOG_FUNCTION_NOARGS();
1135 
1136  os << "DlChannelAns" << std::endl;
1137 }
1138 
1140 // TxParamSetupReq //
1142 
1144 {
1145  NS_LOG_FUNCTION(this);
1146 
1148  m_serializedSize = 1;
1149 }
1150 
1151 void
1152 TxParamSetupReq::Serialize(Buffer::Iterator& start) const
1153 {
1154  NS_LOG_FUNCTION_NOARGS();
1155 
1156  // Write the CID
1158 }
1159 
1160 uint8_t
1161 TxParamSetupReq::Deserialize(Buffer::Iterator& start)
1162 {
1163  NS_LOG_FUNCTION_NOARGS();
1164 
1165  // Consume the CID
1166  start.ReadU8();
1167 
1168  return m_serializedSize;
1169 }
1170 
1171 void
1172 TxParamSetupReq::Print(std::ostream& os) const
1173 {
1174  NS_LOG_FUNCTION_NOARGS();
1175 
1176  os << "TxParamSetupReq" << std::endl;
1177 }
1178 
1180 // TxParamSetupAns //
1182 
1184 {
1185  NS_LOG_FUNCTION(this);
1186 
1188  m_serializedSize = 1;
1189 }
1190 
1191 void
1192 TxParamSetupAns::Serialize(Buffer::Iterator& start) const
1193 {
1194  NS_LOG_FUNCTION_NOARGS();
1195 
1196  // Write the CID
1198 }
1199 
1200 uint8_t
1201 TxParamSetupAns::Deserialize(Buffer::Iterator& start)
1202 {
1203  NS_LOG_FUNCTION_NOARGS();
1204 
1205  // Consume the CID
1206  start.ReadU8();
1207 
1208  return m_serializedSize;
1209 }
1210 
1211 void
1212 TxParamSetupAns::Print(std::ostream& os) const
1213 {
1214  NS_LOG_FUNCTION_NOARGS();
1215 
1216  os << "TxParamSetupAns" << std::endl;
1217 }
1218 
1219 } // namespace ns3
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
uint8_t GetBattery(void)
Get the battery information contained in this MAC command.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
uint8_t GetMargin(void)
Get the demodulation margin contained in this MAC command.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
double GetMaximumAllowedDutyCycle(void) const
Get the maximum duty cycle prescribed by this Mac command, in fraction form.
static uint8_t GetCIDFromLorawanMacCommand(enum MacCommandType commandType)
Get the CID that corresponds to this MAC command.
enum MacCommandType m_commandType
The type of this command.
virtual uint8_t GetSerializedSize(void) const
Get serialized length of this MAC command.
static TypeId GetTypeId(void)
virtual enum MacCommandType GetCommandType(void) const
Get the commandType of this MAC command.
uint8_t m_serializedSize
This MAC command's serialized size.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
uint8_t GetMinDataRate(void)
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
uint8_t GetChannelIndex(void)
uint8_t GetMaxDataRate(void)
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
double m_frequency
The frequency in Hz
uint8_t GetRx1DrOffset(void)
Get this command's Rx1DrOffset parameter.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
uint8_t GetRx2DataRate(void)
Get this command's Rx2DataRate parameter.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
double GetFrequency(void)
Get this command's frequency.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
Time GetDelay(void)
Get the first window delay as a Time instance.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
virtual void Serialize(Buffer::Iterator &start) const
Serialize the contents of this MAC command into a buffer, according to the LoRaWAN standard.
virtual void Print(std::ostream &os) const
Print the contents of this MAC command in human-readable format.
virtual uint8_t Deserialize(Buffer::Iterator &start)
Deserialize the buffer into a MAC command.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
MacCommandType
Enum for every possible command type.
@ TX_PARAM_SETUP_ANS
@ RX_TIMING_SETUP_REQ
@ RX_TIMING_SETUP_ANS
@ RX_PARAM_SETUP_REQ
@ RX_PARAM_SETUP_ANS
@ TX_PARAM_SETUP_REQ