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 29 /** 30 * @file 31 * This file includes definitions for the Raw Link-Layer class. 32 */ 33 34 #ifndef LINK_RAW_HPP_ 35 #define LINK_RAW_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE 40 41 #include <openthread/link_raw.h> 42 43 #include "common/locator.hpp" 44 #include "common/log.hpp" 45 #include "common/non_copyable.hpp" 46 #include "mac/mac_frame.hpp" 47 #include "mac/sub_mac.hpp" 48 49 namespace ot { 50 namespace Mac { 51 52 /** 53 * Defines the raw link-layer object. 54 */ 55 class LinkRaw : public InstanceLocator, private NonCopyable 56 { 57 friend class ot::Instance; 58 59 public: 60 /** 61 * Initializes the object. 62 * 63 * @param[in] aInstance A reference to the OpenThread instance. 64 */ 65 explicit LinkRaw(Instance &aInstance); 66 67 /** 68 * Initializes the states of the raw link-layer. 69 */ 70 void Init(void); 71 72 /** 73 * Returns true if the raw link-layer is enabled. 74 * 75 * @returns true if enabled, false otherwise. 76 */ IsEnabled(void) const77 bool IsEnabled(void) const { return mReceiveDoneCallback != nullptr; } 78 79 /** 80 * Enables/disables the raw link-layer. 81 * 82 * @param[in] aCallback A pointer to a function called on receipt of a IEEE 802.15.4 frame, `nullptr` to disable 83 * raw link-layer. 84 * 85 * 86 * @retval kErrorInvalidState Thread stack is enabled. 87 * @retval kErrorFailed The radio could not be enabled/disabled. 88 * @retval kErrorNone Successfully enabled/disabled raw link. 89 */ 90 Error SetReceiveDone(otLinkRawReceiveDone aCallback); 91 92 /** 93 * Returns the capabilities of the raw link-layer. 94 * 95 * @returns The radio capability bit vector. 96 */ GetCaps(void) const97 otRadioCaps GetCaps(void) const { return mSubMac.GetCaps(); } 98 99 /** 100 * Starts a (recurring) Receive on the link-layer. 101 * 102 * @retval kErrorNone Successfully transitioned to Receive. 103 * @retval kErrorInvalidState The radio was disabled or transmitting. 104 */ 105 Error Receive(void); 106 107 /** 108 * Invokes the mReceiveDoneCallback, if set. 109 * 110 * @param[in] aFrame A pointer to the received frame or `nullptr` if the receive operation failed. 111 * @param[in] aError kErrorNone when successfully received a frame, 112 * kErrorAbort when reception was aborted and a frame was not received, 113 * kErrorNoBufs when a frame could not be received due to lack of rx buffer space. 114 */ 115 void InvokeReceiveDone(RxFrame *aFrame, Error aError); 116 117 /** 118 * Gets the radio transmit frame. 119 * 120 * @returns The transmit frame. 121 */ GetTransmitFrame(void)122 TxFrame &GetTransmitFrame(void) { return mSubMac.GetTransmitFrame(); } 123 124 /** 125 * Starts a (single) Transmit on the link-layer. 126 * 127 * @note The callback @p aCallback will not be called if this call does not return kErrorNone. 128 * 129 * @param[in] aCallback A pointer to a function called on completion of the transmission. 130 * 131 * @retval kErrorNone Successfully transitioned to Transmit. 132 * @retval kErrorInvalidState The radio was not in the Receive state. 133 */ 134 Error Transmit(otLinkRawTransmitDone aCallback); 135 136 /** 137 * Invokes the mTransmitDoneCallback, if set. 138 * 139 * @param[in] aFrame The transmitted frame. 140 * @param[in] aAckFrame A pointer to the ACK frame, `nullptr` if no ACK was received. 141 * @param[in] aError kErrorNone when the frame was transmitted, 142 * kErrorNoAck when the frame was transmitted but no ACK was received, 143 * kErrorChannelAccessFailure tx failed due to activity on the channel, 144 * kErrorAbort when transmission was aborted for other reasons. 145 */ 146 void InvokeTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError); 147 148 /** 149 * Starts a (single) Energy Scan on the link-layer. 150 * 151 * @param[in] aScanChannel The channel to perform the energy scan on. 152 * @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned. 153 * @param[in] aCallback A pointer to a function called on completion of a scanned channel. 154 * 155 * @retval kErrorNone Successfully started scanning the channel. 156 * @retval kErrorBusy The radio is performing energy scanning. 157 * @retval kErrorNotImplemented The radio doesn't support energy scanning. 158 * @retval kErrorInvalidState If the raw link-layer isn't enabled. 159 */ 160 Error EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration, otLinkRawEnergyScanDone aCallback); 161 162 /** 163 * Invokes the mEnergyScanDoneCallback, if set. 164 * 165 * @param[in] aEnergyScanMaxRssi The max RSSI for energy scan. 166 */ 167 void InvokeEnergyScanDone(int8_t aEnergyScanMaxRssi); 168 169 /** 170 * Returns the short address. 171 * 172 * @returns short address. 173 */ GetShortAddress(void) const174 ShortAddress GetShortAddress(void) const { return mSubMac.GetShortAddress(); } 175 176 /** 177 * Updates short address. 178 * 179 * @param[in] aShortAddress The short address. 180 * 181 * @retval kErrorNone If successful. 182 * @retval kErrorInvalidState If the raw link-layer isn't enabled. 183 */ 184 Error SetShortAddress(ShortAddress aShortAddress); 185 186 /** 187 * Sets the alternate short address. 188 * 189 * @param[in] aShortAddress The short address. Use `kShortAddrInvalid` to clear it. 190 * 191 * @retval kErrorNone If successful. 192 * @retval kErrorInvalidState If the raw link-layer isn't enabled. 193 */ 194 Error SetAlternateShortAddress(ShortAddress aShortAddress); 195 196 /** 197 * Returns PANID. 198 * 199 * @returns PANID. 200 */ GetPanId(void) const201 PanId GetPanId(void) const { return mPanId; } 202 203 /** 204 * Updates PANID. 205 * 206 * @param[in] aPanId The PANID. 207 * 208 * @retval kErrorNone If successful. 209 * @retval kErrorInvalidState If the raw link-layer isn't enabled. 210 */ 211 Error SetPanId(PanId aPanId); 212 213 /** 214 * Gets the current receiving channel. 215 * 216 * @returns Current receiving channel. 217 */ GetChannel(void) const218 uint8_t GetChannel(void) const { return mReceiveChannel; } 219 220 /** 221 * Sets the receiving channel. 222 * 223 * @param[in] aChannel The channel to use for receiving. 224 */ 225 Error SetChannel(uint8_t aChannel); 226 227 /** 228 * Returns the extended address. 229 * 230 * @returns A reference to the extended address. 231 */ GetExtAddress(void) const232 const ExtAddress &GetExtAddress(void) const { return mSubMac.GetExtAddress(); } 233 234 /** 235 * Updates extended address. 236 * 237 * @param[in] aExtAddress The extended address. 238 * 239 * @retval kErrorNone If successful. 240 * @retval kErrorInvalidState If the raw link-layer isn't enabled. 241 */ 242 Error SetExtAddress(const ExtAddress &aExtAddress); 243 244 /** 245 * Updates MAC keys and key index. 246 * 247 * @param[in] aKeyIdMode The key ID mode. 248 * @param[in] aKeyId The key index. 249 * @param[in] aPrevKey The previous MAC key. 250 * @param[in] aCurrKey The current MAC key. 251 * @param[in] aNextKey The next MAC key. 252 * 253 * @retval kErrorNone If successful. 254 * @retval kErrorFailed Platform failed to import key. 255 * @retval kErrorInvalidState If the raw link-layer isn't enabled. 256 */ 257 Error SetMacKey(uint8_t aKeyIdMode, uint8_t aKeyId, const Key &aPrevKey, const Key &aCurrKey, const Key &aNextKey); 258 259 /** 260 * Sets the current MAC frame counter value. 261 * 262 * @param[in] aFrameCounter The MAC frame counter value. 263 * @param[in] aSetIfLarger If `true`, set only if the new value @p aFrameCounter is larger than current value. 264 * If `false`, set the new value independent of the current value. 265 * 266 * @retval kErrorNone If successful. 267 * @retval kErrorInvalidState If the raw link-layer isn't enabled. 268 */ 269 Error SetMacFrameCounter(uint32_t aFrameCounter, bool aSetIfLarger); 270 271 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) 272 /** 273 * Records the status of a frame transmission attempt and is mainly used for logging failures. 274 * 275 * Unlike `HandleTransmitDone` which is called after all transmission attempts of frame to indicate final status 276 * of a frame transmission request, this method is invoked on all frame transmission attempts. 277 * 278 * @param[in] aFrame The transmitted frame. 279 * @param[in] aError kErrorNone when the frame was transmitted successfully, 280 * kErrorNoAck when the frame was transmitted but no ACK was received, 281 * kErrorChannelAccessFailure tx failed due to activity on the channel, 282 * kErrorAbort when transmission was aborted for other reasons. 283 * @param[in] aRetryCount Indicates number of transmission retries for this frame. 284 * @param[in] aWillRetx Indicates whether frame will be retransmitted or not. This is applicable only 285 * when there was an error in transmission (i.e., `aError` is not NONE). 286 */ 287 void RecordFrameTransmitStatus(const TxFrame &aFrame, Error aError, uint8_t aRetryCount, bool aWillRetx); 288 #else RecordFrameTransmitStatus(const TxFrame &,Error,uint8_t,bool)289 void RecordFrameTransmitStatus(const TxFrame &, Error, uint8_t, bool) {} 290 #endif 291 292 private: 293 uint8_t mReceiveChannel; 294 PanId mPanId; 295 otLinkRawReceiveDone mReceiveDoneCallback; 296 otLinkRawTransmitDone mTransmitDoneCallback; 297 otLinkRawEnergyScanDone mEnergyScanDoneCallback; 298 299 #if OPENTHREAD_RADIO 300 SubMac mSubMac; 301 #elif OPENTHREAD_CONFIG_LINK_RAW_ENABLE 302 SubMac &mSubMac; 303 #endif 304 }; 305 306 } // namespace Mac 307 } // namespace ot 308 309 #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE 310 311 #endif // LINK_RAW_HPP_ 312