openthread-sys 0.1.4

Rust bindings for OpenThread
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
/*
 *  Copyright (c) 2019, 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 OpenThread radio abstraction.
 */

#ifndef RADIO_HPP_
#define RADIO_HPP_

#include "openthread-core-config.h"

#include <openthread/platform/radio.h>

#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "mac/mac_frame.hpp"
#include "utils/static_assert.hpp"

namespace ot {

/**
 * @addtogroup core-radio
 *
 * @brief
 *   This module includes definitions for OpenThread radio abstraction.
 *
 * @{
 *
 */

/**
 * This class represents an OpenThread radio abstraction.
 *
 */
class Radio : public InstanceLocator, private NonCopyable
{
    friend class Instance;

public:
    /**
     * This enumeration defines the IEEE 802.15.4 channel related parameters.
     *
     */
    enum
    {
#if (OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT && OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT)
        kNumChannelPages       = 2,
        kSupportedChannels     = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK | OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK,
        kChannelMin            = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN,
        kChannelMax            = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX,
        kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK | OT_RADIO_CHANNEL_PAGE_2_MASK,
#elif OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
        kNumChannelPages       = 1,
        kSupportedChannels     = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK,
        kChannelMin            = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN,
        kChannelMax            = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX,
        kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_2_MASK,
#elif OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
        kNumChannelPages       = 1,
        kSupportedChannels     = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK,
        kChannelMin            = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
        kChannelMax            = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX,
        kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK,
#endif
    };

    OT_STATIC_ASSERT((OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT || OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT),
                     "OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT or OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT "
                     "must be set to 1 to specify the radio mode");

    /**
     * This class defines the callbacks from `Radio`.
     *
     */
    class Callbacks : public InstanceLocator
    {
        friend class Radio;

    public:
        /**
         * This callback method handles a "Receive Done" event from radio platform.
         *
         * @param[in]  aFrame    A pointer to the received frame or NULL if the receive operation failed.
         * @param[in]  aError    OT_ERROR_NONE when successfully received a frame,
         *                       OT_ERROR_ABORT when reception was aborted and a frame was not received,
         *                       OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
         *
         */
        void HandleReceiveDone(Mac::RxFrame *aFrame, otError aError);

        /**
         * This callback method handles a "Transmit Started" event from radio platform.
         *
         * @param[in]  aFrame     The frame that is being transmitted.
         *
         */
        void HandleTransmitStarted(Mac::TxFrame &aFrame);

        /**
         * This callback method handles a "Transmit Done" event from radio platform.
         *
         * @param[in]  aFrame     The frame that was transmitted.
         * @param[in]  aAckFrame  A pointer to the ACK frame, NULL if no ACK was received.
         * @param[in]  aError     OT_ERROR_NONE when the frame was transmitted,
         *                        OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received,
         *                        OT_ERROR_CHANNEL_ACCESS_FAILURE tx could not take place due to activity on the
         *                        channel, OT_ERROR_ABORT when transmission was aborted for other reasons.
         *
         */
        void HandleTransmitDone(Mac::TxFrame &aFrame, Mac::RxFrame *aAckFrame, otError aError);

        /**
         * This callback method handles "Energy Scan Done" event from radio platform.
         *
         * This method is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability. It is called from
         * `otPlatRadioEnergyScanDone()`.
         *
         * @param[in]  aInstance           The OpenThread instance structure.
         * @param[in]  aEnergyScanMaxRssi  The maximum RSSI encountered on the scanned channel.
         *
         */
        void HandleEnergyScanDone(int8_t aMaxRssi);

#if OPENTHREAD_CONFIG_DIAG_ENABLE
        /**
         * This callback method handles a "Receive Done" event from radio platform when diagnostics mode is enabled.
         *
         * @param[in]  aFrame    A pointer to the received frame or NULL if the receive operation failed.
         * @param[in]  aError    OT_ERROR_NONE when successfully received a frame,
         *                       OT_ERROR_ABORT when reception was aborted and a frame was not received,
         *                       OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
         *
         */
        void HandleDiagsReceiveDone(Mac::RxFrame *aFrame, otError aError);

        /**
         * This callback method handles a "Transmit Done" event from radio platform when diagnostics mode is enabled.
         *
         * @param[in]  aFrame     The frame that was transmitted.
         * @param[in]  aError     OT_ERROR_NONE when the frame was transmitted,
         *                        OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received,
         *                        OT_ERROR_CHANNEL_ACCESS_FAILURE tx could not take place due to activity on the
         *                        channel, OT_ERROR_ABORT when transmission was aborted for other reasons.
         *
         */
        void HandleDiagsTransmitDone(Mac::TxFrame &aFrame, otError aError);
#endif

