| /* |
| * Copyright (c) 2016-2019, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /** |
| * @file |
| * This file implements MAC types. |
| */ |
| |
| #include "mac_types.hpp" |
| |
| #include <stdio.h> |
| |
| #include "common/code_utils.hpp" |
| #include "common/random.hpp" |
| #include "common/string.hpp" |
| |
| namespace ot { |
| namespace Mac { |
| |
| PanId GenerateRandomPanId(void) |
| { |
| PanId panId; |
| |
| do |
| { |
| panId = Random::NonCrypto::GetUint16(); |
| } while (panId == kPanIdBroadcast); |
| |
| return panId; |
| } |
| |
| #if !OPENTHREAD_RADIO |
| void ExtAddress::GenerateRandom(void) |
| { |
| IgnoreError(Random::Crypto::FillBuffer(m8, sizeof(ExtAddress))); |
| SetGroup(false); |
| SetLocal(true); |
| } |
| #endif |
| |
| ExtAddress::InfoString ExtAddress::ToString(void) const |
| { |
| InfoString string; |
| |
| string.AppendHexBytes(m8, sizeof(ExtAddress)); |
| |
| return string; |
| } |
| |
| void ExtAddress::CopyAddress(uint8_t *aDst, const uint8_t *aSrc, CopyByteOrder aByteOrder) |
| { |
| switch (aByteOrder) |
| { |
| case kNormalByteOrder: |
| memcpy(aDst, aSrc, sizeof(ExtAddress)); |
| break; |
| |
| case kReverseByteOrder: |
| aSrc += sizeof(ExtAddress) - 1; |
| for (uint8_t len = sizeof(ExtAddress); len > 0; len--) |
| { |
| *aDst++ = *aSrc--; |
| } |
| break; |
| } |
| } |
| |
| Address::InfoString Address::ToString(void) const |
| { |
| InfoString string; |
| |
| if (mType == kTypeExtended) |
| { |
| string.AppendHexBytes(GetExtended().m8, sizeof(ExtAddress)); |
| } |
| else if (mType == kTypeNone) |
| { |
| string.Append("None"); |
| } |
| else |
| { |
| string.Append("0x%04x", GetShort()); |
| } |
| |
| return string; |
| } |
| |
| #if OPENTHREAD_CONFIG_MULTI_RADIO |
| |
| const RadioType RadioTypes::kAllRadioTypes[kNumRadioTypes] = { |
| #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE |
| kRadioTypeIeee802154, |
| #endif |
| #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| kRadioTypeTrel, |
| #endif |
| }; |
| |
| void RadioTypes::AddAll(void) |
| { |
| #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE |
| Add(kRadioTypeIeee802154); |
| #endif |
| #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| Add(kRadioTypeTrel); |
| #endif |
| } |
| |
| RadioTypes::InfoString RadioTypes::ToString(void) const |
| { |
| InfoString string; |
| bool addComma = false; |
| |
| string.Append("{"); |
| #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE |
| if (Contains(kRadioTypeIeee802154)) |
| { |
| string.Append("%s%s", addComma ? ", " : " ", RadioTypeToString(kRadioTypeIeee802154)); |
| addComma = true; |
| } |
| #endif |
| |
| #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| if (Contains(kRadioTypeTrel)) |
| { |
| string.Append("%s%s", addComma ? ", " : " ", RadioTypeToString(kRadioTypeTrel)); |
| addComma = true; |
| } |
| #endif |
| |
| OT_UNUSED_VARIABLE(addComma); |
| |
| string.Append(" }"); |
| |
| return string; |
| } |
| |
| const char *RadioTypeToString(RadioType aRadioType) |
| { |
| const char *str = "unknown"; |
| |
| switch (aRadioType) |
| { |
| #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE |
| case kRadioTypeIeee802154: |
| str = "15.4"; |
| break; |
| #endif |
| |
| #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| case kRadioTypeTrel: |
| str = "trel"; |
| break; |
| #endif |
| } |
| |
| return str; |
| } |
| |
| uint32_t LinkFrameCounters::Get(RadioType aRadioType) const |
| { |
| uint32_t counter = 0; |
| |
| switch (aRadioType) |
| { |
| #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE |
| case kRadioTypeIeee802154: |
| counter = m154Counter; |
| break; |
| #endif |
| |
| #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| case kRadioTypeTrel: |
| counter = mTrelCounter; |
| break; |
| #endif |
| } |
| |
| return counter; |
| } |
| |
| void LinkFrameCounters::Set(RadioType aRadioType, uint32_t aCounter) |
| { |
| switch (aRadioType) |
| { |
| #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE |
| case kRadioTypeIeee802154: |
| m154Counter = aCounter; |
| break; |
| #endif |
| |
| #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| case kRadioTypeTrel: |
| mTrelCounter = aCounter; |
| break; |
| #endif |
| } |
| } |
| |
| #endif // OPENTHREAD_CONFIG_MULTI_RADIO |
| |
| uint32_t LinkFrameCounters::GetMaximum(void) const |
| { |
| uint32_t counter = 0; |
| |
| #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE |
| if (counter < m154Counter) |
| { |
| counter = m154Counter; |
| } |
| #endif |
| |
| #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| if (counter < mTrelCounter) |
| { |
| counter = mTrelCounter; |
| } |
| #endif |
| |
| return counter; |
| } |
| |
| void LinkFrameCounters::SetAll(uint32_t aCounter) |
| { |
| #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE |
| m154Counter = aCounter; |
| #endif |
| #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| mTrelCounter = aCounter; |
| #endif |
| } |
| |
| #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE |
| KeyMaterial &KeyMaterial::operator=(const KeyMaterial &aOther) |
| { |
| VerifyOrExit(GetKeyRef() != aOther.GetKeyRef()); |
| DestroyKey(); |
| SetKeyRef(aOther.GetKeyRef()); |
| |
| exit: |
| return *this; |
| } |
| #endif |
| |
| void KeyMaterial::Clear(void) |
| { |
| #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE |
| DestroyKey(); |
| SetKeyRef(kInvalidKeyRef); |
| #else |
| GetKey().Clear(); |
| #endif |
| } |
| |
| void KeyMaterial::SetFrom(const Key &aKey, bool aIsExportable) |
| { |
| #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE |
| { |
| KeyRef keyRef = 0; |
| |
| DestroyKey(); |
| |
| SuccessOrAssert(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeAes, |
| Crypto::Storage::kKeyAlgorithmAesEcb, |
| (aIsExportable ? Crypto::Storage::kUsageExport : 0) | |
| Crypto::Storage::kUsageEncrypt | Crypto::Storage::kUsageDecrypt, |
| Crypto::Storage::kTypeVolatile, aKey.GetBytes(), Key::kSize)); |
| |
| SetKeyRef(keyRef); |
| } |
| #else |
| SetKey(aKey); |
| OT_UNUSED_VARIABLE(aIsExportable); |
| #endif |
| } |
| |
| void KeyMaterial::ExtractKey(Key &aKey) |
| { |
| #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE |
| aKey.Clear(); |
| |
| if (Crypto::Storage::IsKeyRefValid(GetKeyRef())) |
| { |
| size_t keySize; |
| |
| SuccessOrAssert(Crypto::Storage::ExportKey(GetKeyRef(), aKey.m8, Key::kSize, keySize)); |
| } |
| #else |
| aKey = GetKey(); |
| #endif |
| } |
| |
| void KeyMaterial::ConvertToCryptoKey(Crypto::Key &aCryptoKey) const |
| { |
| #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE |
| aCryptoKey.SetAsKeyRef(GetKeyRef()); |
| #else |
| aCryptoKey.Set(GetKey().GetBytes(), Key::kSize); |
| #endif |
| } |
| |
| #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE |
| void KeyMaterial::DestroyKey(void) |
| { |
| Crypto::Storage::DestroyKey(GetKeyRef()); |
| SetKeyRef(kInvalidKeyRef); |
| } |
| #endif |
| |
| bool KeyMaterial::operator==(const KeyMaterial &aOther) const |
| { |
| return |
| #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE |
| (GetKeyRef() == aOther.GetKeyRef()); |
| #else |
| (GetKey() == aOther.GetKey()); |
| #endif |
| } |
| |
| } // namespace Mac |
| } // namespace ot |