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