    private:
        explicit Callbacks(Instance &aInstance)
            : InstanceLocator(aInstance)
        {
        }
    };

    /**
     * This constructor initializes the `Radio` object.
     *
     * @param[in]  aInstance  A reference to the OpenThread instance.
     *
     */
    Radio(Instance &aInstance)
        : InstanceLocator(aInstance)
        , mCallbacks(aInstance)
    {
    }

    /**
     * This method gets the radio capabilities.
     *
     * @returns The radio capability bit vector (see `OT_RADIO_CAP_*` definitions).
     *
     */
    otRadioCaps GetCaps(void) { return otPlatRadioGetCaps(GetInstance()); }

    /**
     * This method gets the radio version string.
     *
     * @returns A pointer to the OpenThread radio version.
     *
     */
    const char *GetVersionString(void) { return otPlatRadioGetVersionString(GetInstance()); }

    /**
     * This method gets the radio receive sensitivity value.
     *
     * @returns The radio receive sensitivity value in dBm.
     *
     */
    int8_t GetReceiveSensitivity(void) { return otPlatRadioGetReceiveSensitivity(GetInstance()); }

    /**
     * This method gets the factory-assigned IEEE EUI-64 for the device.
     *
     * @param[out] aIeeeEui64  A reference to `Mac::ExtAddress` to place the factory-assigned IEEE EUI-64.
     *
     */
    void GetIeeeEui64(Mac::ExtAddress &aIeeeEui64) { otPlatRadioGetIeeeEui64(GetInstance(), aIeeeEui64.m8); }

    /**
     * This method sets the PAN ID for address filtering.
     *
     * @param[in] aPanId     The IEEE 802.15.4 PAN ID.
     *
     */
    void SetPanId(Mac::PanId aPanId) { otPlatRadioSetPanId(GetInstance(), aPanId); }

    /**
     * This method sets the Extended Address for address filtering.
     *
     * @param[in] aExtAddress  The IEEE 802.15.4 Extended Address stored in little-endian byte order.
     *
     */
    void SetExtendedAddress(const Mac::ExtAddress &aExtAddress);

    /**
     * This method sets the Short Address for address filtering.
     *
     * @param[in] aShortAddress  The IEEE 802.15.4 Short Address.
     *
     */
    void SetShortAddress(Mac::ShortAddress aShortAddress);

    /**
     * This method sets MAC key and key ID.
     *
     * @param[in] aKeyIdMode  MAC key ID mode.
     * @param[in] aKeyId      Current MAC key index.
     * @param[in] aPrevKey    The previous MAC key.
     * @param[in] aCurrKey    The current MAC key.
     * @param[in] aNextKey    The next MAC key.
     *
     */
    void SetMacKey(uint8_t         aKeyIdMode,
                   uint8_t         aKeyId,
                   const Mac::Key &aPrevKey,
                   const Mac::Key &aCurrKey,
                   const Mac::Key &aNextKey)
    {
        otPlatRadioSetMacKey(GetInstance(), aKeyIdMode, aKeyId, &aPrevKey, &aCurrKey, &aNextKey);
    }

    /**
     * This method gets the radio's transmit power in dBm.
     *
     * @param[out] aPower    A reference to output the transmit power in dBm.
     *
     * @retval OT_ERROR_NONE             Successfully retrieved the transmit power.
     * @retval OT_ERROR_NOT_IMPLEMENTED  Transmit power configuration via dBm is not implemented.
     *
     */
    otError GetTransmitPower(int8_t &aPower) { return otPlatRadioGetTransmitPower(GetInstance(), &aPower); }

    /**
     * This method sets the radio's transmit power in dBm.
     *
     * @param[in] aPower     The transmit power in dBm.
     *
     * @retval OT_ERROR_NONE             Successfully set the transmit power.
     * @retval OT_ERROR_NOT_IMPLEMENTED  Transmit power configuration via dBm is not implemented.
     *
     */
    otError SetTransmitPower(int8_t aPower) { return otPlatRadioSetTransmitPower(GetInstance(), aPower); }

    /**
     * This method gets the radio's CCA ED threshold in dBm.
     *
     * @param[in] aThreshold    The CCA ED threshold in dBm.
     *
     * @retval OT_ERROR_NONE             A reference to output the CCA ED threshold in dBm.
     * @retval OT_ERROR_NOT_IMPLEMENTED  CCA ED threshold configuration via dBm is not implemented.
     *
     */
    otError GetCcaEnergyDetectThreshold(int8_t &aThreshold)
    {
        return otPlatRadioGetCcaEnergyDetectThreshold(GetInstance(), &aThreshold);
    }

