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 #include <iostream>
30 #include <list>
31 #include <ostream>
32 
33 namespace ns3
34 {
35 
36 NS_LOG_COMPONENT_DEFINE("LorawanLorawanMacCommand");
37 
38 NS_OBJECT_ENSURE_REGISTERED(LorawanMacCommand);
39 
40 TypeId
42 {
43  static TypeId tid = TypeId("ns3::LorawanMacCommand").SetParent<Object>();
44  return tid;
45 }
46 
48 {
49  NS_LOG_FUNCTION(this);
50 }
51 
53 {
54  NS_LOG_FUNCTION(this);
55 }
56 
57 enum MacCommandType
59 {
60  NS_LOG_FUNCTION_NOARGS();
61 
62  return m_commandType;
63 }
64 
65 uint8_t
67 {
68  NS_LOG_FUNCTION_NOARGS();
69 
70  return m_serializedSize;
71 }
72 
73 uint8_t
75 {
76  NS_LOG_FUNCTION_NOARGS();
77 
78  switch (commandType)
79  {
80  case (INVALID): {
81  return 0x0;
82  }
83  case (LINK_CHECK_REQ):
84  case (LINK_CHECK_ANS): {
85  return 0x02;
86  }
87  case (LINK_ADR_REQ):
88  case (LINK_ADR_ANS): {
89  return 0x03;
90  }
91  case (DUTY_CYCLE_REQ):
92  case (DUTY_CYCLE_ANS): {
93  return 0x04;
94  }
95  case (RX_PARAM_SETUP_REQ):
96  case (RX_PARAM_SETUP_ANS): {
97  return 0x05;
98  }
99  case (DEV_STATUS_REQ):
100  case (DEV_STATUS_ANS): {
101  return 0x06;
102  }
103  case (NEW_CHANNEL_REQ):
104  case (NEW_CHANNEL_ANS): {
105  return 0x07;
106  }
107  case (RX_TIMING_SETUP_REQ):
108  case (RX_TIMING_SETUP_ANS): {
109  return 0x08;
110  }
111  case (TX_PARAM_SETUP_REQ):
112  case (TX_PARAM_SETUP_ANS): {
113  return 0x09;
114  }
115  case (DL_CHANNEL_REQ):
116  case (DL_CHANNEL_ANS): {
117  return 0x0A;
118  }
119  }
120  return 0;
121 }
122 
124 // LinkCheckReq //
126 
128 {
129  NS_LOG_FUNCTION_NOARGS();
131  m_serializedSize = 1;
132 }
133 
135 {
136  NS_LOG_FUNCTION_NOARGS();
137 }
138 
139 void
140 LinkCheckReq::Serialize(Buffer::Iterator& start) const
141 {
142  NS_LOG_FUNCTION_NOARGS();
143 
144  // Write the CID and we're done
146  start.WriteU8(cid);
147  NS_LOG_DEBUG("Serialized LinkCheckReq: " << unsigned(cid));
148 }
149 
150 uint8_t
151 LinkCheckReq::Deserialize(Buffer::Iterator& start)
152 {
153  NS_LOG_FUNCTION_NOARGS();
154 
155  // Read the CID
156  start.ReadU8();
157 
158  return m_serializedSize;
159 }
160 
161 void
162 LinkCheckReq::Print(std::ostream& os) const
163 {
164  NS_LOG_FUNCTION_NOARGS();
165 
166  os << "LinkCheckReq" << std::endl;
167 }
168 
170 // LinkCheckAns //
172 
174  : m_margin(0),
175  m_gwCnt(0)
176 {
177  NS_LOG_FUNCTION(this);
178 
180  m_serializedSize = 3;
181 }
182 
183 LinkCheckAns::LinkCheckAns(uint8_t margin, uint8_t gwCnt)
184  : m_margin(margin),
185  m_gwCnt(gwCnt)
186 {
187  NS_LOG_FUNCTION(this << unsigned(margin) << unsigned(gwCnt));
188 
190  m_serializedSize = 3;
191 }
192 
193 void
194 LinkCheckAns::Serialize(Buffer::Iterator& start) const
195 {
196  NS_LOG_FUNCTION_NOARGS();
197 
198  // Write the CID
200  // Write the margin
201  start.WriteU8(m_margin);
202  // Write the gwCnt
203  start.WriteU8(m_gwCnt);
204 }
205 
206 uint8_t
207 LinkCheckAns::Deserialize(Buffer::Iterator& start)
208 {
209  NS_LOG_FUNCTION_NOARGS();
210 
211  // Consume the CID
212  start.ReadU8();
213  m_margin = start.ReadU8();
214  m_gwCnt = start.ReadU8();
215  return m_serializedSize;
216 }
217 
218 void
219 LinkCheckAns::Print(std::ostream& os) const
220 {
221  NS_LOG_FUNCTION_NOARGS();
222 
223  os << "LinkCheckAns" << std::endl;
224  os << "margin: " << unsigned(m_margin) << std::endl;
225  os << "gwCnt: " << unsigned(m_gwCnt) << std::endl;
226 }
227 
228 void
229 LinkCheckAns::SetMargin(uint8_t margin)
230 {
231  NS_LOG_FUNCTION(this << unsigned(margin));
232 
233  m_margin = margin;
234 }
235 
236 uint8_t
238 {
239  NS_LOG_FUNCTION(this);
240 
241  return m_margin;
242 }
243 
244 void
246 {
247  NS_LOG_FUNCTION(this << unsigned(gwCnt));
248 
249  m_gwCnt = gwCnt;
250 }
251 
252 uint8_t
254 {
255  NS_LOG_FUNCTION(this);
256 
257  return m_gwCnt;
258 }
259 
260 void
262 {
263  NS_LOG_FUNCTION(this);
264 
265  m_gwCnt++;
266 }
267 
269 // LinkAdrReq //
271 
273 {
274  NS_LOG_FUNCTION(this);
275 
277  m_serializedSize = 5;
278 }
279 
280 LinkAdrReq::LinkAdrReq(uint8_t dataRate,
281  uint8_t txPower,
282  uint16_t channelMask,
283  uint8_t chMaskCntl,
284  uint8_t nbRep)
285  : m_dataRate(dataRate),
286  m_txPower(txPower),
287  m_channelMask(channelMask),
288  m_chMaskCntl(chMaskCntl),
289  m_nbRep(nbRep)
290 {
291  NS_LOG_FUNCTION(this);
292 
294  m_serializedSize = 5;
295 }
296 
297 void
298 LinkAdrReq::Serialize(Buffer::Iterator& start) const
299 {
300  NS_LOG_FUNCTION_NOARGS();
301 
302  // Write the CID
304  start.WriteU8(m_dataRate << 4 | (m_txPower & 0b1111));
305  start.WriteU16(m_channelMask);
306  start.WriteU8(m_chMaskCntl << 4 | (m_nbRep & 0b1111));
307 }
308 
309 uint8_t
310 LinkAdrReq::Deserialize(Buffer::Iterator& start)
311 {
312  NS_LOG_FUNCTION_NOARGS();
313 
314  // Consume the CID
315  start.ReadU8();
316  uint8_t firstByte = start.ReadU8();
317  m_dataRate = firstByte >> 4;
318  m_txPower = firstByte & 0b1111;
319  m_channelMask = start.ReadU16();
320  uint8_t fourthByte = start.ReadU8();
321  m_chMaskCntl = fourthByte >> 4;
322  m_nbRep = fourthByte & 0b1111;
323 
324  return m_serializedSize;
325 }
326 
327 void
328 LinkAdrReq::Print(std::ostream& os) const
329 {
330  NS_LOG_FUNCTION_NOARGS();
331 
332  os << "LinkAdrReq" << std::endl;
333  os << "dataRate: " << unsigned(m_dataRate) << std::endl;
334  os << "txPower: " << unsigned(m_txPower) << std::endl;
335  os << "channelMask: " << std::bitset<16>(m_channelMask) << std::endl;
336  os << "chMaskCntl: " << unsigned(m_chMaskCntl) << std::endl;
337  os << "nbRep: " << unsigned(m_nbRep) << std::endl;
338 }
339 
340 uint8_t
342 {
343  NS_LOG_FUNCTION(this);
344 
345  return m_dataRate;
346 }
347 
348 uint8_t
350 {
351  NS_LOG_FUNCTION(this);
352 
353  return m_txPower;
354 }
355 
356 std::list<int>
358 {
359  NS_LOG_FUNCTION(this);
360 
361  std::list<int> channelIndices;
362  for (int i = 0; i < 16; i++)
363  {
364  if (m_channelMask & (0b1 << i)) // Take channel mask's i-th bit
365  {
366  NS_LOG_DEBUG("Adding channel index " << i);
367  channelIndices.push_back(i);
368  }
369  }
370 
371  return channelIndices;
372 }
373 
374 int
376 {
377  NS_LOG_FUNCTION(this);
378 
379  return m_nbRep;
380 }
381 
383 // LinkAdrAns //
385 
387 {
388  NS_LOG_FUNCTION(this);
389 
391  m_serializedSize = 2;
392 }
393 
394 LinkAdrAns::LinkAdrAns(bool powerAck, bool dataRateAck, bool channelMaskAck)
395  : m_powerAck(powerAck),
396  m_dataRateAck(dataRateAck),
397  m_channelMaskAck(channelMaskAck)
398 {
399  NS_LOG_FUNCTION(this);
400 
402  m_serializedSize = 2;
403 }
404 
405 void
406 LinkAdrAns::Serialize(Buffer::Iterator& start) const
407 {
408  NS_LOG_FUNCTION_NOARGS();
409 
410  // Write the CID
412  // We can assume that true will be converted to 1 and that false will be
413  // converted to 0 on any C++ compiler
414  start.WriteU8((uint8_t(m_powerAck) << 2) | (uint8_t(m_dataRateAck) << 1) |
415  uint8_t(m_channelMaskAck));
416 }
417 
418 uint8_t
419 LinkAdrAns::Deserialize(Buffer::Iterator& start)
420 {
421  NS_LOG_FUNCTION_NOARGS();
422 
423  // Consume the CID
424  start.ReadU8();
425 
426  uint8_t byte = start.ReadU8();
427 
428  m_powerAck = byte & 0b100;
429  m_dataRateAck = byte & 0b10;
430  m_channelMaskAck = byte & 0b1;
431 
432  return m_serializedSize;
433 }
434 
435 void
436 LinkAdrAns::Print(std::ostream& os) const
437 {
438  NS_LOG_FUNCTION_NOARGS();
439 
440  os << "LinkAdrAns" << std::endl;
441 }
442 
444 // DutyCycleReq //
446 
448 {
449  NS_LOG_FUNCTION(this);
450 
452  m_serializedSize = 2;
453 }
454 
455 DutyCycleReq::DutyCycleReq(uint8_t dutyCycle)
456  : m_maxDCycle(dutyCycle)
457 {
458  NS_LOG_FUNCTION(this);
459 
461  m_serializedSize = 2;
462 }
463 
464 void
465 DutyCycleReq::Serialize(Buffer::Iterator& start) const
466 {
467  NS_LOG_FUNCTION_NOARGS();
468 
469  // Write the CID
471  start.WriteU8(m_maxDCycle);
472 }
473 
474 uint8_t
475 DutyCycleReq::Deserialize(Buffer::Iterator& start)
476 {
477  NS_LOG_FUNCTION_NOARGS();
478 
479  // Consume the CID
480  start.ReadU8();
481  m_maxDCycle = start.ReadU8();
482 
483  return m_serializedSize;
484 }
485 
486 void
487 DutyCycleReq::Print(std::ostream& os) const
488 {
489  NS_LOG_FUNCTION_NOARGS();
490 
491  os << "DutyCycleReq" << std::endl;
492  os << "maxDCycle: " << unsigned(m_maxDCycle) << std::endl;
493  os << "maxDCycle (fraction): " << GetMaximumAllowedDutyCycle() << std::endl;
494 }
495 
496 double
498 {
499  NS_LOG_FUNCTION(this);
500 
501  // Check if we need to turn off completely
502  if (m_maxDCycle == 255)
503  {
504  return 0;
505  }
506 
507  if (m_maxDCycle == 0)
508  {
509  return 1;
510  }
511 
512  return 1 / std::pow(2, double(m_maxDCycle));
513 }
514 
516 // DutyCycleAns //
518 
520 {
521  NS_LOG_FUNCTION(this);
522 
524  m_serializedSize = 1;
525 }
526 
527 void
528 DutyCycleAns::Serialize(Buffer::Iterator& start) const
529 {
530  NS_LOG_FUNCTION_NOARGS();
531 
532  // Write the CID
534 }
535 
536 uint8_t
537 DutyCycleAns::Deserialize(Buffer::Iterator& start)
538 {
539  NS_LOG_FUNCTION_NOARGS();
540 
541  // Consume the CID
542  start.ReadU8();
543  return m_serializedSize;
544 }
545 
546 void
547 DutyCycleAns::Print(std::ostream& os) const
548 {
549  NS_LOG_FUNCTION_NOARGS();
550 
551  os << "DutyCycleAns" << std::endl;
552 }
553 
555 // RxParamSetupReq //
557 
559 {
560  NS_LOG_FUNCTION(this);
561 
563  m_serializedSize = 5;
564 }
565 
566 RxParamSetupReq::RxParamSetupReq(uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequency)
567  : m_rx1DrOffset(rx1DrOffset),
568  m_rx2DataRate(rx2DataRate),
569  m_frequency(frequency)
570 {
571  NS_LOG_FUNCTION(this << unsigned(rx1DrOffset) << unsigned(rx2DataRate) << frequency);
572 
573  if ((rx1DrOffset & 0b11111000) != 0)
574  {
575  NS_LOG_WARN(
576  "Warning: received an rx1DrOffset greater than 7. Actual value will be different.");
577  }
578  if ((rx2DataRate & 0b11110000) != 0)
579  {
580  NS_LOG_WARN(
581  "Warning: received a rx2DataRate greater than 15. Actual value will be different.");
582  }
583 
585  m_serializedSize = 5;
586 }
587 
588 void
589 RxParamSetupReq::Serialize(Buffer::Iterator& start) const
590 {
591  NS_LOG_FUNCTION_NOARGS();
592 
593  // Write the CID
595  // Data serialization
596  start.WriteU8((m_rx1DrOffset & 0b111) << 4 | (m_rx2DataRate & 0b1111));
597  uint32_t encodedFrequency = uint32_t(m_frequency / 100);
598  NS_LOG_DEBUG(unsigned(encodedFrequency));
599  NS_LOG_DEBUG(std::bitset<32>(encodedFrequency));
600  start.WriteU8((encodedFrequency & 0xff0000) >> 16); // Most significant byte
601  start.WriteU8((encodedFrequency & 0xff00) >> 8); // Middle byte
602  start.WriteU8(encodedFrequency & 0xff); // Least significant byte
603 }
604 
605 uint8_t
606 RxParamSetupReq::Deserialize(Buffer::Iterator& start)
607 {
608  NS_LOG_FUNCTION_NOARGS();
609 
610  // Consume the CID
611  start.ReadU8();
612  // Data serialization
613  uint8_t firstByte = start.ReadU8();
614  m_rx1DrOffset = (firstByte & 0b1110000) >> 4;
615  m_rx2DataRate = firstByte & 0b1111;
616  uint32_t secondByte = start.ReadU8();
617  uint32_t thirdByte = start.ReadU8();
618  uint32_t fourthByte = start.ReadU8();
619  uint32_t encodedFrequency = (secondByte << 16) | (thirdByte << 8) | fourthByte;
620  NS_LOG_DEBUG(std::bitset<32>(encodedFrequency));
621  m_frequency = double(encodedFrequency) * 100;
622 
623  return m_serializedSize;
624 }
625 
626 void
627 RxParamSetupReq::Print(std::ostream& os) const
628 {
629  NS_LOG_FUNCTION_NOARGS();
630 
631  os << "RxParamSetupReq" << std::endl;
632  os << "rx1DrOffset: " << unsigned(m_rx1DrOffset) << std::endl;
633  os << "rx2DataRate: " << unsigned(m_rx2DataRate) << std::endl;
634  os << "frequency: " << m_frequency << std::endl;
635 }
636 
637 uint8_t
639 {
640  NS_LOG_FUNCTION(this);
641 
642  return m_rx1DrOffset;
643 }
644 
645 uint8_t
647 {
648  NS_LOG_FUNCTION(this);
649 
650  return m_rx2DataRate;
651 }
652 
653 double
655 {
656  NS_LOG_FUNCTION(this);
657 
658  return m_frequency;
659 }
660 
662 // RxParamSetupAns //
664 
666 {
667  NS_LOG_FUNCTION(this);
668 
670  m_serializedSize = 2;
671 }
672 
673 RxParamSetupAns::RxParamSetupAns(bool rx1DrOffsetAck, bool rx2DataRateAck, bool channelAck)
674  : m_rx1DrOffsetAck(rx1DrOffsetAck),
675  m_rx2DataRateAck(rx2DataRateAck),
676  m_channelAck(channelAck)
677 {
678  NS_LOG_FUNCTION(this << rx1DrOffsetAck << rx2DataRateAck << channelAck);
679 
681  m_serializedSize = 2;
682 }
683 
684 void
685 RxParamSetupAns::Serialize(Buffer::Iterator& start) const
686 {
687  NS_LOG_FUNCTION_NOARGS();
688 
689  // Write the CID
691  // Data serialization
692  start.WriteU8(uint8_t(m_rx1DrOffsetAck) << 2 | uint8_t(m_rx2DataRateAck) << 1 |
693  uint8_t(m_channelAck));
694 }
695 
696 uint8_t
697 RxParamSetupAns::Deserialize(Buffer::Iterator& start)
698 {
699  NS_LOG_FUNCTION_NOARGS();
700 
701  // Consume the CID
702  start.ReadU8();
703 
704  uint8_t byte = start.ReadU8();
705 
706  m_rx1DrOffsetAck = (byte & 0b100) >> 2;
707  m_rx2DataRateAck = (byte & 0b10) >> 1;
708  m_channelAck = byte & 0b1;
709 
710  return m_serializedSize;
711 }
712 
713 void
714 RxParamSetupAns::Print(std::ostream& os) const
715 {
716  NS_LOG_FUNCTION_NOARGS();
717 
718  os << "RxParamSetupAns" << std::endl;
719  os << "m_rx1DrOffsetAck: " << m_rx1DrOffsetAck << std::endl;
720  os << "m_rx2DataRateAck: " << m_rx2DataRateAck << std::endl;
721  os << "m_channelAck: " << m_channelAck << std::endl;
722 }
723 
725 // DevStatusReq //
727 
729 {
730  NS_LOG_FUNCTION(this);
731 
733  m_serializedSize = 1;
734 }
735 
736 void
737 DevStatusReq::Serialize(Buffer::Iterator& start) const
738 {
739  NS_LOG_FUNCTION_NOARGS();
740 
741  // Write the CID
743 }
744 
745 uint8_t
746 DevStatusReq::Deserialize(Buffer::Iterator& start)
747 {
748  NS_LOG_FUNCTION_NOARGS();
749 
750  // Consume the CID
751  start.ReadU8();
752 
753  return m_serializedSize;
754 }
755 
756 void
757 DevStatusReq::Print(std::ostream& os) const
758 {
759  NS_LOG_FUNCTION_NOARGS();
760 
761  os << "DevStatusReq" << std::endl;
762 }
763 
765 // DevStatusAns //
767 
769 {
770  NS_LOG_FUNCTION(this);
771 
773  m_serializedSize = 3;
774 }
775 
776 DevStatusAns::DevStatusAns(uint8_t battery, uint8_t margin)
777  : m_battery(battery),
778  m_margin(margin)
779 {
780  NS_LOG_FUNCTION(this << unsigned(battery) << unsigned(margin));
781 
783  m_serializedSize = 3;
784 }
785 
786 void
787 DevStatusAns::Serialize(Buffer::Iterator& start) const
788 {
789  NS_LOG_FUNCTION_NOARGS();
790 
791  // Write the CID
793  start.WriteU8(m_battery);
794  start.WriteU8(m_margin);
795 }
796 
797 uint8_t
798 DevStatusAns::Deserialize(Buffer::Iterator& start)
799 {
800  NS_LOG_FUNCTION_NOARGS();
801 
802  // Consume the CID
803  start.ReadU8();
804  m_battery = start.ReadU8();
805  m_margin = start.ReadU8() & 0b111111;
806 
807  return m_serializedSize;
808 }
809 
810 void
811 DevStatusAns::Print(std::ostream& os) const
812 {
813  NS_LOG_FUNCTION_NOARGS();
814 
815  os << "DevStatusAns" << std::endl;
816  os << "Battery: " << unsigned(m_battery) << std::endl;
817  os << "Margin: " << unsigned(m_margin) << std::endl;
818 }
819 
820 uint8_t
822 {
823  NS_LOG_FUNCTION_NOARGS();
824 
825  return m_battery;
826 }
827 
828 uint8_t
830 {
831  NS_LOG_FUNCTION_NOARGS();
832 
833  return m_margin;
834 }
835 
837 // NewChannelReq //
839 
841 {
842  NS_LOG_FUNCTION(this);
843 
845  m_serializedSize = 6;
846 }
847 
849  double frequency,
850  uint8_t minDataRate,
851  uint8_t maxDataRate)
852  : m_chIndex(chIndex),
853  m_frequency(frequency),
854  m_minDataRate(minDataRate),
855  m_maxDataRate(maxDataRate)
856 {
857  NS_LOG_FUNCTION(this);
858 
860  m_serializedSize = 6;
861 }
862 
863 void
864 NewChannelReq::Serialize(Buffer::Iterator& start) const
865 {
866  NS_LOG_FUNCTION_NOARGS();
867 
868  // Write the CID
870 
871  start.WriteU8(m_chIndex);
872  uint32_t encodedFrequency = uint32_t(m_frequency / 100);
873  start.WriteU8((encodedFrequency & 0xff0000) >> 16);
874  start.WriteU8((encodedFrequency & 0xff00) >> 8);
875  start.WriteU8(encodedFrequency & 0xff);
876  start.WriteU8((m_maxDataRate << 4) | (m_minDataRate & 0xf));
877 }
878 
879 uint8_t
880 NewChannelReq::Deserialize(Buffer::Iterator& start)
881 {
882  NS_LOG_FUNCTION_NOARGS();
883 
884  // Consume the CID
885  start.ReadU8();
886  // Read the data
887  m_chIndex = start.ReadU8();
888  uint32_t encodedFrequency = 0;
889  encodedFrequency |= uint32_t(start.ReadU16()) << 8;
890  encodedFrequency |= uint32_t(start.ReadU8());
891  m_frequency = double(encodedFrequency) * 100;
892  uint8_t dataRateByte = start.ReadU8();
893  m_maxDataRate = dataRateByte >> 4;
894  m_minDataRate = dataRateByte & 0xf;
895 
896  return m_serializedSize;
897 }
898 
899 void
900 NewChannelReq::Print(std::ostream& os) const
901 {
902  NS_LOG_FUNCTION_NOARGS();
903 
904  os << "NewChannelReq" << std::endl;
905 }
906 
907 uint8_t
909 {
910  NS_LOG_FUNCTION_NOARGS();
911 
912  return m_chIndex;
913 }
914 
915 double
917 {
918  NS_LOG_FUNCTION_NOARGS();
919 
920  return m_frequency;
921 }
922 
923 uint8_t
925 {
926  NS_LOG_FUNCTION_NOARGS();
927 
928  return m_minDataRate;
929 }
930 
931 uint8_t
933 {
934  NS_LOG_FUNCTION_NOARGS();
935 
936  return m_maxDataRate;
937 }
938 
940 // NewChannelAns //
942 
944 {
945  NS_LOG_FUNCTION(this);
946 
948  m_serializedSize = 2;
949 }
950 
951 NewChannelAns::NewChannelAns(bool dataRateRangeOk, bool channelFrequencyOk)
952  : m_dataRateRangeOk(dataRateRangeOk),
953  m_channelFrequencyOk(channelFrequencyOk)
954 {
955  NS_LOG_FUNCTION(this);
956 
958  m_serializedSize = 2;
959 }
960 
961 void
962 NewChannelAns::Serialize(Buffer::Iterator& start) const
963 {
964  NS_LOG_FUNCTION_NOARGS();
965 
966  // Write the CID
968 
969  start.WriteU8((uint8_t(m_dataRateRangeOk) << 1) | uint8_t(m_channelFrequencyOk));
970 }
971 
972 uint8_t
973 NewChannelAns::Deserialize(Buffer::Iterator& start)
974 {
975  NS_LOG_FUNCTION_NOARGS();
976 
977  // Consume the CID
978  start.ReadU8();
979  // Read the data
980  uint8_t byte = start.ReadU8();
981  m_dataRateRangeOk = (byte & 0b10) >> 1;
982  m_channelFrequencyOk = (byte & 0b1);
983 
984  return m_serializedSize;
985 }
986 
987 void
988 NewChannelAns::Print(std::ostream& os) const
989 {
990  NS_LOG_FUNCTION_NOARGS();
991 
992  os << "NewChannelAns" << std::endl;
993  os << "DataRateRangeOk: " << m_dataRateRangeOk << std::endl;
994  os << "ChannelFrequencyOk: " << m_channelFrequencyOk << std::endl;
995 }
996 
998 // RxTimingSetupReq //
1000 
1002 {
1003  NS_LOG_FUNCTION(this);
1004 
1006  m_serializedSize = 2;
1007 }
1008 
1010  : m_delay(delay)
1011 {
1012  NS_LOG_FUNCTION(this);
1013 
1015  m_serializedSize = 2;
1016 }
1017 
1018 void
1019 RxTimingSetupReq::Serialize(Buffer::Iterator& start) const
1020 {
1021  NS_LOG_FUNCTION_NOARGS();
1022 
1023  // Write the CID
1025  // Write the data
1026  start.WriteU8(m_delay & 0xf);
1027 }
1028 
1029 uint8_t
1030 RxTimingSetupReq::Deserialize(Buffer::Iterator& start)
1031 {
1032  NS_LOG_FUNCTION_NOARGS();
1033 
1034  // Consume the CID
1035  start.ReadU8();
1036  // Read the data
1037  m_delay = start.ReadU8() & 0xf;
1038 
1039  return m_serializedSize;
1040 }
1041 
1042 void
1043 RxTimingSetupReq::Print(std::ostream& os) const
1044 {
1045  NS_LOG_FUNCTION_NOARGS();
1046 
1047  os << "RxTimingSetupReq" << std::endl;
1048 }
1049 
1050 Time
1052 {
1053  NS_LOG_FUNCTION(this);
1054 
1055  if (m_delay == 0)
1056  {
1057  return Seconds(1);
1058  }
1059  return Seconds(m_delay);
1060 }
1061 
1063 // RxTimingSetupAns //
1065 
1067 {
1068  NS_LOG_FUNCTION(this);
1069 
1071  m_serializedSize = 1;
1072 }
1073 
1074 void
1075 RxTimingSetupAns::Serialize(Buffer::Iterator& start) const
1076 {
1077  NS_LOG_FUNCTION_NOARGS();
1078 
1079  // Write the CID
1081 }
1082 
1083 uint8_t
1084 RxTimingSetupAns::Deserialize(Buffer::Iterator& start)
1085 {
1086  NS_LOG_FUNCTION_NOARGS();
1087 
1088  // Consume the CID
1089  start.ReadU8();
1090 
1091  return m_serializedSize;
1092 }
1093 
1094 void
1095 RxTimingSetupAns::Print(std::ostream& os) const
1096 {
1097  NS_LOG_FUNCTION_NOARGS();
1098 
1099  os << "RxTimingSetupAns" << std::endl;
1100 }
1101 
1103 // DlChannelAns //
1105 
1107 {
1108  NS_LOG_FUNCTION(this);
1109 
1111  m_serializedSize = 1;
1112 }
1113 
1114 void
1115 DlChannelAns::Serialize(Buffer::Iterator& start) const
1116 {
1117  NS_LOG_FUNCTION_NOARGS();
1118 
1119  // Write the CID
1121 }
1122 
1123 uint8_t
1124 DlChannelAns::Deserialize(Buffer::Iterator& start)
1125 {
1126  NS_LOG_FUNCTION_NOARGS();
1127 
1128  // Consume the CID
1129  start.ReadU8();
1130 
1131  return m_serializedSize;
1132 }
1133 
1134 void
1135 DlChannelAns::Print(std::ostream& os) const
1136 {
1137  NS_LOG_FUNCTION_NOARGS();
1138 
1139  os << "DlChannelAns" << std::endl;
1140 }
1141 
1143 // TxParamSetupReq //
1145 
1147 {
1148  NS_LOG_FUNCTION(this);
1149 
1151  m_serializedSize = 1;
1152 }
1153 
1154 void
1155 TxParamSetupReq::Serialize(Buffer::Iterator& start) const
1156 {
1157  NS_LOG_FUNCTION_NOARGS();
1158 
1159  // Write the CID
1161 }
1162 
1163 uint8_t
1164 TxParamSetupReq::Deserialize(Buffer::Iterator& start)
1165 {
1166  NS_LOG_FUNCTION_NOARGS();
1167 
1168  // Consume the CID
1169  start.ReadU8();
1170 
1171  return m_serializedSize;
1172 }
1173 
1174 void
1175 TxParamSetupReq::Print(std::ostream& os) const
1176 {
1177  NS_LOG_FUNCTION_NOARGS();
1178 
1179  os << "TxParamSetupReq" << std::endl;
1180 }
1181 
1183 // TxParamSetupAns //
1185 
1187 {
1188  NS_LOG_FUNCTION(this);
1189 
1191  m_serializedSize = 1;
1192 }
1193 
1194 void
1195 TxParamSetupAns::Serialize(Buffer::Iterator& start) const
1196 {
1197  NS_LOG_FUNCTION_NOARGS();
1198 
1199  // Write the CID
1201 }
1202 
1203 uint8_t
1204 TxParamSetupAns::Deserialize(Buffer::Iterator& start)
1205 {
1206  NS_LOG_FUNCTION_NOARGS();
1207 
1208  // Consume the CID
1209  start.ReadU8();
1210 
1211  return m_serializedSize;
1212 }
1213 
1214 void
1215 TxParamSetupAns::Print(std::ostream& os) const
1216 {
1217  NS_LOG_FUNCTION_NOARGS();
1218 
1219  os << "TxParamSetupAns" << std::endl;
1220 }
1221 
1222 } // 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