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