    /**
     * This method sets the radio's CCA ED threshold in dBm.
     *
     * @param[in] aThreshold    The CCA ED threshold in dBm.
     *
     * @retval OT_ERROR_NONE             Successfully set the CCA ED threshold.
     * @retval OT_ERROR_NOT_IMPLEMENTED  CCA ED threshold configuration via dBm is not implemented.
     *
     */
    otError SetCcaEnergyDetectThreshold(int8_t aThreshold)
    {
        return otPlatRadioSetCcaEnergyDetectThreshold(GetInstance(), aThreshold);
    }

    /**
     * This method gets the status of promiscuous mode.
     *
     * @retval TRUE   Promiscuous mode is enabled.
     * @retval FALSE  Promiscuous mode is disabled.
     *
     */
    bool GetPromiscuous(void) { return otPlatRadioGetPromiscuous(GetInstance()); }

    /**
     * This method enables or disables promiscuous mode.
     *
     * @param[in]  aEnable   TRUE to enable or FALSE to disable promiscuous mode.
     *
     */
    void SetPromiscuous(bool aEnable) { otPlatRadioSetPromiscuous(GetInstance(), aEnable); }

    /**
     * This method returns the current state of the radio.
     *
     * This function is not required by OpenThread. It may be used for debugging and/or application-specific purposes.
     *
     * @note This function may be not implemented. In this case it always returns OT_RADIO_STATE_INVALID state.
     *
     * @return  Current state of the radio.
     *
     */
    otRadioState GetState(void) { return otPlatRadioGetState(GetInstance()); }

    /**
     * This method enables the radio.
     *
     * @retval OT_ERROR_NONE     Successfully enabled.
     * @retval OT_ERROR_FAILED   The radio could not be enabled.
     *
     */
    otError Enable(void) { return otPlatRadioEnable(GetInstance()); }

    /**
     * This method disables the radio.
     *
     * @retval OT_ERROR_NONE            Successfully transitioned to Disabled.
     * @retval OT_ERROR_INVALID_STATE   The radio was not in sleep state.
     *
     */
    otError Disable(void) { return otPlatRadioDisable(GetInstance()); }

    /**
     * This method indicates whether radio is enabled or not.
     *
     * @returns TRUE if the radio is enabled, FALSE otherwise.
     *
     */
    bool IsEnabled(void) { return otPlatRadioIsEnabled(GetInstance()); }

    /**
     * This method transitions the radio from Receive to Sleep (turn off the radio).
     *
     * @retval OT_ERROR_NONE          Successfully transitioned to Sleep.
     * @retval OT_ERROR_BUSY          The radio was transmitting.
     * @retval OT_ERROR_INVALID_STATE The radio was disabled.
     *
     */
    otError Sleep(void) { return otPlatRadioSleep(GetInstance()); }

    /**
     * This method transitions the radio from Sleep to Receive (turn on the radio).
     *
     * @param[in]  aChannel   The channel to use for receiving.
     *
     * @retval OT_ERROR_NONE          Successfully transitioned to Receive.
     * @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting.
     *
     */
    otError Receive(uint8_t aChannel) { return otPlatRadioReceive(GetInstance(), aChannel); }

    /**
     * This method gets the radio transmit frame buffer.
     *
     * OpenThread forms the IEEE 802.15.4 frame in this buffer then calls `Transmit()` to request transmission.
     *
     * @returns A reference to the transmit frame buffer.
     *
     */
    Mac::TxFrame &GetTransmitBuffer(void)
    {
        return *static_cast<Mac::TxFrame *>(otPlatRadioGetTransmitBuffer(GetInstance()));
    }

    /**
     * This method starts the transmit sequence on the radio.
     *
     * The caller must form the IEEE 802.15.4 frame in the buffer provided by `GetTransmitBuffer()` before
     * requesting transmission.  The channel and transmit power are also included in the frame.
     *
     * @param[in] aFrame     A reference to the frame to be transmitted.
     *
     * @retval OT_ERROR_NONE          Successfully transitioned to Transmit.
     * @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state.
     *
     */
    otError Transmit(Mac::TxFrame &aFrame) { return otPlatRadioTransmit(GetInstance(), &aFrame); }

    /**
     * This method gets the most recent RSSI measurement.
     *
     * @returns The RSSI in dBm when it is valid.  127 when RSSI is invalid.
     *
     */
    int8_t GetRssi(void) { return otPlatRadioGetRssi(GetInstance()); }

