• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016-2019, 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 MAC types.
32  */
33 
34 #include "mac_types.hpp"
35 
36 #include <stdio.h>
37 
38 #include "common/code_utils.hpp"
39 #include "common/random.hpp"
40 #include "common/string.hpp"
41 
42 namespace ot {
43 namespace Mac {
44 
GenerateRandomPanId(void)45 PanId GenerateRandomPanId(void)
46 {
47     PanId panId;
48 
49     do
50     {
51         panId = Random::NonCrypto::GetUint16();
52     } while (panId == kPanIdBroadcast);
53 
54     return panId;
55 }
56 
57 #if OPENTHREAD_FTD || OPENTHREAD_MTD
GenerateRandom(void)58 void ExtAddress::GenerateRandom(void)
59 {
60     IgnoreError(Random::Crypto::Fill(*this));
61     SetGroup(false);
62     SetLocal(true);
63 }
64 #endif
65 
operator ==(const ExtAddress & aOther) const66 bool ExtAddress::operator==(const ExtAddress &aOther) const { return (memcmp(m8, aOther.m8, sizeof(m8)) == 0); }
67 
ToString(void) const68 ExtAddress::InfoString ExtAddress::ToString(void) const
69 {
70     InfoString string;
71 
72     string.AppendHexBytes(m8, sizeof(ExtAddress));
73 
74     return string;
75 }
76 
CopyAddress(uint8_t * aDst,const uint8_t * aSrc,CopyByteOrder aByteOrder)77 void ExtAddress::CopyAddress(uint8_t *aDst, const uint8_t *aSrc, CopyByteOrder aByteOrder)
78 {
79     switch (aByteOrder)
80     {
81     case kNormalByteOrder:
82         memcpy(aDst, aSrc, sizeof(ExtAddress));
83         break;
84 
85     case kReverseByteOrder:
86         aSrc += sizeof(ExtAddress) - 1;
87         for (uint8_t len = sizeof(ExtAddress); len > 0; len--)
88         {
89             *aDst++ = *aSrc--;
90         }
91         break;
92     }
93 }
94 
operator ==(const Address & aOther) const95 bool Address::operator==(const Address &aOther) const
96 {
97     bool ret = false;
98 
99     VerifyOrExit(GetType() == aOther.GetType());
100 
101     switch (GetType())
102     {
103     case kTypeNone:
104         ret = true;
105         break;
106 
107     case kTypeShort:
108         ret = (GetShort() == aOther.GetShort());
109         break;
110 
111     case kTypeExtended:
112         ret = (GetExtended() == aOther.GetExtended());
113         break;
114 
115     default:
116         OT_ASSERT(false);
117         break;
118     }
119 
120 exit:
121     return ret;
122 }
123 
ToString(void) const124 Address::InfoString Address::ToString(void) const
125 {
126     InfoString string;
127 
128     if (mType == kTypeExtended)
129     {
130         string.AppendHexBytes(GetExtended().m8, sizeof(ExtAddress));
131     }
132     else if (mType == kTypeNone)
133     {
134         string.Append("None");
135     }
136     else
137     {
138         string.Append("0x%04x", GetShort());
139     }
140 
141     return string;
142 }
143 
SetSource(PanId aPanId)144 void PanIds::SetSource(PanId aPanId)
145 {
146     mSource          = aPanId;
147     mIsSourcePresent = true;
148 }
149 
SetDestination(PanId aPanId)150 void PanIds::SetDestination(PanId aPanId)
151 {
152     mDestination          = aPanId;
153     mIsDestinationPresent = true;
154 }
155 
SetBothSourceDestination(PanId aPanId)156 void PanIds::SetBothSourceDestination(PanId aPanId)
157 {
158     SetSource(aPanId);
159     SetDestination(aPanId);
160 }
161 
162 #if OPENTHREAD_CONFIG_MULTI_RADIO
163 
164 const RadioType RadioTypes::kAllRadioTypes[kNumRadioTypes] = {
165 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
166     kRadioTypeIeee802154,
167 #endif
168 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
169     kRadioTypeTrel,
170 #endif
171 };
172 
AddAll(void)173 void RadioTypes::AddAll(void)
174 {
175 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
176     Add(kRadioTypeIeee802154);
177 #endif
178 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
179     Add(kRadioTypeTrel);
180 #endif
181 }
182 
ToString(void) const183 RadioTypes::InfoString RadioTypes::ToString(void) const
184 {
185     InfoString string;
186     bool       addComma = false;
187 
188     string.Append("{");
189 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
190     if (Contains(kRadioTypeIeee802154))
191     {
192         string.Append("%s%s", addComma ? ", " : " ", RadioTypeToString(kRadioTypeIeee802154));
193         addComma = true;
194     }
195 #endif
196 
197 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
198     if (Contains(kRadioTypeTrel))
199     {
200         string.Append("%s%s", addComma ? ", " : " ", RadioTypeToString(kRadioTypeTrel));
201         addComma = true;
202     }
203 #endif
204 
205     OT_UNUSED_VARIABLE(addComma);
206 
207     string.Append(" }");
208 
209     return string;
210 }
211 
RadioTypeToString(RadioType aRadioType)212 const char *RadioTypeToString(RadioType aRadioType)
213 {
214     const char *str = "unknown";
215 
216     switch (aRadioType)
217     {
218 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
219     case kRadioTypeIeee802154:
220         str = "15.4";
221         break;
222 #endif
223 
224 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
225     case kRadioTypeTrel:
226         str = "trel";
227         break;
228 #endif
229     }
230 
231     return str;
232 }
233 
Get(RadioType aRadioType) const234 uint32_t LinkFrameCounters::Get(RadioType aRadioType) const
235 {
236     uint32_t counter = 0;
237 
238     switch (aRadioType)
239     {
240 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
241     case kRadioTypeIeee802154:
242         counter = m154Counter;
243         break;
244 #endif
245 
246 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
247     case kRadioTypeTrel:
248         counter = mTrelCounter;
249         break;
250 #endif
251     }
252 
253     return counter;
254 }
255 
Set(RadioType aRadioType,uint32_t aCounter)256 void LinkFrameCounters::Set(RadioType aRadioType, uint32_t aCounter)
257 {
258     switch (aRadioType)
259     {
260 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
261     case kRadioTypeIeee802154:
262         m154Counter = aCounter;
263         break;
264 #endif
265 
266 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
267     case kRadioTypeTrel:
268         mTrelCounter = aCounter;
269         break;
270 #endif
271     }
272 }
273 
274 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
275 
GetMaximum(void) const276 uint32_t LinkFrameCounters::GetMaximum(void) const
277 {
278     uint32_t counter = 0;
279 
280 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
281     counter = Max(counter, m154Counter);
282 #endif
283 
284 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
285     counter = Max(counter, mTrelCounter);
286 #endif
287 
288     return counter;
289 }
290 
SetAll(uint32_t aCounter)291 void LinkFrameCounters::SetAll(uint32_t aCounter)
292 {
293 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
294     m154Counter = aCounter;
295 #endif
296 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
297     mTrelCounter = aCounter;
298 #endif
299 }
300 
301 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
operator =(const KeyMaterial & aOther)302 KeyMaterial &KeyMaterial::operator=(const KeyMaterial &aOther)
303 {
304     VerifyOrExit(GetKeyRef() != aOther.GetKeyRef());
305     DestroyKey();
306     SetKeyRef(aOther.GetKeyRef());
307 
308 exit:
309     return *this;
310 }
311 #endif
312 
Clear(void)313 void KeyMaterial::Clear(void)
314 {
315 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
316     DestroyKey();
317     SetKeyRef(kInvalidKeyRef);
318 #else
319     GetKey().Clear();
320 #endif
321 }
322 
SetFrom(const Key & aKey,bool aIsExportable)323 void KeyMaterial::SetFrom(const Key &aKey, bool aIsExportable)
324 {
325 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
326     {
327         KeyRef keyRef = 0;
328 
329         DestroyKey();
330 
331         SuccessOrAssert(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeAes,
332                                                    Crypto::Storage::kKeyAlgorithmAesEcb,
333                                                    (aIsExportable ? Crypto::Storage::kUsageExport : 0) |
334                                                        Crypto::Storage::kUsageEncrypt | Crypto::Storage::kUsageDecrypt,
335                                                    Crypto::Storage::kTypeVolatile, aKey.GetBytes(), Key::kSize));
336 
337         SetKeyRef(keyRef);
338     }
339 #else
340     SetKey(aKey);
341     OT_UNUSED_VARIABLE(aIsExportable);
342 #endif
343 }
344 
ExtractKey(Key & aKey) const345 void KeyMaterial::ExtractKey(Key &aKey) const
346 {
347 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
348     aKey.Clear();
349 
350     if (Crypto::Storage::IsKeyRefValid(GetKeyRef()))
351     {
352         size_t keySize;
353 
354         SuccessOrAssert(Crypto::Storage::ExportKey(GetKeyRef(), aKey.m8, Key::kSize, keySize));
355     }
356 #else
357     aKey = GetKey();
358 #endif
359 }
360 
ConvertToCryptoKey(Crypto::Key & aCryptoKey) const361 void KeyMaterial::ConvertToCryptoKey(Crypto::Key &aCryptoKey) const
362 {
363 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
364     aCryptoKey.SetAsKeyRef(GetKeyRef());
365 #else
366     aCryptoKey.Set(GetKey().GetBytes(), Key::kSize);
367 #endif
368 }
369 
370 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
DestroyKey(void)371 void KeyMaterial::DestroyKey(void)
372 {
373     Crypto::Storage::DestroyKey(GetKeyRef());
374     SetKeyRef(kInvalidKeyRef);
375 }
376 #endif
377 
operator ==(const KeyMaterial & aOther) const378 bool KeyMaterial::operator==(const KeyMaterial &aOther) const
379 {
380     return
381 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
382         (GetKeyRef() == aOther.GetKeyRef());
383 #else
384         (GetKey() == aOther.GetKey());
385 #endif
386 }
387 
388 } // namespace Mac
389 } // namespace ot
390