/* * Copyright (c) 2016, 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 includes definitions for the Raw Link-Layer class. */ #ifndef LINK_RAW_HPP_ #define LINK_RAW_HPP_ #include "openthread-core-config.h" #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE #include #include "common/locator.hpp" #include "common/log.hpp" #include "common/non_copyable.hpp" #include "mac/mac_frame.hpp" #include "mac/sub_mac.hpp" namespace ot { namespace Mac { /** * Defines the raw link-layer object. */ class LinkRaw : public InstanceLocator, private NonCopyable { friend class ot::Instance; public: /** * Initializes the object. * * @param[in] aInstance A reference to the OpenThread instance. */ explicit LinkRaw(Instance &aInstance); /** * Initializes the states of the raw link-layer. */ void Init(void); /** * Returns true if the raw link-layer is enabled. * * @returns true if enabled, false otherwise. */ bool IsEnabled(void) const { return mReceiveDoneCallback != nullptr; } /** * Enables/disables the raw link-layer. * * @param[in] aCallback A pointer to a function called on receipt of a IEEE 802.15.4 frame, `nullptr` to disable * raw link-layer. * * * @retval kErrorInvalidState Thread stack is enabled. * @retval kErrorFailed The radio could not be enabled/disabled. * @retval kErrorNone Successfully enabled/disabled raw link. */ Error SetReceiveDone(otLinkRawReceiveDone aCallback); /** * Returns the capabilities of the raw link-layer. * * @returns The radio capability bit vector. */ otRadioCaps GetCaps(void) const { return mSubMac.GetCaps(); } /** * Starts a (recurring) Receive on the link-layer. * * @retval kErrorNone Successfully transitioned to Receive. * @retval kErrorInvalidState The radio was disabled or transmitting. */ Error Receive(void); /** * Invokes the mReceiveDoneCallback, if set. * * @param[in] aFrame A pointer to the received frame or `nullptr` if the receive operation failed. * @param[in] aError kErrorNone when successfully received a frame, * kErrorAbort when reception was aborted and a frame was not received, * kErrorNoBufs when a frame could not be received due to lack of rx buffer space. */ void InvokeReceiveDone(RxFrame *aFrame, Error aError); /** * Gets the radio transmit frame. * * @returns The transmit frame. */ TxFrame &GetTransmitFrame(void) { return mSubMac.GetTransmitFrame(); } /** * Starts a (single) Transmit on the link-layer. * * @note The callback @p aCallback will not be called if this call does not return kErrorNone. * * @param[in] aCallback A pointer to a function called on completion of the transmission. * * @retval kErrorNone Successfully transitioned to Transmit. * @retval kErrorInvalidState The radio was not in the Receive state. */ Error Transmit(otLinkRawTransmitDone aCallback); /** * Invokes the mTransmitDoneCallback, if set. * * @param[in] aFrame The transmitted frame. * @param[in] aAckFrame A pointer to the ACK frame, `nullptr` if no ACK was received. * @param[in] aError kErrorNone when the frame was transmitted, * kErrorNoAck when the frame was transmitted but no ACK was received, * kErrorChannelAccessFailure tx failed due to activity on the channel, * kErrorAbort when transmission was aborted for other reasons. */ void InvokeTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError); /** * Starts a (single) Energy Scan on the link-layer. * * @param[in] aScanChannel The channel to perform the energy scan on. * @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned. * @param[in] aCallback A pointer to a function called on completion of a scanned channel. * * @retval kErrorNone Successfully started scanning the channel. * @retval kErrorBusy The radio is performing energy scanning. * @retval kErrorNotImplemented The radio doesn't support energy scanning. * @retval kErrorInvalidState If the raw link-layer isn't enabled. */ Error EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration, otLinkRawEnergyScanDone aCallback); /** * Invokes the mEnergyScanDoneCallback, if set. * * @param[in] aEnergyScanMaxRssi The max RSSI for energy scan. */ void InvokeEnergyScanDone(int8_t aEnergyScanMaxRssi); /** * Returns the short address. * * @returns short address. */ ShortAddress GetShortAddress(void) const { return mSubMac.GetShortAddress(); } /** * Updates short address. * * @param[in] aShortAddress The short address. * * @retval kErrorNone If successful. * @retval kErrorInvalidState If the raw link-layer isn't enabled. */ Error SetShortAddress(ShortAddress aShortAddress); /** * Sets the alternate short address. * * @param[in] aShortAddress The short address. Use `kShortAddrInvalid` to clear it. * * @retval kErrorNone If successful. * @retval kErrorInvalidState If the raw link-layer isn't enabled. */ Error SetAlternateShortAddress(ShortAddress aShortAddress); /** * Returns PANID. * * @returns PANID. */ PanId GetPanId(void) const { return mPanId; } /** * Updates PANID. * * @param[in] aPanId The PANID. * * @retval kErrorNone If successful. * @retval kErrorInvalidState If the raw link-layer isn't enabled. */ Error SetPanId(PanId aPanId); /** * Gets the current receiving channel. * * @returns Current receiving channel. */ uint8_t GetChannel(void) const { return mReceiveChannel; } /** * Sets the receiving channel. * * @param[in] aChannel The channel to use for receiving. */ Error SetChannel(uint8_t aChannel); /** * Returns the extended address. * * @returns A reference to the extended address. */ const ExtAddress &GetExtAddress(void) const { return mSubMac.GetExtAddress(); } /** * Updates extended address. * * @param[in] aExtAddress The extended address. * * @retval kErrorNone If successful. * @retval kErrorInvalidState If the raw link-layer isn't enabled. */ Error SetExtAddress(const ExtAddress &aExtAddress); /** * Updates MAC keys and key index. * * @param[in] aKeyIdMode The key ID mode. * @param[in] aKeyId The key index. * @param[in] aPrevKey The previous MAC key. * @param[in] aCurrKey The current MAC key. * @param[in] aNextKey The next MAC key. * * @retval kErrorNone If successful. * @retval kErrorFailed Platform failed to import key. * @retval kErrorInvalidState If the raw link-layer isn't enabled. */ Error SetMacKey(uint8_t aKeyIdMode, uint8_t aKeyId, const Key &aPrevKey, const Key &aCurrKey, const Key &aNextKey); /** * Sets the current MAC frame counter value. * * @param[in] aFrameCounter The MAC frame counter value. * @param[in] aSetIfLarger If `true`, set only if the new value @p aFrameCounter is larger than current value. * If `false`, set the new value independent of the current value. * * @retval kErrorNone If successful. * @retval kErrorInvalidState If the raw link-layer isn't enabled. */ Error SetMacFrameCounter(uint32_t aFrameCounter, bool aSetIfLarger); #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) /** * Records the status of a frame transmission attempt and is mainly used for logging failures. * * Unlike `HandleTransmitDone` which is called after all transmission attempts of frame to indicate final status * of a frame transmission request, this method is invoked on all frame transmission attempts. * * @param[in] aFrame The transmitted frame. * @param[in] aError kErrorNone when the frame was transmitted successfully, * kErrorNoAck when the frame was transmitted but no ACK was received, * kErrorChannelAccessFailure tx failed due to activity on the channel, * kErrorAbort when transmission was aborted for other reasons. * @param[in] aRetryCount Indicates number of transmission retries for this frame. * @param[in] aWillRetx Indicates whether frame will be retransmitted or not. This is applicable only * when there was an error in transmission (i.e., `aError` is not NONE). */ void RecordFrameTransmitStatus(const TxFrame &aFrame, Error aError, uint8_t aRetryCount, bool aWillRetx); #else void RecordFrameTransmitStatus(const TxFrame &, Error, uint8_t, bool) {} #endif private: uint8_t mReceiveChannel; PanId mPanId; otLinkRawReceiveDone mReceiveDoneCallback; otLinkRawTransmitDone mTransmitDoneCallback; otLinkRawEnergyScanDone mEnergyScanDoneCallback; #if OPENTHREAD_RADIO SubMac mSubMac; #elif OPENTHREAD_CONFIG_LINK_RAW_ENABLE SubMac &mSubMac; #endif }; } // namespace Mac } // namespace ot #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE #endif // LINK_RAW_HPP_