xref: /aosp_15_r20/external/ot-br-posix/src/rest/json.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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 #include "rest/json.hpp"
30 #include <sstream>
31 
32 #include "common/code_utils.hpp"
33 #include "common/types.hpp"
34 
35 extern "C" {
36 #include <cJSON.h>
37 }
38 
39 namespace otbr {
40 namespace rest {
41 namespace Json {
42 
Bytes2HexJson(const uint8_t * aBytes,uint8_t aLength)43 static cJSON *Bytes2HexJson(const uint8_t *aBytes, uint8_t aLength)
44 {
45     char hex[2 * aLength + 1];
46 
47     otbr::Utils::Bytes2Hex(aBytes, aLength, hex);
48     hex[2 * aLength] = '\0';
49 
50     return cJSON_CreateString(hex);
51 }
52 
String2JsonString(const std::string & aString)53 std::string String2JsonString(const std::string &aString)
54 {
55     std::string ret;
56     cJSON      *json    = nullptr;
57     char       *jsonOut = nullptr;
58 
59     VerifyOrExit(aString.size() > 0);
60 
61     json    = cJSON_CreateString(aString.c_str());
62     jsonOut = cJSON_Print(json);
63     ret     = jsonOut;
64     if (jsonOut != nullptr)
65     {
66         cJSON_free(jsonOut);
67         jsonOut = nullptr;
68     }
69 
70     cJSON_Delete(json);
71 
72 exit:
73     return ret;
74 }
75 
JsonString2String(const std::string & aJsonString,std::string & aString)76 bool JsonString2String(const std::string &aJsonString, std::string &aString)
77 {
78     cJSON *jsonString;
79     bool   ret = true;
80 
81     VerifyOrExit((jsonString = cJSON_Parse(aJsonString.c_str())) != nullptr, ret = false);
82     VerifyOrExit(cJSON_IsString(jsonString), ret = false);
83 
84     aString = std::string(jsonString->valuestring);
85 
86 exit:
87     cJSON_Delete(jsonString);
88 
89     return ret;
90 }
91 
Json2String(const cJSON * aJson)92 std::string Json2String(const cJSON *aJson)
93 {
94     std::string ret;
95     char       *jsonOut = nullptr;
96 
97     VerifyOrExit(aJson != nullptr);
98 
99     jsonOut = cJSON_Print(aJson);
100     ret     = jsonOut;
101     if (jsonOut != nullptr)
102     {
103         cJSON_free(jsonOut);
104         jsonOut = nullptr;
105     }
106 
107 exit:
108     return ret;
109 }
110 
CString2Json(const char * aString)111 static cJSON *CString2Json(const char *aString)
112 {
113     return cJSON_CreateString(aString);
114 }
115 
Mode2Json(const otLinkModeConfig & aMode)116 static cJSON *Mode2Json(const otLinkModeConfig &aMode)
117 {
118     cJSON *mode = cJSON_CreateObject();
119 
120     cJSON_AddItemToObject(mode, "RxOnWhenIdle", cJSON_CreateNumber(aMode.mRxOnWhenIdle));
121     cJSON_AddItemToObject(mode, "DeviceType", cJSON_CreateNumber(aMode.mDeviceType));
122     cJSON_AddItemToObject(mode, "NetworkData", cJSON_CreateNumber(aMode.mNetworkData));
123 
124     return mode;
125 }
126 
IpAddr2Json(const otIp6Address & aAddress)127 static cJSON *IpAddr2Json(const otIp6Address &aAddress)
128 {
129     Ip6Address addr(aAddress.mFields.m8);
130 
131     return cJSON_CreateString(addr.ToString().c_str());
132 }
133 
IpPrefix2Json(const otIp6NetworkPrefix & aAddress)134 static cJSON *IpPrefix2Json(const otIp6NetworkPrefix &aAddress)
135 {
136     std::stringstream ss;
137     otIp6Address      address = {};
138 
139     address.mFields.mComponents.mNetworkPrefix = aAddress;
140     Ip6Address addr(address.mFields.m8);
141 
142     ss << addr.ToString() << "/" << OT_IP6_PREFIX_BITSIZE;
143 
144     return cJSON_CreateString(ss.str().c_str());
145 }
146 
Json2IpPrefix(const cJSON * aJson,otIp6NetworkPrefix & aIpPrefix)147 otbrError Json2IpPrefix(const cJSON *aJson, otIp6NetworkPrefix &aIpPrefix)
148 {
149     otbrError          error = OTBR_ERROR_NONE;
150     std::istringstream ipPrefixStr(std::string(aJson->valuestring));
151     std::string        tmp;
152     Ip6Address         addr;
153 
154     VerifyOrExit(std::getline(ipPrefixStr, tmp, '/'), error = OTBR_ERROR_INVALID_ARGS);
155     VerifyOrExit((error = addr.FromString(tmp.c_str(), addr)) == OTBR_ERROR_NONE);
156 
157     memcpy(aIpPrefix.m8, addr.m8, OT_IP6_PREFIX_SIZE);
158 exit:
159     return error;
160 }
161 
Timestamp2Json(const otTimestamp & aTimestamp)162 static cJSON *Timestamp2Json(const otTimestamp &aTimestamp)
163 {
164     cJSON *timestamp = cJSON_CreateObject();
165 
166     cJSON_AddItemToObject(timestamp, "Seconds", cJSON_CreateNumber(aTimestamp.mSeconds));
167     cJSON_AddItemToObject(timestamp, "Ticks", cJSON_CreateNumber(aTimestamp.mTicks));
168     cJSON_AddItemToObject(timestamp, "Authoritative", cJSON_CreateBool(aTimestamp.mAuthoritative));
169 
170     return timestamp;
171 }
172 
Json2Timestamp(const cJSON * jsonTimestamp,otTimestamp & aTimestamp)173 bool Json2Timestamp(const cJSON *jsonTimestamp, otTimestamp &aTimestamp)
174 {
175     cJSON *value;
176 
177     value = cJSON_GetObjectItemCaseSensitive(jsonTimestamp, "Seconds");
178     if (cJSON_IsNumber(value))
179     {
180         aTimestamp.mSeconds = static_cast<uint64_t>(value->valuedouble);
181     }
182     else if (value != nullptr)
183     {
184         return false;
185     }
186 
187     value = cJSON_GetObjectItemCaseSensitive(jsonTimestamp, "Ticks");
188     if (cJSON_IsNumber(value))
189     {
190         aTimestamp.mTicks = static_cast<uint16_t>(value->valueint);
191     }
192     else if (value != nullptr)
193     {
194         return false;
195     }
196 
197     value                     = cJSON_GetObjectItemCaseSensitive(jsonTimestamp, "Authoritative");
198     aTimestamp.mAuthoritative = cJSON_IsTrue(value);
199 
200     return true;
201 }
202 
SecurityPolicy2Json(const otSecurityPolicy & aSecurityPolicy)203 static cJSON *SecurityPolicy2Json(const otSecurityPolicy &aSecurityPolicy)
204 {
205     cJSON *securityPolicy = cJSON_CreateObject();
206 
207     cJSON_AddItemToObject(securityPolicy, "RotationTime", cJSON_CreateNumber(aSecurityPolicy.mRotationTime));
208     cJSON_AddItemToObject(securityPolicy, "ObtainNetworkKey",
209                           cJSON_CreateBool(aSecurityPolicy.mObtainNetworkKeyEnabled));
210     cJSON_AddItemToObject(securityPolicy, "NativeCommissioning",
211                           cJSON_CreateBool(aSecurityPolicy.mNativeCommissioningEnabled));
212     cJSON_AddItemToObject(securityPolicy, "Routers", cJSON_CreateBool(aSecurityPolicy.mRoutersEnabled));
213     cJSON_AddItemToObject(securityPolicy, "ExternalCommissioning",
214                           cJSON_CreateBool(aSecurityPolicy.mExternalCommissioningEnabled));
215     cJSON_AddItemToObject(securityPolicy, "CommercialCommissioning",
216                           cJSON_CreateBool(aSecurityPolicy.mCommercialCommissioningEnabled));
217     cJSON_AddItemToObject(securityPolicy, "AutonomousEnrollment",
218                           cJSON_CreateBool(aSecurityPolicy.mAutonomousEnrollmentEnabled));
219     cJSON_AddItemToObject(securityPolicy, "NetworkKeyProvisioning",
220                           cJSON_CreateBool(aSecurityPolicy.mNetworkKeyProvisioningEnabled));
221     cJSON_AddItemToObject(securityPolicy, "TobleLink", cJSON_CreateBool(aSecurityPolicy.mTobleLinkEnabled));
222     cJSON_AddItemToObject(securityPolicy, "NonCcmRouters", cJSON_CreateBool(aSecurityPolicy.mNonCcmRoutersEnabled));
223 
224     return securityPolicy;
225 }
226 
Json2SecurityPolicy(const cJSON * jsonSecurityPolicy,otSecurityPolicy & aSecurityPolicy)227 bool Json2SecurityPolicy(const cJSON *jsonSecurityPolicy, otSecurityPolicy &aSecurityPolicy)
228 {
229     cJSON *value;
230 
231     value = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "RotationTime");
232     if (cJSON_IsNumber(value))
233     {
234         aSecurityPolicy.mRotationTime = static_cast<uint16_t>(value->valueint);
235     }
236 
237     value                                    = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "ObtainNetworkKey");
238     aSecurityPolicy.mObtainNetworkKeyEnabled = cJSON_IsTrue(value);
239     value = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "NativeCommissioning");
240     aSecurityPolicy.mNativeCommissioningEnabled = cJSON_IsTrue(value);
241     value                                       = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "Routers");
242     aSecurityPolicy.mRoutersEnabled             = cJSON_IsTrue(value);
243     value = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "ExternalCommissioning");
244     aSecurityPolicy.mExternalCommissioningEnabled = cJSON_IsTrue(value);
245     value = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "CommercialCommissioning");
246     aSecurityPolicy.mCommercialCommissioningEnabled = cJSON_IsTrue(value);
247     value = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "AutonomousEnrollment");
248     aSecurityPolicy.mAutonomousEnrollmentEnabled = cJSON_IsTrue(value);
249     value = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "NetworkKeyProvisioning");
250     aSecurityPolicy.mNetworkKeyProvisioningEnabled = cJSON_IsTrue(value);
251     value                                          = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "TobleLink");
252     aSecurityPolicy.mTobleLinkEnabled              = cJSON_IsTrue(value);
253     value                                 = cJSON_GetObjectItemCaseSensitive(jsonSecurityPolicy, "NonCcmRouters");
254     aSecurityPolicy.mNonCcmRoutersEnabled = cJSON_IsTrue(value);
255 
256     return true;
257 }
258 
ChildTableEntry2Json(const otNetworkDiagChildEntry & aChildEntry)259 static cJSON *ChildTableEntry2Json(const otNetworkDiagChildEntry &aChildEntry)
260 {
261     cJSON *childEntry = cJSON_CreateObject();
262 
263     cJSON_AddItemToObject(childEntry, "ChildId", cJSON_CreateNumber(aChildEntry.mChildId));
264     cJSON_AddItemToObject(childEntry, "Timeout", cJSON_CreateNumber(aChildEntry.mTimeout));
265 
266     cJSON *mode = Mode2Json(aChildEntry.mMode);
267     cJSON_AddItemToObject(childEntry, "Mode", mode);
268 
269     return childEntry;
270 }
271 
MacCounters2Json(const otNetworkDiagMacCounters & aMacCounters)272 static cJSON *MacCounters2Json(const otNetworkDiagMacCounters &aMacCounters)
273 {
274     cJSON *macCounters = cJSON_CreateObject();
275 
276     cJSON_AddItemToObject(macCounters, "IfInUnknownProtos", cJSON_CreateNumber(aMacCounters.mIfInUnknownProtos));
277     cJSON_AddItemToObject(macCounters, "IfInErrors", cJSON_CreateNumber(aMacCounters.mIfInErrors));
278     cJSON_AddItemToObject(macCounters, "IfOutErrors", cJSON_CreateNumber(aMacCounters.mIfOutErrors));
279     cJSON_AddItemToObject(macCounters, "IfInUcastPkts", cJSON_CreateNumber(aMacCounters.mIfInUcastPkts));
280     cJSON_AddItemToObject(macCounters, "IfInBroadcastPkts", cJSON_CreateNumber(aMacCounters.mIfInBroadcastPkts));
281     cJSON_AddItemToObject(macCounters, "IfInDiscards", cJSON_CreateNumber(aMacCounters.mIfInDiscards));
282     cJSON_AddItemToObject(macCounters, "IfOutUcastPkts", cJSON_CreateNumber(aMacCounters.mIfOutUcastPkts));
283     cJSON_AddItemToObject(macCounters, "IfOutBroadcastPkts", cJSON_CreateNumber(aMacCounters.mIfOutBroadcastPkts));
284     cJSON_AddItemToObject(macCounters, "IfOutDiscards", cJSON_CreateNumber(aMacCounters.mIfOutDiscards));
285 
286     return macCounters;
287 }
288 
Connectivity2Json(const otNetworkDiagConnectivity & aConnectivity)289 static cJSON *Connectivity2Json(const otNetworkDiagConnectivity &aConnectivity)
290 {
291     cJSON *connectivity = cJSON_CreateObject();
292 
293     cJSON_AddItemToObject(connectivity, "ParentPriority", cJSON_CreateNumber(aConnectivity.mParentPriority));
294     cJSON_AddItemToObject(connectivity, "LinkQuality3", cJSON_CreateNumber(aConnectivity.mLinkQuality3));
295     cJSON_AddItemToObject(connectivity, "LinkQuality2", cJSON_CreateNumber(aConnectivity.mLinkQuality2));
296     cJSON_AddItemToObject(connectivity, "LinkQuality1", cJSON_CreateNumber(aConnectivity.mLinkQuality1));
297     cJSON_AddItemToObject(connectivity, "LeaderCost", cJSON_CreateNumber(aConnectivity.mLeaderCost));
298     cJSON_AddItemToObject(connectivity, "IdSequence", cJSON_CreateNumber(aConnectivity.mIdSequence));
299     cJSON_AddItemToObject(connectivity, "ActiveRouters", cJSON_CreateNumber(aConnectivity.mActiveRouters));
300     cJSON_AddItemToObject(connectivity, "SedBufferSize", cJSON_CreateNumber(aConnectivity.mSedBufferSize));
301     cJSON_AddItemToObject(connectivity, "SedDatagramCount", cJSON_CreateNumber(aConnectivity.mSedDatagramCount));
302 
303     return connectivity;
304 }
305 
RouteData2Json(const otNetworkDiagRouteData & aRouteData)306 static cJSON *RouteData2Json(const otNetworkDiagRouteData &aRouteData)
307 {
308     cJSON *routeData = cJSON_CreateObject();
309 
310     cJSON_AddItemToObject(routeData, "RouteId", cJSON_CreateNumber(aRouteData.mRouterId));
311     cJSON_AddItemToObject(routeData, "LinkQualityOut", cJSON_CreateNumber(aRouteData.mLinkQualityOut));
312     cJSON_AddItemToObject(routeData, "LinkQualityIn", cJSON_CreateNumber(aRouteData.mLinkQualityIn));
313     cJSON_AddItemToObject(routeData, "RouteCost", cJSON_CreateNumber(aRouteData.mRouteCost));
314 
315     return routeData;
316 }
317 
Route2Json(const otNetworkDiagRoute & aRoute)318 static cJSON *Route2Json(const otNetworkDiagRoute &aRoute)
319 {
320     cJSON *route = cJSON_CreateObject();
321 
322     cJSON_AddItemToObject(route, "IdSequence", cJSON_CreateNumber(aRoute.mIdSequence));
323 
324     cJSON *RouteData = cJSON_CreateArray();
325     for (uint16_t i = 0; i < aRoute.mRouteCount; ++i)
326     {
327         cJSON *RouteDatavalue = RouteData2Json(aRoute.mRouteData[i]);
328         cJSON_AddItemToArray(RouteData, RouteDatavalue);
329     }
330 
331     cJSON_AddItemToObject(route, "RouteData", RouteData);
332 
333     return route;
334 }
335 
LeaderData2Json(const otLeaderData & aLeaderData)336 static cJSON *LeaderData2Json(const otLeaderData &aLeaderData)
337 {
338     cJSON *leaderData = cJSON_CreateObject();
339 
340     cJSON_AddItemToObject(leaderData, "PartitionId", cJSON_CreateNumber(aLeaderData.mPartitionId));
341     cJSON_AddItemToObject(leaderData, "Weighting", cJSON_CreateNumber(aLeaderData.mWeighting));
342     cJSON_AddItemToObject(leaderData, "DataVersion", cJSON_CreateNumber(aLeaderData.mDataVersion));
343     cJSON_AddItemToObject(leaderData, "StableDataVersion", cJSON_CreateNumber(aLeaderData.mStableDataVersion));
344     cJSON_AddItemToObject(leaderData, "LeaderRouterId", cJSON_CreateNumber(aLeaderData.mLeaderRouterId));
345 
346     return leaderData;
347 }
348 
IpAddr2JsonString(const otIp6Address & aAddress)349 std::string IpAddr2JsonString(const otIp6Address &aAddress)
350 {
351     std::string ret;
352     cJSON      *ipAddr = IpAddr2Json(aAddress);
353 
354     ret = Json2String(ipAddr);
355     cJSON_Delete(ipAddr);
356 
357     return ret;
358 }
359 
Node2JsonString(const NodeInfo & aNode)360 std::string Node2JsonString(const NodeInfo &aNode)
361 {
362     cJSON      *node = cJSON_CreateObject();
363     std::string ret;
364 
365     cJSON_AddItemToObject(node, "BaId", Bytes2HexJson(aNode.mBaId.mId, sizeof(aNode.mBaId)));
366     cJSON_AddItemToObject(node, "State", cJSON_CreateString(aNode.mRole.c_str()));
367     cJSON_AddItemToObject(node, "NumOfRouter", cJSON_CreateNumber(aNode.mNumOfRouter));
368     cJSON_AddItemToObject(node, "RlocAddress", IpAddr2Json(aNode.mRlocAddress));
369     cJSON_AddItemToObject(node, "ExtAddress", Bytes2HexJson(aNode.mExtAddress, OT_EXT_ADDRESS_SIZE));
370     cJSON_AddItemToObject(node, "NetworkName", cJSON_CreateString(aNode.mNetworkName.c_str()));
371     cJSON_AddItemToObject(node, "Rloc16", cJSON_CreateNumber(aNode.mRloc16));
372     cJSON_AddItemToObject(node, "LeaderData", LeaderData2Json(aNode.mLeaderData));
373     cJSON_AddItemToObject(node, "ExtPanId", Bytes2HexJson(aNode.mExtPanId, OT_EXT_PAN_ID_SIZE));
374 
375     ret = Json2String(node);
376     cJSON_Delete(node);
377 
378     return ret;
379 }
380 
Diag2JsonString(const std::vector<std::vector<otNetworkDiagTlv>> & aDiagSet)381 std::string Diag2JsonString(const std::vector<std::vector<otNetworkDiagTlv>> &aDiagSet)
382 {
383     cJSON      *diagInfo          = cJSON_CreateArray();
384     cJSON      *diagInfoOfOneNode = nullptr;
385     cJSON      *addrList          = nullptr;
386     cJSON      *tableList         = nullptr;
387     std::string ret;
388     uint64_t    timeout;
389 
390     for (auto diagItem : aDiagSet)
391     {
392         diagInfoOfOneNode = cJSON_CreateObject();
393         for (auto diagTlv : diagItem)
394         {
395             switch (diagTlv.mType)
396             {
397             case OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS:
398 
399                 cJSON_AddItemToObject(diagInfoOfOneNode, "ExtAddress",
400                                       Bytes2HexJson(diagTlv.mData.mExtAddress.m8, OT_EXT_ADDRESS_SIZE));
401 
402                 break;
403             case OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS:
404 
405                 cJSON_AddItemToObject(diagInfoOfOneNode, "Rloc16", cJSON_CreateNumber(diagTlv.mData.mAddr16));
406 
407                 break;
408             case OT_NETWORK_DIAGNOSTIC_TLV_MODE:
409 
410                 cJSON_AddItemToObject(diagInfoOfOneNode, "Mode", Mode2Json(diagTlv.mData.mMode));
411 
412                 break;
413             case OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT:
414 
415                 timeout = static_cast<uint64_t>(diagTlv.mData.mTimeout);
416                 cJSON_AddItemToObject(diagInfoOfOneNode, "Timeout", cJSON_CreateNumber(timeout));
417 
418                 break;
419             case OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY:
420 
421                 cJSON_AddItemToObject(diagInfoOfOneNode, "Connectivity",
422                                       Connectivity2Json(diagTlv.mData.mConnectivity));
423 
424                 break;
425             case OT_NETWORK_DIAGNOSTIC_TLV_ROUTE:
426 
427                 cJSON_AddItemToObject(diagInfoOfOneNode, "Route", Route2Json(diagTlv.mData.mRoute));
428 
429                 break;
430             case OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA:
431 
432                 cJSON_AddItemToObject(diagInfoOfOneNode, "LeaderData", LeaderData2Json(diagTlv.mData.mLeaderData));
433 
434                 break;
435             case OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA:
436 
437                 cJSON_AddItemToObject(diagInfoOfOneNode, "NetworkData",
438                                       Bytes2HexJson(diagTlv.mData.mNetworkData.m8, diagTlv.mData.mNetworkData.mCount));
439 
440                 break;
441             case OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST:
442 
443                 addrList = cJSON_CreateArray();
444 
445                 for (uint16_t i = 0; i < diagTlv.mData.mIp6AddrList.mCount; ++i)
446                 {
447                     cJSON_AddItemToArray(addrList, IpAddr2Json(diagTlv.mData.mIp6AddrList.mList[i]));
448                 }
449                 cJSON_AddItemToObject(diagInfoOfOneNode, "IP6AddressList", addrList);
450 
451                 break;
452             case OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS:
453 
454                 cJSON_AddItemToObject(diagInfoOfOneNode, "MACCounters", MacCounters2Json(diagTlv.mData.mMacCounters));
455 
456                 break;
457             case OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL:
458 
459                 cJSON_AddItemToObject(diagInfoOfOneNode, "BatteryLevel",
460                                       cJSON_CreateNumber(diagTlv.mData.mBatteryLevel));
461 
462                 break;
463             case OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE:
464 
465                 cJSON_AddItemToObject(diagInfoOfOneNode, "SupplyVoltage",
466                                       cJSON_CreateNumber(diagTlv.mData.mSupplyVoltage));
467 
468                 break;
469             case OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE:
470 
471                 tableList = cJSON_CreateArray();
472 
473                 for (uint16_t i = 0; i < diagTlv.mData.mChildTable.mCount; ++i)
474                 {
475                     cJSON_AddItemToArray(tableList, ChildTableEntry2Json(diagTlv.mData.mChildTable.mTable[i]));
476                 }
477 
478                 cJSON_AddItemToObject(diagInfoOfOneNode, "ChildTable", tableList);
479 
480                 break;
481             case OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES:
482 
483                 cJSON_AddItemToObject(
484                     diagInfoOfOneNode, "ChannelPages",
485                     Bytes2HexJson(diagTlv.mData.mChannelPages.m8, diagTlv.mData.mChannelPages.mCount));
486 
487                 break;
488             case OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT:
489 
490                 cJSON_AddItemToObject(diagInfoOfOneNode, "MaxChildTimeout",
491                                       cJSON_CreateNumber(diagTlv.mData.mMaxChildTimeout));
492 
493                 break;
494             default:
495                 break;
496             }
497         }
498         cJSON_AddItemToArray(diagInfo, diagInfoOfOneNode);
499     }
500 
501     ret = Json2String(diagInfo);
502 
503     cJSON_Delete(diagInfo);
504 
505     return ret;
506 }
507 
Bytes2HexJsonString(const uint8_t * aBytes,uint8_t aLength)508 std::string Bytes2HexJsonString(const uint8_t *aBytes, uint8_t aLength)
509 {
510     cJSON      *hex = Bytes2HexJson(aBytes, aLength);
511     std::string ret = Json2String(hex);
512 
513     cJSON_Delete(hex);
514 
515     return ret;
516 }
517 
Hex2BytesJsonString(const std::string & aHexString,uint8_t * aBytes,uint8_t aMaxLength)518 int Hex2BytesJsonString(const std::string &aHexString, uint8_t *aBytes, uint8_t aMaxLength)
519 {
520     return otbr::Utils::Hex2Bytes(aHexString.c_str(), aBytes, aMaxLength);
521 }
522 
Number2JsonString(const uint32_t & aNumber)523 std::string Number2JsonString(const uint32_t &aNumber)
524 {
525     cJSON      *number = cJSON_CreateNumber(aNumber);
526     std::string ret    = Json2String(number);
527 
528     cJSON_Delete(number);
529 
530     return ret;
531 }
532 
Mode2JsonString(const otLinkModeConfig & aMode)533 std::string Mode2JsonString(const otLinkModeConfig &aMode)
534 {
535     cJSON      *mode = Mode2Json(aMode);
536     std::string ret  = Json2String(mode);
537 
538     cJSON_Delete(mode);
539 
540     return ret;
541 }
542 
Connectivity2JsonString(const otNetworkDiagConnectivity & aConnectivity)543 std::string Connectivity2JsonString(const otNetworkDiagConnectivity &aConnectivity)
544 {
545     cJSON      *connectivity = Connectivity2Json(aConnectivity);
546     std::string ret          = Json2String(connectivity);
547 
548     cJSON_Delete(connectivity);
549 
550     return ret;
551 }
552 
RouteData2JsonString(const otNetworkDiagRouteData & aRouteData)553 std::string RouteData2JsonString(const otNetworkDiagRouteData &aRouteData)
554 {
555     cJSON      *routeData = RouteData2Json(aRouteData);
556     std::string ret       = Json2String(routeData);
557 
558     cJSON_Delete(routeData);
559 
560     return ret;
561 }
562 
Route2JsonString(const otNetworkDiagRoute & aRoute)563 std::string Route2JsonString(const otNetworkDiagRoute &aRoute)
564 {
565     cJSON      *route = Route2Json(aRoute);
566     std::string ret   = Json2String(route);
567 
568     cJSON_Delete(route);
569 
570     return ret;
571 }
572 
LeaderData2JsonString(const otLeaderData & aLeaderData)573 std::string LeaderData2JsonString(const otLeaderData &aLeaderData)
574 {
575     cJSON      *leaderData = LeaderData2Json(aLeaderData);
576     std::string ret        = Json2String(leaderData);
577 
578     cJSON_Delete(leaderData);
579 
580     return ret;
581 }
582 
MacCounters2JsonString(const otNetworkDiagMacCounters & aMacCounters)583 std::string MacCounters2JsonString(const otNetworkDiagMacCounters &aMacCounters)
584 {
585     cJSON      *macCounters = MacCounters2Json(aMacCounters);
586     std::string ret         = Json2String(macCounters);
587 
588     cJSON_Delete(macCounters);
589 
590     return ret;
591 }
592 
ChildTableEntry2JsonString(const otNetworkDiagChildEntry & aChildEntry)593 std::string ChildTableEntry2JsonString(const otNetworkDiagChildEntry &aChildEntry)
594 {
595     cJSON      *childEntry = ChildTableEntry2Json(aChildEntry);
596     std::string ret        = Json2String(childEntry);
597 
598     cJSON_Delete(childEntry);
599 
600     return ret;
601 }
602 
CString2JsonString(const char * aCString)603 std::string CString2JsonString(const char *aCString)
604 {
605     cJSON      *cString = CString2Json(aCString);
606     std::string ret     = Json2String(cString);
607 
608     cJSON_Delete(cString);
609 
610     return ret;
611 }
612 
Error2JsonString(HttpStatusCode aErrorCode,std::string aErrorMessage)613 std::string Error2JsonString(HttpStatusCode aErrorCode, std::string aErrorMessage)
614 {
615     std::string ret;
616     cJSON      *error = cJSON_CreateObject();
617 
618     cJSON_AddItemToObject(error, "ErrorCode", cJSON_CreateNumber(static_cast<int16_t>(aErrorCode)));
619     cJSON_AddItemToObject(error, "ErrorMessage", cJSON_CreateString(aErrorMessage.c_str()));
620 
621     ret = Json2String(error);
622 
623     cJSON_Delete(error);
624 
625     return ret;
626 }
627 
ActiveDataset2Json(const otOperationalDataset & aActiveDataset)628 cJSON *ActiveDataset2Json(const otOperationalDataset &aActiveDataset)
629 {
630     cJSON *node = cJSON_CreateObject();
631 
632     if (aActiveDataset.mComponents.mIsActiveTimestampPresent)
633     {
634         cJSON_AddItemToObject(node, "ActiveTimestamp", Timestamp2Json(aActiveDataset.mActiveTimestamp));
635     }
636     if (aActiveDataset.mComponents.mIsNetworkKeyPresent)
637     {
638         cJSON_AddItemToObject(node, "NetworkKey", Bytes2HexJson(aActiveDataset.mNetworkKey.m8, OT_NETWORK_KEY_SIZE));
639     }
640     if (aActiveDataset.mComponents.mIsNetworkNamePresent)
641     {
642         cJSON_AddItemToObject(node, "NetworkName", cJSON_CreateString(aActiveDataset.mNetworkName.m8));
643     }
644     if (aActiveDataset.mComponents.mIsExtendedPanIdPresent)
645     {
646         cJSON_AddItemToObject(node, "ExtPanId", Bytes2HexJson(aActiveDataset.mExtendedPanId.m8, OT_EXT_PAN_ID_SIZE));
647     }
648     if (aActiveDataset.mComponents.mIsMeshLocalPrefixPresent)
649     {
650         cJSON_AddItemToObject(node, "MeshLocalPrefix", IpPrefix2Json(aActiveDataset.mMeshLocalPrefix));
651     }
652     if (aActiveDataset.mComponents.mIsPanIdPresent)
653     {
654         cJSON_AddItemToObject(node, "PanId", cJSON_CreateNumber(aActiveDataset.mPanId));
655     }
656     if (aActiveDataset.mComponents.mIsChannelPresent)
657     {
658         cJSON_AddItemToObject(node, "Channel", cJSON_CreateNumber(aActiveDataset.mChannel));
659     }
660     if (aActiveDataset.mComponents.mIsPskcPresent)
661     {
662         cJSON_AddItemToObject(node, "PSKc", Bytes2HexJson(aActiveDataset.mPskc.m8, OT_PSKC_MAX_SIZE));
663     }
664     if (aActiveDataset.mComponents.mIsSecurityPolicyPresent)
665     {
666         cJSON_AddItemToObject(node, "SecurityPolicy", SecurityPolicy2Json(aActiveDataset.mSecurityPolicy));
667     }
668     if (aActiveDataset.mComponents.mIsChannelMaskPresent)
669     {
670         cJSON_AddItemToObject(node, "ChannelMask", cJSON_CreateNumber(aActiveDataset.mChannelMask));
671     }
672 
673     return node;
674 }
675 
ActiveDataset2JsonString(const otOperationalDataset & aActiveDataset)676 std::string ActiveDataset2JsonString(const otOperationalDataset &aActiveDataset)
677 {
678     cJSON      *node;
679     std::string ret;
680 
681     node = ActiveDataset2Json(aActiveDataset);
682     ret  = Json2String(node);
683     cJSON_Delete(node);
684 
685     return ret;
686 }
687 
PendingDataset2JsonString(const otOperationalDataset & aPendingDataset)688 std::string PendingDataset2JsonString(const otOperationalDataset &aPendingDataset)
689 {
690     cJSON      *nodeActiveDataset;
691     cJSON      *node = cJSON_CreateObject();
692     std::string ret;
693 
694     nodeActiveDataset = ActiveDataset2Json(aPendingDataset);
695     cJSON_AddItemToObject(node, "ActiveDataset", nodeActiveDataset);
696     if (aPendingDataset.mComponents.mIsPendingTimestampPresent)
697     {
698         cJSON_AddItemToObject(node, "PendingTimestamp", Timestamp2Json(aPendingDataset.mPendingTimestamp));
699     }
700     if (aPendingDataset.mComponents.mIsDelayPresent)
701     {
702         cJSON_AddItemToObject(node, "Delay", cJSON_CreateNumber(aPendingDataset.mDelay));
703     }
704 
705     ret = Json2String(node);
706     cJSON_Delete(node);
707 
708     return ret;
709 }
710 
JsonActiveDataset2Dataset(const cJSON * jsonActiveDataset,otOperationalDataset & aDataset)711 bool JsonActiveDataset2Dataset(const cJSON *jsonActiveDataset, otOperationalDataset &aDataset)
712 {
713     cJSON      *value;
714     otTimestamp timestamp;
715     bool        ret = true;
716 
717     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "ActiveTimestamp");
718     if (cJSON_IsObject(value))
719     {
720         VerifyOrExit(Json2Timestamp(value, timestamp), ret = false);
721         aDataset.mActiveTimestamp                      = timestamp;
722         aDataset.mComponents.mIsActiveTimestampPresent = true;
723     }
724     else if (cJSON_IsNull(value))
725     {
726         aDataset.mComponents.mIsActiveTimestampPresent = false;
727     }
728     else if (value != nullptr)
729     {
730         ExitNow(ret = false);
731     }
732 
733     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "NetworkKey");
734     if (cJSON_IsString(value))
735     {
736         VerifyOrExit(value->valuestring != nullptr, ret = false);
737         VerifyOrExit(Hex2BytesJsonString(std::string(value->valuestring), aDataset.mNetworkKey.m8,
738                                          OT_NETWORK_KEY_SIZE) == OT_NETWORK_KEY_SIZE,
739                      ret = false);
740         aDataset.mComponents.mIsNetworkKeyPresent = true;
741     }
742     else if (cJSON_IsNull(value))
743     {
744         aDataset.mComponents.mIsNetworkKeyPresent = false;
745     }
746 
747     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "NetworkName");
748     if (cJSON_IsString(value))
749     {
750         VerifyOrExit(value->valuestring != nullptr, ret = false);
751         VerifyOrExit(strlen(value->valuestring) <= OT_NETWORK_NAME_MAX_SIZE, ret = false);
752         strncpy(aDataset.mNetworkName.m8, value->valuestring, OT_NETWORK_NAME_MAX_SIZE);
753         aDataset.mComponents.mIsNetworkNamePresent = true;
754     }
755     else if (cJSON_IsNull(value))
756     {
757         aDataset.mComponents.mIsNetworkNamePresent = false;
758     }
759 
760     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "ExtPanId");
761     if (cJSON_IsString(value))
762     {
763         VerifyOrExit(value->valuestring != nullptr, ret = false);
764         VerifyOrExit(Hex2BytesJsonString(std::string(value->valuestring), aDataset.mExtendedPanId.m8,
765                                          OT_EXT_PAN_ID_SIZE) == OT_EXT_PAN_ID_SIZE,
766                      ret = false);
767         aDataset.mComponents.mIsExtendedPanIdPresent = true;
768     }
769     else if (cJSON_IsNull(value))
770     {
771         aDataset.mComponents.mIsExtendedPanIdPresent = false;
772     }
773 
774     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "MeshLocalPrefix");
775     if (cJSON_IsString(value))
776     {
777         VerifyOrExit(value->valuestring != nullptr, ret = false);
778         VerifyOrExit(Json2IpPrefix(value, aDataset.mMeshLocalPrefix) == OTBR_ERROR_NONE, ret = false);
779         aDataset.mComponents.mIsMeshLocalPrefixPresent = true;
780     }
781     else if (cJSON_IsNull(value))
782     {
783         aDataset.mComponents.mIsMeshLocalPrefixPresent = false;
784     }
785 
786     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "PanId");
787     if (cJSON_IsNumber(value))
788     {
789         aDataset.mPanId                      = static_cast<otPanId>(value->valueint);
790         aDataset.mComponents.mIsPanIdPresent = true;
791     }
792     else if (cJSON_IsNull(value))
793     {
794         aDataset.mComponents.mIsPanIdPresent = false;
795     }
796 
797     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "Channel");
798     if (cJSON_IsNumber(value))
799     {
800         aDataset.mChannel                      = static_cast<uint16_t>(value->valueint);
801         aDataset.mComponents.mIsChannelPresent = true;
802     }
803     else if (cJSON_IsNull(value))
804     {
805         aDataset.mComponents.mIsChannelPresent = false;
806     }
807 
808     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "PSKc");
809     if (cJSON_IsString(value))
810     {
811         VerifyOrExit(value->valuestring != nullptr, ret = false);
812         VerifyOrExit(Hex2BytesJsonString(std::string(value->valuestring), aDataset.mPskc.m8, OT_PSKC_MAX_SIZE) ==
813                          OT_PSKC_MAX_SIZE,
814                      ret = false);
815         aDataset.mComponents.mIsPskcPresent = true;
816     }
817     else if (cJSON_IsNull(value))
818     {
819         aDataset.mComponents.mIsPskcPresent = false;
820     }
821 
822     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "SecurityPolicy");
823     if (cJSON_IsObject(value))
824     {
825         VerifyOrExit(Json2SecurityPolicy(value, aDataset.mSecurityPolicy), ret = false);
826         aDataset.mComponents.mIsSecurityPolicyPresent = true;
827     }
828     else if (cJSON_IsNull(value))
829     {
830         aDataset.mComponents.mIsSecurityPolicyPresent = false;
831     }
832 
833     value = cJSON_GetObjectItemCaseSensitive(jsonActiveDataset, "ChannelMask");
834     if (cJSON_IsNumber(value))
835     {
836         aDataset.mChannelMask                      = value->valueint;
837         aDataset.mComponents.mIsChannelMaskPresent = true;
838     }
839     else if (cJSON_IsNull(value))
840     {
841         aDataset.mComponents.mIsChannelMaskPresent = false;
842     }
843 
844 exit:
845     return ret;
846 }
847 
JsonActiveDatasetString2Dataset(const std::string & aJsonActiveDataset,otOperationalDataset & aDataset)848 bool JsonActiveDatasetString2Dataset(const std::string &aJsonActiveDataset, otOperationalDataset &aDataset)
849 {
850     cJSON *jsonActiveDataset;
851     bool   ret = true;
852 
853     VerifyOrExit((jsonActiveDataset = cJSON_Parse(aJsonActiveDataset.c_str())) != nullptr, ret = false);
854     VerifyOrExit(cJSON_IsObject(jsonActiveDataset), ret = false);
855 
856     ret = JsonActiveDataset2Dataset(jsonActiveDataset, aDataset);
857 
858 exit:
859     cJSON_Delete(jsonActiveDataset);
860 
861     return ret;
862 }
863 
JsonPendingDatasetString2Dataset(const std::string & aJsonPendingDataset,otOperationalDataset & aDataset)864 bool JsonPendingDatasetString2Dataset(const std::string &aJsonPendingDataset, otOperationalDataset &aDataset)
865 {
866     cJSON      *value;
867     cJSON      *jsonDataset;
868     otTimestamp timestamp;
869     bool        ret = true;
870 
871     VerifyOrExit((jsonDataset = cJSON_Parse(aJsonPendingDataset.c_str())) != nullptr, ret = false);
872     VerifyOrExit(cJSON_IsObject(jsonDataset), ret = false);
873 
874     value = cJSON_GetObjectItemCaseSensitive(jsonDataset, "ActiveDataset");
875     if (cJSON_IsObject(value))
876     {
877         VerifyOrExit(JsonActiveDataset2Dataset(value, aDataset), ret = false);
878     }
879     else if (cJSON_IsString(value))
880     {
881         otOperationalDatasetTlvs datasetTlvs;
882         int                      len;
883 
884         len =
885             Hex2BytesJsonString(std::string(value->valuestring), datasetTlvs.mTlvs, OT_OPERATIONAL_DATASET_MAX_LENGTH);
886         VerifyOrExit(len > 0, ret = false);
887         datasetTlvs.mLength = len;
888 
889         VerifyOrExit(otDatasetParseTlvs(&datasetTlvs, &aDataset) == OT_ERROR_NONE, ret = false);
890     }
891     else
892     {
893         ExitNow(ret = false);
894     }
895 
896     value = cJSON_GetObjectItemCaseSensitive(jsonDataset, "PendingTimestamp");
897     if (cJSON_IsObject(value))
898     {
899         VerifyOrExit(Json2Timestamp(value, timestamp), ret = false);
900         aDataset.mPendingTimestamp                      = timestamp;
901         aDataset.mComponents.mIsPendingTimestampPresent = true;
902     }
903     else if (cJSON_IsNull(value))
904     {
905         aDataset.mComponents.mIsPendingTimestampPresent = false;
906     }
907     else if (value != nullptr)
908     {
909         ExitNow(ret = false);
910     }
911 
912     value = cJSON_GetObjectItemCaseSensitive(jsonDataset, "Delay");
913     if (cJSON_IsNumber(value))
914     {
915         aDataset.mDelay                      = value->valueint;
916         aDataset.mComponents.mIsDelayPresent = true;
917     }
918     else if (cJSON_IsNull(value))
919     {
920         aDataset.mComponents.mIsDelayPresent = false;
921     }
922 
923 exit:
924     cJSON_Delete(jsonDataset);
925 
926     return ret;
927 }
928 
929 } // namespace Json
930 } // namespace rest
931 } // namespace otbr
932