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  */
56 class LinkRaw : public InstanceLocator, private NonCopyable
57 {
58     friend class ot::Instance;
59 
60 public:
61     /**
62      * Initializes the object.
63      *
64      * @param[in]   aInstance   A reference to the OpenThread instance.
65      *
66      */
67     explicit LinkRaw(Instance &aInstance);
68 
69     /**
70      * Initializes the states of the raw link-layer.
71      *
72      */
73     void Init(void);
74 
75     /**
76      * 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      * 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      * 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      * 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      * 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      * 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      * 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      * 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      * 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      * 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      * Returns the short address.
184      *
185      * @returns short address.
186      *
187      */
GetShortAddress(void) const188     ShortAddress GetShortAddress(void) const { return mSubMac.GetShortAddress(); }
189 
190     /**
191      * 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      * Returns PANID.
203      *
204      * @returns PANID.
205      *
206      */
GetPanId(void) const207     PanId GetPanId(void) const { return mPanId; }
208 
209     /**
210      * 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      * 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      * 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      * 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      * 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      * 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      * Sets the current MAC frame counter value.
273      *
274      * @param[in] aFrameCounter  The MAC frame counter value.
275      * @param[in] aSetIfLarger   If `true`, set only if the new value @p aFrameCounter is larger than current value.
276      *                           If `false`, set the new value independent of the current value.
277      *
278      * @retval kErrorNone            If successful.
279      * @retval kErrorInvalidState    If the raw link-layer isn't enabled.
280      *
281      */
282     Error SetMacFrameCounter(uint32_t aFrameCounter, bool aSetIfLarger);
283 
284 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
285     /**
286      * Records the status of a frame transmission attempt and is mainly used for logging failures.
287      *
288      * Unlike `HandleTransmitDone` which is called after all transmission attempts of frame to indicate final status
289      * of a frame transmission request, this method is invoked on all frame transmission attempts.
290      *
291      * @param[in] aFrame      The transmitted frame.
292      * @param[in] aError      kErrorNone when the frame was transmitted successfully,
293      *                        kErrorNoAck when the frame was transmitted but no ACK was received,
294      *                        kErrorChannelAccessFailure tx failed due to activity on the channel,
295      *                        kErrorAbort when transmission was aborted for other reasons.
296      * @param[in] aRetryCount Indicates number of transmission retries for this frame.
297      * @param[in] aWillRetx   Indicates whether frame will be retransmitted or not. This is applicable only
298      *                        when there was an error in transmission (i.e., `aError` is not NONE).
299      *
300      */
301     void RecordFrameTransmitStatus(const TxFrame &aFrame, Error aError, uint8_t aRetryCount, bool aWillRetx);
302 #else
RecordFrameTransmitStatus(const TxFrame &,Error,uint8_t,bool)303     void    RecordFrameTransmitStatus(const TxFrame &, Error, uint8_t, bool) {}
304 #endif
305 
306 private:
307     uint8_t                 mReceiveChannel;
308     PanId                   mPanId;
309     otLinkRawReceiveDone    mReceiveDoneCallback;
310     otLinkRawTransmitDone   mTransmitDoneCallback;
311     otLinkRawEnergyScanDone mEnergyScanDoneCallback;
312 
313 #if OPENTHREAD_RADIO
314     SubMac mSubMac;
315 #elif OPENTHREAD_CONFIG_LINK_RAW_ENABLE
316     SubMac &mSubMac;
317 #endif
318 };
319 
320 } // namespace Mac
321 } // namespace ot
322 
323 #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
324 
325 #endif // LINK_RAW_HPP_
326