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     OT_NETWORK_DIAGNOSTIC_TLV_VERSION              = 24, ///< Version TLV
86     OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_NAME          = 25, ///< Vendor Name TLV
87     OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_MODEL         = 26, ///< Vendor Model TLV
88     OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_SW_VERSION    = 27, ///< Vendor SW Version TLV
89     OT_NETWORK_DIAGNOSTIC_TLV_THREAD_STACK_VERSION = 28, ///< Thread Stack Version TLV
90 };
91 
92 #define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_NAME_TLV_LENGTH 32          ///< Max length of Vendor Name TLV.
93 #define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_MODEL_TLV_LENGTH 32         ///< Max length of Vendor Model TLV.
94 #define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_SW_VERSION_TLV_LENGTH 16    ///< Max length of Vendor SW Version TLV.
95 #define OT_NETWORK_DIAGNOSTIC_MAX_THREAD_STACK_VERSION_TLV_LENGTH 64 ///< Max length of Thread Stack Version TLV.
96 
97 typedef uint16_t otNetworkDiagIterator; ///< Used to iterate through Network Diagnostic TLV.
98 
99 /**
100  * This structure represents a Network Diagnostic Connectivity value.
101  *
102  */
103 typedef struct otNetworkDiagConnectivity
104 {
105     /**
106      * The priority of the sender as a parent.
107      */
108     int8_t mParentPriority;
109 
110     /**
111      * The number of neighboring devices with which the sender shares a link of quality 3.
112      */
113     uint8_t mLinkQuality3;
114 
115     /**
116      * The number of neighboring devices with which the sender shares a link of quality 2.
117      */
118     uint8_t mLinkQuality2;
119 
120     /**
121      * The number of neighboring devices with which the sender shares a link of quality 1.
122      */
123     uint8_t mLinkQuality1;
124 
125     /**
126      * The sender's routing cost to the Leader.
127      */
128     uint8_t mLeaderCost;
129 
130     /**
131      * The most recent ID sequence number received by the sender.
132      */
133     uint8_t mIdSequence;
134 
135     /**
136      * The number of active Routers in the sender's Thread Network Partition.
137      */
138     uint8_t mActiveRouters;
139 
140     /**
141      * The guaranteed buffer capacity in octets for all IPv6 datagrams destined to a given SED. Optional.
142      */
143     uint16_t mSedBufferSize;
144 
145     /**
146      * The guaranteed queue capacity in number of IPv6 datagrams destined to a given SED. Optional.
147      */
148     uint8_t mSedDatagramCount;
149 } otNetworkDiagConnectivity;
150 
151 /**
152  * This structure represents a Network Diagnostic Route data.
153  *
154  */
155 typedef struct otNetworkDiagRouteData
156 {
157     uint8_t mRouterId;           ///< The Assigned Router ID.
158     uint8_t mLinkQualityOut : 2; ///< Link Quality Out.
159     uint8_t mLinkQualityIn : 2;  ///< Link Quality In.
160     uint8_t mRouteCost : 4;      ///< Routing Cost. Infinite routing cost is represented by value 0.
161 } otNetworkDiagRouteData;
162 
163 /**
164  * This structure represents a Network Diagnostic Route TLV value.
165  *
166  */
167 typedef struct otNetworkDiagRoute
168 {
169     /**
170      * The sequence number associated with the set of Router ID assignments in #mRouteData.
171      */
172     uint8_t mIdSequence;
173 
174     /**
175      * Number of elements in #mRouteData.
176      */
177     uint8_t mRouteCount;
178 
179     /**
180      * Link Quality and Routing Cost data.
181      */
182     otNetworkDiagRouteData mRouteData[OT_NETWORK_MAX_ROUTER_ID + 1];
183 } otNetworkDiagRoute;
184 
185 /**
186  * This structure represents a Network Diagnostic Mac Counters value.
187  *
188  * See <a href="https://www.ietf.org/rfc/rfc2863">RFC 2863</a> for definitions of member fields.
189  *
190  */
191 typedef struct otNetworkDiagMacCounters
192 {
193     uint32_t mIfInUnknownProtos;
194     uint32_t mIfInErrors;
195     uint32_t mIfOutErrors;
196     uint32_t mIfInUcastPkts;
197     uint32_t mIfInBroadcastPkts;
198     uint32_t mIfInDiscards;
199     uint32_t mIfOutUcastPkts;
200     uint32_t mIfOutBroadcastPkts;
201     uint32_t mIfOutDiscards;
202 } otNetworkDiagMacCounters;
203 
204 /**
205  * This structure represents a Network Diagnostic Child Table Entry.
206  *
207  */
208 typedef struct otNetworkDiagChildEntry
209 {
210     /**
211      * Expected poll time expressed as 2^(Timeout-4) seconds.
212      */
213     uint16_t mTimeout : 5;
214 
215     /**
216      * Link Quality In value in [0,3].
217      *
218      * Value 0 indicates that sender does not support the feature to provide link quality info.
219      *
220      */
221     uint8_t mLinkQuality : 2;
222 
223     /**
224      * Child ID from which an RLOC can be generated.
225      */
226     uint16_t mChildId : 9;
227 
228     /**
229      * Link mode bits.
230      */
231     otLinkModeConfig mMode;
232 } otNetworkDiagChildEntry;
233 
234 /**
235  * This structure represents a Network Diagnostic TLV.
236  *
237  */
238 typedef struct otNetworkDiagTlv
239 {
240     /**
241      * The Network Diagnostic TLV type.
242      */
243     uint8_t mType;
244 
245     union
246     {
247         otExtAddress              mExtAddress;
248         uint16_t                  mAddr16;
249         otLinkModeConfig          mMode;
250         uint32_t                  mTimeout;
251         otNetworkDiagConnectivity mConnectivity;
252         otNetworkDiagRoute        mRoute;
253         otLeaderData              mLeaderData;
254         otNetworkDiagMacCounters  mMacCounters;
255         uint8_t                   mBatteryLevel;
256         uint16_t                  mSupplyVoltage;
257         uint32_t                  mMaxChildTimeout;
258         uint16_t                  mVersion;
259         char                      mVendorName[OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_NAME_TLV_LENGTH + 1];
260         char                      mVendorModel[OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_MODEL_TLV_LENGTH + 1];
261         char                      mVendorSwVersion[OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_SW_VERSION_TLV_LENGTH + 1];
262         char                      mThreadStackVersion[OT_NETWORK_DIAGNOSTIC_MAX_THREAD_STACK_VERSION_TLV_LENGTH + 1];
263         struct
264         {
265             uint8_t mCount;
266             uint8_t m8[OT_NETWORK_BASE_TLV_MAX_LENGTH];
267         } mNetworkData;
268         struct
269         {
270             uint8_t      mCount;
271             otIp6Address mList[OT_NETWORK_BASE_TLV_MAX_LENGTH / OT_IP6_ADDRESS_SIZE];
272         } mIp6AddrList;
273         struct
274         {
275             uint8_t mCount;
276             otNetworkDiagChildEntry
277                 mTable[OT_NETWORK_BASE_TLV_MAX_LENGTH / OT_NETWORK_DIAGNOSTIC_CHILD_TABLE_ENTRY_SIZE];
278         } mChildTable;
279         struct
280         {
281             uint8_t mCount;
282             uint8_t m8[OT_NETWORK_BASE_TLV_MAX_LENGTH];
283         } mChannelPages;
284     } mData;
285 } otNetworkDiagTlv;
286 
287 /**
288  * This function gets the next Network Diagnostic TLV in the message.
289  *
290  * Requires `OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE`.
291  *
292  * @param[in]      aMessage         A pointer to a message.
293  * @param[in,out]  aIterator        A pointer to the Network Diagnostic iterator context. To get the first
294  *                                  Network Diagnostic TLV it should be set to OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT.
295  * @param[out]     aNetworkDiagTlv  A pointer to where the Network Diagnostic TLV information will be placed.
296  *
297  * @retval OT_ERROR_NONE       Successfully found the next Network Diagnostic TLV.
298  * @retval OT_ERROR_NOT_FOUND  No subsequent Network Diagnostic TLV exists in the message.
299  * @retval OT_ERROR_PARSE      Parsing the next Network Diagnostic failed.
300  *
301  * @Note A subsequent call to this function is allowed only when current return value is OT_ERROR_NONE.
302  *
303  */
304 otError otThreadGetNextDiagnosticTlv(const otMessage       *aMessage,
305                                      otNetworkDiagIterator *aIterator,
306                                      otNetworkDiagTlv      *aNetworkDiagTlv);
307 
308 /**
309  * This function pointer is called when Network Diagnostic Get response is received.
310  *
311  * @param[in]  aError        The error when failed to get the response.
312  * @param[in]  aMessage      A pointer to the message buffer containing the received Network Diagnostic
313  *                           Get response payload. Available only when @p aError is `OT_ERROR_NONE`.
314  * @param[in]  aMessageInfo  A pointer to the message info for @p aMessage. Available only when
315  *                           @p aError is `OT_ERROR_NONE`.
316  * @param[in]  aContext      A pointer to application-specific context.
317  *
318  */
319 typedef void (*otReceiveDiagnosticGetCallback)(otError              aError,
320                                                otMessage           *aMessage,
321                                                const otMessageInfo *aMessageInfo,
322                                                void                *aContext);
323 
324 /**
325  * Send a Network Diagnostic Get request.
326  *
327  * Requires `OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE`.
328  *
329  * @param[in]  aInstance         A pointer to an OpenThread instance.
330  * @param[in]  aDestination      A pointer to destination address.
331  * @param[in]  aTlvTypes         An array of Network Diagnostic TLV types.
332  * @param[in]  aCount            Number of types in aTlvTypes.
333  * @param[in]  aCallback         A pointer to a function that is called when Network Diagnostic Get response
334  *                               is received or NULL to disable the callback.
335  * @param[in]  aCallbackContext  A pointer to application-specific context.
336  *
337  * @retval OT_ERROR_NONE    Successfully queued the DIAG_GET.req.
338  * @retval OT_ERROR_NO_BUFS Insufficient message buffers available to send DIAG_GET.req.
339  *
340  */
341 otError otThreadSendDiagnosticGet(otInstance                    *aInstance,
342                                   const otIp6Address            *aDestination,
343                                   const uint8_t                  aTlvTypes[],
344                                   uint8_t                        aCount,
345                                   otReceiveDiagnosticGetCallback aCallback,
346                                   void                          *aCallbackContext);
347 
348 /**
349  * Send a Network Diagnostic Reset request.
350  *
351  * Requires `OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE`.
352  *
353  * @param[in]  aInstance      A pointer to an OpenThread instance.
354  * @param[in]  aDestination   A pointer to destination address.
355  * @param[in]  aTlvTypes      An array of Network Diagnostic TLV types. Currently only Type 9 is allowed.
356  * @param[in]  aCount         Number of types in aTlvTypes
357  *
358  * @retval OT_ERROR_NONE    Successfully queued the DIAG_RST.ntf.
359  * @retval OT_ERROR_NO_BUFS Insufficient message buffers available to send DIAG_RST.ntf.
360  *
361  */
362 otError otThreadSendDiagnosticReset(otInstance         *aInstance,
363                                     const otIp6Address *aDestination,
364                                     const uint8_t       aTlvTypes[],
365                                     uint8_t             aCount);
366 
367 /**
368  * Get the vendor name string.
369  *
370  * @param[in]  aInstance      A pointer to an OpenThread instance.
371  *
372  * @returns The vendor name string.
373  *
374  */
375 const char *otThreadGetVendorName(otInstance *aInstance);
376 
377 /**
378  * Get the vendor model string.
379  *
380  * @param[in]  aInstance      A pointer to an OpenThread instance.
381  *
382  * @returns The vendor model string.
383  *
384  */
385 const char *otThreadGetVendorModel(otInstance *aInstance);
386 
387 /**
388  * Get the vendor sw version string.
389  *
390  * @param[in]  aInstance      A pointer to an OpenThread instance.
391  *
392  * @returns The vendor sw version string.
393  *
394  */
395 const char *otThreadGetVendorSwVersion(otInstance *aInstance);
396 
397 /**
398  * Set the vendor name string.
399  *
400  * Requires `OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_API_ENABLE`.
401  *
402  * @p aVendorName should be UTF8 with max length of 32 chars (`MAX_VENDOR_NAME_TLV_LENGTH`). Maximum length does not
403  * include the null `\0` character.
404  *
405  * @param[in] aInstance       A pointer to an OpenThread instance.
406  * @param[in] aVendorName     The vendor name string.
407  *
408  * @retval OT_ERROR_NONE          Successfully set the vendor name.
409  * @retval OT_ERROR_INVALID_ARGS  @p aVendorName is not valid (too long or not UTF8).
410  *
411  */
412 otError otThreadSetVendorName(otInstance *aInstance, const char *aVendorName);
413 
414 /**
415  * Set the vendor model string.
416  *
417  * Requires `OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_API_ENABLE`.
418  *
419  * @p aVendorModel should be UTF8 with max length of 32 chars (`MAX_VENDOR_MODEL_TLV_LENGTH`). Maximum length does not
420  * include the null `\0` character.
421  *
422  * @param[in] aInstance       A pointer to an OpenThread instance.
423  * @param[in] aVendorModel    The vendor model string.
424  *
425  * @retval OT_ERROR_NONE          Successfully set the vendor model.
426  * @retval OT_ERROR_INVALID_ARGS  @p aVendorModel is not valid (too long or not UTF8).
427  *
428  */
429 otError otThreadSetVendorModel(otInstance *aInstance, const char *aVendorModel);
430 
431 /**
432  * Set the vendor software version string.
433  *
434  * Requires `OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_API_ENABLE`.
435  *
436  * @p aVendorSwVersion should be UTF8 with max length of 16 chars(`MAX_VENDOR_SW_VERSION_TLV_LENGTH`). Maximum length
437  * does not include the null `\0` character.
438  *
439  * @param[in] aInstance          A pointer to an OpenThread instance.
440  * @param[in] aVendorSwVersion   The vendor software version string.
441  *
442  * @retval OT_ERROR_NONE          Successfully set the vendor software version.
443  * @retval OT_ERROR_INVALID_ARGS  @p aVendorSwVersion is not valid (too long or not UTF8).
444  *
445  */
446 otError otThreadSetVendorSwVersion(otInstance *aInstance, const char *aVendorSwVersion);
447 
448 /**
449  * @}
450  *
451  */
452 
453 #ifdef __cplusplus
454 } // extern "C"
455 #endif
456 
457 #endif // OPENTHREAD_NETDIAG_H_
458