1 /* 2 * Copyright (c) 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 includes definitions for radio selector (for multi radio links). 32 */ 33 34 #ifndef RADIO_SELECTOR_HPP_ 35 #define RADIO_SELECTOR_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_MULTI_RADIO 40 41 #include <openthread/multi_radio.h> 42 43 #include "common/locator.hpp" 44 #include "common/log.hpp" 45 #include "common/message.hpp" 46 #include "mac/mac_frame.hpp" 47 #include "mac/mac_links.hpp" 48 #include "mac/mac_types.hpp" 49 50 namespace ot { 51 52 /** 53 * @addtogroup core-radio-selector 54 * 55 * @brief 56 * This module includes definition for radio selector (for multi radio links). 57 * 58 * @{ 59 * 60 */ 61 62 class Neighbor; 63 64 class RadioSelector : InstanceLocator 65 { 66 public: 67 /** 68 * This class defines all the neighbor info required for multi radio link and radio selection. 69 * 70 * `Neighbor` class publicly inherits from this class. 71 * 72 */ 73 class NeighborInfo 74 { 75 friend class RadioSelector; 76 77 public: 78 /** 79 * This type represents multi radio information associated with a neighbor. 80 * 81 */ 82 typedef otMultiRadioNeighborInfo MultiRadioInfo; 83 84 /** 85 * This method returns the supported radio types by the neighbor. 86 * 87 * @returns The supported radio types set. 88 * 89 */ GetSupportedRadioTypes(void) const90 Mac::RadioTypes GetSupportedRadioTypes(void) const { return mSupportedRadioTypes; } 91 92 /** 93 * This method retrieves the multi radio information `otMultiRadioNeighborInfo` associated with the neighbor. 94 * 95 * @param[out] aInfo A reference to `MultiRadioInfo` to populate with neighbor info. 96 * 97 */ 98 void PopulateMultiRadioInfo(MultiRadioInfo &aInfo); 99 100 private: AddSupportedRadioType(Mac::RadioType aType)101 void AddSupportedRadioType(Mac::RadioType aType) { mSupportedRadioTypes.Add(aType); } RemoveSupportedRadioType(Mac::RadioType aType)102 void RemoveSupportedRadioType(Mac::RadioType aType) { mSupportedRadioTypes.Remove(aType); } ClearSupportedRadioType(void)103 void ClearSupportedRadioType(void) { mSupportedRadioTypes.Clear(); } 104 GetRadioPreference(Mac::RadioType aType) const105 uint8_t GetRadioPreference(Mac::RadioType aType) const { return mRadioPreference[aType]; } SetRadioPreference(Mac::RadioType aType,uint8_t aValue)106 void SetRadioPreference(Mac::RadioType aType, uint8_t aValue) { mRadioPreference[aType] = aValue; } 107 108 Mac::RadioTypes mSupportedRadioTypes; 109 uint8_t mRadioPreference[Mac::kNumRadioTypes]; 110 }; 111 112 /** 113 * This constructor initializes the RadioSelector object. 114 * 115 * @param[in] aInstance A reference to the OpenThread instance. 116 * 117 */ 118 explicit RadioSelector(Instance &aInstance); 119 120 /** 121 * This method updates the neighbor info (for multi radio support) on a received frame event. 122 * 123 * This method notifies `RadioSelector` of a received secure frame/message on a radio link type for neighbor. If 124 * the frame/message happens to be received earlier on another radio link, the `aIsDuplicate` is set to `true`. 125 * A duplicate frame/message should have passed the security check (i.e., tag/MIC should be valid). 126 * 127 * @param[in] aNeighbor The neighbor for which a frame/message was received. 128 * @param[in] aRadioType The radio link type on which the frame/message was received. 129 * @param[in] aIsDuplicate Indicates whether the received frame/message is a duplicate or not. 130 * 131 */ 132 void UpdateOnReceive(Neighbor &aNeighbor, Mac::RadioType aRadioType, bool aIsDuplicate); 133 134 /** 135 * This method updates the neighbor info (for multi radio support) on a send done event. 136 * 137 * This method notifies `RadioSelector` the status of frame transmission on a radio link type. The radio link 138 * type is provided by the `aFrame` itself. 139 * 140 * @param[in] aFrame A transmitted frame. 141 * @param[in] aTxError The transmission error. 142 * 143 */ 144 void UpdateOnSendDone(Mac::TxFrame &aFrame, Error aTxError); 145 146 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 147 /** 148 * This method updates the neighbor info (for multi radio support) on a deferred ack event. 149 * 150 * The deferred ack model is used by TREL radio link. 151 * 152 * @param[in] aNeighbor The neighbor from which ack was expected 153 * @param[in] aError The deferred ack status (`kErrorNone` indicates ack was received). 154 * @param[out] aAllowNeighborRemove Boolean variable to output whether the neighbor is allowed to be removed. 155 * 156 */ 157 void UpdateOnDeferredAck(Neighbor &aNeighbor, Error aTxError, bool &aAllowNeighborRemove); 158 #endif 159 160 /** 161 * This method selects the radio link type for sending a data poll frame to a given parent neighbor. 162 * 163 * @param[in] aParent The parent to which the data poll frame will be sent. 164 * 165 * @returns The radio type on which the data poll frame should be sent. 166 * 167 */ 168 Mac::RadioType SelectPollFrameRadio(const Neighbor &aParent); 169 170 /** 171 * This method selects the radio link for sending a given message to a specified MAC destination. 172 * 173 * The `aMessage` will be updated to store the selected radio type (please see `Message::GetRadioType()`). 174 * The `aTxFrames` will also be updated to indicate which radio links are to be used. 175 * 176 * @param[in,out] aMessage The message to send. 177 * @param[in] aMacDest The MAC destination address. 178 * @param[in,out] aTxFrames The set of TxFrames for all radio links. 179 * 180 * @returns A reference to `mTxFrame` to use when preparing the frame for tx. 181 * 182 */ 183 Mac::TxFrame &SelectRadio(Message &aMessage, const Mac::Address &aMacDest, Mac::TxFrames &aTxFrames); 184 185 private: 186 static constexpr int16_t kPreferenceChangeOnTxError = -35; // Change on a tx error on a radio link. 187 static constexpr int16_t kPreferenceChangeOnTxSuccess = 25; // Change on tx success on a radio link. 188 static constexpr int16_t kPreferenceChangeOnDeferredAckSuccess = 25; // Change on deferred ack success. 189 static constexpr int16_t kPreferenceChangeOnDeferredAckTimeout = -100; // Change on deferred ack timeout. 190 static constexpr int16_t kPreferenceChangeOnRx = 15; // Change on new (secure) rx. 191 static constexpr int16_t kPreferenceChangeOnRxDuplicate = 15; // Change on new (secure) duplicate rx. 192 193 static constexpr uint8_t kMinPreference = 0; // Minimum preference value. 194 static constexpr uint8_t kMaxPreference = 255; // Maximum preference value. 195 static constexpr uint8_t kInitPreference = 200; // Initial preference value 196 static constexpr uint8_t kHighPreference = 220; // High preference. 197 198 static constexpr uint8_t kTrelProbeProbability = 25; // Probability percentage to probe on TREL link 199 200 static constexpr uint16_t kRadioPreferenceStringSize = 75; 201 202 LogLevel UpdatePreference(Neighbor &aNeighbor, Mac::RadioType aRadioType, int16_t aDifference); 203 Mac::RadioType Select(Mac::RadioTypes aRadioOptions, const Neighbor &aNeighbor); 204 void Log(LogLevel aLogLevel, const char *aActionText, Mac::RadioType aType, const Neighbor &aNeighbor); 205 206 static const Mac::RadioType sRadioSelectionOrder[Mac::kNumRadioTypes]; 207 }; 208 209 /** 210 * @} 211 * 212 */ 213 214 } // namespace ot 215 216 #endif // #if OPENTHREAD_CONFIG_MULTI_RADIO 217 218 #endif // RADIO_SELECTOR_HPP_ 219