2 * Copyright (c) 2020, The OpenThread Authors.
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.
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.
29 #include "rest/json.hpp"
31 #include "common/code_utils.hpp"
32 #include "common/types.hpp"
42 static cJSON *Bytes2HexJson(const uint8_t *aBytes, uint8_t aLength)
44 char hex[2 * aLength + 1];
46 otbr::Utils::Bytes2Hex(aBytes, aLength, hex);
47 hex[2 * aLength] = '\0';
49 return cJSON_CreateString(hex);
52 std::string String2JsonString(const std::string &aString)
55 cJSON * json = nullptr;
56 char * jsonOut = nullptr;
58 VerifyOrExit(aString.size() > 0);
60 json = cJSON_CreateString(aString.c_str());
61 jsonOut = cJSON_Print(json);
63 if (jsonOut != nullptr)
75 std::string Json2String(const cJSON *aJson)
78 char * jsonOut = nullptr;
80 VerifyOrExit(aJson != nullptr);
82 jsonOut = cJSON_Print(aJson);
84 if (jsonOut != nullptr)
94 static cJSON *CString2Json(const char *aString)
96 return cJSON_CreateString(aString);
99 static cJSON *Mode2Json(const otLinkModeConfig &aMode)
101 cJSON *mode = cJSON_CreateObject();
103 cJSON_AddItemToObject(mode, "RxOnWhenIdle", cJSON_CreateNumber(aMode.mRxOnWhenIdle));
104 cJSON_AddItemToObject(mode, "DeviceType", cJSON_CreateNumber(aMode.mDeviceType));
105 cJSON_AddItemToObject(mode, "NetworkData", cJSON_CreateNumber(aMode.mNetworkData));
110 static cJSON *IpAddr2Json(const otIp6Address &aAddress)
112 Ip6Address addr(aAddress.mFields.m8);
114 return cJSON_CreateString(addr.ToString().c_str());
117 static cJSON *ChildTableEntry2Json(const otNetworkDiagChildEntry &aChildEntry)
119 cJSON *childEntry = cJSON_CreateObject();
121 cJSON_AddItemToObject(childEntry, "ChildId", cJSON_CreateNumber(aChildEntry.mChildId));
122 cJSON_AddItemToObject(childEntry, "Timeout", cJSON_CreateNumber(aChildEntry.mTimeout));
124 cJSON *mode = Mode2Json(aChildEntry.mMode);
125 cJSON_AddItemToObject(childEntry, "Mode", mode);
130 static cJSON *MacCounters2Json(const otNetworkDiagMacCounters &aMacCounters)
132 cJSON *macCounters = cJSON_CreateObject();
134 cJSON_AddItemToObject(macCounters, "IfInUnknownProtos", cJSON_CreateNumber(aMacCounters.mIfInUnknownProtos));
135 cJSON_AddItemToObject(macCounters, "IfInErrors", cJSON_CreateNumber(aMacCounters.mIfInErrors));
136 cJSON_AddItemToObject(macCounters, "IfOutErrors", cJSON_CreateNumber(aMacCounters.mIfOutErrors));
137 cJSON_AddItemToObject(macCounters, "IfInUcastPkts", cJSON_CreateNumber(aMacCounters.mIfInUcastPkts));
138 cJSON_AddItemToObject(macCounters, "IfInBroadcastPkts", cJSON_CreateNumber(aMacCounters.mIfInBroadcastPkts));
139 cJSON_AddItemToObject(macCounters, "IfInDiscards", cJSON_CreateNumber(aMacCounters.mIfInDiscards));
140 cJSON_AddItemToObject(macCounters, "IfOutUcastPkts", cJSON_CreateNumber(aMacCounters.mIfOutUcastPkts));
141 cJSON_AddItemToObject(macCounters, "IfOutBroadcastPkts", cJSON_CreateNumber(aMacCounters.mIfOutBroadcastPkts));
142 cJSON_AddItemToObject(macCounters, "IfOutDiscards", cJSON_CreateNumber(aMacCounters.mIfOutDiscards));
147 static cJSON *Connectivity2Json(const otNetworkDiagConnectivity &aConnectivity)
149 cJSON *connectivity = cJSON_CreateObject();
151 cJSON_AddItemToObject(connectivity, "ParentPriority", cJSON_CreateNumber(aConnectivity.mParentPriority));
152 cJSON_AddItemToObject(connectivity, "LinkQuality3", cJSON_CreateNumber(aConnectivity.mLinkQuality3));
153 cJSON_AddItemToObject(connectivity, "LinkQuality2", cJSON_CreateNumber(aConnectivity.mLinkQuality2));
154 cJSON_AddItemToObject(connectivity, "LinkQuality1", cJSON_CreateNumber(aConnectivity.mLinkQuality1));
155 cJSON_AddItemToObject(connectivity, "LeaderCost", cJSON_CreateNumber(aConnectivity.mLeaderCost));
156 cJSON_AddItemToObject(connectivity, "IdSequence", cJSON_CreateNumber(aConnectivity.mIdSequence));
157 cJSON_AddItemToObject(connectivity, "ActiveRouters", cJSON_CreateNumber(aConnectivity.mActiveRouters));
158 cJSON_AddItemToObject(connectivity, "SedBufferSize", cJSON_CreateNumber(aConnectivity.mSedBufferSize));
159 cJSON_AddItemToObject(connectivity, "SedDatagramCount", cJSON_CreateNumber(aConnectivity.mSedDatagramCount));
164 static cJSON *RouteData2Json(const otNetworkDiagRouteData &aRouteData)
166 cJSON *routeData = cJSON_CreateObject();
168 cJSON_AddItemToObject(routeData, "RouteId", cJSON_CreateNumber(aRouteData.mRouterId));
169 cJSON_AddItemToObject(routeData, "LinkQualityOut", cJSON_CreateNumber(aRouteData.mLinkQualityOut));
170 cJSON_AddItemToObject(routeData, "LinkQualityIn", cJSON_CreateNumber(aRouteData.mLinkQualityIn));
171 cJSON_AddItemToObject(routeData, "RouteCost", cJSON_CreateNumber(aRouteData.mRouteCost));
176 static cJSON *Route2Json(const otNetworkDiagRoute &aRoute)
178 cJSON *route = cJSON_CreateObject();
180 cJSON_AddItemToObject(route, "IdSequence", cJSON_CreateNumber(aRoute.mIdSequence));
182 cJSON *RouteData = cJSON_CreateArray();
183 for (uint16_t i = 0; i < aRoute.mRouteCount; ++i)
185 cJSON *RouteDatavalue = RouteData2Json(aRoute.mRouteData[i]);
186 cJSON_AddItemToArray(RouteData, RouteDatavalue);
189 cJSON_AddItemToObject(route, "RouteData", RouteData);
194 static cJSON *LeaderData2Json(const otLeaderData &aLeaderData)
196 cJSON *leaderData = cJSON_CreateObject();
198 cJSON_AddItemToObject(leaderData, "PartitionId", cJSON_CreateNumber(aLeaderData.mPartitionId));
199 cJSON_AddItemToObject(leaderData, "Weighting", cJSON_CreateNumber(aLeaderData.mWeighting));
200 cJSON_AddItemToObject(leaderData, "DataVersion", cJSON_CreateNumber(aLeaderData.mDataVersion));
201 cJSON_AddItemToObject(leaderData, "StableDataVersion", cJSON_CreateNumber(aLeaderData.mStableDataVersion));
202 cJSON_AddItemToObject(leaderData, "LeaderRouterId", cJSON_CreateNumber(aLeaderData.mLeaderRouterId));
207 std::string IpAddr2JsonString(const otIp6Address &aAddress)
210 cJSON * ipAddr = IpAddr2Json(aAddress);
212 ret = Json2String(ipAddr);
213 cJSON_Delete(ipAddr);
218 std::string Node2JsonString(const NodeInfo &aNode)
220 cJSON * node = cJSON_CreateObject();
223 cJSON_AddItemToObject(node, "State", cJSON_CreateNumber(aNode.mRole));
224 cJSON_AddItemToObject(node, "NumOfRouter", cJSON_CreateNumber(aNode.mNumOfRouter));
225 cJSON_AddItemToObject(node, "RlocAddress", IpAddr2Json(aNode.mRlocAddress));
226 cJSON_AddItemToObject(node, "ExtAddress", Bytes2HexJson(aNode.mExtAddress, OT_EXT_ADDRESS_SIZE));
227 cJSON_AddItemToObject(node, "NetworkName", cJSON_CreateString(aNode.mNetworkName.c_str()));
228 cJSON_AddItemToObject(node, "Rloc16", cJSON_CreateNumber(aNode.mRloc16));
229 cJSON_AddItemToObject(node, "LeaderData", LeaderData2Json(aNode.mLeaderData));
230 cJSON_AddItemToObject(node, "ExtPanId", Bytes2HexJson(aNode.mExtPanId, OT_EXT_PAN_ID_SIZE));
232 ret = Json2String(node);
238 std::string Diag2JsonString(const std::vector<std::vector<otNetworkDiagTlv>> &aDiagSet)
240 cJSON * diagInfo = cJSON_CreateArray();
241 cJSON * diagInfoOfOneNode = nullptr;
242 cJSON * addrList = nullptr;
243 cJSON * tableList = nullptr;
247 for (auto diagItem : aDiagSet)
249 diagInfoOfOneNode = cJSON_CreateObject();
250 for (auto diagTlv : diagItem)
252 switch (diagTlv.mType)
254 case OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS:
256 cJSON_AddItemToObject(diagInfoOfOneNode, "ExtAddress",
257 Bytes2HexJson(diagTlv.mData.mExtAddress.m8, OT_EXT_ADDRESS_SIZE));
260 case OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS:
262 cJSON_AddItemToObject(diagInfoOfOneNode, "Rloc16", cJSON_CreateNumber(diagTlv.mData.mAddr16));
265 case OT_NETWORK_DIAGNOSTIC_TLV_MODE:
267 cJSON_AddItemToObject(diagInfoOfOneNode, "Mode", Mode2Json(diagTlv.mData.mMode));
270 case OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT:
272 timeout = static_cast<uint64_t>(diagTlv.mData.mTimeout);
273 cJSON_AddItemToObject(diagInfoOfOneNode, "Timeout", cJSON_CreateNumber(timeout));
276 case OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY:
278 cJSON_AddItemToObject(diagInfoOfOneNode, "Connectivity",
279 Connectivity2Json(diagTlv.mData.mConnectivity));
282 case OT_NETWORK_DIAGNOSTIC_TLV_ROUTE:
284 cJSON_AddItemToObject(diagInfoOfOneNode, "Route", Route2Json(diagTlv.mData.mRoute));
287 case OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA:
289 cJSON_AddItemToObject(diagInfoOfOneNode, "LeaderData", LeaderData2Json(diagTlv.mData.mLeaderData));
292 case OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA:
294 cJSON_AddItemToObject(diagInfoOfOneNode, "NetworkData",
295 Bytes2HexJson(diagTlv.mData.mNetworkData.m8, diagTlv.mData.mNetworkData.mCount));
298 case OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST:
300 addrList = cJSON_CreateArray();
302 for (uint16_t i = 0; i < diagTlv.mData.mIp6AddrList.mCount; ++i)
304 cJSON_AddItemToArray(addrList, IpAddr2Json(diagTlv.mData.mIp6AddrList.mList[i]));
306 cJSON_AddItemToObject(diagInfoOfOneNode, "IP6AddressList", addrList);
309 case OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS:
311 cJSON_AddItemToObject(diagInfoOfOneNode, "MACCounters", MacCounters2Json(diagTlv.mData.mMacCounters));
314 case OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL:
316 cJSON_AddItemToObject(diagInfoOfOneNode, "BatteryLevel",
317 cJSON_CreateNumber(diagTlv.mData.mBatteryLevel));
320 case OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE:
322 cJSON_AddItemToObject(diagInfoOfOneNode, "SupplyVoltage",
323 cJSON_CreateNumber(diagTlv.mData.mSupplyVoltage));
326 case OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE:
328 tableList = cJSON_CreateArray();
330 for (uint16_t i = 0; i < diagTlv.mData.mChildTable.mCount; ++i)
332 cJSON_AddItemToArray(tableList, ChildTableEntry2Json(diagTlv.mData.mChildTable.mTable[i]));
335 cJSON_AddItemToObject(diagInfoOfOneNode, "ChildTable", tableList);
338 case OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES:
340 cJSON_AddItemToObject(
341 diagInfoOfOneNode, "ChannelPages",
342 Bytes2HexJson(diagTlv.mData.mChannelPages.m8, diagTlv.mData.mChannelPages.mCount));
345 case OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT:
347 cJSON_AddItemToObject(diagInfoOfOneNode, "MaxChildTimeout",
348 cJSON_CreateNumber(diagTlv.mData.mMaxChildTimeout));
355 cJSON_AddItemToArray(diagInfo, diagInfoOfOneNode);
358 ret = Json2String(diagInfo);
360 cJSON_Delete(diagInfo);
365 std::string Bytes2HexJsonString(const uint8_t *aBytes, uint8_t aLength)
367 cJSON * hex = Bytes2HexJson(aBytes, aLength);
368 std::string ret = Json2String(hex);
375 std::string Number2JsonString(const uint32_t &aNumber)
377 cJSON * number = cJSON_CreateNumber(aNumber);
378 std::string ret = Json2String(number);
380 cJSON_Delete(number);
385 std::string Mode2JsonString(const otLinkModeConfig &aMode)
387 cJSON * mode = Mode2Json(aMode);
388 std::string ret = Json2String(mode);
395 std::string Connectivity2JsonString(const otNetworkDiagConnectivity &aConnectivity)
397 cJSON * connectivity = Connectivity2Json(aConnectivity);
398 std::string ret = Json2String(connectivity);
400 cJSON_Delete(connectivity);
405 std::string RouteData2JsonString(const otNetworkDiagRouteData &aRouteData)
407 cJSON * routeData = RouteData2Json(aRouteData);
408 std::string ret = Json2String(routeData);
410 cJSON_Delete(routeData);
415 std::string Route2JsonString(const otNetworkDiagRoute &aRoute)
417 cJSON * route = Route2Json(aRoute);
418 std::string ret = Json2String(route);
425 std::string LeaderData2JsonString(const otLeaderData &aLeaderData)
427 cJSON * leaderData = LeaderData2Json(aLeaderData);
428 std::string ret = Json2String(leaderData);
430 cJSON_Delete(leaderData);
435 std::string MacCounters2JsonString(const otNetworkDiagMacCounters &aMacCounters)
437 cJSON * macCounters = MacCounters2Json(aMacCounters);
438 std::string ret = Json2String(macCounters);
440 cJSON_Delete(macCounters);
445 std::string ChildTableEntry2JsonString(const otNetworkDiagChildEntry &aChildEntry)
447 cJSON * childEntry = ChildTableEntry2Json(aChildEntry);
448 std::string ret = Json2String(childEntry);
450 cJSON_Delete(childEntry);
455 std::string CString2JsonString(const char *aCString)
457 cJSON * cString = CString2Json(aCString);
458 std::string ret = Json2String(cString);
460 cJSON_Delete(cString);
465 std::string Error2JsonString(HttpStatusCode aErrorCode, std::string aErrorMessage)
468 cJSON * error = cJSON_CreateObject();
470 cJSON_AddItemToObject(error, "ErrorCode", cJSON_CreateNumber(static_cast<int16_t>(aErrorCode)));
471 cJSON_AddItemToObject(error, "ErrorMessage", cJSON_CreateString(aErrorMessage.c_str()));
473 ret = Json2String(error);