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 #define OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS 0           ///< MAC Extended Address TLV
53 #define OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS 1         ///< Address16 TLV
54 #define OT_NETWORK_DIAGNOSTIC_TLV_MODE 2                  ///< Mode TLV
55 #define OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT 3               ///< Timeout TLV (max polling time period for SEDs)
56 #define OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY 4          ///< Connectivity TLV
57 #define OT_NETWORK_DIAGNOSTIC_TLV_ROUTE 5                 ///< Route64 TLV
58 #define OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA 6           ///< Leader Data TLV
59 #define OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA 7          ///< Network Data TLV
60 #define OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST 8         ///< IPv6 Address List TLV
61 #define OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS 9          ///< MAC Counters TLV
62 #define OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL 14        ///< Battery Level TLV
63 #define OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE 15       ///< Supply Voltage TLV
64 #define OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE 16          ///< Child Table TLV
65 #define OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES 17        ///< Channel Pages TLV
66 #define OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST 18            ///< Type List TLV
67 #define OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT 19    ///< Max Child Timeout TLV
68 #define OT_NETWORK_DIAGNOSTIC_TLV_EUI64 23                ///< EUI64 TLV
69 #define OT_NETWORK_DIAGNOSTIC_TLV_VERSION 24              ///< Thread Version TLV
70 #define OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_NAME 25          ///< Vendor Name TLV
71 #define OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_MODEL 26         ///< Vendor Model TLV
72 #define OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_SW_VERSION 27    ///< Vendor SW Version TLV
73 #define OT_NETWORK_DIAGNOSTIC_TLV_THREAD_STACK_VERSION 28 ///< Thread Stack Version TLV (codebase/commit version)
74 #define OT_NETWORK_DIAGNOSTIC_TLV_CHILD 29                ///< Child TLV
75 #define OT_NETWORK_DIAGNOSTIC_TLV_CHILD_IP6_ADDR_LIST 30  ///< Child IPv6 Address List TLV
76 #define OT_NETWORK_DIAGNOSTIC_TLV_ROUTER_NEIGHBOR 31      ///< Router Neighbor TLV
77 #define OT_NETWORK_DIAGNOSTIC_TLV_ANSWER 32               ///< Answer TLV
78 #define OT_NETWORK_DIAGNOSTIC_TLV_QUERY_ID 33             ///< Query ID TLV
79 #define OT_NETWORK_DIAGNOSTIC_TLV_MLE_COUNTERS 34         ///< MLE Counters TLV
80 #define OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_APP_URL 35       ///< Vendor App URL TLV
81 
82 #define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_NAME_TLV_LENGTH 32          ///< Max length of Vendor Name TLV.
83 #define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_MODEL_TLV_LENGTH 32         ///< Max length of Vendor Model TLV.
84 #define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_SW_VERSION_TLV_LENGTH 16    ///< Max length of Vendor SW Version TLV.
85 #define OT_NETWORK_DIAGNOSTIC_MAX_THREAD_STACK_VERSION_TLV_LENGTH 64 ///< Max length of Thread Stack Version TLV.
86 #define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_APP_URL_TLV_LENGTH 96       ///< Max length of Vendor App URL TLV.
87 
88 #define OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT 0 ///<  Initializer for `otNetworkDiagIterator`.
89 
90 typedef uint16_t otNetworkDiagIterator; ///< Used to iterate through Network Diagnostic TLV.
91 
92 /**
93  * Represents a Network Diagnostic Connectivity value.
94  *
95  */
96 typedef struct otNetworkDiagConnectivity
97 {
98     int8_t   mParentPriority;   ///< The priority of the sender as a parent.
99     uint8_t  mLinkQuality3;     ///< Number of neighbors with link of quality 3.
100     uint8_t  mLinkQuality2;     ///< Number of neighbors with link of quality 2.
101     uint8_t  mLinkQuality1;     ///< Number of neighbors with link of quality 1.
102     uint8_t  mLeaderCost;       ///< Cost to the Leader.
103     uint8_t  mIdSequence;       ///< Most recent received ID seq number.
104     uint8_t  mActiveRouters;    ///< Number of active routers.
105     uint16_t mSedBufferSize;    ///< Buffer capacity in bytes for SEDs. Optional.
106     uint8_t  mSedDatagramCount; ///< Queue capacity (number of IPv6 datagrams) per SED. Optional.
107 } otNetworkDiagConnectivity;
108 
109 /**
110  * Represents a Network Diagnostic Route data.
111  *
112  */
113 typedef struct otNetworkDiagRouteData
114 {
115     uint8_t mRouterId;           ///< The Assigned Router ID.
116     uint8_t mLinkQualityOut : 2; ///< Link Quality Out.
117     uint8_t mLinkQualityIn : 2;  ///< Link Quality In.
118     uint8_t mRouteCost : 4;      ///< Routing Cost. Infinite routing cost is represented by value 0.
119 } otNetworkDiagRouteData;
120 
121 /**
122  * Represents a Network Diagnostic Route64 TLV value.
123  *
124  */
125 typedef struct otNetworkDiagRoute
126 {
127     /**
128      * The sequence number associated with the set of Router ID assignments in #mRouteData.
129      */
130     uint8_t                mIdSequence;                              ///< Sequence number for Router ID assignments.
131     uint8_t                mRouteCount;                              ///< Number of routes.
132     otNetworkDiagRouteData mRouteData[OT_NETWORK_MAX_ROUTER_ID + 1]; ///< Link Quality and Routing Cost data.
133 } otNetworkDiagRoute;
134 
135 /**
136  * Represents a Network Diagnostic Mac Counters value.
137  *
138  * See <a href="https://www.ietf.org/rfc/rfc2863">RFC 2863</a> for definitions of member fields.
139  *
140  */
141 typedef struct otNetworkDiagMacCounters
142 {
143     uint32_t mIfInUnknownProtos;
144     uint32_t mIfInErrors;
145     uint32_t mIfOutErrors;
146     uint32_t mIfInUcastPkts;
147     uint32_t mIfInBroadcastPkts;
148     uint32_t mIfInDiscards;
149     uint32_t mIfOutUcastPkts;
150     uint32_t mIfOutBroadcastPkts;
151     uint32_t mIfOutDiscards;
152 } otNetworkDiagMacCounters;
153 
154 /**
155  * Represents a Network Diagnostics MLE Counters value.
156  *
157  */
158 typedef struct otNetworkDiagMleCounters
159 {
160     uint16_t mDisabledRole;                  ///< Number of times device entered disabled role.
161     uint16_t mDetachedRole;                  ///< Number of times device entered detached role.
162     uint16_t mChildRole;                     ///< Number of times device entered child role.
163     uint16_t mRouterRole;                    ///< Number of times device entered router role.
164     uint16_t mLeaderRole;                    ///< Number of times device entered leader role.
165     uint16_t mAttachAttempts;                ///< Number of attach attempts while device was detached.
166     uint16_t mPartitionIdChanges;            ///< Number of changes to partition ID.
167     uint16_t mBetterPartitionAttachAttempts; ///< Number of attempts to attach to a better partition.
168     uint16_t mParentChanges;                 ///< Number of time device changed its parent.
169     uint64_t mTrackedTime;                   ///< Milliseconds tracked by next counters (zero if not supported).
170     uint64_t mDisabledTime;                  ///< Milliseconds device has been in disabled role.
171     uint64_t mDetachedTime;                  ///< Milliseconds device has been in detached role.
172     uint64_t mChildTime;                     ///< Milliseconds device has been in child role.
173     uint64_t mRouterTime;                    ///< Milliseconds device has been in router role.
174     uint64_t mLeaderTime;                    ///< Milliseconds device has been in leader role.
175 } otNetworkDiagMleCounters;
176 
177 /**
178  * Represents a Network Diagnostic Child Table Entry.
179  *
180  */
181 typedef struct otNetworkDiagChildEntry
182 {
183     uint16_t mTimeout : 5;     ///< Expected poll timeout expressed as 2^(Timeout-4) seconds.
184     uint8_t  mLinkQuality : 2; ///< Link Quality In value [0,3]. Zero indicate sender cannot provide link quality info.
185     uint16_t mChildId : 9;     ///< Child ID (derived from child RLOC)
186     otLinkModeConfig mMode;    ///< Link mode.
187 } otNetworkDiagChildEntry;
188 
189 /**
190  * Represents a Network Diagnostic TLV.
191  *
192  */
193 typedef struct otNetworkDiagTlv
194 {
195     uint8_t mType; ///< The Network Diagnostic TLV type.
196 
197     union
198     {
199         otExtAddress              mExtAddress;
200         otExtAddress              mEui64;
201         uint16_t                  mAddr16;
202         otLinkModeConfig          mMode;
203         uint32_t                  mTimeout;
204         otNetworkDiagConnectivity mConnectivity;
205         otNetworkDiagRoute        mRoute;
206         otLeaderData              mLeaderData;
207         otNetworkDiagMacCounters  mMacCounters;
208         otNetworkDiagMleCounters  mMleCounters;
209         uint8_t                   mBatteryLevel;
210         uint16_t                  mSupplyVoltage;
211         uint32_t                  mMaxChildTimeout;
212         uint16_t                  mVersion;
213         char                      mVendorName[OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_NAME_TLV_LENGTH + 1];
214         char                      mVendorModel[OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_MODEL_TLV_LENGTH + 1];
215         char                      mVendorSwVersion[OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_SW_VERSION_TLV_LENGTH + 1];
216         char                      mThreadStackVersion[OT_NETWORK_DIAGNOSTIC_MAX_THREAD_STACK_VERSION_TLV_LENGTH + 1];
217         char                      mVendorAppUrl[OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_APP_URL_TLV_LENGTH + 1];
218         struct
219         {
220             uint8_t mCount;
221             uint8_t m8[OT_NETWORK_BASE_TLV_MAX_LENGTH];
222         } mNetworkData;
223         struct
224         {
225             uint8_t      mCount;
226             otIp6Address mList[OT_NETWORK_BASE_TLV_MAX_LENGTH / sizeof(otIp6Address)];
227         } mIp6AddrList;
228         struct
229         {
230             uint8_t                 mCount;
231             otNetworkDiagChildEntry mTable[OT_NETWORK_BASE_TLV_MAX_LENGTH / sizeof(otNetworkDiagChildEntry)];
232         } mChildTable;
233         struct
234         {
235             uint8_t mCount;
236             uint8_t m8[OT_NETWORK_BASE_TLV_MAX_LENGTH];
237         } mChannelPages;
238     } mData;
239 } otNetworkDiagTlv;
240 
241 /**
242  * Gets the next Network Diagnostic TLV in the message.
243  *
244  * Requires `OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE`.
245  *
246  * @param[in]      aMessage         A pointer to a message.
247  * @param[in,out]  aIterator        A pointer to the Network Diagnostic iterator context. To get the first
248  *                                  Network Diagnostic TLV it should be set to OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT.
249  * @param[out]     aNetworkDiagTlv  A pointer to where the Network Diagnostic TLV information will be placed.
250  *
251  * @retval OT_ERROR_NONE       Successfully found the next Network Diagnostic TLV.
252  * @retval OT_ERROR_NOT_FOUND  No subsequent Network Diagnostic TLV exists in the message.
253  * @retval OT_ERROR_PARSE      Parsing the next Network Diagnostic failed.
254  *
255  * @Note A subsequent call to this function is allowed only when current return value is OT_ERROR_NONE.
256  *
257  */
258 otError otThreadGetNextDiagnosticTlv(const otMessage       *aMessage,
259                                      otNetworkDiagIterator *aIterator,
260                                      otNetworkDiagTlv      *aNetworkDiagTlv);
261 
262 /**
263  * Pointer is called when Network Diagnostic Get response is received.
264  *
265  * @param[in]  aError        The error when failed to get the response.
266  * @param[in]  aMessage      A pointer to the message buffer containing the received Network Diagnostic
267  *                           Get response payload. Available only when @p aError is `OT_ERROR_NONE`.
268  * @param[in]  aMessageInfo  A pointer to the message info for @p aMessage. Available only when
269  *                           @p aError is `OT_ERROR_NONE`.
270  * @param[in]  aContext      A pointer to application-specific context.
271  *
272  */
273 typedef void (*otReceiveDiagnosticGetCallback)(otError              aError,
274                                                otMessage           *aMessage,
275                                                const otMessageInfo *aMessageInfo,
276                                                void                *aContext);
277 
278 /**
279  * Send a Network Diagnostic Get request.
280  *
281  * Requires `OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE`.
282  *
283  * @param[in]  aInstance         A pointer to an OpenThread instance.
284  * @param[in]  aDestination      A pointer to destination address.
285  * @param[in]  aTlvTypes         An array of Network Diagnostic TLV types.
286  * @param[in]  aCount            Number of types in aTlvTypes.
287  * @param[in]  aCallback         A pointer to a function that is called when Network Diagnostic Get response
288  *                               is received or NULL to disable the callback.
289  * @param[in]  aCallbackContext  A pointer to application-specific context.
290  *
291  * @retval OT_ERROR_NONE    Successfully queued the DIAG_GET.req.
292  * @retval OT_ERROR_NO_BUFS Insufficient message buffers available to send DIAG_GET.req.
293  *
294  */
295 otError otThreadSendDiagnosticGet(otInstance                    *aInstance,
296                                   const otIp6Address            *aDestination,
297                                   const uint8_t                  aTlvTypes[],
298                                   uint8_t                        aCount,
299                                   otReceiveDiagnosticGetCallback aCallback,
300                                   void                          *aCallbackContext);
301 
302 /**
303  * Send a Network Diagnostic Reset request.
304  *
305  * Requires `OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE`.
306  *
307  * @param[in]  aInstance      A pointer to an OpenThread instance.
308  * @param[in]  aDestination   A pointer to destination address.
309  * @param[in]  aTlvTypes      An array of Network Diagnostic TLV types. Currently only Type 9 is allowed.
310  * @param[in]  aCount         Number of types in aTlvTypes
311  *
312  * @retval OT_ERROR_NONE    Successfully queued the DIAG_RST.ntf.
313  * @retval OT_ERROR_NO_BUFS Insufficient message buffers available to send DIAG_RST.ntf.
314  *
315  */
316 otError otThreadSendDiagnosticReset(otInstance         *aInstance,
317                                     const otIp6Address *aDestination,
318                                     const uint8_t       aTlvTypes[],
319                                     uint8_t             aCount);
320 
321 /**
322  * Get the vendor name string.
323  *
324  * @param[in]  aInstance      A pointer to an OpenThread instance.
325  *
326  * @returns The vendor name string.
327  *
328  */
329 const char *otThreadGetVendorName(otInstance *aInstance);
330 
331 /**
332  * Get the vendor model string.
333  *
334  * @param[in]  aInstance      A pointer to an OpenThread instance.
335  *
336  * @returns The vendor model string.
337  *
338  */
339 const char *otThreadGetVendorModel(otInstance *aInstance);
340 
341 /**
342  * Get the vendor software version string.
343  *
344  * @param[in]  aInstance      A pointer to an OpenThread instance.
345  *
346  * @returns The vendor software version string.
347  *
348  */
349 const char *otThreadGetVendorSwVersion(otInstance *aInstance);
350 
351 /**
352  * Get the vendor app URL string.
353  *
354  * @param[in]  aInstance      A pointer to an OpenThread instance.
355  *
356  * @returns The vendor app URL string.
357  *
358  */
359 const char *otThreadGetVendorAppUrl(otInstance *aInstance);
360 
361 /**
362  * Set the vendor name string.
363  *
364  * Requires `OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_API_ENABLE`.
365  *
366  * @p aVendorName should be UTF8 with max length of 32 chars (`MAX_VENDOR_NAME_TLV_LENGTH`). Maximum length does not
367  * include the null `\0` character.
368  *
369  * @param[in] aInstance       A pointer to an OpenThread instance.
370  * @param[in] aVendorName     The vendor name string.
371  *
372  * @retval OT_ERROR_NONE          Successfully set the vendor name.
373  * @retval OT_ERROR_INVALID_ARGS  @p aVendorName is not valid (too long or not UTF8).
374  *
375  */
376 otError otThreadSetVendorName(otInstance *aInstance, const char *aVendorName);
377 
378 /**
379  * Set the vendor model string.
380  *
381  * Requires `OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_API_ENABLE`.
382  *
383  * @p aVendorModel should be UTF8 with max length of 32 chars (`MAX_VENDOR_MODEL_TLV_LENGTH`). Maximum length does not
384  * include the null `\0` character.
385  *
386  * @param[in] aInstance       A pointer to an OpenThread instance.
387  * @param[in] aVendorModel    The vendor model string.
388  *
389  * @retval OT_ERROR_NONE          Successfully set the vendor model.
390  * @retval OT_ERROR_INVALID_ARGS  @p aVendorModel is not valid (too long or not UTF8).
391  *
392  */
393 otError otThreadSetVendorModel(otInstance *aInstance, const char *aVendorModel);
394 
395 /**
396  * Set the vendor software version string.
397  *
398  * Requires `OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_API_ENABLE`.
399  *
400  * @p aVendorSwVersion should be UTF8 with max length of 16 chars(`MAX_VENDOR_SW_VERSION_TLV_LENGTH`). Maximum length
401  * does not include the null `\0` character.
402  *
403  * @param[in] aInstance          A pointer to an OpenThread instance.
404  * @param[in] aVendorSwVersion   The vendor software version string.
405  *
406  * @retval OT_ERROR_NONE          Successfully set the vendor software version.
407  * @retval OT_ERROR_INVALID_ARGS  @p aVendorSwVersion is not valid (too long or not UTF8).
408  *
409  */
410 otError otThreadSetVendorSwVersion(otInstance *aInstance, const char *aVendorSwVersion);
411 
412 /**
413  * Set the vendor app URL string.
414  *
415  * Requires `OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_API_ENABLE`.
416  *
417  * @p aVendorAppUrl should be UTF8 with max length of 64 chars (`MAX_VENDOR_APPL_URL_TLV_LENGTH`). Maximum length
418  * does not include the null `\0` character.
419  *
420  * @param[in] aInstance          A pointer to an OpenThread instance.
421  * @param[in] aVendorAppUrl      The vendor app URL string.
422  *
423  * @retval OT_ERROR_NONE          Successfully set the vendor app URL string.
424  * @retval OT_ERROR_INVALID_ARGS  @p aVendorAppUrl is not valid (too long or not UTF8).
425  *
426  */
427 otError otThreadSetVendorAppUrl(otInstance *aInstance, const char *aVendorAppUrl);
428 
429 /**
430  * @}
431  *
432  */
433 
434 #ifdef __cplusplus
435 } // extern "C"
436 #endif
437 
438 #endif // OPENTHREAD_NETDIAG_H_
439