    /**
     * This method begins the energy scan sequence on the radio.
     *
     * This function is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability.
     *
     * @param[in] aScanChannel   The channel to perform the energy scan on.
     * @param[in] aScanDuration  The duration, in milliseconds, for the channel to be scanned.
     *
     * @retval OT_ERROR_NONE             Successfully started scanning the channel.
     * @retval OT_ERROR_NOT_IMPLEMENTED  The radio doesn't support energy scanning.
     *
     */
    otError EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration)
    {
        return otPlatRadioEnergyScan(GetInstance(), aScanChannel, aScanDuration);
    }

    /**
     * This method enables/disables source address match feature.
     *
     * The source address match feature controls how the radio layer decides the "frame pending" bit for acks sent in
     * response to data request commands from children.
     *
     * If disabled, the radio layer must set the "frame pending" on all acks to data request commands.
     *
     * If enabled, the radio layer uses the source address match table to determine whether to set or clear the "frame
     * pending" bit in an ack to a data request command.
     *
     * The source address match table provides the list of children for which there is a pending frame. Either a short
     * address or an extended/long address can be added to the source address match table.
     *
     * @param[in]  aEnable     Enable/disable source address match feature.
     *
     */
    void EnableSrcMatch(bool aEnable) { return otPlatRadioEnableSrcMatch(GetInstance(), aEnable); }

    /**
     * This method adds a short address to the source address match table.
     *
     * @param[in]  aShortAddress  The short address to be added.
     *
     * @retval OT_ERROR_NONE      Successfully added short address to the source match table.
     * @retval OT_ERROR_NO_BUFS   No available entry in the source match table.
     *
     */
    otError AddSrcMatchShortEntry(Mac::ShortAddress aShortAddress)
    {
        return otPlatRadioAddSrcMatchShortEntry(GetInstance(), aShortAddress);
    }

    /**
     * This method adds an extended address to the source address match table.
     *
     * @param[in]  aExtAddress  The extended address to be added stored in little-endian byte order.
     *
     * @retval OT_ERROR_NONE      Successfully added extended address to the source match table.
     * @retval OT_ERROR_NO_BUFS   No available entry in the source match table.
     *
     */
    otError AddSrcMatchExtEntry(const Mac::ExtAddress &aExtAddress)
    {
        return otPlatRadioAddSrcMatchExtEntry(GetInstance(), &aExtAddress);
    }

    /**
     * This method removes a short address from the source address match table.
     *
     * @param[in]  aShortAddress  The short address to be removed.
     *
     * @retval OT_ERROR_NONE        Successfully removed short address from the source match table.
     * @retval OT_ERROR_NO_ADDRESS  The short address is not in source address match table.
     *
     */
    otError ClearSrcMatchShortEntry(Mac::ShortAddress aShortAddress)
    {
        return otPlatRadioClearSrcMatchShortEntry(GetInstance(), aShortAddress);
    }

    /**
     * This method removes an extended address from the source address match table.
     *
     * @param[in]  aExtAddress  The extended address to be removed stored in little-endian byte order.
     *
     * @retval OT_ERROR_NONE        Successfully removed the extended address from the source match table.
     * @retval OT_ERROR_NO_ADDRESS  The extended address is not in source address match table.
     *
     */
    otError ClearSrcMatchExtEntry(const Mac::ExtAddress &aExtAddress)
    {
        return otPlatRadioClearSrcMatchExtEntry(GetInstance(), &aExtAddress);
    }

    /**
     * This method clears all short addresses from the source address match table.
     *
     */
    void ClearSrcMatchShortEntries(void) { otPlatRadioClearSrcMatchShortEntries(GetInstance()); }

    /**
     * This method clears all the extended/long addresses from source address match table.
     *
     */
    void ClearSrcMatchExtEntries(void) { otPlatRadioClearSrcMatchExtEntries(GetInstance()); }

    /**
     * This method gets the radio supported channel mask that the device is allowed to be on.
     *
     * @returns The radio supported channel mask.
     *
     */
    uint32_t GetSupportedChannelMask(void) { return otPlatRadioGetSupportedChannelMask(GetInstance()); }

    /**
     * This method gets the radio preferred channel mask that the device prefers to form on.
     *
     * @returns The radio preferred channel mask.
     *
     */
    uint32_t GetPreferredChannelMask(void) { return otPlatRadioGetPreferredChannelMask(GetInstance()); }

private:
    otInstance *GetInstance(void) { return reinterpret_cast<otInstance *>(&InstanceLocator::GetInstance()); }

    Callbacks mCallbacks;
};

} // namespace ot

#endif // RADIO_HPP_