@@ -79,6 +79,20 @@ static void service_free(otSrpClientService *service)
79
79
}
80
80
}
81
81
82
+ static void print_bytes (const uint8_t * data , size_t data_len )
83
+ {
84
+ printk ("Data:\n" );
85
+ for (size_t i = 0 ; i < data_len ; i ++ ) {
86
+ printk ("%02x" , data [i ]);
87
+ if ((i + 1 ) % 16 == 0 ) {
88
+ printk ("\n" );
89
+ } else if ((i + 1 ) % 8 == 0 ) {
90
+ printk (" " );
91
+ }
92
+ }
93
+ printk ("\n" );
94
+ }
95
+
82
96
static int ot_cli_output_cb (void * context , const char * format , va_list arg )
83
97
{
84
98
const struct shell * sh = context ;
@@ -1042,6 +1056,240 @@ static int cmd_test_vendor_data(const struct shell *sh, size_t argc, char *argv[
1042
1056
return 0 ;
1043
1057
}
1044
1058
1059
+ static void handle_receive_diagnostic_get (otError aError , otMessage * aMessage ,
1060
+ const otMessageInfo * aMessageInfo , void * aContext )
1061
+ {
1062
+ otNetworkDiagTlv diagTlv ;
1063
+ otNetworkDiagIterator iterator = OT_NETWORK_DIAGNOSTIC_ITERATOR_INIT ;
1064
+
1065
+ char addr_string [NET_IPV6_ADDR_LEN ];
1066
+
1067
+ ARG_UNUSED (aContext );
1068
+
1069
+ if (!net_addr_ntop (AF_INET6 , aMessageInfo -> mPeerAddr .mFields .m8 ,
1070
+ addr_string , sizeof (addr_string ))) {
1071
+ printk ("Failed to convert the IPv6 address" );
1072
+ return ;
1073
+ }
1074
+
1075
+ printk ("------------------------------------------------------------------\n" );
1076
+ printk ("Received DIAG_GET.rsp/ans from %s\n" , addr_string );
1077
+
1078
+ while (otThreadGetNextDiagnosticTlv (aMessage , & iterator , & diagTlv ) == OT_ERROR_NONE ) {
1079
+ printk ("\nTLV type: 0x%x " , diagTlv .mType );
1080
+ switch (diagTlv .mType ) {
1081
+ case OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS :
1082
+ printk ("(MAC Extended Address TLV)\n" );
1083
+ print_bytes (diagTlv .mData .mExtAddress .m8 , OT_EXT_ADDRESS_SIZE );
1084
+ break ;
1085
+ case OT_NETWORK_DIAGNOSTIC_TLV_EUI64 :
1086
+ printk ("(EUI64 TLV)\n" );
1087
+ print_bytes (diagTlv .mData .mEui64 .m8 , OT_EXT_ADDRESS_SIZE );
1088
+ break ;
1089
+ case OT_NETWORK_DIAGNOSTIC_TLV_MODE :
1090
+ printk ("(Mode TLV)\n" );
1091
+ printk ("RX on when idle: %s\n" , diagTlv .mData .mMode .mRxOnWhenIdle ?
1092
+ "true" : "false" );
1093
+ printk ("Device type: %s\n" , diagTlv .mData .mMode .mDeviceType ?
1094
+ "true" : "false" );
1095
+ printk ("Network data: %s\n" , diagTlv .mData .mMode .mNetworkData ?
1096
+ "true" : "false" );
1097
+ break ;
1098
+ case OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY :
1099
+ printk ("(Connectivity TLV)\n" );
1100
+ printk ("Parent priority: %d\n" ,
1101
+ diagTlv .mData .mConnectivity .mParentPriority );
1102
+ printk ("Link quality 3: %u\n" , diagTlv .mData .mConnectivity .mLinkQuality3 );
1103
+ printk ("Link quality 2: %u\n" , diagTlv .mData .mConnectivity .mLinkQuality2 );
1104
+ printk ("Link quality 1: %u\n" , diagTlv .mData .mConnectivity .mLinkQuality1 );
1105
+ printk ("Leader cost: %u\n" , diagTlv .mData .mConnectivity .mLeaderCost );
1106
+ printk ("ID sequence: %u\n" , diagTlv .mData .mConnectivity .mIdSequence );
1107
+ printk ("Active routers: %u\n" , diagTlv .mData .mConnectivity .mActiveRouters );
1108
+ printk ("SED buffer size: %u\n" ,
1109
+ diagTlv .mData .mConnectivity .mSedBufferSize );
1110
+ printk ("SED datagram count: %u\n" ,
1111
+ diagTlv .mData .mConnectivity .mSedDatagramCount );
1112
+ break ;
1113
+ case OT_NETWORK_DIAGNOSTIC_TLV_ROUTE :
1114
+ printk ("(Route64 TLV)\n" );
1115
+ printk ("ID sequence: %u\n" , diagTlv .mData .mRoute .mIdSequence );
1116
+ printk ("Route count: %u\n\n" , diagTlv .mData .mRoute .mRouteCount );
1117
+
1118
+ for (int i = 0 ; i < diagTlv .mData .mRoute .mRouteCount ; i ++ ) {
1119
+ printk ("Router ID: %u\n" ,
1120
+ diagTlv .mData .mRoute .mRouteData [i ].mRouterId );
1121
+ printk ("Link quality in: %u\n" ,
1122
+ diagTlv .mData .mRoute .mRouteData [i ].mLinkQualityIn );
1123
+ printk ("Link quality out: %u\n" ,
1124
+ diagTlv .mData .mRoute .mRouteData [i ].mLinkQualityOut );
1125
+ printk ("Route cost: %u\n\n" ,
1126
+ diagTlv .mData .mRoute .mRouteData [i ].mRouteCost );
1127
+ }
1128
+ break ;
1129
+ case OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA :
1130
+ printk ("(Leader Data TLV)\n" );
1131
+ printk ("Partition ID: 0x%x\n" , diagTlv .mData .mLeaderData .mPartitionId );
1132
+ printk ("Weighting: %u\n" , diagTlv .mData .mLeaderData .mWeighting );
1133
+ printk ("Data version: %u\n" , diagTlv .mData .mLeaderData .mDataVersion );
1134
+ printk ("Stable data version: %u\n" ,
1135
+ diagTlv .mData .mLeaderData .mStableDataVersion );
1136
+ printk ("Leader router ID: 0x%x\n" ,
1137
+ diagTlv .mData .mLeaderData .mLeaderRouterId );
1138
+ break ;
1139
+ case OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS :
1140
+ printk ("(MAC Counters TLV)\n" );
1141
+ printk ("IfInUnknownProtos: %u\n" ,
1142
+ diagTlv .mData .mMacCounters .mIfInUnknownProtos );
1143
+ printk ("IfInErrors: %u\n" , diagTlv .mData .mMacCounters .mIfInErrors );
1144
+ printk ("IfOutErrors: %u\n" , diagTlv .mData .mMacCounters .mIfOutErrors );
1145
+ printk ("IfInUcastPkts: %u\n" , diagTlv .mData .mMacCounters .mIfInUcastPkts );
1146
+ printk ("IfInBroadcastPkts: %u\n" ,
1147
+ diagTlv .mData .mMacCounters .mIfInBroadcastPkts );
1148
+ printk ("IfInDiscards: %u\n" , diagTlv .mData .mMacCounters .mIfInDiscards );
1149
+ printk ("IfOutUcastPkts: %u\n" , diagTlv .mData .mMacCounters .mIfOutUcastPkts );
1150
+ printk ("IfOutBroadcastPkts: %u\n" ,
1151
+ diagTlv .mData .mMacCounters .mIfOutBroadcastPkts );
1152
+ printk ("IfOutDiscards: %u\n" , diagTlv .mData .mMacCounters .mIfOutDiscards );
1153
+ break ;
1154
+ case OT_NETWORK_DIAGNOSTIC_TLV_MLE_COUNTERS :
1155
+ printk ("(MLE Counters TLV)\n" );
1156
+ printk ("DisabledRole: %u\n" , diagTlv .mData .mMleCounters .mDisabledRole );
1157
+ printk ("DetachedRole: %u\n" , diagTlv .mData .mMleCounters .mDetachedRole );
1158
+ printk ("ChildRole: %u\n" , diagTlv .mData .mMleCounters .mChildRole );
1159
+ printk ("RouterRole: %u\n" , diagTlv .mData .mMleCounters .mRouterRole );
1160
+ printk ("LeaderRole: %u\n" , diagTlv .mData .mMleCounters .mLeaderRole );
1161
+ printk ("AttachAttempts: %u\n" , diagTlv .mData .mMleCounters .mAttachAttempts );
1162
+ printk ("PartitionIdChanges: %u\n" ,
1163
+ diagTlv .mData .mMleCounters .mPartitionIdChanges );
1164
+ printk ("BetterPartitionAttachAttempts: %u\n" ,
1165
+ diagTlv .mData .mMleCounters .mBetterPartitionAttachAttempts );
1166
+ printk ("ParentChanges: %u\n" , diagTlv .mData .mMleCounters .mParentChanges );
1167
+ printk ("TrackedTime: %llu\n" , diagTlv .mData .mMleCounters .mTrackedTime );
1168
+ printk ("DisabledTime: %llu\n" , diagTlv .mData .mMleCounters .mDisabledTime );
1169
+ printk ("DetachedTime: %llu\n" , diagTlv .mData .mMleCounters .mDetachedTime );
1170
+ printk ("ChildTime: %llu\n" , diagTlv .mData .mMleCounters .mChildTime );
1171
+ printk ("RouterTime: %llu\n" , diagTlv .mData .mMleCounters .mRouterTime );
1172
+ printk ("LeaderTime: %llu\n" , diagTlv .mData .mMleCounters .mLeaderTime );
1173
+ break ;
1174
+ case OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL :
1175
+ printk ("(Battery Level TLV)\n" );
1176
+ printk ("Battery level: %u\n" , diagTlv .mData .mBatteryLevel );
1177
+ break ;
1178
+ case OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT :
1179
+ printk ("(Timeout TLV)\n" );
1180
+ printk ("Timeout: %u\n" , diagTlv .mData .mTimeout );
1181
+ break ;
1182
+ case OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT :
1183
+ printk ("(Max Child Timeout TLV)\n" );
1184
+ printk ("Max child timeout: %u\n" , diagTlv .mData .mMaxChildTimeout );
1185
+ break ;
1186
+ case OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS :
1187
+ printk ("(Address16 TLV)\n" );
1188
+ printk ("Rloc16: 0x%x\n" , diagTlv .mData .mAddr16 );
1189
+ break ;
1190
+ case OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE :
1191
+ printk ("(Supply Voltage TLV)\n" );
1192
+ printk ("Supply voltage: %u\n" , diagTlv .mData .mSupplyVoltage );
1193
+ break ;
1194
+ case OT_NETWORK_DIAGNOSTIC_TLV_VERSION :
1195
+ printk ("(Thread Version TLV)\n" );
1196
+ printk ("Version: %u\n" , diagTlv .mData .mVersion );
1197
+ break ;
1198
+ case OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_NAME :
1199
+ printk ("(Vendor Name TLV)\n" );
1200
+ printk ("Vendor name: %s\n" , diagTlv .mData .mVendorName );
1201
+ break ;
1202
+ case OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_MODEL :
1203
+ printk ("(Vendor Model TLV)\n" );
1204
+ printk ("Vendor model: %s\n" , diagTlv .mData .mVendorModel );
1205
+ break ;
1206
+ case OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_SW_VERSION :
1207
+ printk ("(Vendor SW Version TLV)\n" );
1208
+ printk ("Vendor SW version: %s\n" , diagTlv .mData .mVendorSwVersion );
1209
+ break ;
1210
+ case OT_NETWORK_DIAGNOSTIC_TLV_THREAD_STACK_VERSION :
1211
+ printk ("(Thread Stack Version TLV)\n" );
1212
+ printk ("Thread stack version: %s\n" , diagTlv .mData .mThreadStackVersion );
1213
+ break ;
1214
+ case OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_APP_URL :
1215
+ printk ("(Vendor App URL TLV)\n" );
1216
+ printk ("Vendor app URL: %s\n" , diagTlv .mData .mVendorAppUrl );
1217
+ break ;
1218
+ case OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA :
1219
+ printk ("(Network Data TLV)\n" );
1220
+ print_bytes (diagTlv .mData .mNetworkData .m8 ,
1221
+ diagTlv .mData .mNetworkData .mCount );
1222
+ break ;
1223
+ case OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES :
1224
+ printk ("(Channel Pages TLV)\n" );
1225
+ print_bytes (diagTlv .mData .mChannelPages .m8 ,
1226
+ diagTlv .mData .mChannelPages .mCount );
1227
+ break ;
1228
+ case OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST :
1229
+ printk ("(IPv6 Address List TLV)\n" );
1230
+ for (int i = 0 ; i < diagTlv .mData .mIp6AddrList .mCount ; i ++ ) {
1231
+ print_bytes (diagTlv .mData .mIp6AddrList .mList [i ].mFields .m8 ,
1232
+ OT_IP6_ADDRESS_SIZE );
1233
+ }
1234
+ break ;
1235
+ case OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE :
1236
+ printk ("(Child Table TLV)\n" );
1237
+ for (int i = 0 ; i < diagTlv .mData .mChildTable .mCount ; i ++ ) {
1238
+ printk ("Child ID: %u\n" ,
1239
+ diagTlv .mData .mChildTable .mTable [i ].mChildId );
1240
+ printk ("Timeout: %u\n" ,
1241
+ diagTlv .mData .mChildTable .mTable [i ].mTimeout );
1242
+ printk ("Link quality: %u\n" ,
1243
+ diagTlv .mData .mChildTable .mTable [i ].mLinkQuality );
1244
+ printk ("RX on when idle: %s\n" ,
1245
+ diagTlv .mData .mChildTable .mTable [i ].mMode .mRxOnWhenIdle ?
1246
+ "true" : "false" );
1247
+ printk ("Device type: %s\n" ,
1248
+ diagTlv .mData .mChildTable .mTable [i ].mMode .mDeviceType ?
1249
+ "true" : "false" );
1250
+ printk ("Network data: %s\n" ,
1251
+ diagTlv .mData .mChildTable .mTable [i ].mMode .mNetworkData ?
1252
+ "true" : "false" );
1253
+ }
1254
+ break ;
1255
+
1256
+ default :
1257
+ printk ("(Unknown TLV)\n" );
1258
+ }
1259
+ }
1260
+ }
1261
+
1262
+ static int cmd_test_net_diag (const struct shell * sh , size_t argc , char * argv [])
1263
+ {
1264
+ uint8_t tlv_types [35 ];
1265
+ uint8_t count = 0 ;
1266
+ otIp6Address addr ;
1267
+
1268
+ if (net_addr_pton (AF_INET6 , argv [2 ], addr .mFields .m8 )) {
1269
+ shell_error (sh , "Failed to parse IPv6 address: %s" , argv [1 ]);
1270
+ return - EINVAL ;
1271
+ }
1272
+
1273
+ for (int arg = 3 ; arg < argc ; ++ arg ) {
1274
+ tlv_types [count ] = shell_strtoul (argv [arg ], 0 , NULL );
1275
+ count ++ ;
1276
+ }
1277
+
1278
+ if (strcmp (argv [1 ], "get" ) == 0 ) {
1279
+ otThreadSendDiagnosticGet (NULL , & addr , tlv_types , count ,
1280
+ handle_receive_diagnostic_get , NULL );
1281
+
1282
+ } else if (strcmp (argv [1 ], "reset" ) == 0 ) {
1283
+ otThreadSendDiagnosticReset (NULL , & addr , tlv_types , count );
1284
+
1285
+ } else {
1286
+ shell_error (sh , "Invalid argument %s" , argv [1 ]);
1287
+ return - EINVAL ;
1288
+ }
1289
+
1290
+ return 0 ;
1291
+ }
1292
+
1045
1293
static void print_txt_entry (const struct shell * sh , const otDnsTxtEntry * entry )
1046
1294
{
1047
1295
char buffer [128 ];
@@ -1592,6 +1840,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
1592
1840
SHELL_CMD_ARG (test_vendor_data , NULL , "Vendor data, args: <vendor-name> <vendor-model>"
1593
1841
" <vendor-sw-version>" ,
1594
1842
cmd_test_vendor_data , 4 , 0 ),
1843
+ SHELL_CMD_ARG (test_net_diag , NULL , "Network diag, args: <get|reset> <IPv6-address>"
1844
+ " <tlv-type ...>" ,
1845
+ cmd_test_net_diag , 4 , 255 ),
1595
1846
SHELL_SUBCMD_SET_END );
1596
1847
1597
1848
SHELL_CMD_ARG_REGISTER (ot , & ot_cmds ,
0 commit comments