1 /* 2 * Copyright (c) 2023, 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 Mesh Diagnostic APIs. 33 */ 34 35 #ifndef OPENTHREAD_MESH_DIAG_H_ 36 #define OPENTHREAD_MESH_DIAG_H_ 37 38 #include <openthread/instance.h> 39 #include <openthread/thread.h> 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 /** 46 * @addtogroup api-mesh-diag 47 * 48 * @brief 49 * This module includes definitions and functions for Mesh Diagnostics. 50 * 51 * The Mesh Diagnostics APIs require `OPENTHREAD_CONFIG_MESH_DIAG_ENABLE` and `OPENTHREAD_FTD`. 52 * 53 * @{ 54 * 55 */ 56 57 /** 58 * This structure represents the set of configurations used when discovering mesh topology indicating which items to 59 * discover. 60 * 61 */ 62 typedef struct otMeshDiagDiscoverConfig 63 { 64 bool mDiscoverIp6Addresses : 1; ///< Whether or not to discover IPv6 addresses of every router. 65 bool mDiscoverChildTable : 1; ///< Whether or not to discover children of every router. 66 } otMeshDiagDiscoverConfig; 67 68 /** 69 * This type is an opaque iterator to iterate over list of IPv6 addresses of a router. 70 * 71 * Pointers to instance of this type are provided in `otMeshDiagRouterInfo`. 72 * 73 */ 74 typedef struct otMeshDiagIp6AddrIterator otMeshDiagIp6AddrIterator; 75 76 /** 77 * This type is an opaque iterator to iterate over list of children of a router. 78 * 79 * Pointers to instance of this type are provided in `otMeshDiagRouterInfo`. 80 * 81 */ 82 typedef struct otMeshDiagChildIterator otMeshDiagChildIterator; 83 84 /** 85 * This constant indicates that Thread Version is unknown. 86 * 87 * This is used in `otMeshDiagRouterInfo` for `mVersion` property when device does not provide its version. This 88 * indicates that device is likely running 1.3.0 (version value 4) or earlier. 89 * 90 */ 91 #define OT_MESH_DIAG_VERSION_UNKNOWN 0xffff 92 93 /** 94 * This type represents information about a router in Thread mesh. 95 * 96 */ 97 typedef struct otMeshDiagRouterInfo 98 { 99 otExtAddress mExtAddress; ///< Extended MAC address. 100 uint16_t mRloc16; ///< RLOC16. 101 uint8_t mRouterId; ///< Router ID. 102 uint16_t mVersion; ///< Thread Version. `OT_MESH_DIAG_VERSION_UNKNOWN` if unknown. 103 bool mIsThisDevice : 1; ///< Whether router is this device itself. 104 bool mIsThisDeviceParent : 1; ///< Whether router is parent of this device (when device is a child). 105 bool mIsLeader : 1; ///< Whether router is leader. 106 bool mIsBorderRouter : 1; ///< Whether router acts as a border router providing ext connectivity. 107 108 /** 109 * This array provides the link quality from this router to other routers, also indicating whether a link is 110 * established between the routers. 111 * 112 * The array is indexed based on Router ID. `mLinkQualities[routerId]` indicates the incoming link quality, the 113 * router sees to the router with `routerId`. Link quality is a value in [0, 3]. Value zero indicates no link. 114 * Larger value indicate better link quality (as defined by Thread specification). 115 * 116 */ 117 uint8_t mLinkQualities[OT_NETWORK_MAX_ROUTER_ID + 1]; 118 119 /** 120 * A pointer to an iterator to go through the list of IPv6 addresses of the router. 121 * 122 * The pointer is valid only while `otMeshDiagRouterInfo` is valid. It can be used in `otMeshDiagGetNextIp6Address` 123 * to iterate through the IPv6 addresses. 124 * 125 * The pointer can be NULL when there was no request to discover IPv6 addresses (in `otMeshDiagDiscoverConfig`) or 126 * if the router did not provide the list. 127 * 128 */ 129 otMeshDiagIp6AddrIterator *mIp6AddrIterator; 130 131 /** 132 * A pointer to an iterator to go through the list of children of the router. 133 * 134 * The pointer is valid only while `otMeshDiagRouterInfo` is valid. It can be used in `otMeshDiagGetNextChildInfo` 135 * to iterate through the children of the router. 136 * 137 * The pointer can be NULL when there was no request to discover children (in `otMeshDiagDiscoverConfig`) or 138 * if the router did not provide the list. 139 * 140 */ 141 otMeshDiagChildIterator *mChildIterator; 142 } otMeshDiagRouterInfo; 143 144 /** 145 * This type represents information about a discovered child in Thread mesh. 146 * 147 */ 148 typedef struct otMeshDiagChildInfo 149 { 150 uint16_t mRloc16; ///< RLOC16. 151 otLinkModeConfig mMode; ///< Device mode. 152 uint8_t mLinkQuality; ///< Incoming link quality to child from parent. 153 bool mIsThisDevice : 1; ///< Whether child is this device itself. 154 bool mIsBorderRouter : 1; ///< Whether child acts as a border router providing ext connectivity. 155 } otMeshDiagChildInfo; 156 157 /** 158 * This function pointer type represents the callback used by `otMeshDiagDiscoverTopology()` to provide information 159 * about a discovered router. 160 * 161 * When @p aError is `OT_ERROR_PENDING`, it indicates that the discovery is not yet finished and there will be more 162 * routers to discover and the callback will be invoked again. 163 * 164 * @param[in] aError OT_ERROR_PENDING Indicates there are more routers to be discovered. 165 * OT_ERROR_NONE Indicates this is the last router and mesh discovery is done. 166 * OT_ERROR_RESPONSE_TIMEOUT Timed out waiting for response from one or more routers. 167 * @param[in] aRouterInfo The discovered router info (can be null if `aError` is OT_ERROR_RESPONSE_TIMEOUT). 168 * @param[in] aContext Application-specific context. 169 * 170 */ 171 typedef void (*otMeshDiagDiscoverCallback)(otError aError, otMeshDiagRouterInfo *aRouterInfo, void *aContext); 172 173 /** 174 * This function starts network topology discovery. 175 * 176 * @param[in] aInstance The OpenThread instance. 177 * @param[in] aConfig The configuration to use for discovery (e.g., which items to discover). 178 * @param[in] aCallback The callback to report the discovered routers. 179 * @param[in] aContext A context to pass in @p aCallback. 180 * 181 * @retval OT_ERROR_NONE The network topology discovery started successfully. 182 * @retval OT_ERROR_BUSY A previous discovery request is still ongoing. 183 * @retval OT_ERROR_INVALID_STATE Device is not attached. 184 * @retval OT_ERROR_NO_BUFS Could not allocate buffer to send discovery messages. 185 * 186 */ 187 otError otMeshDiagDiscoverTopology(otInstance *aInstance, 188 const otMeshDiagDiscoverConfig *aConfig, 189 otMeshDiagDiscoverCallback aCallback, 190 void *aContext); 191 192 /** 193 * This function cancels an ongoing topology discovery if there is one, otherwise no action. 194 * 195 * When ongoing discovery is cancelled, the callback from `otMeshDiagDiscoverTopology()` will not be called anymore. 196 * 197 */ 198 void otMeshDiagCancel(otInstance *aInstance); 199 200 /** 201 * This function iterates through the discovered IPv6 address of a router. 202 * 203 * @param[in,out] aIterator The address iterator to use. 204 * @param[out] aIp6Address A pointer to return the next IPv6 address (if any). 205 * 206 * @retval OT_ERROR_NONE Successfully retrieved the next address. @p aIp6Address and @p aIterator are updated. 207 * @retval OT_ERROR_NOT_FOUND No more address. Reached the end of the list. 208 * 209 */ 210 otError otMeshDiagGetNextIp6Address(otMeshDiagIp6AddrIterator *aIterator, otIp6Address *aIp6Address); 211 212 /** 213 * This function iterates through the discovered children of a router. 214 * 215 * @param[in,out] aIterator The address iterator to use. 216 * @param[out] aChildInfo A pointer to return the child info (if any). 217 * 218 * @retval OT_ERROR_NONE Successfully retrieved the next child. @p aChildInfo and @p aIterator are updated. 219 * @retval OT_ERROR_NOT_FOUND No more child. Reached the end of the list. 220 * 221 */ 222 otError otMeshDiagGetNextChildInfo(otMeshDiagChildIterator *aIterator, otMeshDiagChildInfo *aChildInfo); 223 224 /** 225 * @} 226 * 227 */ 228 229 #ifdef __cplusplus 230 } // extern "C" 231 #endif 232 233 #endif // OPENTHREAD_MESH_DIAG_H_ 234