0.01.00
lowpan.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, The OpenThread Authors.
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 are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. Neither the name of the copyright holder nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
34 #ifndef LOWPAN_HPP_
35 #define LOWPAN_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/locator.hpp"
40 #include "common/message.hpp"
41 #include "mac/mac_frame.hpp"
42 #include "net/ip6.hpp"
43 #include "net/ip6_address.hpp"
44 
45 namespace ot {
46 
63 namespace Lowpan {
64 
69 struct Context
70 {
71  const uint8_t *mPrefix;
72  uint8_t mPrefixLength;
73  uint8_t mContextId;
75 };
76 
81 class Lowpan: public InstanceLocator
82 {
83 public:
90  explicit Lowpan(otInstance &aInstance);
91 
100  static bool IsLowpanHc(uint8_t *aHeader) {
101  return (aHeader[0] & (Lowpan::kHcDispatchMask >> 8)) == (Lowpan::kHcDispatch >> 8);
102  }
103 
115  int Compress(Message &aMessage, const Mac::Address &aMacSource, const Mac::Address &aMacDest, uint8_t *aBuf);
116 
130  int Decompress(Message &aMessage, const Mac::Address &aMacSource, const Mac::Address &aMacDest,
131  const uint8_t *aBuf, uint16_t aBufLen, uint16_t aDatagramLen);
132 
145  int DecompressBaseHeader(Ip6::Header &aHeader, const Mac::Address &aMacSource, const Mac::Address &aMacDest,
146  const uint8_t *aBuf, uint16_t aBufLength);
147 
148 private:
149  enum
150  {
151  kHcDispatch = 3 << 13,
152  kHcDispatchMask = 7 << 13,
153 
154  kHcTrafficClass = 1 << 11,
155  kHcFlowLabel = 2 << 11,
156  kHcTrafficFlow = 3 << 11,
157  kHcTrafficFlowMask = 3 << 11,
158  kHcNextHeader = 1 << 10,
159  kHcHopLimit1 = 1 << 8,
160  kHcHopLimit64 = 2 << 8,
161  kHcHopLimit255 = 3 << 8,
162  kHcHopLimitMask = 3 << 8,
163  kHcContextId = 1 << 7,
164  kHcSrcAddrContext = 1 << 6,
165  kHcSrcAddrMode0 = 0 << 4,
166  kHcSrcAddrMode1 = 1 << 4,
167  kHcSrcAddrMode2 = 2 << 4,
168  kHcSrcAddrMode3 = 3 << 4,
169  kHcSrcAddrModeMask = 3 << 4,
170  kHcMulticast = 1 << 3,
171  kHcDstAddrContext = 1 << 2,
172  kHcDstAddrMode0 = 0 << 0,
173  kHcDstAddrMode1 = 1 << 0,
174  kHcDstAddrMode2 = 2 << 0,
175  kHcDstAddrMode3 = 3 << 0,
176  kHcDstAddrModeMask = 3 << 0,
177 
178  kExtHdrDispatch = 0xe0,
179  kExtHdrDispatchMask = 0xf0,
180 
181  kExtHdrEidHbh = 0x00,
182  kExtHdrEidRouting = 0x02,
183  kExtHdrEidFragment = 0x04,
184  kExtHdrEidDst = 0x06,
185  kExtHdrEidMobility = 0x08,
186  kExtHdrEidIp6 = 0x0e,
187  kExtHdrEidMask = 0x0e,
188 
189  kExtHdrNextHeader = 0x01,
190 
191  kUdpDispatch = 0xf0,
192  kUdpDispatchMask = 0xf8,
193  kUdpChecksum = 1 << 2,
194  kUdpPortMask = 3 << 0,
195  };
196 
197  int CompressExtensionHeader(Message &aMessage, uint8_t *aBuf, uint8_t &aNextHeader);
198  int CompressSourceIid(const Mac::Address &aMacAddr, const Ip6::Address &aIpAddr, const Context &aContext,
199  uint16_t &aHcCtl, uint8_t *aBuf);
200  int CompressDestinationIid(const Mac::Address &aMacAddr, const Ip6::Address &aIpAddr, const Context &aContext,
201  uint16_t &aHcCtl, uint8_t *aBuf);
202  int CompressMulticast(const Ip6::Address &aIpAddr, uint16_t &aHcCtl, uint8_t *aBuf);
203  int CompressUdp(Message &aMessage, uint8_t *aBuf);
204 
205  int DecompressExtensionHeader(Message &aMessage, const uint8_t *aBuf, uint16_t aBufLength);
206  int DecompressUdpHeader(Message &aMessage, const uint8_t *aBuf, uint16_t aBufLength, uint16_t aDatagramLength);
207  otError DispatchToNextHeader(uint8_t aDispatch, Ip6::IpProto &aNextHeader);
208 
209  static otError CopyContext(const Context &aContext, Ip6::Address &aAddress);
210  static otError ComputeIid(const Mac::Address &aMacAddr, const Context &aContext, Ip6::Address &aIpAddress);
211 };
212 
219 {
220 public:
221  enum
222  {
223  kAdditionalHopsLeft = 1
224  };
225 
230  MeshHeader(void) { memset(this, 0, sizeof(*this)); }
231 
236  void Init(void) { mDispatchHopsLeft = kDispatch | kSourceShort | kDestinationShort; }
237 
248  otError Init(const uint8_t *aFrame, uint8_t aFrameLength);
249 
259  otError Init(const Message &aMessage);
260 
268  bool IsMeshHeader(void) { return (mDispatchHopsLeft & kDispatchMask) == kDispatch; }
269 
277  bool IsValid(void) { return (mDispatchHopsLeft & kSourceShort) && (mDispatchHopsLeft & kDestinationShort); }
278 
286  bool IsDeepHopsLeftField(void) { return (mDispatchHopsLeft & kHopsLeftMask) == kDeepHopsLeft; }
287 
294  uint8_t GetHeaderLength(void) { return sizeof(*this) - (IsDeepHopsLeftField() ? 0 : sizeof(mDeepHopsLeft)) ; }
295 
302  uint8_t GetHopsLeft(void) { return IsDeepHopsLeftField() ? mDeepHopsLeft : mDispatchHopsLeft & kHopsLeftMask; }
303 
310  void SetHopsLeft(uint8_t aHops) {
311  if (aHops < kDeepHopsLeft && !IsDeepHopsLeftField()) {
312  mDispatchHopsLeft = (mDispatchHopsLeft & ~kHopsLeftMask) | aHops;
313  }
314  else {
315  mDispatchHopsLeft = (mDispatchHopsLeft & ~kHopsLeftMask) | kDeepHopsLeft;
316  mDeepHopsLeft = aHops;
317  }
318  }
319 
326  uint16_t GetSource(void) { return HostSwap16(mAddress.mSource); }
327 
334  void SetSource(uint16_t aSource) { mAddress.mSource = HostSwap16(aSource); }
335 
342  uint16_t GetDestination(void) { return HostSwap16(mAddress.mDestination); }
343 
350  void SetDestination(uint16_t aDestination) { mAddress.mDestination = HostSwap16(aDestination); }
351 
358  void AppendTo(uint8_t *aFrame) {
359  *aFrame++ = mDispatchHopsLeft;
360 
361  if (IsDeepHopsLeftField()) {
362  *aFrame++ = mDeepHopsLeft;
363  }
364 
365  memcpy(aFrame, &mAddress, sizeof(mAddress));
366  }
367 
368 private:
369  enum
370  {
371  kDispatch = 2 << 6,
372  kDispatchMask = 3 << 6,
373  kHopsLeftMask = 0x0f,
374  kSourceShort = 1 << 5,
375  kDestinationShort = 1 << 4,
376  kDeepHopsLeft = 0x0f
377  };
378 
379  uint8_t mDispatchHopsLeft;
380  uint8_t mDeepHopsLeft;
381  struct OT_TOOL_PACKED_FIELD
382  {
383  uint16_t mSource;
384  uint16_t mDestination;
385  } mAddress;
387 
394 {
395 public:
400  FragmentHeader(void) { mDispatchSize = HostSwap16(kDispatch); mTag = 0; mOffset = 0; }
401 
406  void Init(void) { mDispatchSize = HostSwap16(kDispatch); }
407 
418  otError Init(const uint8_t *aFrame, uint8_t aFrameLength);
419 
427  bool IsFragmentHeader(void) { return (HostSwap16(mDispatchSize) & kDispatchMask) == kDispatch; }
428 
435  uint8_t GetHeaderLength(void) const { return IsOffsetPresent() ? sizeof(*this) : sizeof(*this) - sizeof(mOffset); }
436 
443  bool IsOffsetPresent(void) const { return (HostSwap16(mDispatchSize) & kOffset) != 0; }
444 
451  uint16_t GetDatagramSize(void) const { return HostSwap16(mDispatchSize) & kSizeMask; }
452 
459  void SetDatagramSize(uint16_t aSize) {
460  mDispatchSize = HostSwap16((HostSwap16(mDispatchSize) & ~kSizeMask) | (aSize & kSizeMask));
461  }
462 
469  uint16_t GetDatagramTag(void) const { return HostSwap16(mTag); }
470 
477  void SetDatagramTag(uint16_t aTag) { mTag = HostSwap16(aTag); }
478 
485  uint16_t GetDatagramOffset(void) const { return IsOffsetPresent() ? static_cast<uint16_t>(mOffset) * 8 : 0; }
486 
493  void SetDatagramOffset(uint16_t aOffset) {
494  if (aOffset == 0) {
495  mDispatchSize = HostSwap16(HostSwap16(mDispatchSize) & ~kOffset);
496  }
497  else {
498  mDispatchSize = HostSwap16(HostSwap16(mDispatchSize) | kOffset);
499  mOffset = (aOffset >> 3) & kOffsetMask;
500  }
501  }
502 
503 private:
504  enum
505  {
506  kDispatch = 3 << 14,
507  kOffset = 1 << 13,
508  kDispatchMask = 0xd800,
509  kSizeMask = 0x7ff,
510  kOffsetMask = 0xff,
511  };
512 
513  uint16_t mDispatchSize;
514  uint16_t mTag;
515  uint8_t mOffset;
517 
522 } // namespace Lowpan
523 } // namespace ot
524 
525 #endif // LOWPAN_HPP_
This class implements IPv6 header generation and parsing.
Definition: ip6_headers.hpp:136
This type represents all the static / global variables used by OpenThread allocated in one place...
Definition: openthread-instance.h:59
Definition: cli.cpp:90
void SetDestination(uint16_t aDestination)
This method sets the Mesh Destination address.
Definition: lowpan.hpp:350
This structure represents a LOWPAN_IPHC Context.
Definition: lowpan.hpp:69
This structure represents an IEEE 802.15.4 Short or Extended Address.
Definition: mac_frame.hpp:147
uint8_t mPrefixLength
The prefix length.
Definition: lowpan.hpp:72
void SetHopsLeft(uint8_t aHops)
This method sets the Hops Left value.
Definition: lowpan.hpp:310
void Init(void)
This method initializes the Fragment Header.
Definition: lowpan.hpp:406
This file includes definitions for IPv6 addresses.
This class implements an IPv6 address object.
Definition: ip6_address.hpp:60
This file includes definitions for locator class for OpenThread objects.
#define OT_TOOL_PACKED_FIELD
Indicate to the compiler a nested struct or union to be packed within byte packed class or struct...
Definition: toolchain.h:171
bool mCompressFlag
The Context compression flag.
Definition: lowpan.hpp:74
bool IsMeshHeader(void)
This method indicates whether or not the header is a Mesh Header.
Definition: lowpan.hpp:268
void SetDatagramSize(uint16_t aSize)
This method sets the Datagram Size value.
Definition: lowpan.hpp:459
bool IsFragmentHeader(void)
This method indicates whether or not the header is a Fragment Header.
Definition: lowpan.hpp:427
uint8_t mContextId
The Context ID.
Definition: lowpan.hpp:73
uint16_t GetSource(void)
This method returns the Mesh Source address.
Definition: lowpan.hpp:326
void SetDatagramTag(uint16_t aTag)
This method sets the Datagram Tag value.
Definition: lowpan.hpp:477
bool IsDeepHopsLeftField(void)
This method indicates whether or not the header contains Deep Hops Left field.
Definition: lowpan.hpp:286
uint16_t GetDestination(void)
This method returns the Mesh Destination address.
Definition: lowpan.hpp:342
#define OT_TOOL_PACKED_BEGIN
Compiler-specific indication that a class or struct must be byte packed.
Definition: toolchain.h:170
uint16_t GetDatagramOffset(void) const
This method returns the Datagram Offset value.
Definition: lowpan.hpp:485
void AppendTo(uint8_t *aFrame)
This method appends Mesh Header to the aFrame frame.
Definition: lowpan.hpp:358
uint16_t GetDatagramSize(void) const
This method returns the Datagram Size value.
Definition: lowpan.hpp:451
bool IsOffsetPresent(void) const
This method indicates whether or not the Offset field is present.
Definition: lowpan.hpp:443
IpProto
Internet Protocol Numbers.
Definition: ip6_headers.hpp:93
This file includes definitions for generating and processing IEEE 802.15.4 MAC frames.
uint8_t GetHopsLeft(void)
This method returns the Hops Left value.
Definition: lowpan.hpp:302
This class represents a message.
Definition: message.hpp:195
This class implements Mesh Header generation and processing.
Definition: lowpan.hpp:218
uint8_t GetHeaderLength(void) const
This method returns the Fragment Header length.
Definition: lowpan.hpp:435
void Init(void)
This method initializes the header.
Definition: lowpan.hpp:236
This file includes definitions for the message buffer pool and message buffers.
This class implements locator for otInstance object.
Definition: locator.hpp:63
FragmentHeader(void)
This constructor initializes the Fragment Header.
Definition: lowpan.hpp:400
bool IsValid(void)
This method indicates whether or not the Mesh Header appears to be well-formed.
Definition: lowpan.hpp:277
uint16_t GetDatagramTag(void) const
This method returns the Datagram Tag value.
Definition: lowpan.hpp:469
void SetDatagramOffset(uint16_t aOffset)
This method sets the Datagram Offset value.
Definition: lowpan.hpp:493
This class implements Fragment Header generation and parsing.
Definition: lowpan.hpp:393
#define OT_TOOL_PACKED_END
Compiler-specific indication at the end of a byte packed class or struct.
Definition: toolchain.h:172
const uint8_t * mPrefix
A pointer to the prefix.
Definition: lowpan.hpp:71
This file includes definitions for IPv6 packet processing.
This class implements LOWPAN_IPHC header compression.
Definition: lowpan.hpp:81
static bool IsLowpanHc(uint8_t *aHeader)
This method indicates whether or not the header is a LOWPAN_IPHC header.
Definition: lowpan.hpp:100
MeshHeader(void)
Default constructor for the object.
Definition: lowpan.hpp:230
void SetSource(uint16_t aSource)
This method sets the Mesh Source address.
Definition: lowpan.hpp:334
otError
This enumeration represents error codes used throughout OpenThread.
Definition: types.h:107
This file includes compile-time configuration constants for OpenThread.
uint8_t GetHeaderLength(void)
This static method returns the size of the Mesh Header in bytes.
Definition: lowpan.hpp:294