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 Network Diagnostic API.
33  */
34 
35 #ifndef OPENTHREAD_NETDIAG_H_
36 #define OPENTHREAD_NETDIAG_H_
37 
38 #include <openthread/ip6.h>
39 #include <openthread/thread.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /**
46  * @addtogroup api-thread-general
47  *
48  * @{
49  *
50  */
51 
52 /**
53  * Maximum Number of Network Diagnostic TLV Types to Request or Reset.
54  */
55 #define OT_NETWORK_DIAGNOSTIC_TYPELIST_MAX_ENTRIES 19
56 
57 /**
58  * Size of Network Diagnostic Child Table entry.
59  */
60 #define OT_NETWORK_DIAGNOSTIC_CHILD_TABLE_ENTRY_SIZE 3
61 
62 /**
63  * Initializer for otNetworkDiagIterator.
64  */
65 #define OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT 0
66 
67 enum
68 {
69     OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS       = 0,  ///< MAC Extended Address TLV
70     OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS     = 1,  ///< Address16 TLV
71     OT_NETWORK_DIAGNOSTIC_TLV_MODE              = 2,  ///< Mode TLV
72     OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT           = 3,  ///< Timeout TLV (the maximum polling time period for SEDs)
73     OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY      = 4,  ///< Connectivity TLV
74     OT_NETWORK_DIAGNOSTIC_TLV_ROUTE             = 5,  ///< Route64 TLV
75     OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA       = 6,  ///< Leader Data TLV
76     OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA      = 7,  ///< Network Data TLV
77     OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST     = 8,  ///< IPv6 Address List TLV
78     OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS      = 9,  ///< MAC Counters TLV
79     OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL     = 14, ///< Battery Level TLV
80     OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE    = 15, ///< Supply Voltage TLV
81     OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE       = 16, ///< Child Table TLV
82     OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES     = 17, ///< Channel Pages TLV
83     OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST         = 18, ///< Type List TLV
84     OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT = 19, ///< Max Child Timeout TLV
85 };
86 
87 typedef uint16_t otNetworkDiagIterator; ///< Used to iterate through Network Diagnostic TLV.
88 
89 /**
90  * This structure represents a Network Diagnostic Connectivity value.
91  *
92  */
93 typedef struct otNetworkDiagConnectivity
94 {
95     /**
96      * The priority of the sender as a parent.
97      */
98     int8_t mParentPriority;
99 
100     /**
101      * The number of neighboring devices with which the sender shares a link of quality 3.
102      */
103     uint8_t mLinkQuality3;
104 
105     /**
106      * The number of neighboring devices with which the sender shares a link of quality 2.
107      */
108     uint8_t mLinkQuality2;
109 
110     /**
111      * The number of neighboring devices with which the sender shares a link of quality 1.
112      */
113     uint8_t mLinkQuality1;
114 
115     /**
116      * The sender's routing cost to the Leader.
117      */
118     uint8_t mLeaderCost;
119 
120     /**
121      * The most recent ID sequence number received by the sender.
122      */
123     uint8_t mIdSequence;
124 
125     /**
126      * The number of active Routers in the sender's Thread Network Partition.
127      */
128     uint8_t mActiveRouters;
129 
130     /**
131      * The guaranteed buffer capacity in octets for all IPv6 datagrams destined to a given SED. Optional.
132      */
133     uint16_t mSedBufferSize;
134 
135     /**
136      * The guaranteed queue capacity in number of IPv6 datagrams destined to a given SED. Optional.
137      */
138     uint8_t mSedDatagramCount;
139 } otNetworkDiagConnectivity;
140 
141 /**
142  * This structure represents a Network Diagnostic Route data.
143  *
144  */
145 typedef struct otNetworkDiagRouteData
146 {
147     uint8_t mRouterId;           ///< The Assigned Router ID.
148     uint8_t mLinkQualityOut : 2; ///< Link Quality Out.
149     uint8_t mLinkQualityIn : 2;  ///< Link Quality In.
150     uint8_t mRouteCost : 4;      ///< Routing Cost. Infinite routing cost is represented by value 0.
151 } otNetworkDiagRouteData;
152 
153 /**
154  * This structure represents a Network Diagnostic Route TLV value.
155  *
156  */
157 typedef struct otNetworkDiagRoute
158 {
159     /**
160      * The sequence number associated with the set of Router ID assignments in #mRouteData.
161      */
162     uint8_t mIdSequence;
163 
164     /**
165      * Number of elements in #mRouteData.
166      */
167     uint8_t mRouteCount;
168 
169     /**
170      * Link Quality and Routing Cost data.
171      */
172     otNetworkDiagRouteData mRouteData[OT_NETWORK_MAX_ROUTER_ID + 1];
173 } otNetworkDiagRoute;
174 
175 /**
176  * This structure represents a Network Diagnostic Mac Counters value.
177  *
178  * See <a href="https://www.ietf.org/rfc/rfc2863">RFC 2863</a> for definitions of member fields.
179  *
180  */
181 typedef struct otNetworkDiagMacCounters
182 {
183     uint32_t mIfInUnknownProtos;
184     uint32_t mIfInErrors;
185     uint32_t mIfOutErrors;
186     uint32_t mIfInUcastPkts;
187     uint32_t mIfInBroadcastPkts;
188     uint32_t mIfInDiscards;
189     uint32_t mIfOutUcastPkts;
190     uint32_t mIfOutBroadcastPkts;
191     uint32_t mIfOutDiscards;
192 } otNetworkDiagMacCounters;
193 
194 /**
195  * This structure represents a Network Diagnostic Child Table Entry.
196  *
197  */
198 typedef struct otNetworkDiagChildEntry
199 {
200     /**
201      * Expected poll time expressed as 2^(Timeout-4) seconds.
202      */
203     uint16_t mTimeout : 5;
204 
205     /**
206      * Child ID from which an RLOC can be generated.
207      */
208     uint16_t mChildId : 9;
209 
210     /**
211      * Link mode bits.
212      */
213     otLinkModeConfig mMode;
214 } otNetworkDiagChildEntry;
215 
216 /**
217  * This structure represents a Network Diagnostic TLV.
218  *
219  */
220 typedef struct otNetworkDiagTlv
221 {
222     /**
223      * The Network Diagnostic TLV type.
224      */
225     uint8_t mType;
226 
227     union
228     {
229         otExtAddress              mExtAddress;
230         uint16_t                  mAddr16;
231         otLinkModeConfig          mMode;
232         uint32_t                  mTimeout;
233         otNetworkDiagConnectivity mConnectivity;
234         otNetworkDiagRoute        mRoute;
235         otLeaderData              mLeaderData;
236         otNetworkDiagMacCounters  mMacCounters;
237         uint8_t                   mBatteryLevel;
238         uint16_t                  mSupplyVoltage;
239         uint32_t                  mMaxChildTimeout;
240         struct
241         {
242             uint8_t mCount;
243             uint8_t m8[OT_NETWORK_BASE_TLV_MAX_LENGTH];
244         } mNetworkData;
245         struct
246         {
247             uint8_t      mCount;
248             otIp6Address mList[OT_NETWORK_BASE_TLV_MAX_LENGTH / OT_IP6_ADDRESS_SIZE];
249         } mIp6AddrList;
250         struct
251         {
252             uint8_t mCount;
253             otNetworkDiagChildEntry
254                 mTable[OT_NETWORK_BASE_TLV_MAX_LENGTH / OT_NETWORK_DIAGNOSTIC_CHILD_TABLE_ENTRY_SIZE];
255         } mChildTable;
256         struct
257         {
258             uint8_t mCount;
259             uint8_t m8[OT_NETWORK_BASE_TLV_MAX_LENGTH];
260         } mChannelPages;
261     } mData;
262 } otNetworkDiagTlv;
263 
264 /**
265  * This function gets the next Network Diagnostic TLV in the message.
266  *
267  * @param[in]     aMessage         A pointer to a message.
268  * @param[inout]  aIterator        A pointer to the Network Diagnostic iterator context. To get the first
269  *                                 Network Diagnostic TLV it should be set to OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT.
270  * @param[out]    aNetworkDiagTlv  A pointer to where the Network Diagnostic TLV information will be placed.
271  *
272  * @retval OT_ERROR_NONE       Successfully found the next Network Diagnostic TLV.
273  * @retval OT_ERROR_NOT_FOUND  No subsequent Network Diagnostic TLV exists in the message.
274  * @retval OT_ERROR_PARSE      Parsing the next Network Diagnostic failed.
275  *
276  * @Note A subsequent call to this function is allowed only when current return value is OT_ERROR_NONE.
277  *
278  */
279 otError otThreadGetNextDiagnosticTlv(const otMessage *      aMessage,
280                                      otNetworkDiagIterator *aIterator,
281                                      otNetworkDiagTlv *     aNetworkDiagTlv);
282 
283 /**
284  * This function pointer is called when Network Diagnostic Get response is received.
285  *
286  * @param[in]  aError        The error when failed to get the response.
287  * @param[in]  aMessage      A pointer to the message buffer containing the received Network Diagnostic
288  *                           Get response payload. Available only when @p aError is `OT_ERROR_NONE`.
289  * @param[in]  aMessageInfo  A pointer to the message info for @p aMessage. Available only when
290  *                           @p aError is `OT_ERROR_NONE`.
291  * @param[in]  aContext      A pointer to application-specific context.
292  *
293  */
294 typedef void (*otReceiveDiagnosticGetCallback)(otError              aError,
295                                                otMessage *          aMessage,
296                                                const otMessageInfo *aMessageInfo,
297                                                void *               aContext);
298 
299 /**
300  * Send a Network Diagnostic Get request.
301  *
302  * @param[in]  aInstance         A pointer to an OpenThread instance.
303  * @param[in]  aDestination      A pointer to destination address.
304  * @param[in]  aTlvTypes         An array of Network Diagnostic TLV types.
305  * @param[in]  aCount            Number of types in aTlvTypes.
306  * @param[in]  aCallback         A pointer to a function that is called when Network Diagnostic Get response
307  *                               is received or NULL to disable the callback.
308  * @param[in]  aCallbackContext  A pointer to application-specific context.
309  *
310  * @retval OT_ERROR_NONE    Successfully queued the DIAG_GET.req.
311  * @retval OT_ERROR_NO_BUFS Insufficient message buffers available to send DIAG_GET.req.
312  *
313  */
314 otError otThreadSendDiagnosticGet(otInstance *                   aInstance,
315                                   const otIp6Address *           aDestination,
316                                   const uint8_t                  aTlvTypes[],
317                                   uint8_t                        aCount,
318                                   otReceiveDiagnosticGetCallback aCallback,
319                                   void *                         aCallbackContext);
320 
321 /**
322  * Send a Network Diagnostic Reset request.
323  *
324  * @param[in]  aInstance      A pointer to an OpenThread instance.
325  * @param[in]  aDestination   A pointer to destination address.
326  * @param[in]  aTlvTypes      An array of Network Diagnostic TLV types. Currently only Type 9 is allowed.
327  * @param[in]  aCount         Number of types in aTlvTypes
328  *
329  * @retval OT_ERROR_NONE    Successfully queued the DIAG_RST.ntf.
330  * @retval OT_ERROR_NO_BUFS Insufficient message buffers available to send DIAG_RST.ntf.
331  *
332  */
333 otError otThreadSendDiagnosticReset(otInstance *        aInstance,
334                                     const otIp6Address *aDestination,
335                                     const uint8_t       aTlvTypes[],
336                                     uint8_t             aCount);
337 
338 /**
339  * @}
340  *
341  */
342 
343 #ifdef __cplusplus
344 } // extern "C"
345 #endif
346 
347 #endif // OPENTHREAD_NETDIAG_H_
348