1 /*
2  *  Copyright (c) 2020, 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  * @brief
32  *   This file defines the OpenThread Link Metrics API.
33  */
34 
35 #ifndef LINK_METRICS_H_
36 #define LINK_METRICS_H_
37 
38 #include "openthread-core-config.h"
39 
40 #include <openthread/ip6.h>
41 #include <openthread/message.h>
42 #include <openthread/platform/radio.h>
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 /**
49  * @addtogroup api-link-metrics
50  *
51  * @brief
52  *   This module includes functions that control the Link Metrics protocol.
53  *
54  * @{
55  *
56  */
57 
58 /**
59  * This structure represents the result (value) for a Link Metrics query.
60  *
61  */
62 typedef struct otLinkMetricsValues
63 {
64     otLinkMetrics mMetrics; ///< Specifies which metrics values are present/included.
65 
66     uint32_t mPduCountValue;   ///< The value of Pdu Count.
67     uint8_t  mLqiValue;        ///< The value LQI.
68     uint8_t  mLinkMarginValue; ///< The value of Link Margin.
69     int8_t   mRssiValue;       ///< The value of Rssi.
70 } otLinkMetricsValues;
71 
72 /**
73  * This structure represents which frames are accounted in a Forward Tracking Series.
74  *
75  */
76 typedef struct otLinkMetricsSeriesFlags
77 {
78     bool mLinkProbe : 1;      ///< MLE Link Probe.
79     bool mMacData : 1;        ///< MAC Data frame.
80     bool mMacDataRequest : 1; ///< MAC Data Request.
81     bool mMacAck : 1;         ///< MAC Ack.
82 } otLinkMetricsSeriesFlags;
83 
84 /**
85  * Enhanced-ACK Flags.
86  *
87  * These are used in Enhanced-ACK Based Probing to indicate whether to register or clear the probing.
88  *
89  */
90 typedef enum otLinkMetricsEnhAckFlags
91 {
92     OT_LINK_METRICS_ENH_ACK_CLEAR    = 0, ///< Clear.
93     OT_LINK_METRICS_ENH_ACK_REGISTER = 1, ///< Register.
94 } otLinkMetricsEnhAckFlags;
95 
96 /**
97  * Link Metrics Status values.
98  *
99  */
100 typedef enum otLinkMetricsStatus
101 {
102     OT_LINK_METRICS_STATUS_SUCCESS                     = 0,
103     OT_LINK_METRICS_STATUS_CANNOT_SUPPORT_NEW_SERIES   = 1,
104     OT_LINK_METRICS_STATUS_SERIESID_ALREADY_REGISTERED = 2,
105     OT_LINK_METRICS_STATUS_SERIESID_NOT_RECOGNIZED     = 3,
106     OT_LINK_METRICS_STATUS_NO_MATCHING_FRAMES_RECEIVED = 4,
107     OT_LINK_METRICS_STATUS_OTHER_ERROR                 = 254,
108 } otLinkMetricsStatus;
109 
110 /**
111  * This function pointer is called when a Link Metrics report is received.
112  *
113  * @param[in]  aSource         A pointer to the source address.
114  * @param[in]  aMetricsValues  A pointer to the Link Metrics values (the query result).
115  * @param[in]  aStatus         The status code in the report (only useful when @p aMetricsValues is NULL).
116  * @param[in]  aContext        A pointer to application-specific context.
117  *
118  */
119 typedef void (*otLinkMetricsReportCallback)(const otIp6Address        *aSource,
120                                             const otLinkMetricsValues *aMetricsValues,
121                                             uint8_t                    aStatus,
122                                             void                      *aContext);
123 /**
124  * This function pointer is called when a Link Metrics Management Response is received.
125  *
126  * @param[in]  aSource         A pointer to the source address.
127  * @param[in]  aStatus         The status code in the response.
128  * @param[in]  aContext        A pointer to application-specific context.
129  *
130  */
131 typedef void (*otLinkMetricsMgmtResponseCallback)(const otIp6Address *aSource, uint8_t aStatus, void *aContext);
132 
133 /**
134  * This function pointer is called when Enh-ACK Probing IE is received.
135  *
136  * @param[in] aShortAddress     The Mac short address of the Probing Subject.
137  * @param[in] aExtAddress       A pointer to the Mac extended address of the Probing Subject.
138  * @param[in] aMetricsValues    A pointer to the Link Metrics values obtained from the IE.
139  * @param[in] aContext          A pointer to application-specific context.
140  *
141  */
142 typedef void (*otLinkMetricsEnhAckProbingIeReportCallback)(otShortAddress             aShortAddress,
143                                                            const otExtAddress        *aExtAddress,
144                                                            const otLinkMetricsValues *aMetricsValues,
145                                                            void                      *aContext);
146 
147 /**
148  * This function sends an MLE Data Request to query Link Metrics.
149  *
150  * It could be either Single Probe or Forward Tracking Series.
151  *
152  * @param[in]  aInstance            A pointer to an OpenThread instance.
153  * @param[in]  aDestination         A pointer to the destination address.
154  * @param[in]  aSeriesId            The Series ID to query about, 0 for Single Probe.
155  * @param[in]  aLinkMetricsFlags    A pointer to flags specifying what metrics to query.
156  * @param[in]  aCallback            A pointer to a function that is called when Link Metrics report is received.
157  * @param[in]  aCallbackContext     A pointer to application-specific context.
158  *
159  * @retval OT_ERROR_NONE              Successfully sent a Link Metrics query message.
160  * @retval OT_ERROR_NO_BUFS           Insufficient buffers to generate the MLE Data Request message.
161  * @retval OT_ERROR_UNKNOWN_NEIGHBOR  @p aDestination is not link-local or the neighbor is not found.
162  * @retval OT_ERROR_NOT_CAPABLE       The neighbor is not a Thread 1.2 device and does not support Link Metrics.
163  *
164  */
165 otError otLinkMetricsQuery(otInstance                 *aInstance,
166                            const otIp6Address         *aDestination,
167                            uint8_t                     aSeriesId,
168                            const otLinkMetrics        *aLinkMetricsFlags,
169                            otLinkMetricsReportCallback aCallback,
170                            void                       *aCallbackContext);
171 
172 /**
173  * Sends an MLE Link Metrics Management Request to configure or clear a Forward Tracking Series.
174  *
175  * @param[in] aInstance          A pointer to an OpenThread instance.
176  * @param[in] aDestination       A pointer to the destination address.
177  * @param[in] aSeriesId          The Series ID to operate with.
178  * @param[in] aSeriesFlags       The Series Flags that specifies which frames are to be accounted.
179  * @param[in] aLinkMetricsFlags  A pointer to flags specifying what metrics to query. Should be `NULL` when
180  *                               `aSeriesFlags` is `0`.
181  * @param[in]  aCallback         A pointer to a function that is called when Link Metrics Management Response is
182  *                               received.
183  * @param[in]  aCallbackContext  A pointer to application-specific context.
184  *
185  * @retval OT_ERROR_NONE              Successfully sent a Link Metrics Management Request message.
186  * @retval OT_ERROR_NO_BUFS           Insufficient buffers to generate the MLE Link Metrics Management Request message.
187  * @retval OT_ERROR_INVALID_ARGS      @p aSeriesId is not within the valid range.
188  * @retval OT_ERROR_UNKNOWN_NEIGHBOR  @p aDestination is not link-local or the neighbor is not found.
189  * @retval OT_ERROR_NOT_CAPABLE       The neighbor is not a Thread 1.2 device and does not support Link Metrics.
190  *
191  */
192 otError otLinkMetricsConfigForwardTrackingSeries(otInstance                       *aInstance,
193                                                  const otIp6Address               *aDestination,
194                                                  uint8_t                           aSeriesId,
195                                                  otLinkMetricsSeriesFlags          aSeriesFlags,
196                                                  const otLinkMetrics              *aLinkMetricsFlags,
197                                                  otLinkMetricsMgmtResponseCallback aCallback,
198                                                  void                             *aCallbackContext);
199 
200 /**
201  * This function sends an MLE Link Metrics Management Request to configure/clear an Enhanced-ACK Based Probing.
202  * This functionality requires OT_LINK_METRICS_INITIATOR feature enabled.
203  *
204  * @param[in] aInstance          A pointer to an OpenThread instance.
205  * @param[in] aDestination       A pointer to the destination address.
206  * @param[in] aEnhAckFlags       Enh-ACK Flags to indicate whether to register or clear the probing. `0` to clear and
207  *                               `1` to register. Other values are reserved.
208  * @param[in] aLinkMetricsFlags  A pointer to flags specifying what metrics to query. Should be `NULL` when
209  *                               `aEnhAckFlags` is `0`.
210  * @param[in] aCallback          A pointer to a function that is called when an Enhanced Ack with Link Metrics is
211  *                               received.
212  * @param[in] aCallbackContext   A pointer to application-specific context.
213  *
214  * @retval OT_ERROR_NONE              Successfully sent a Link Metrics Management Request message.
215  * @retval OT_ERROR_NO_BUFS           Insufficient buffers to generate the MLE Link Metrics Management Request message.
216  * @retval OT_ERROR_INVALID_ARGS      @p aEnhAckFlags is not a valid value or @p aLinkMetricsFlags isn't correct.
217  * @retval OT_ERROR_UNKNOWN_NEIGHBOR  @p aDestination is not link-local or the neighbor is not found.
218  * @retval OT_ERROR_NOT_CAPABLE       The neighbor is not a Thread 1.2 device and does not support Link Metrics.
219  *
220  */
221 otError otLinkMetricsConfigEnhAckProbing(otInstance                                *aInstance,
222                                          const otIp6Address                        *aDestination,
223                                          otLinkMetricsEnhAckFlags                   aEnhAckFlags,
224                                          const otLinkMetrics                       *aLinkMetricsFlags,
225                                          otLinkMetricsMgmtResponseCallback          aCallback,
226                                          void                                      *aCallbackContext,
227                                          otLinkMetricsEnhAckProbingIeReportCallback aEnhAckCallback,
228                                          void                                      *aEnhAckCallbackContext);
229 
230 /**
231  * Sends an MLE Link Probe message.
232  *
233  * @param[in] aInstance       A pointer to an OpenThread instance.
234  * @param[in] aDestination    A pointer to the destination address.
235  * @param[in] aSeriesId       The Series ID [1, 254] which the Probe message aims at.
236  * @param[in] aLength         The length of the data payload in Link Probe TLV, [0, 64] (per Thread 1.2 spec, 4.4.37).
237  *
238  * @retval OT_ERROR_NONE              Successfully sent a Link Probe message.
239  * @retval OT_ERROR_NO_BUFS           Insufficient buffers to generate the MLE Link Probe message.
240  * @retval OT_ERROR_INVALID_ARGS      @p aSeriesId or @p aLength is not within the valid range.
241  * @retval OT_ERROR_UNKNOWN_NEIGHBOR  @p aDestination is not link-local or the neighbor is not found.
242  * @retval OT_ERROR_NOT_CAPABLE       The neighbor is not a Thread 1.2 device and does not support Link Metrics.
243  *
244  */
245 otError otLinkMetricsSendLinkProbe(otInstance         *aInstance,
246                                    const otIp6Address *aDestination,
247                                    uint8_t             aSeriesId,
248                                    uint8_t             aLength);
249 
250 /**
251  * @}
252  *
253  */
254 
255 #ifdef __cplusplus
256 } // extern "C"
257 #endif
258 
259 #endif // LINK_METRICS_H_
260