1 /*
2 * Copyright (c) 2022, 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
29 /**
30 * @file
31 * This file implements function for generating and processing MLE TLVs.
32 */
33
34 #include "mle_tlvs.hpp"
35
36 #include "common/clearable.hpp"
37 #include "common/code_utils.hpp"
38 #include "common/numeric_limits.hpp"
39 #include "radio/radio.hpp"
40
41 namespace ot {
42 namespace Mle {
43
44 #if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
45
Init(void)46 void RouteTlv::Init(void)
47 {
48 SetType(kRoute);
49 SetLength(sizeof(*this) - sizeof(Tlv));
50 mRouterIdMask.Clear();
51 ClearAllBytes(mRouteData);
52 }
53
IsValid(void) const54 bool RouteTlv::IsValid(void) const
55 {
56 bool isValid = false;
57 uint8_t numAllocatedIds;
58
59 VerifyOrExit(GetLength() >= sizeof(mRouterIdSequence) + sizeof(mRouterIdMask));
60
61 numAllocatedIds = mRouterIdMask.GetNumberOfAllocatedIds();
62 VerifyOrExit(numAllocatedIds <= Mle::kMaxRouters);
63
64 isValid = (GetRouteDataLength() >= numAllocatedIds);
65
66 exit:
67 return isValid;
68 }
69
70 #endif // #if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
71
IncrementLinkQuality(LinkQuality aLinkQuality)72 void ConnectivityTlv::IncrementLinkQuality(LinkQuality aLinkQuality)
73 {
74 switch (aLinkQuality)
75 {
76 case kLinkQuality0:
77 break;
78 case kLinkQuality1:
79 mLinkQuality1++;
80 break;
81 case kLinkQuality2:
82 mLinkQuality2++;
83 break;
84 case kLinkQuality3:
85 mLinkQuality3++;
86 break;
87 }
88 }
89
GetParentPriority(void) const90 int8_t ConnectivityTlv::GetParentPriority(void) const
91 {
92 return Preference::From2BitUint(mFlags >> kFlagsParentPriorityOffset);
93 }
94
SetParentPriority(int8_t aParentPriority)95 void ConnectivityTlv::SetParentPriority(int8_t aParentPriority)
96 {
97 mFlags = static_cast<uint8_t>(Preference::To2BitUint(aParentPriority) << kFlagsParentPriorityOffset);
98 }
99
SetChannelAndPage(uint16_t aChannel)100 void ChannelTlvValue::SetChannelAndPage(uint16_t aChannel)
101 {
102 uint8_t channelPage = OT_RADIO_CHANNEL_PAGE_0;
103
104 #if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
105 if ((OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN <= aChannel) && (aChannel <= OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX))
106 {
107 channelPage = OT_RADIO_CHANNEL_PAGE_2;
108 }
109 #endif
110
111 #if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
112 if ((OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN == aChannel) ||
113 ((OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN < aChannel) &&
114 (aChannel <= OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX)))
115 {
116 channelPage = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE;
117 }
118 #endif
119
120 SetChannelPage(channelPage);
121 SetChannel(aChannel);
122 }
123
IsValid(void) const124 bool ChannelTlvValue::IsValid(void) const
125 {
126 bool isValid = false;
127 uint16_t channel;
128
129 VerifyOrExit(Radio::SupportsChannelPage(mChannelPage));
130
131 channel = GetChannel();
132 VerifyOrExit((Radio::kChannelMin <= channel) && (channel <= Radio::kChannelMax));
133
134 isValid = true;
135
136 exit:
137 return isValid;
138 }
139
140 } // namespace Mle
141 } // namespace ot
142