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