Build fixes for new toolchain
[platform/core/api/webapi-plugins.git] / src / iotcon / iotcon_utils.cc
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #include "iotcon_utils.h"
18
19 #include <memory>
20
21 #include "common/logger.h"
22 #include "common/platform_exception.h"
23 #include "common/scope_exit.h"
24 #include "common/tools.h"
25
26 #include "iotcon/iotcon_client_manager.h"
27 #include "iotcon/iotcon_server_manager.h"
28
29 namespace extension {
30 namespace iotcon {
31
32 namespace {
33
34 #define IOTCON_CONNECTIVITY_TYPE_E                \
35   X(IOTCON_CONNECTIVITY_IP, "IP")                 \
36   X(IOTCON_CONNECTIVITY_PREFER_UDP, "PREFER_UDP") \
37   X(IOTCON_CONNECTIVITY_PREFER_TCP, "PREFER_TCP") \
38   X(IOTCON_CONNECTIVITY_IPV4_ONLY, "IPV4_ONLY")   \
39   X(IOTCON_CONNECTIVITY_IPV6_ONLY, "IPV6_ONLY")   \
40   X(IOTCON_CONNECTIVITY_ALL, "ALL")               \
41   XD(IOTCON_CONNECTIVITY_ALL, "unknown")
42
43 #define IOTCON_REQUEST_TYPE_E          \
44   X(IOTCON_REQUEST_UNKNOWN, "unknown") \
45   X(IOTCON_REQUEST_GET, "GET")         \
46   X(IOTCON_REQUEST_PUT, "PUT")         \
47   X(IOTCON_REQUEST_POST, "POST")       \
48   X(IOTCON_REQUEST_DELETE, "DELETE")   \
49   XD(IOTCON_REQUEST_UNKNOWN, "unknown")
50
51 #define IOTCON_OBSERVE_TYPE_E                \
52   X(IOTCON_OBSERVE_NO_TYPE, "NO_TYPE")       \
53   X(IOTCON_OBSERVE_REGISTER, "REGISTER")     \
54   X(IOTCON_OBSERVE_DEREGISTER, "DEREGISTER") \
55   XD(IOTCON_OBSERVE_NO_TYPE, "unknown")
56
57 #define IOTCON_QOS_E         \
58   X(IOTCON_QOS_LOW, "LOW")   \
59   X(IOTCON_QOS_HIGH, "HIGH") \
60   XD(IOTCON_QOS_LOW, "unknown")
61
62 #define IOTCON_PRESENCE_RESULT_E        \
63   X(IOTCON_PRESENCE_OK, "OK")           \
64   X(IOTCON_PRESENCE_STOPPED, "STOPPED") \
65   XD(IOTCON_PRESENCE_TIMEOUT, "TIMEOUT")
66
67 #define IOTCON_PRESENCE_TRIGGER_E                \
68   X(IOTCON_PRESENCE_RESOURCE_CREATED, "CREATED") \
69   X(IOTCON_PRESENCE_RESOURCE_UPDATED, "UPDATED") \
70   XD(IOTCON_PRESENCE_RESOURCE_DESTROYED, "DESTROYED")
71
72 #define IOTCON_RESPONSE_RESULT_E                          \
73   X(IOTCON_RESPONSE_OK, "SUCCESS")                        \
74   X(IOTCON_RESPONSE_ERROR, "ERROR")                       \
75   X(IOTCON_RESPONSE_RESOURCE_CREATED, "RESOURCE_CREATED") \
76   X(IOTCON_RESPONSE_RESOURCE_DELETED, "RESOURCE_DELETED") \
77   X(IOTCON_RESPONSE_RESOURCE_CHANGED, "RESOURCE_CHANGED") \
78   X(IOTCON_RESPONSE_SLOW, "SLOW")                         \
79   X(IOTCON_RESPONSE_FORBIDDEN, "FORBIDDEN")               \
80   XD(IOTCON_RESPONSE_ERROR, "unknown")
81
82 #define IOTCON_OBSERVE_POLICY_E                                \
83   X(IOTCON_OBSERVE_IGNORE_OUT_OF_ORDER, "IGNORE_OUT_OF_ORDER") \
84   X(IOTCON_OBSERVE_ACCEPT_OUT_OF_ORDER, "ACCEPT_OUT_OF_ORDER") \
85   XD(IOTCON_OBSERVE_ACCEPT_OUT_OF_ORDER, "unknown")
86
87 }  // namespace
88
89 const std::string kIsDiscoverable = "isDiscoverable";
90 const std::string kIsObservable = "isObservable";
91 const std::string kIsActive = "isActive";
92 const std::string kIsSlow = "isSlow";
93 const std::string kIsSecure = "isSecure";
94 const std::string kIsExplicitDiscoverable = "isExplicitDiscoverable";
95 const std::string kResourceTypes = "resourceTypes";
96 const std::string kResourceInterfaces = "resourceInterfaces";
97 const std::string kResourceChildren = "resources";
98 const std::string kUriPath = "uriPath";
99 const std::string kAttributes = "attributes";
100 const std::string kId = "id";
101 const std::string kKeepId = "keepId";
102 const std::string kDeviceId = "deviceId";
103 const std::string kDeviceName = "deviceName";
104 const std::string kHostAddress = "hostAddress";
105 const std::string kConnectivityType = "connectivityType";
106 const std::string kObservePolicy = "observePolicy";
107
108 const std::string kRepresentation = "representation";
109 const std::string kChildren = "children";
110 const std::string kRequestType = "type";
111 const std::string kRequest = "request";
112 const std::string kOptions = "options";
113 const std::string kQuery = "query";
114 const std::string kObserverId = "observerId";
115 const std::string kObserveType = "observeType";
116
117 const std::string kOptionsId = "id";
118 const std::string kOptionsData = "data";
119
120 const std::string kResourceType = "resourceType";
121 const std::string kResourceInterface = "resourceInterface";
122 const std::string kFilter = "filter";
123
124 const std::string kHexPrefix = "0x";
125
126 const std::string kPlatformId = "platformId";
127 const std::string kManufacturerName = "manufacturerName";
128 const std::string kManufacturerUrl = "manufacturerUrl";
129 const std::string kModelNumber = "modelNumber";
130 const std::string kManufactureDate = "manufactureDate";
131 const std::string kPlatformVersion = "platformVersion";
132 const std::string kOperatingSystemVersion = "operatingSystemVersion";
133 const std::string kHardwareVersion = "hardwareVersion";
134 const std::string kFirmwareVersion = "firmwareVersion";
135 const std::string kSupportUrl = "supportUrl";
136 const std::string kSystemTime = "systemTime";
137
138 const std::string kSpecVersion = "specVersion";
139 const std::string kOicDeviceId = "oicDeviceId";
140 const std::string kDataModelVersion = "dataModelVersion";
141
142 const std::string kResultType = "resultType";
143 const std::string kTriggerType = "triggerType";
144
145 const std::string kResult = "result";
146
147 const int defRemoteResTimeInterval = 10;
148
149 using common::TizenResult;
150 using common::TizenSuccess;
151
152 const picojson::value& IotconUtils::GetArg(const picojson::object& args, const std::string& name) {
153   static const picojson::value kNull;
154
155   auto it = args.find(name);
156   if (args.end() == it) {
157     return kNull;
158   } else {
159     return it->second;
160   }
161 }
162
163 int IotconUtils::GetProperties(const picojson::object& args) {
164   int properties = IOTCON_RESOURCE_NO_POLICY;
165
166   const auto& observable = IotconUtils::GetArg(args, kIsObservable);
167   properties |= (observable.is<bool>() ? observable.get<bool>() : false)
168                     ? IOTCON_RESOURCE_OBSERVABLE
169                     : IOTCON_RESOURCE_NO_POLICY;
170
171   const auto& discoverable = IotconUtils::GetArg(args, kIsDiscoverable);
172   properties |= (discoverable.is<bool>() ? discoverable.get<bool>() : true)
173                     ? IOTCON_RESOURCE_DISCOVERABLE
174                     : IOTCON_RESOURCE_NO_POLICY;
175
176   const auto& active = IotconUtils::GetArg(args, kIsActive);
177   properties |= (active.is<bool>() ? active.get<bool>() : false) ? IOTCON_RESOURCE_ACTIVE
178                                                                  : IOTCON_RESOURCE_NO_POLICY;
179
180   const auto& slow = IotconUtils::GetArg(args, kIsSlow);
181   properties |= (slow.is<bool>() ? slow.get<bool>() : false) ? IOTCON_RESOURCE_SLOW
182                                                              : IOTCON_RESOURCE_NO_POLICY;
183
184   const auto& secure = IotconUtils::GetArg(args, kIsSecure);
185   properties |= (secure.is<bool>() ? secure.get<bool>() : false) ? IOTCON_RESOURCE_SECURE
186                                                                  : IOTCON_RESOURCE_NO_POLICY;
187
188   const auto& explicit_discoverable = IotconUtils::GetArg(args, kIsExplicitDiscoverable);
189   properties |= (explicit_discoverable.is<bool>() ? explicit_discoverable.get<bool>() : false)
190                     ? IOTCON_RESOURCE_EXPLICIT_DISCOVERABLE
191                     : IOTCON_RESOURCE_NO_POLICY;
192
193   return properties;
194 }
195
196 void IotconUtils::PropertiesToJson(int properties, picojson::object* res) {
197   bool value = properties & IOTCON_RESOURCE_OBSERVABLE;
198   res->insert(std::make_pair(kIsObservable, picojson::value(value)));
199   value = properties & IOTCON_RESOURCE_DISCOVERABLE;
200   res->insert(std::make_pair(kIsDiscoverable, picojson::value(value)));
201   value = properties & IOTCON_RESOURCE_ACTIVE;
202   res->insert(std::make_pair(kIsActive, picojson::value(value)));
203   value = properties & IOTCON_RESOURCE_SLOW;
204   res->insert(std::make_pair(kIsSlow, picojson::value(value)));
205   value = properties & IOTCON_RESOURCE_SECURE;
206   res->insert(std::make_pair(kIsSecure, picojson::value(value)));
207   value = properties & IOTCON_RESOURCE_EXPLICIT_DISCOVERABLE;
208   res->insert(std::make_pair(kIsExplicitDiscoverable, picojson::value(value)));
209 }
210
211 TizenResult IotconUtils::ArrayToInterfaces(const picojson::array& i,
212                                            iotcon_resource_interfaces_h* out) {
213   ScopeLogger();
214
215   iotcon_resource_interfaces_h interfaces = nullptr;
216
217   auto result = ConvertIotconError(iotcon_resource_interfaces_create(&interfaces));
218   if (!result) {
219     LogAndReturnTizenError(result, ("iotcon_resource_interfaces_create() failed"));
220   }
221
222   std::unique_ptr<std::remove_pointer<iotcon_resource_interfaces_h>::type,
223                   int (*)(iotcon_resource_interfaces_h)>
224       ptr{interfaces, &iotcon_resource_interfaces_destroy};
225
226   for (const auto& iter : i) {
227     if (!iter.is<std::string>()) {
228       return LogAndCreateTizenError(InvalidValuesError, "Interface name should be a string");
229     } else {
230       result = ConvertIotconError(
231           iotcon_resource_interfaces_add(interfaces, iter.get<std::string>().c_str()));
232       if (!result) {
233         LogAndReturnTizenError(result, ("iotcon_resource_interfaces_add() failed"));
234       }
235     }
236   }
237
238   *out = ptr.release();
239   return TizenSuccess();
240 }
241
242 TizenResult IotconUtils::InterfacesToArray(iotcon_resource_interfaces_h interfaces,
243                                            picojson::array* arr) {
244   ScopeLogger();
245
246   if (interfaces) {
247     auto result = ConvertIotconError(iotcon_resource_interfaces_foreach(
248         interfaces,
249         [](const char* iface, void* user_data) -> bool {
250           ScopeLogger("Entered into asynchronous function, iotcon_resource_interfaces_foreach");
251
252           if (iface) {
253             auto arr = static_cast<picojson::array*>(user_data);
254             arr->push_back(picojson::value(iface));
255           }
256
257           // always continue with iteration
258           return true;
259         },
260         arr));
261     if (!result) {
262       LogAndReturnTizenError(result, ("iotcon_resource_interfaces_foreach() failed"));
263     }
264   } else {
265     LoggerW("Interface handle is null, ignoring");
266   }
267   return TizenSuccess();
268 }
269
270 TizenResult IotconUtils::ArrayToTypes(const picojson::array& types, iotcon_resource_types_h* res) {
271   ScopeLogger();
272
273   iotcon_resource_types_h resource_types = nullptr;
274   auto result = ConvertIotconError(iotcon_resource_types_create(&resource_types));
275   if (!result) {
276     LogAndReturnTizenError(result, ("iotcon_resource_types_create() failed"));
277   }
278
279   std::unique_ptr<std::remove_pointer<iotcon_resource_types_h>::type,
280                   int (*)(iotcon_resource_types_h)>
281       ptr{resource_types, &iotcon_resource_types_destroy};
282
283   for (const auto& iter : types) {
284     if (!iter.is<std::string>()) {
285       return LogAndCreateTizenError(InvalidValuesError, "Resource type should be a string");
286     } else {
287       result = ConvertIotconError(
288           iotcon_resource_types_add(resource_types, iter.get<std::string>().c_str()));
289       if (!result) {
290         LogAndReturnTizenError(result, ("iotcon_resource_types_add() failed"));
291       }
292     }
293   }
294
295   *res = ptr.release();
296   return TizenSuccess();
297 }
298
299 static bool ResourceTypeIterator(const char* type, void* user_data) {
300   ScopeLogger();
301
302   picojson::array* array_data = static_cast<picojson::array*>(user_data);
303   if (!array_data) {
304     LoggerE("user_data is NULL");
305     return false;
306   }
307
308   array_data->push_back(picojson::value(type));
309   return true;
310 }
311
312 TizenResult IotconUtils::ExtractFromResource(const ResourceInfoPtr& pointer, char** uri_path,
313                                              iotcon_resource_types_h* res_types,
314                                              iotcon_resource_interfaces_h* ifaces,
315                                              uint8_t* properties) {
316   ScopeLogger();
317
318   auto result = ConvertIotconError(iotcon_resource_get_uri_path(pointer->handle, uri_path));
319   if (!result) {
320     LogAndReturnTizenError(result, ("Gathering resource uri path failed"));
321   }
322
323   result = ConvertIotconError(iotcon_resource_get_types(pointer->handle, res_types));
324   if (!result) {
325     LogAndReturnTizenError(result, ("Gathering resource types failed"));
326   }
327
328   result = ConvertIotconError(iotcon_resource_get_interfaces(pointer->handle, ifaces));
329   if (!result) {
330     LogAndReturnTizenError(result, ("Gathering resource interfaces failed"));
331   }
332
333   result = ConvertIotconError(iotcon_resource_get_policies(pointer->handle, properties));
334   if (!result) {
335     LogAndReturnTizenError(result, ("Gathering resource properties failed"));
336   }
337   return TizenSuccess();
338 }
339
340 TizenResult IotconUtils::ResourceToJson(ResourceInfoPtr pointer, picojson::object* res) {
341   ScopeLogger();
342
343   char* uri_path = nullptr;
344   iotcon_resource_types_h res_types = nullptr;
345   iotcon_resource_interfaces_h ifaces = nullptr;
346   uint8_t properties = 0;
347   auto ret = ExtractFromResource(pointer, &uri_path, &res_types, &ifaces, &properties);
348   if (!ret) {
349     return ret;
350   }
351   res->insert(std::make_pair(kId, picojson::value(static_cast<double>(pointer->id))));
352   res->insert(std::make_pair(kUriPath, picojson::value(uri_path)));
353
354   picojson::array types;
355   iotcon_resource_types_foreach(res_types, ResourceTypeIterator, &types);
356   res->insert(std::make_pair(kResourceTypes, picojson::value(types)));
357
358   picojson::array interfaces;
359   ret = InterfacesToArray(ifaces, &interfaces);
360   if (!ret) {
361     LogAndReturnTizenError(ret, ("InterfacesToArray() failed"));
362   }
363   res->insert(std::make_pair(kResourceInterfaces, picojson::value(interfaces)));
364   IotconUtils::PropertiesToJson(properties, res);
365
366   picojson::array children;
367   for (const auto& child_resource : pointer->children) {
368     picojson::value child = picojson::value(picojson::object());
369     ret = IotconUtils::ResourceToJson(child_resource, &(child.get<picojson::object>()));
370     if (ret.IsSuccess()) {
371       children.push_back(child);
372     }
373   }
374   res->insert(std::make_pair(kResourceChildren, picojson::value(children)));
375
376   // observerIds would be done on demand from JS
377
378   return TizenSuccess();
379 }
380
381 TizenResult IotconUtils::ExtractFromRemoteResource(RemoteResourceInfo* resource) {
382   ScopeLogger();
383
384   auto result = ConvertIotconError(
385       iotcon_remote_resource_get_uri_path(resource->resource, &resource->uri_path));
386   if (!result) {
387     LogAndReturnTizenError(result, ("Gathering uri path failed"));
388   }
389
390   result = ConvertIotconError(iotcon_remote_resource_get_connectivity_type(
391       resource->resource, &resource->connectivity_type));
392   if (!result) {
393     LogAndReturnTizenError(result, ("Gathering connectivity type failed"));
394   }
395
396   result = ConvertIotconError(
397       iotcon_remote_resource_get_host_address(resource->resource, &resource->host_address));
398   if (!result) {
399     LogAndReturnTizenError(result, ("Gathering host address failed"));
400   }
401
402   result = ConvertIotconError(
403       iotcon_remote_resource_get_device_id(resource->resource, &resource->device_id));
404   if (!result) {
405     LogAndReturnTizenError(result, ("Gathering device id failed"));
406   }
407
408   result = ConvertIotconError(
409       iotcon_remote_resource_get_device_name(resource->resource, &resource->device_name));
410   if (!result) {
411     LogAndReturnTizenError(result, ("Gathering device name failed"));
412   }
413
414   result =
415       ConvertIotconError(iotcon_remote_resource_get_types(resource->resource, &resource->types));
416   if (!result) {
417     LogAndReturnTizenError(result, ("Gathering types failed"));
418   }
419
420   result = ConvertIotconError(
421       iotcon_remote_resource_get_interfaces(resource->resource, &resource->ifaces));
422   if (!result) {
423     LogAndReturnTizenError(result, ("Gathering interfaces failed"));
424   }
425
426   result = ConvertIotconError(
427       iotcon_remote_resource_get_policies(resource->resource, &resource->properties));
428   if (!result) {
429     LogAndReturnTizenError(result, ("Gathering properties failed"));
430   }
431
432   result = ConvertIotconError(iotcon_remote_resource_get_cached_representation(
433       resource->resource, &resource->representation));
434   if (!result) {
435     LoggerD("Gathering cached representation failed");
436     // TODO check: native method returns error here, now ignoring fail instead of returning error
437     // LogAndReturnTizenError(result, ("Gathering cached representation failed"));
438   }
439
440   result = ConvertIotconError(
441       iotcon_remote_resource_get_options(resource->resource, &resource->options));
442   if (!result) {
443     LogAndReturnTizenError(result, ("Gathering options failed"));
444   }
445
446   return TizenSuccess();
447 }
448
449 TizenResult IotconUtils::RemoteResourceToJson(iotcon_remote_resource_h handle,
450                                               picojson::object* res) {
451   ScopeLogger();
452
453   RemoteResourceInfo remote_res;
454   remote_res.resource = handle;
455   auto result = ExtractFromRemoteResource(&remote_res);
456   if (!result) {
457     return result;
458   }
459   res->insert(std::make_pair(kUriPath, picojson::value(remote_res.uri_path)));
460   res->insert(std::make_pair(kConnectivityType,
461                              picojson::value(FromConnectivityType(remote_res.connectivity_type))));
462   res->insert(std::make_pair(kHostAddress, picojson::value(remote_res.host_address)));
463   res->insert(std::make_pair(kDeviceId, picojson::value(remote_res.device_id)));
464   res->insert(std::make_pair(kDeviceName, picojson::value(remote_res.device_name)));
465
466   if (remote_res.types) {
467     picojson::array types;
468     iotcon_resource_types_foreach(remote_res.types, ResourceTypeIterator, &types);
469     res->insert(std::make_pair(kResourceTypes, picojson::value(types)));
470   }
471
472   if (remote_res.ifaces) {
473     picojson::array interfaces;
474     result = InterfacesToArray(remote_res.ifaces, &interfaces);
475     if (!result) {
476       LogAndReturnTizenError(result, ("InterfacesToArray() failed"));
477     }
478     res->insert(std::make_pair(kResourceInterfaces, picojson::value(interfaces)));
479   }
480
481   IotconUtils::PropertiesToJson(remote_res.properties, res);
482
483   if (remote_res.representation) {
484     picojson::value repr_json{picojson::object{}};
485     result = RepresentationToJson(remote_res.representation, &repr_json.get<picojson::object>());
486     if (!result) {
487       LogAndReturnTizenError(result, ("RepresentationToJson() failed"));
488     }
489     res->insert(std::make_pair(kRepresentation, repr_json));
490   }
491
492   if (remote_res.options) {
493     picojson::array options;
494     result = OptionsToJson(remote_res.options, &options);
495     if (!result) {
496       LogAndReturnTizenError(result, ("OptionsToJson() failed"));
497     }
498     res->insert(std::make_pair(kOptions, picojson::value(options)));
499   }
500
501   return TizenSuccess();
502 }
503
504 common::TizenResult IotconUtils::RemoteResourceFromJson(const picojson::object& source,
505                                                         FoundRemoteInfoPtr* ptr) {
506   ScopeLogger();
507   // checking if resource has id
508   long long id = 0;
509   if (source.find(kId)->second.is<double>()) {
510     id = static_cast<long long>(source.find(kId)->second.get<double>());
511   }
512   if (id > 0) {
513     LoggerD("Resource stored, getting it from IotconClientManager");
514     return IotconClientManager::GetInstance().GetRemoteById(id, ptr);
515   } else {
516     LoggerD("Id is not defined, creating handle using resource info");
517   }
518
519   (*ptr).reset(new FoundRemoteInfo{});
520   CHECK_EXIST(source, kHostAddress);
521   char* host_address = nullptr;
522   if (source.find(kHostAddress)->second.is<std::string>()) {
523     host_address = const_cast<char*>(source.find(kHostAddress)->second.get<std::string>().c_str());
524   }
525
526   CHECK_EXIST(source, kConnectivityType);
527   iotcon_connectivity_type_e connectivity_type =
528       IotconUtils::ToConnectivityType(source.find(kConnectivityType)->second.get<std::string>());
529
530   CHECK_EXIST(source, kUriPath);
531   char* uri_path = nullptr;
532   if (source.find(kUriPath)->second.is<std::string>()) {
533     uri_path = const_cast<char*>(source.find(kUriPath)->second.get<std::string>().c_str());
534   }
535
536   int properties = IotconUtils::GetProperties(source);
537
538   CHECK_EXIST(source, kResourceTypes);
539   const auto& types_array = source.find(kResourceTypes)->second.get<picojson::array>();
540   iotcon_resource_types_h resource_types = nullptr;
541   auto res = IotconUtils::ArrayToTypes(types_array, &resource_types);
542   if (!res) {
543     return res;
544   }
545   SCOPE_EXIT {
546     iotcon_resource_types_destroy(resource_types);
547   };
548
549   CHECK_EXIST(source, kResourceInterfaces);
550   const auto& interfaces_array = source.find(kResourceInterfaces)->second.get<picojson::array>();
551   iotcon_resource_interfaces_h interfaces = nullptr;
552   res = IotconUtils::ArrayToInterfaces(interfaces_array, &interfaces);
553   if (!res) {
554     return res;
555   }
556   SCOPE_EXIT {
557     iotcon_resource_interfaces_destroy(interfaces);
558   };
559
560   res = IotconUtils::ConvertIotconError(
561       iotcon_remote_resource_create(host_address, connectivity_type, uri_path, properties,
562                                     resource_types, interfaces, &((*ptr)->handle)));
563   if (!res) {
564     LogAndReturnTizenError(res, ("creating handle failed"));
565   }
566
567   // options is optional nullable. if it's not present or is null, just ignore it
568   auto options_it = source.find(kOptions);
569   if (source.end() != options_it) {
570     iotcon_options_h options = nullptr;
571     // if array supplied, set it. Other cases just clear options with nullptr
572     if (options_it->second.is<picojson::array>()) {
573       const auto& options_array = options_it->second.get<picojson::array>();
574       res = IotconUtils::OptionsFromJson(options_array, &options);
575       if (!res) {
576         return res;
577       }
578     }
579     res = IotconUtils::ConvertIotconError(
580         iotcon_remote_resource_set_options((*ptr)->handle, options));
581     if (!res) {
582       LogAndReturnTizenError(res, ("iotcon_response_set_options() failed"));
583     }
584   }
585
586   return TizenSuccess();
587 }
588
589 common::TizenResult IotconUtils::RequestToJson(iotcon_request_h request, picojson::object* out) {
590   ScopeLogger();
591
592   if (request) {
593     {
594       // hostAddress
595       char* host_address = nullptr;
596       auto result = ConvertIotconError(iotcon_request_get_host_address(request, &host_address));
597       if (!result || !host_address) {
598         LogAndReturnTizenError(result, ("iotcon_request_get_host_address() failed"));
599       }
600       out->insert(std::make_pair(kHostAddress, picojson::value{host_address}));
601     }
602
603     {
604       // connectivityType
605       iotcon_connectivity_type_e connectivity_type;
606       auto result =
607           ConvertIotconError(iotcon_request_get_connectivity_type(request, &connectivity_type));
608       if (!result) {
609         LogAndReturnTizenError(result, ("iotcon_request_get_connectivity_type() failed"));
610       }
611       out->insert(std::make_pair(kConnectivityType,
612                                  picojson::value{FromConnectivityType(connectivity_type)}));
613     }
614
615     {
616       // representation
617       iotcon_representation_h representation = nullptr;
618       auto result = ConvertIotconError(iotcon_request_get_representation(request, &representation));
619       if (!result) {
620         LogAndReturnTizenError(result, ("iotcon_request_get_representation() failed"));
621       }
622       if (representation) {
623         picojson::value v{picojson::object{}};
624         result = RepresentationToJson(representation, &v.get<picojson::object>());
625         if (!result) {
626           LogAndReturnTizenError(result, ("RepresentationToJson() failed"));
627         }
628         out->insert(std::make_pair(kRepresentation, v));
629       } else {
630         LoggerD("Request doesn't have representation.");
631       }
632     }
633
634     {
635       // options
636       iotcon_options_h options = nullptr;
637       auto result = ConvertIotconError(iotcon_request_get_options(request, &options));
638       if (!result) {
639         LogAndReturnTizenError(result, ("iotcon_request_get_options() failed"));
640       }
641       picojson::value v{picojson::array{}};
642       result = OptionsToJson(options, &v.get<picojson::array>());
643       if (!result) {
644         LogAndReturnTizenError(result, ("OptionsToJson() failed"));
645       }
646       out->insert(std::make_pair(kOptions, v));
647     }
648
649     {
650       // query
651       iotcon_query_h query = nullptr;
652       auto result = ConvertIotconError(iotcon_request_get_query(request, &query));
653       if (!result) {
654         LogAndReturnTizenError(result, ("iotcon_request_get_query() failed"));
655       }
656       picojson::value v{picojson::object{}};
657       result = QueryToJson(query, &v.get<picojson::object>());
658       if (!result) {
659         LogAndReturnTizenError(result, ("QueryToJson() failed"));
660       }
661       out->insert(std::make_pair(kQuery, v));
662     }
663   } else {
664     LoggerW("Request handle is null, ignoring");
665   }
666   return TizenSuccess();
667 }
668
669 common::TizenResult IotconUtils::RepresentationToJson(iotcon_representation_h representation,
670                                                       picojson::object* out) {
671   ScopeLogger();
672
673   if (representation) {
674     {
675       // uriPath
676       char* uri_path = nullptr;
677       auto result =
678           ConvertIotconError(iotcon_representation_get_uri_path(representation, &uri_path));
679       if (!result || !uri_path) {
680         LogAndReturnTizenError(result, ("iotcon_representation_get_uri_path() failed"));
681       }
682       out->insert(std::make_pair(kUriPath, picojson::value{uri_path}));
683     }
684
685     {
686       // resourceTypes
687       iotcon_resource_types_h resource_types = nullptr;
688       auto result = ConvertIotconError(
689           iotcon_representation_get_resource_types(representation, &resource_types));
690       if (!result) {
691         LogAndReturnTizenError(result, ("iotcon_representation_get_resource_types() failed"));
692       }
693       picojson::value v{picojson::array{}};
694       iotcon_resource_types_foreach(resource_types, ResourceTypeIterator,
695                                     &v.get<picojson::array>());
696       out->insert(std::make_pair(kResourceTypes, v));
697     }
698
699     {
700       // resourceInterfaces
701       iotcon_resource_interfaces_h interfaces = nullptr;
702       auto result = ConvertIotconError(
703           iotcon_representation_get_resource_interfaces(representation, &interfaces));
704       if (!result) {
705         LogAndReturnTizenError(result, ("iotcon_representation_get_resource_interfaces() failed"));
706       }
707       picojson::array js_interfaces;
708       result = InterfacesToArray(interfaces, &js_interfaces);
709       if (!result) {
710         LogAndReturnTizenError(result, ("InterfacesToArray() failed"));
711       }
712       out->insert(std::make_pair(kResourceInterfaces, picojson::value{js_interfaces}));
713     }
714
715     {
716       // attributes
717       iotcon_attributes_h attributes = nullptr;
718       auto result =
719           ConvertIotconError(iotcon_representation_get_attributes(representation, &attributes));
720       if (!result) {
721         LogAndReturnTizenError(result, ("iotcon_representation_get_attributes() failed"));
722       }
723       picojson::value v{picojson::object{}};
724       result = AttributesToJson(attributes, &v.get<picojson::object>());
725       if (!result) {
726         LogAndReturnTizenError(result, ("AttributesToJson() failed"));
727       }
728       out->insert(std::make_pair(kAttributes, v));
729     }
730
731     {
732       // children
733       picojson::value v{picojson::array{}};
734       auto result = ConvertIotconError(iotcon_representation_foreach_children(
735           representation,
736           [](iotcon_representation_h child, void* user_data) -> bool {
737             ScopeLogger(
738                 "Entered into asynchronous function, iotcon_representation_foreach_children's "
739                 "argument");
740             auto arr = static_cast<picojson::array*>(user_data);
741             arr->push_back(picojson::value{picojson::object{}});
742             auto result = RepresentationToJson(child, &arr->back().get<picojson::object>());
743             if (!result) {
744               LoggerE("Failed to convert child representation");
745             }
746             // always continue with iteration
747             return true;
748           },
749           &v.get<picojson::array>()));
750       if (!result) {
751         LogAndReturnTizenError(result, ("iotcon_representation_foreach_children() failed"));
752       }
753       out->insert(std::make_pair(kChildren, v));
754     }
755   } else {
756     LoggerW("Representation handle is null, ignoring");
757   }
758
759   return TizenSuccess();
760 }
761
762 common::TizenResult IotconUtils::AttributesToJson(iotcon_attributes_h attributes,
763                                                   picojson::object* out) {
764   ScopeLogger();
765
766   if (attributes) {
767     auto result = ConvertIotconError(iotcon_attributes_foreach(
768         attributes,
769         [](iotcon_attributes_h attributes, const char* key, void* user_data) -> bool {
770           ScopeLogger("Entered into asynchronous function, iotcon_attributes_foreach's argument");
771           iotcon_type_e type = IOTCON_TYPE_NONE;
772           auto result = ConvertIotconError(iotcon_attributes_get_type(attributes, key, &type));
773
774           if (result) {
775             auto out = static_cast<picojson::object*>(user_data);
776
777             switch (type) {
778               case IOTCON_TYPE_NONE:
779                 LoggerE("Key %s has type NONE", key);
780                 break;
781
782               case IOTCON_TYPE_INT: {
783                 int value = 0;
784                 result = ConvertIotconError(iotcon_attributes_get_int(attributes, key, &value));
785                 if (result) {
786                   out->insert(std::make_pair(key, picojson::value{static_cast<double>(value)}));
787                 } else {
788                   LoggerE("iotcon_attributes_get_int() failed");
789                 }
790               } break;
791
792               case IOTCON_TYPE_BOOL: {
793                 bool value = false;
794                 result = ConvertIotconError(iotcon_attributes_get_bool(attributes, key, &value));
795                 if (result) {
796                   out->insert(std::make_pair(key, picojson::value{value}));
797                 } else {
798                   LoggerE("iotcon_attributes_get_bool() failed");
799                 }
800               } break;
801
802               case IOTCON_TYPE_DOUBLE: {
803                 double value = 0.0;
804                 result = ConvertIotconError(iotcon_attributes_get_double(attributes, key, &value));
805                 if (result) {
806                   out->insert(std::make_pair(key, picojson::value{value}));
807                 } else {
808                   LoggerE("iotcon_attributes_get_double() failed");
809                 }
810               } break;
811
812               case IOTCON_TYPE_STR: {
813                 char* value = nullptr;
814                 result = ConvertIotconError(iotcon_attributes_get_str(attributes, key, &value));
815                 if (result && value) {
816                   out->insert(std::make_pair(key, picojson::value{value}));
817                 } else {
818                   LoggerE("iotcon_attributes_get_str() failed");
819                 }
820               } break;
821
822               case IOTCON_TYPE_BYTE_STR: {
823                 unsigned char* value = nullptr;
824                 int length = 0;
825                 result = ConvertIotconError(
826                     iotcon_attributes_get_byte_str(attributes, key, &value, &length));
827
828                 if (result && length) {
829                   std::unique_ptr<char[]> data{new char[2 * length]};
830                   common::tools::BinToHex(value, length, data.get(), 2 * length);
831                   out->insert(std::make_pair(key, picojson::value{kHexPrefix + data.get()}));
832                 } else {
833                   LoggerE("iotcon_attributes_get_byte_str() failed");
834                 }
835               } break;
836
837               case IOTCON_TYPE_NULL:
838                 out->insert(std::make_pair(key, picojson::value{}));
839                 break;
840
841               case IOTCON_TYPE_LIST: {
842                 iotcon_list_h list = nullptr;
843                 result = ConvertIotconError(iotcon_attributes_get_list(attributes, key, &list));
844                 if (result) {
845                   picojson::value value{picojson::array{}};
846
847                   result = StateListToJson(list, &value.get<picojson::array>());
848                   if (result) {
849                     out->insert(std::make_pair(key, picojson::value{value}));
850                   } else {
851                     LoggerE("StateListToJson() failed");
852                   }
853                 } else {
854                   LoggerE("iotcon_attributes_get_list() failed");
855                 }
856               } break;
857
858               case IOTCON_TYPE_ATTRIBUTES: {
859                 iotcon_attributes_h child = nullptr;
860                 result =
861                     ConvertIotconError(iotcon_attributes_get_attributes(attributes, key, &child));
862                 if (result) {
863                   picojson::value value{picojson::object{}};
864
865                   result = AttributesToJson(child, &value.get<picojson::object>());
866                   if (result) {
867                     out->insert(std::make_pair(key, picojson::value{value}));
868                   } else {
869                     LoggerE("AttributesToJson() failed");
870                   }
871                 } else {
872                   LoggerE("iotcon_attributes_get_attributes() failed");
873                 }
874               } break;
875             }
876           } else {
877             LoggerE("iotcon_attributes_get_type() failed");
878           }
879
880           // always continue with iteration
881           return true;
882         },
883         out));
884
885     if (!result) {
886       LogAndReturnTizenError(result, ("iotcon_attributes_foreach() failed"));
887     }
888   } else {
889     LoggerW("attributes handle is null, ignoring");
890   }
891
892   return TizenSuccess();
893 }
894
895 common::TizenResult IotconUtils::StateListToJson(iotcon_list_h list, picojson::array* out) {
896   ScopeLogger();
897
898   if (list) {
899     iotcon_type_e type = IOTCON_TYPE_NONE;
900     auto result = ConvertIotconError(iotcon_list_get_type(list, &type));
901
902     if (!result) {
903       LogAndReturnTizenError(result, ("iotcon_list_get_type() failed"));
904     }
905
906     switch (type) {
907       case IOTCON_TYPE_NONE:
908         LoggerE("List has type NONE");
909         break;
910
911       case IOTCON_TYPE_INT:
912         result = ConvertIotconError(iotcon_list_foreach_int(
913             list,
914             [](int, int value, void* user_data) -> bool {
915               ScopeLogger("Entered into asynchronous function, iotcon_list_foreach_int's argument");
916               auto out = static_cast<picojson::array*>(user_data);
917               out->push_back(picojson::value{static_cast<double>(value)});
918               // always continue with iteration
919               return true;
920             },
921             out));
922         if (!result) {
923           LogAndReturnTizenError(result, ("iotcon_list_foreach_int() failed"));
924         }
925         break;
926
927       case IOTCON_TYPE_BOOL:
928         result = ConvertIotconError(iotcon_list_foreach_bool(
929             list,
930             [](int, bool value, void* user_data) -> bool {
931               ScopeLogger(
932                   "Entered into asynchronous function, iotcon_list_foreach_bool's argument");
933               auto out = static_cast<picojson::array*>(user_data);
934               out->push_back(picojson::value{value});
935               // always continue with iteration
936               return true;
937             },
938             out));
939         if (!result) {
940           LogAndReturnTizenError(result, ("iotcon_list_foreach_bool() failed"));
941         }
942         break;
943
944       case IOTCON_TYPE_DOUBLE:
945         result = ConvertIotconError(iotcon_list_foreach_double(
946             list,
947             [](int, double value, void* user_data) -> bool {
948               ScopeLogger(
949                   "Entered into asynchronous function, iotcon_list_foreach_double's argument");
950               auto out = static_cast<picojson::array*>(user_data);
951               out->push_back(picojson::value{value});
952               // always continue with iteration
953               return true;
954             },
955             out));
956         if (!result) {
957           LogAndReturnTizenError(result, ("iotcon_list_foreach_double() failed"));
958         }
959         break;
960
961       case IOTCON_TYPE_STR:
962         result = ConvertIotconError(iotcon_list_foreach_str(
963             list,
964             [](int, const char* value, void* user_data) -> bool {
965               if (value) {
966                 ScopeLogger(
967                     "Entered into asynchronous function, iotcon_list_foreach_str's argument");
968                 auto out = static_cast<picojson::array*>(user_data);
969                 out->push_back(picojson::value{value});
970               }
971               // always continue with iteration
972               return true;
973             },
974             out));
975         if (!result) {
976           LogAndReturnTizenError(result, ("iotcon_list_foreach_str() failed"));
977         }
978         break;
979
980       case IOTCON_TYPE_BYTE_STR:
981         result = ConvertIotconError(iotcon_list_foreach_byte_str(
982             list,
983             [](int, const unsigned char* value, int length, void* user_data) -> bool {
984               ScopeLogger(
985                   "Entered into asynchronous function, iotcon_list_foreach_byte_str's argument");
986               if (length) {
987                 std::unique_ptr<char[]> data{new char[2 * length]};
988                 common::tools::BinToHex(value, length, data.get(), 2 * length);
989
990                 auto out = static_cast<picojson::array*>(user_data);
991                 out->push_back(picojson::value{kHexPrefix + data.get()});
992               }
993               // always continue with iteration
994               return true;
995             },
996             out));
997         if (!result) {
998           LogAndReturnTizenError(result, ("iotcon_list_foreach_str() failed"));
999         }
1000         break;
1001
1002       case IOTCON_TYPE_NULL:
1003         LoggerE("List has type NULL");
1004         break;
1005
1006       case IOTCON_TYPE_LIST:
1007         result = ConvertIotconError(iotcon_list_foreach_list(
1008             list,
1009             [](int, iotcon_list_h list, void* user_data) -> bool {
1010               ScopeLogger(
1011                   "Entered into asynchronous function, iotcon_list_foreach_list's argument");
1012               picojson::value value{picojson::array{}};
1013               auto result = StateListToJson(list, &value.get<picojson::array>());
1014               if (result) {
1015                 auto out = static_cast<picojson::array*>(user_data);
1016                 out->push_back(picojson::value{value});
1017               } else {
1018                 LoggerE("StateListToJson() failed");
1019               }
1020               // always continue with iteration
1021               return true;
1022             },
1023             out));
1024         if (!result) {
1025           LogAndReturnTizenError(result, ("iotcon_list_foreach_list() failed"));
1026         }
1027         break;
1028
1029       case IOTCON_TYPE_ATTRIBUTES:
1030         result = ConvertIotconError(iotcon_list_foreach_attributes(
1031             list,
1032             [](int, iotcon_attributes_h attributes, void* user_data) -> bool {
1033               ScopeLogger(
1034                   "Entered into asynchronous function, iotcon_list_foreach_attributes' argument");
1035               picojson::value value{picojson::object{}};
1036               auto result = AttributesToJson(attributes, &value.get<picojson::object>());
1037               if (result) {
1038                 auto out = static_cast<picojson::array*>(user_data);
1039                 out->push_back(picojson::value{value});
1040               } else {
1041                 LoggerE("AttributesToJson() failed");
1042               }
1043               // always continue with iteration
1044               return true;
1045             },
1046             out));
1047         if (!result) {
1048           LogAndReturnTizenError(result, ("iotcon_list_foreach_attributes() failed"));
1049         }
1050         break;
1051     }
1052   } else {
1053     LoggerW("List handle is null, ignoring");
1054   }
1055
1056   return TizenSuccess();
1057 }
1058
1059 common::TizenResult IotconUtils::OptionsToJson(iotcon_options_h options, picojson::array* out) {
1060   ScopeLogger();
1061
1062   if (options) {
1063     auto result = ConvertIotconError(iotcon_options_foreach(
1064         options,
1065         [](unsigned short id, const char* data, void* user_data) -> bool {
1066           ScopeLogger("Entered into asynchronous function, iotcon_options_foreach's argument");
1067           if (data) {
1068             picojson::value v{picojson::object{}};
1069             auto& obj = v.get<picojson::object>();
1070
1071             obj.insert(std::make_pair(kOptionsId, picojson::value{static_cast<double>(id)}));
1072             obj.insert(std::make_pair(kOptionsData, picojson::value{data}));
1073
1074             auto out = static_cast<picojson::array*>(user_data);
1075             out->push_back(v);
1076           }
1077           // always continue with iteration
1078           return true;
1079         },
1080         out));
1081
1082     if (!result) {
1083       LogAndReturnTizenError(result, ("iotcon_options_foreach() failed"));
1084     }
1085   } else {
1086     LoggerW("Options handle is null, ignoring");
1087   }
1088
1089   return TizenSuccess();
1090 }
1091
1092 common::TizenResult IotconUtils::QueryToJson(iotcon_query_h query, picojson::object* out) {
1093   ScopeLogger();
1094
1095   if (query) {
1096     {
1097       // resourceType
1098       char* resource_type = nullptr;
1099       auto result = ConvertIotconError(iotcon_query_get_resource_type(query, &resource_type));
1100       if (!result || !resource_type) {
1101         LogAndReturnTizenError(result, ("iotcon_query_get_resource_type() failed"));
1102       }
1103       out->insert(std::make_pair(kResourceType, picojson::value{resource_type}));
1104     }
1105
1106     {
1107       // resourceInterface
1108       char* interface = nullptr;
1109       int err_code = iotcon_query_get_interface(query, &interface);
1110       if (IOTCON_ERROR_NONE != err_code) {
1111         // if no interface is set to query we continue execution to set other values
1112         LoggerW("iotcon_query_get_interface() failed: %d, ignoring resource interface in query",
1113                 err_code);
1114       } else {
1115         out->insert(std::make_pair(kResourceInterface, picojson::value{interface}));
1116       }
1117     }
1118
1119     {
1120       // filter
1121       picojson::value v{picojson::object{}};
1122       auto result = ConvertIotconError(iotcon_query_foreach(
1123           query,
1124           [](const char* key, const char* value, void* user_data) -> bool {
1125             ScopeLogger("Entered into asynchronous function, iotcon_query_foreach's argument");
1126             if (key && value) {
1127               auto obj = static_cast<picojson::object*>(user_data);
1128               obj->insert(std::make_pair(key, picojson::value{value}));
1129             }
1130             // always continue with iteration
1131             return true;
1132           },
1133           &v.get<picojson::object>()));
1134       if (!result) {
1135         LogAndReturnTizenError(result, ("iotcon_query_foreach() failed"));
1136       }
1137       out->insert(std::make_pair(kFilter, v));
1138     }
1139   } else {
1140     LoggerW("Query handle is null, ignoring");
1141   }
1142   return TizenSuccess();
1143 }
1144
1145 common::TizenResult IotconUtils::QueryFromJson(const picojson::object& source,
1146                                                iotcon_query_h* res) {
1147   ScopeLogger();
1148   iotcon_query_h query = nullptr;
1149   auto result = ConvertIotconError(iotcon_query_create(&query));
1150   if (!result) {
1151     LogAndReturnTizenError(result, ("iotcon_query_create() failed"));
1152   }
1153   std::unique_ptr<std::remove_pointer<iotcon_query_h>::type, int (*)(iotcon_query_h)> query_ptr(
1154       query, &iotcon_query_destroy);  // automatically release the memory
1155   {
1156     // resourceType
1157     auto it = source.find(kResourceType);
1158     if (source.end() != it && it->second.is<std::string>()) {
1159       const char* resource_type = it->second.get<std::string>().c_str();
1160       auto result = ConvertIotconError(iotcon_query_set_resource_type(query, resource_type));
1161       if (!result) {
1162         LogAndReturnTizenError(result, ("iotcon_query_set_resource_type() failed"));
1163       }
1164     }
1165   }
1166
1167   {
1168     // resourceInterface
1169     auto it = source.find(kResourceInterface);
1170     if (source.end() != it && it->second.is<std::string>()) {
1171       auto& interface = it->second.get<std::string>();
1172       auto result = ConvertIotconError(iotcon_query_set_interface(query, interface.c_str()));
1173       if (!result) {
1174         LogAndReturnTizenError(result, ("iotcon_query_set_interface() failed"));
1175       }
1176     }
1177   }
1178
1179   {
1180     // filter
1181     auto it = source.find(kFilter);
1182     if (source.end() != it) {
1183       const auto& filter = IotconUtils::GetArg(source, kFilter);
1184       if (filter.is<picojson::object>()) {
1185         const auto& filter_obj = filter.get<picojson::object>();
1186         for (const auto& it : filter_obj) {
1187           if (it.second.is<std::string>()) {
1188             const std::string& key = it.first;
1189             const std::string& value = it.second.get<std::string>();
1190             LoggerD("key: %s  ----  value: %s", key.c_str(), value.c_str());
1191
1192             auto result = ConvertIotconError(iotcon_query_add(query, key.c_str(), value.c_str()));
1193             if (!result) {
1194               LogAndReturnTizenError(result, ("iotcon_query_add() failed"));
1195             }
1196           }
1197         }
1198       }
1199     }
1200   }
1201
1202   *res = query_ptr.release();
1203   return TizenSuccess();
1204 }
1205
1206 common::TizenResult IotconUtils::ResponseToJson(iotcon_response_h handle, picojson::object* res) {
1207   ScopeLogger();
1208
1209   if (handle) {
1210     {
1211       // ResponseResult result
1212       iotcon_response_result_e response = IOTCON_RESPONSE_ERROR;
1213       auto result = ConvertIotconError(iotcon_response_get_result(handle, &response));
1214       if (!result) {
1215         LogAndReturnTizenError(result, ("iotcon_response_get_result() failed"));
1216       }
1217       std::string result_str = FromResponseResultType(response);
1218       res->insert(std::make_pair(kResult, picojson::value{result_str}));
1219     }
1220
1221     {
1222       // Representation representation
1223       iotcon_representation_h repr = nullptr;
1224       auto result = ConvertIotconError(iotcon_response_get_representation(handle, &repr));
1225       if (!result) {
1226         LogAndReturnTizenError(result, ("iotcon_response_get_representation() failed"));
1227       }
1228       picojson::value repr_json{picojson::object{}};
1229       result = RepresentationToJson(repr, &repr_json.get<picojson::object>());
1230       if (!result) {
1231         LogAndReturnTizenError(result, ("RepresentationToJson() failed"));
1232       }
1233       res->insert(std::make_pair(kRepresentation, repr_json));
1234     }
1235
1236     {
1237       // IotconOption[]? options
1238       iotcon_options_h options = nullptr;
1239       int native_ret = iotcon_response_get_options(handle, &options);
1240       auto result = ConvertIotconError(native_ret);
1241       if (!result && IOTCON_ERROR_NO_DATA != native_ret) {
1242         LogAndReturnTizenError(result, ("iotcon_response_get_options() failed"));
1243       }
1244       if (options) {
1245         picojson::value opt_json{picojson::array{}};
1246         result = OptionsToJson(options, &opt_json.get<picojson::array>());
1247         if (!result) {
1248           LogAndReturnTizenError(result, ("OptionsToJson() failed"));
1249         }
1250         res->insert(std::make_pair(kOptions, opt_json));
1251       } else {
1252         res->insert(std::make_pair(kOptions, picojson::value{}));
1253       }
1254     }
1255   } else {
1256     LoggerW("Response handle is null, ignoring");
1257   }
1258
1259   return TizenSuccess();
1260 }
1261
1262 common::TizenResult IotconUtils::RepresentationFromResource(const ResourceInfoPtr& resource,
1263                                                             const picojson::value& states,
1264                                                             iotcon_representation_h* out) {
1265   ScopeLogger();
1266
1267   iotcon_representation_h representation = nullptr;
1268
1269   auto result = IotconUtils::ConvertIotconError(iotcon_representation_create(&representation));
1270   if (!result) {
1271     LogAndReturnTizenError(result, ("iotcon_representation_create() failed"));
1272   }
1273
1274   std::unique_ptr<std::remove_pointer<iotcon_representation_h>::type,
1275                   int (*)(iotcon_representation_h)>
1276       ptr{representation, &iotcon_representation_destroy};
1277
1278   {
1279     char* uri_path = nullptr;
1280     result =
1281         IotconUtils::ConvertIotconError(iotcon_resource_get_uri_path(resource->handle, &uri_path));
1282     if (!result) {
1283       LogAndReturnTizenError(result, ("iotcon_resource_get_uri_path() failed"));
1284     }
1285     result = IotconUtils::ConvertIotconError(
1286         iotcon_representation_set_uri_path(representation, uri_path));
1287     if (!result) {
1288       LogAndReturnTizenError(result, ("iotcon_representation_set_uri_path() failed"));
1289     }
1290   }
1291
1292   {
1293     iotcon_resource_types_h types = nullptr;
1294     result = IotconUtils::ConvertIotconError(iotcon_resource_get_types(resource->handle, &types));
1295     if (!result) {
1296       LogAndReturnTizenError(result, ("iotcon_resource_get_types() failed"));
1297     }
1298     result = IotconUtils::ConvertIotconError(
1299         iotcon_representation_set_resource_types(representation, types));
1300     if (!result) {
1301       LogAndReturnTizenError(result, ("iotcon_representation_set_resource_types() failed"));
1302     }
1303   }
1304
1305   {
1306     iotcon_resource_interfaces_h intrefaces = nullptr;
1307     result = IotconUtils::ConvertIotconError(
1308         iotcon_resource_get_interfaces(resource->handle, &intrefaces));
1309     if (!result) {
1310       LogAndReturnTizenError(result, ("iotcon_resource_get_interfaces() failed"));
1311     }
1312     result = IotconUtils::ConvertIotconError(
1313         iotcon_representation_set_resource_interfaces(representation, intrefaces));
1314     if (!result) {
1315       LogAndReturnTizenError(result, ("iotcon_representation_set_resource_interfaces() failed"));
1316     }
1317   }
1318
1319   {
1320     auto& state = states.get(std::to_string(resource->id));
1321     if (state.is<picojson::object>()) {
1322       iotcon_attributes_h attributes_handle = nullptr;
1323       result = IotconUtils::AttributesFromJson(state.get<picojson::object>(), &attributes_handle);
1324       if (!result) {
1325         LogAndReturnTizenError(result, ("AttributesFromJson() failed"));
1326       }
1327       SCOPE_EXIT {
1328         iotcon_attributes_destroy(attributes_handle);
1329       };
1330       result = IotconUtils::ConvertIotconError(
1331           iotcon_representation_set_attributes(representation, attributes_handle));
1332       if (!result) {
1333         LogAndReturnTizenError(result, ("iotcon_representation_set_attributes() failed"));
1334       }
1335     }
1336   }
1337
1338   {
1339     unsigned int children = 0;
1340     result = IotconUtils::ConvertIotconError(
1341         iotcon_resource_get_child_count(resource->handle, &children));
1342     if (!result) {
1343       LogAndReturnTizenError(result, ("iotcon_resource_get_child_count() failed"));
1344     }
1345
1346     for (unsigned int i = 0; i < children; ++i) {
1347       iotcon_resource_h child = nullptr;
1348       result = IotconUtils::ConvertIotconError(
1349           iotcon_resource_get_nth_child(resource->handle, i, &child));
1350       if (!result) {
1351         LogAndReturnTizenError(result, ("iotcon_resource_get_nth_child() failed"));
1352       }
1353
1354       ResourceInfoPtr child_resource;
1355       result = IotconServerManager::GetInstance().GetResourceByHandle(child, &child_resource);
1356       if (!result) {
1357         LogAndReturnTizenError(result, ("GetResourceByHandle() failed"));
1358       }
1359
1360       iotcon_representation_h child_representation = nullptr;
1361       result = RepresentationFromResource(child_resource, states, &child_representation);
1362       if (!result) {
1363         LogAndReturnTizenError(result, ("RepresentationFromResource() failed"));
1364       }
1365       SCOPE_EXIT {
1366         iotcon_representation_destroy(child_representation);
1367       };
1368       result = IotconUtils::ConvertIotconError(
1369           iotcon_representation_add_child(representation, child_representation));
1370       if (!result) {
1371         LogAndReturnTizenError(result, ("iotcon_representation_add_child() failed"));
1372       }
1373     }
1374   }
1375
1376   *out = ptr.release();
1377   return TizenSuccess();
1378 }
1379
1380 common::TizenResult IotconUtils::AttributesFromJson(const picojson::object& s,
1381                                                     iotcon_attributes_h* out) {
1382   ScopeLogger();
1383
1384   iotcon_attributes_h attributes = nullptr;
1385
1386   auto result = IotconUtils::ConvertIotconError(iotcon_attributes_create(&attributes));
1387   if (!result) {
1388     LogAndReturnTizenError(result, ("iotcon_attributes_create() failed"));
1389   }
1390
1391   std::unique_ptr<std::remove_pointer<iotcon_attributes_h>::type, int (*)(iotcon_attributes_h)> ptr{
1392       attributes, &iotcon_attributes_destroy};
1393
1394   for (const auto& property : s) {
1395     const auto& key = property.first;
1396
1397     if (property.second.is<picojson::null>()) {
1398       result = IotconUtils::ConvertIotconError(iotcon_attributes_add_null(attributes, key.c_str()));
1399       if (!result) {
1400         LogAndReturnTizenError(result, ("iotcon_attributes_add_null() failed"));
1401       }
1402     } else if (property.second.is<bool>()) {
1403       result = IotconUtils::ConvertIotconError(
1404           iotcon_attributes_add_bool(attributes, key.c_str(), property.second.get<bool>()));
1405       if (!result) {
1406         LogAndReturnTizenError(result, ("iotcon_attributes_add_bool() failed"));
1407       }
1408     } else if (property.second.is<double>()) {
1409       result = IotconUtils::ConvertIotconError(
1410           iotcon_attributes_add_double(attributes, key.c_str(), property.second.get<double>()));
1411       if (!result) {
1412         LogAndReturnTizenError(result, ("iotcon_attributes_attributes_double() failed"));
1413       }
1414     } else if (property.second.is<std::string>()) {
1415       const auto& value = property.second.get<std::string>();
1416
1417       if (0 == value.find(kHexPrefix)) {
1418         auto data = value.c_str() + kHexPrefix.length();  // skip prefix
1419         auto size = value.length() - kHexPrefix.length();
1420         auto length = size / 2;
1421         std::unique_ptr<unsigned char[]> hex{new unsigned char[length]};
1422         common::tools::HexToBin(data, size, hex.get(), length);
1423         result = IotconUtils::ConvertIotconError(
1424             iotcon_attributes_add_byte_str(attributes, key.c_str(), hex.get(), length));
1425         if (!result) {
1426           LogAndReturnTizenError(result, ("iotcon_attributes_add_byte_str() failed"));
1427         }
1428       } else {
1429         result = IotconUtils::ConvertIotconError(
1430             iotcon_attributes_add_str(attributes, key.c_str(), const_cast<char*>(value.c_str())));
1431         if (!result) {
1432           LogAndReturnTizenError(result, ("iotcon_attributes_add_str() failed"));
1433         }
1434       }
1435     } else if (property.second.is<picojson::array>()) {
1436       iotcon_list_h list = nullptr;
1437       result = StateListFromJson(property.second.get<picojson::array>(), &list);
1438       if (!result) {
1439         LogAndReturnTizenError(result, ("StateListFromJson() failed"));
1440       }
1441       if (list) {
1442         SCOPE_EXIT {
1443           iotcon_list_destroy(list);
1444         };
1445         result = IotconUtils::ConvertIotconError(
1446             iotcon_attributes_add_list(attributes, key.c_str(), list));
1447         if (!result) {
1448           LogAndReturnTizenError(result, ("iotcon_attributes_add_list() failed"));
1449         }
1450       }
1451     } else if (property.second.is<picojson::object>()) {
1452       iotcon_attributes_h sub_attributes = nullptr;
1453       result = AttributesFromJson(property.second.get<picojson::object>(), &sub_attributes);
1454       if (!result) {
1455         LogAndReturnTizenError(result, ("AttributesFromJson() failed"));
1456       }
1457       SCOPE_EXIT {
1458         iotcon_attributes_destroy(sub_attributes);
1459       };
1460       result = IotconUtils::ConvertIotconError(
1461           iotcon_attributes_add_attributes(attributes, key.c_str(), sub_attributes));
1462       if (!result) {
1463         LogAndReturnTizenError(result, ("iotcon_attributes_add_attributes() failed"));
1464       }
1465     }
1466   }
1467
1468   *out = ptr.release();
1469   return TizenSuccess();
1470 }
1471
1472 common::TizenResult IotconUtils::StateListFromJson(const picojson::array& l, iotcon_list_h* out) {
1473   ScopeLogger();
1474
1475   iotcon_list_h list = nullptr;
1476   iotcon_type_e type = IOTCON_TYPE_NONE;
1477
1478   // check first element in array for type
1479   if (l.size() > 0) {
1480     if (l[0].is<bool>()) {
1481       type = IOTCON_TYPE_BOOL;
1482     } else if (l[0].is<double>()) {
1483       type = IOTCON_TYPE_DOUBLE;
1484     } else if (l[0].is<std::string>()) {
1485       if (0 == l[0].get<std::string>().find(kHexPrefix)) {
1486         type = IOTCON_TYPE_BYTE_STR;
1487       } else {
1488         type = IOTCON_TYPE_STR;
1489       }
1490     } else if (l[0].is<picojson::array>()) {
1491       type = IOTCON_TYPE_LIST;
1492     } else if (l[0].is<picojson::object>()) {
1493       type = IOTCON_TYPE_ATTRIBUTES;
1494     }
1495   }
1496
1497   if (IOTCON_TYPE_NONE == type) {
1498     LoggerD("Empty list");
1499     return TizenSuccess();
1500   }
1501
1502   auto result = IotconUtils::ConvertIotconError(iotcon_list_create(type, &list));
1503   if (!result) {
1504     LogAndReturnTizenError(result, ("iotcon_list_create() failed"));
1505   }
1506
1507   std::unique_ptr<std::remove_pointer<iotcon_list_h>::type, int (*)(iotcon_list_h)> ptr{
1508       list, &iotcon_list_destroy};
1509
1510   int position = 0;
1511
1512   // we're ignoring values with wrong type
1513   for (const auto& v : l) {
1514     switch (type) {
1515       case IOTCON_TYPE_BOOL:
1516         if (v.is<bool>()) {
1517           result = IotconUtils::ConvertIotconError(
1518               iotcon_list_add_bool(list, v.get<bool>(), position++));
1519           if (!result) {
1520             LogAndReturnTizenError(result, ("iotcon_list_add_bool() failed"));
1521           }
1522         }
1523         break;
1524
1525       case IOTCON_TYPE_DOUBLE:
1526         if (v.is<double>()) {
1527           result = IotconUtils::ConvertIotconError(
1528               iotcon_list_add_double(list, v.get<double>(), position++));
1529           if (!result) {
1530             LogAndReturnTizenError(result, ("iotcon_list_add_double() failed"));
1531           }
1532         }
1533         break;
1534
1535       case IOTCON_TYPE_BYTE_STR:
1536         if (v.is<std::string>()) {
1537           const auto& str = v.get<std::string>();
1538           if (0 == str.find(kHexPrefix)) {
1539             auto data = str.c_str() + kHexPrefix.length();  // skip prefix
1540             auto size = str.length() - kHexPrefix.length();
1541             auto length = size / 2;
1542             std::unique_ptr<unsigned char[]> hex{new unsigned char[length]};
1543             common::tools::HexToBin(data, size, hex.get(), length);
1544             result = IotconUtils::ConvertIotconError(
1545                 iotcon_list_add_byte_str(list, hex.get(), length, position++));
1546             if (!result) {
1547               LogAndReturnTizenError(result, ("iotcon_list_add_byte_str() failed"));
1548             }
1549           }
1550         }
1551         break;
1552
1553       case IOTCON_TYPE_STR:
1554         if (v.is<std::string>()) {
1555           result = IotconUtils::ConvertIotconError(iotcon_list_add_str(
1556               list, const_cast<char*>(v.get<std::string>().c_str()), position++));
1557           if (!result) {
1558             LogAndReturnTizenError(result, ("iotcon_list_add_str() failed"));
1559           }
1560         }
1561         break;
1562
1563       case IOTCON_TYPE_LIST:
1564         if (v.is<picojson::array>()) {
1565           iotcon_list_h sub_list = nullptr;
1566           result = StateListFromJson(v.get<picojson::array>(), &sub_list);
1567           if (!result) {
1568             LogAndReturnTizenError(result, ("StateListFromJson() failed"));
1569           }
1570           SCOPE_EXIT {
1571             iotcon_list_destroy(sub_list);
1572           };
1573           result =
1574               IotconUtils::ConvertIotconError(iotcon_list_add_list(list, sub_list, position++));
1575           if (!result) {
1576             LogAndReturnTizenError(result, ("iotcon_list_add_list() failed"));
1577           }
1578         }
1579         break;
1580
1581       case IOTCON_TYPE_ATTRIBUTES:
1582         if (v.is<picojson::object>()) {
1583           iotcon_attributes_h attributes = nullptr;
1584           result = AttributesFromJson(v.get<picojson::object>(), &attributes);
1585           if (!result) {
1586             LogAndReturnTizenError(result, ("AttributesFromJson() failed"));
1587           }
1588           SCOPE_EXIT {
1589             iotcon_attributes_destroy(attributes);
1590           };
1591           result = IotconUtils::ConvertIotconError(
1592               iotcon_list_add_attributes(list, attributes, position++));
1593           if (!result) {
1594             LogAndReturnTizenError(result, ("iotcon_list_add_attributes() failed"));
1595           }
1596         }
1597         break;
1598
1599       default:
1600         // should not happen
1601         LoggerE("Unexpected type: %d", type);
1602         return common::AbortError("Unexpected list type");
1603     }
1604   }
1605
1606   *out = ptr.release();
1607   return TizenSuccess();
1608 }
1609
1610 common::TizenResult IotconUtils::PresenceResponseToJson(iotcon_presence_response_h presence,
1611                                                         picojson::object* out) {
1612   ScopeLogger();
1613
1614   if (presence) {
1615     {
1616       // hostAddress
1617       char* host = nullptr;
1618       auto result = ConvertIotconError(iotcon_presence_response_get_host_address(presence, &host));
1619       if (!result || !host) {
1620         LogAndReturnTizenError(result, ("iotcon_presence_response_get_host_address() failed"));
1621       }
1622       out->insert(std::make_pair(kHostAddress, picojson::value{std::string(host)}));
1623     }
1624
1625     {
1626       // connectivityType
1627       iotcon_connectivity_type_e con_type;
1628       auto result =
1629           ConvertIotconError(iotcon_presence_response_get_connectivity_type(presence, &con_type));
1630       if (!result) {
1631         LogAndReturnTizenError(result, ("iotcon_presence_response_get_connectivity_type() failed"));
1632       }
1633       out->insert(
1634           std::make_pair(kConnectivityType, picojson::value{FromConnectivityType(con_type)}));
1635     }
1636
1637     {
1638       // resourceType
1639       char* resource_type = nullptr;
1640       auto result =
1641           ConvertIotconError(iotcon_presence_response_get_resource_type(presence, &resource_type));
1642       if (!result || !resource_type) {
1643         LoggerE("iotcon_presence_response_get_resource_type() failed");
1644         out->insert(std::make_pair(kResourceType, picojson::value()));
1645       } else {
1646         out->insert(std::make_pair(kResourceType, picojson::value{std::string(resource_type)}));
1647       }
1648     }
1649
1650     // resultType
1651     iotcon_presence_result_e result_type = IOTCON_PRESENCE_OK;
1652     {
1653       auto result = ConvertIotconError(iotcon_presence_response_get_result(presence, &result_type));
1654       if (!result) {
1655         LogAndReturnTizenError(result, ("iotcon_presence_response_get_result() failed"));
1656       }
1657
1658       out->insert(std::make_pair(kResultType,
1659                                  picojson::value{FromPresenceResponseResultType(result_type)}));
1660     }
1661
1662     {
1663       // triggerType
1664       iotcon_presence_trigger_e trigger_type = IOTCON_PRESENCE_RESOURCE_CREATED;
1665       if (IOTCON_PRESENCE_OK == result_type) {
1666         auto result =
1667             ConvertIotconError(iotcon_presence_response_get_trigger(presence, &trigger_type));
1668         if (!result) {
1669           LoggerE("iotcon_presence_response_get_trigger() failed");
1670           out->insert(std::make_pair(kTriggerType, picojson::value()));
1671         } else {
1672           out->insert(
1673               std::make_pair(kTriggerType, picojson::value{FromPresenceTriggerType(trigger_type)}));
1674         }
1675       } else {
1676         out->insert(std::make_pair(kTriggerType, picojson::value()));
1677       }
1678     }
1679   } else {
1680     LoggerW("Presence handle is null, ignoring");
1681   }
1682
1683   return TizenSuccess();
1684 }
1685
1686 common::TizenResult IotconUtils::ExtractFromPresenceEvent(const PresenceEventPtr& pointer,
1687                                                           char** host,
1688                                                           iotcon_connectivity_type_e* con_type,
1689                                                           char** resource_type) {
1690   ScopeLogger();
1691
1692   auto result = ConvertIotconError(iotcon_presence_get_host_address(pointer->handle, host));
1693   if (!result) {
1694     LogAndReturnTizenError(result, ("Gathering presence host address failed"));
1695   }
1696
1697   result = ConvertIotconError(iotcon_presence_get_connectivity_type(pointer->handle, con_type));
1698   if (!result) {
1699     LogAndReturnTizenError(result, ("Gathering presence connectivity type failed"));
1700   }
1701
1702   result = ConvertIotconError(iotcon_presence_get_resource_type(pointer->handle, resource_type));
1703   if (!result) {
1704     LogAndReturnTizenError(result, ("Gathering presence resource type failed"));
1705   }
1706
1707   return TizenSuccess();
1708 }
1709
1710 common::TizenResult IotconUtils::OptionsFromJson(const picojson::array& o, iotcon_options_h* out) {
1711   ScopeLogger();
1712
1713   iotcon_options_h options = nullptr;
1714
1715   auto result = ConvertIotconError(iotcon_options_create(&options));
1716   if (!result) {
1717     LogAndReturnTizenError(result, ("iotcon_options_create() failed"));
1718   }
1719
1720   std::unique_ptr<std::remove_pointer<iotcon_options_h>::type, int (*)(iotcon_options_h)> ptr{
1721       options, &iotcon_options_destroy};
1722
1723   // we ignore values with incorrect types
1724   // TODO: should we convert them in JS?
1725   for (const auto& option : o) {
1726     if (option.is<picojson::object>()) {
1727       const auto& js_id = option.get(kOptionsId);
1728       const auto& js_data = option.get(kOptionsData);
1729
1730       if (js_id.is<double>() && js_data.is<std::string>()) {
1731         result = ConvertIotconError(
1732             iotcon_options_add(options, js_id.get<double>(), js_data.get<std::string>().c_str()));
1733         if (!result) {
1734           LogAndReturnTizenError(result, ("iotcon_options_add() failed"));
1735         }
1736       }
1737     }
1738   }
1739
1740   *out = ptr.release();
1741   return TizenSuccess();
1742 }
1743
1744 common::TizenResult IotconUtils::RepresentationFromJson(const picojson::object& r,
1745                                                         iotcon_representation_h* out) {
1746   ScopeLogger();
1747
1748   iotcon_representation_h representation = nullptr;
1749
1750   auto result = ConvertIotconError(iotcon_representation_create(&representation));
1751   if (!result) {
1752     LogAndReturnTizenError(result, ("iotcon_representation_create() failed"));
1753   }
1754
1755   std::unique_ptr<std::remove_pointer<iotcon_representation_h>::type,
1756                   int (*)(iotcon_representation_h)>
1757       ptr{representation, &iotcon_representation_destroy};
1758
1759   {
1760     const auto& uri_path = r.find(kUriPath);
1761     if (r.end() != uri_path && uri_path->second.is<std::string>()) {
1762       result = ConvertIotconError(iotcon_representation_set_uri_path(
1763           representation, uri_path->second.get<std::string>().c_str()));
1764       if (!result) {
1765         LogAndReturnTizenError(result, ("iotcon_representation_set_uri_path() failed"));
1766       }
1767     } else {
1768       return LogAndCreateTizenError(
1769           TypeMismatchError,
1770           "Representation object needs to have an uriPath attribute which is a string.");
1771     }
1772   }
1773
1774   {
1775     const auto& resource_types = r.find(kResourceTypes);
1776     if (r.end() != resource_types && resource_types->second.is<picojson::array>()) {
1777       iotcon_resource_types_h types = nullptr;
1778
1779       result = ArrayToTypes(resource_types->second.get<picojson::array>(), &types);
1780       if (!result) {
1781         LogAndReturnTizenError(result, ("ArrayToTypes() failed"));
1782       }
1783       SCOPE_EXIT {
1784         iotcon_resource_types_destroy(types);
1785       };
1786
1787       result = ConvertIotconError(iotcon_representation_set_resource_types(representation, types));
1788       if (!result) {
1789         LogAndReturnTizenError(result, ("iotcon_representation_set_resource_types() failed"));
1790       }
1791     } else {
1792       return LogAndCreateTizenError(
1793           TypeMismatchError,
1794           "Representation object needs to have a resourceTypes attribute which is an array.");
1795     }
1796   }
1797
1798   {
1799     const auto& resource_interfaces = r.find(kResourceInterfaces);
1800     if (r.end() != resource_interfaces && resource_interfaces->second.is<picojson::array>()) {
1801       iotcon_resource_interfaces_h interfaces = nullptr;
1802
1803       result = ArrayToInterfaces(resource_interfaces->second.get<picojson::array>(), &interfaces);
1804       if (!result) {
1805         LogAndReturnTizenError(result, ("ArrayToInterfaces() failed"));
1806       }
1807       SCOPE_EXIT {
1808         iotcon_resource_interfaces_destroy(interfaces);
1809       };
1810       result = ConvertIotconError(
1811           iotcon_representation_set_resource_interfaces(representation, interfaces));
1812       if (!result) {
1813         LogAndReturnTizenError(result, ("iotcon_representation_set_resource_interfaces() failed"));
1814       }
1815     } else {
1816       return LogAndCreateTizenError(
1817           TypeMismatchError,
1818           "Representation object needs to have a resourceInterfaces attribute which is an array.");
1819     }
1820   }
1821
1822   {
1823     const auto& states = r.find(kAttributes);
1824     if (r.end() != states && states->second.is<picojson::object>()) {
1825       iotcon_attributes_h s = nullptr;
1826
1827       result = AttributesFromJson(states->second.get<picojson::object>(), &s);
1828       if (!result) {
1829         LogAndReturnTizenError(result, ("AttributesFromJson() failed"));
1830       }
1831       SCOPE_EXIT {
1832         iotcon_attributes_destroy(s);
1833       };
1834
1835       result = ConvertIotconError(iotcon_representation_set_attributes(representation, s));
1836       if (!result) {
1837         LogAndReturnTizenError(result, ("iotcon_representation_set_attributes() failed"));
1838       }
1839     }
1840   }
1841
1842   {
1843     const auto& children = r.find(kChildren);
1844     if (r.end() != children && children->second.is<picojson::array>()) {
1845       for (const auto& js_child : children->second.get<picojson::array>()) {
1846         if (js_child.is<picojson::object>()) {
1847           iotcon_representation_h child = nullptr;
1848
1849           result = RepresentationFromJson(js_child.get<picojson::object>(), &child);
1850           if (!result) {
1851             LogAndReturnTizenError(result, ("RepresentationFromJson() failed"));
1852           }
1853           SCOPE_EXIT {
1854             iotcon_representation_destroy(child);
1855           };
1856
1857           result = ConvertIotconError(iotcon_representation_add_child(representation, child));
1858           if (!result) {
1859             LogAndReturnTizenError(result, ("iotcon_representation_add_child() failed"));
1860           }
1861         } else {
1862           return LogAndCreateTizenError(TypeMismatchError,
1863                                         "The Representation.children attribute needs to be an "
1864                                         "array of Representation objects.");
1865         }
1866       }
1867     }
1868   }
1869
1870   *out = ptr.release();
1871   return TizenSuccess();
1872 }
1873
1874 common::TizenResult IotconUtils::PlatformInfoGetProperty(iotcon_platform_info_h platform,
1875                                                          iotcon_platform_info_e property_e,
1876                                                          const std::string& name,
1877                                                          picojson::object* out) {
1878   ScopeLogger();
1879
1880   char* property = nullptr;
1881   auto result =
1882       ConvertIotconError(iotcon_platform_info_get_property(platform, property_e, &property));
1883   if (!result) {
1884     LogAndReturnTizenError(result, ("iotcon_platform_info_get_property() failed"));
1885   }
1886
1887   if (!property) {
1888     out->insert(std::make_pair(name, picojson::value{""}));
1889   } else {
1890     out->insert(std::make_pair(name, picojson::value{property}));
1891   }
1892
1893   return TizenSuccess();
1894 }
1895
1896 common::TizenResult IotconUtils::PlatformInfoToJson(iotcon_platform_info_h platform,
1897                                                     picojson::object* out) {
1898   ScopeLogger();
1899
1900   {
1901     // platformId
1902     auto result = PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_ID, kPlatformId, out);
1903     if (!result) {
1904       return result;
1905     }
1906   }
1907
1908   {
1909     // manufacturerName
1910     auto result =
1911         PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_MANUF_NAME, kManufacturerName, out);
1912     if (!result) {
1913       return result;
1914     }
1915   }
1916
1917   {
1918     // manufacturerUrl
1919     auto result =
1920         PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_MANUF_URL, kManufacturerUrl, out);
1921     if (!result) {
1922       return result;
1923     }
1924   }
1925
1926   {
1927     // modelNumber
1928     auto result =
1929         PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_MODEL_NUMBER, kModelNumber, out);
1930     if (!result) {
1931       return result;
1932     }
1933   }
1934
1935   {
1936     // manufactureDate
1937     auto result = PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_DATE_OF_MANUF,
1938                                           kManufactureDate, out);
1939     if (!result) {
1940       return result;
1941     }
1942   }
1943
1944   {
1945     // platformVersion
1946     auto result =
1947         PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_PLATFORM_VER, kPlatformVersion, out);
1948     if (!result) {
1949       return result;
1950     }
1951   }
1952
1953   {
1954     // operatingSystemVersion
1955     auto result = PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_OS_VER,
1956                                           kOperatingSystemVersion, out);
1957     if (!result) {
1958       return result;
1959     }
1960   }
1961
1962   {
1963     // hardwareVersion
1964     auto result =
1965         PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_HARDWARE_VER, kHardwareVersion, out);
1966     if (!result) {
1967       return result;
1968     }
1969   }
1970
1971   {
1972     // firmwareVersion
1973     auto result =
1974         PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_FIRMWARE_VER, kFirmwareVersion, out);
1975     if (!result) {
1976       return result;
1977     }
1978   }
1979
1980   {
1981     // supportUrl
1982     auto result =
1983         PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_SUPPORT_URL, kSupportUrl, out);
1984     if (!result) {
1985       return result;
1986     }
1987   }
1988
1989   {
1990     // systemTime
1991     auto result =
1992         PlatformInfoGetProperty(platform, IOTCON_PLATFORM_INFO_SYSTEM_TIME, kSystemTime, out);
1993     if (!result) {
1994       return result;
1995     }
1996   }
1997   return TizenSuccess();
1998 }
1999
2000 common::TizenResult IotconUtils::DeviceInfoGetProperty(iotcon_device_info_h device,
2001                                                        iotcon_device_info_e property_e,
2002                                                        const std::string& name,
2003                                                        picojson::object* out) {
2004   ScopeLogger();
2005
2006   char* property = nullptr;
2007   auto result = ConvertIotconError(iotcon_device_info_get_property(device, property_e, &property));
2008   if (!result) {
2009     LogAndReturnTizenError(result, ("iotcon_device_info_get_property() failed"));
2010   }
2011
2012   if (!property) {
2013     out->insert(std::make_pair(name, picojson::value{""}));
2014   } else {
2015     out->insert(std::make_pair(name, picojson::value{property}));
2016   }
2017
2018   return TizenSuccess();
2019 }
2020
2021 common::TizenResult IotconUtils::DeviceInfoToJson(iotcon_device_info_h device,
2022                                                   picojson::object* out) {
2023   ScopeLogger();
2024
2025   {
2026     // deviceName
2027     auto result = DeviceInfoGetProperty(device, IOTCON_DEVICE_INFO_NAME, kDeviceName, out);
2028     if (!result) {
2029       return result;
2030     }
2031   }
2032
2033   {
2034     // specVersion
2035     auto result = DeviceInfoGetProperty(device, IOTCON_DEVICE_INFO_SPEC_VER, kSpecVersion, out);
2036     if (!result) {
2037       return result;
2038     }
2039   }
2040
2041   {
2042     // oicDeviceId
2043     auto result = DeviceInfoGetProperty(device, IOTCON_DEVICE_INFO_ID, kOicDeviceId, out);
2044     if (!result) {
2045       return result;
2046     }
2047   }
2048
2049   {
2050     // dataModelVersion
2051     auto result =
2052         DeviceInfoGetProperty(device, IOTCON_DEVICE_INFO_DATA_MODEL_VER, kDataModelVersion, out);
2053     if (!result) {
2054       return result;
2055     }
2056   }
2057
2058   return TizenSuccess();
2059 }
2060
2061 common::TizenResult IotconUtils::ConvertIotconError(int error) {
2062   switch (error) {
2063     case IOTCON_ERROR_NONE:
2064       return common::TizenSuccess();
2065
2066     case IOTCON_ERROR_IO_ERROR:
2067       return common::IoError(error);
2068
2069     case IOTCON_ERROR_PERMISSION_DENIED:
2070       return common::SecurityError(error);
2071
2072     case IOTCON_ERROR_NOT_SUPPORTED:
2073       return common::NotSupportedError(error);
2074
2075     case IOTCON_ERROR_NO_DATA:
2076     case IOTCON_ERROR_INVALID_PARAMETER:
2077       return common::InvalidValuesError(error);
2078
2079     case IOTCON_ERROR_TIMEOUT:
2080       return common::TimeoutError(error);
2081
2082     case IOTCON_ERROR_INVALID_TYPE:
2083       return common::TypeMismatchError(error);
2084
2085     case IOTCON_ERROR_ALREADY:
2086       return common::InvalidStateError(error);
2087
2088     case IOTCON_ERROR_OUT_OF_MEMORY:
2089     case IOTCON_ERROR_IOTIVITY:
2090     case IOTCON_ERROR_REPRESENTATION:
2091     case IOTCON_ERROR_SYSTEM:
2092     default:
2093       return common::AbortError(error);
2094   }
2095 }
2096
2097 #define X(v, s) \
2098   case v:       \
2099     return s;
2100 #define XD(v, s)                                               \
2101   default:                                                     \
2102     LoggerE("Unknown value: %d, returning default: %s", e, s); \
2103     return s;
2104
2105 std::string IotconUtils::FromConnectivityType(iotcon_connectivity_type_e e) {
2106   ScopeLogger();
2107
2108   switch (e) { IOTCON_CONNECTIVITY_TYPE_E }
2109 }
2110
2111 std::string IotconUtils::FromRequestType(iotcon_request_type_e e) {
2112   ScopeLogger();
2113
2114   switch (e) { IOTCON_REQUEST_TYPE_E }
2115 }
2116
2117 std::string IotconUtils::FromObserveType(iotcon_observe_type_e e) {
2118   ScopeLogger();
2119
2120   switch (e) { IOTCON_OBSERVE_TYPE_E }
2121 }
2122
2123 std::string IotconUtils::FromPresenceResponseResultType(iotcon_presence_result_e e) {
2124   ScopeLogger();
2125
2126   switch (e) { IOTCON_PRESENCE_RESULT_E }
2127 }
2128
2129 std::string IotconUtils::FromPresenceTriggerType(iotcon_presence_trigger_e e) {
2130   ScopeLogger();
2131
2132   switch (e) { IOTCON_PRESENCE_TRIGGER_E }
2133 }
2134
2135 std::string IotconUtils::FromResponseResultType(iotcon_response_result_e e) {
2136   ScopeLogger();
2137
2138   switch (e) { IOTCON_RESPONSE_RESULT_E }
2139 }
2140
2141 #undef X
2142 #undef XD
2143
2144 #define X(v, s) \
2145   if (e == s) return v;
2146 #define XD(v, s)                                                     \
2147   LoggerE("Unknown value: %s, returning default: %d", e.c_str(), v); \
2148   return v;
2149
2150 iotcon_qos_e IotconUtils::ToQos(const std::string& e) {
2151   ScopeLogger();
2152
2153   IOTCON_QOS_E
2154 }
2155
2156 iotcon_connectivity_type_e IotconUtils::ToConnectivityType(const std::string& e) {
2157   ScopeLogger();
2158
2159   IOTCON_CONNECTIVITY_TYPE_E
2160 }
2161
2162 int IotconUtils::ToConnectivityType2(const std::string& connectivity_type) {
2163   ScopeLogger();
2164   int ret = IOTCON_CONNECTIVITY_ALL;
2165   if (connectivity_type == "IP") {
2166     ret = IOTCON_CONNECTIVITY_IP;
2167   } else if (connectivity_type == "PREFER_UDP") {
2168     ret = IOTCON_CONNECTIVITY_IP | IOTCON_CONNECTIVITY_PREFER_UDP;
2169   } else if (connectivity_type == "PREFER_TCP") {
2170     ret = IOTCON_CONNECTIVITY_IP | IOTCON_CONNECTIVITY_PREFER_TCP;
2171   } else if (connectivity_type == "IPV4_ONLY") {
2172     ret = IOTCON_CONNECTIVITY_IP | IOTCON_CONNECTIVITY_IPV4_ONLY | IOTCON_CONNECTIVITY_PREFER_UDP;
2173   } else if (connectivity_type == "IPV6_ONLY") {
2174     ret = IOTCON_CONNECTIVITY_IP | IOTCON_CONNECTIVITY_IPV6_ONLY | IOTCON_CONNECTIVITY_PREFER_UDP;
2175   } else {
2176     ret = IOTCON_CONNECTIVITY_ALL;
2177   }
2178
2179   LoggerD("ToConnectivityType2: %s  ,%d", connectivity_type.c_str(), ret);
2180   return ret;
2181 }
2182
2183 iotcon_observe_policy_e IotconUtils::ToObservePolicy(const std::string& e) {
2184   ScopeLogger();
2185
2186   IOTCON_OBSERVE_POLICY_E
2187 }
2188
2189 iotcon_response_result_e IotconUtils::ToResponseResult(const std::string& e) {
2190   IOTCON_RESPONSE_RESULT_E
2191 }
2192
2193 #undef X
2194 #undef XD
2195
2196 }  // namespace iotcon
2197 }  // namespace extension