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