[iotcon] Implementation of Resource.notify()
authorPawel Andruszkiewicz <p.andruszkie@samsung.com>
Tue, 9 Feb 2016 09:29:54 +0000 (10:29 +0100)
committerPawel Andruszkiewicz <p.andruszkie@samsung.com>
Wed, 10 Feb 2016 10:51:34 +0000 (19:51 +0900)
Change-Id: I1fe061bed96770c5537def77f8c0c4702c5072fd
Signed-off-by: Pawel Andruszkiewicz <p.andruszkie@samsung.com>
src/iotcon/iotcon_api.js
src/iotcon/iotcon_instance.cc
src/iotcon/iotcon_instance.h
src/iotcon/iotcon_server_manager.cc
src/iotcon/iotcon_server_manager.h
src/iotcon/iotcon_utils.cc
src/iotcon/iotcon_utils.h

index e6ab904..98e7ffc 100644 (file)
@@ -173,6 +173,11 @@ var PresenceTriggerType = {
   DEREGISTER: 'DEREGISTER'
 };
 
+var QosLevel = {
+  LOW: 'LOW',
+  HIGH: 'HIGH'
+};
+
 function DeviceInfo(data) {
   decorateWithData(data, this);
 }
@@ -300,6 +305,10 @@ function Resource(data) {
 
 Resource.prototype.notify = function() {
   var args = validator.validateMethod(arguments, [{
+    name: 'qos',
+    type: types.ENUM,
+    values: T.getValues(QosLevel)
+  }, {
     name: 'observerIds',
     type: types.ARRAY,
     values: types.LONG,
@@ -307,11 +316,22 @@ Resource.prototype.notify = function() {
     nullable: true
   }]);
 
+  var states = {};
+  function getStates(r) {
+    states[r[kIdKey]] = r.states;
+    for (var i = 0; i < r.resources.length; ++i) {
+      getStates(r.resources[i]);
+    }
+  }
+  getStates(this);
+
   var callArgs = {};
   callArgs.id = this[kIdKey];
+  callArgs.qos = args.qos;
   callArgs.observerIds = args.observerIds;
+  callArgs.states = states;
 
-  var result = native.call('IotconResource_notify', callArgs);
+  var result = native.callSync('IotconResource_notify', callArgs);
 
   if (native.isFailure(result)) {
     throw native.getErrorObject(result);
index 9d39039..7dfec2b 100644 (file)
@@ -19,6 +19,7 @@
 #include <thread>
 
 #include "common/logger.h"
+#include "common/scope_exit.h"
 
 #include "iotcon/iotcon_utils.h"
 
@@ -49,9 +50,12 @@ const picojson::value& GetArg(const picojson::object& args, const std::string& n
 
 const common::ListenerToken kResourceRequestListenerToken{"ResourceRequestListener"};
 
+const std::string kObserverIds = "observerIds";
+const std::string kQos = "qos";
+
 }  // namespace
 
-IotconInstance::IotconInstance() : manager_(this) {
+IotconInstance::IotconInstance() {
   ScopeLogger();
 
   using std::placeholders::_1;
@@ -61,6 +65,7 @@ IotconInstance::IotconInstance() : manager_(this) {
   RegisterSyncHandler(c, std::bind(&IotconInstance::x, this, _1))
 
   REGISTER_SYNC("IotconResource_getObserverIds", ResourceGetObserverIds);
+  REGISTER_SYNC("IotconResource_notify", ResourceNotify);
   REGISTER_SYNC("IotconResource_setRequestListener", ResourceSetRequestListener);
   REGISTER_SYNC("IotconResource_unsetRequestListener", ResourceUnsetRequestListener);
   REGISTER_SYNC("IotconResponse_send", ResponseSend);
@@ -83,7 +88,6 @@ IotconInstance::IotconInstance() : manager_(this) {
 #define REGISTER_ASYNC(c, x) \
   RegisterHandler(c, std::bind(&IotconInstance::x, this, _1, _2));
 
-  REGISTER_ASYNC("IotconResource_notify", ResourceNotify);
   REGISTER_ASYNC("IotconResource_addResourceTypes", ResourceAddResourceTypes);
   REGISTER_ASYNC("IotconResource_addResourceInterfaces", ResourceAddResourceInterfaces);
   REGISTER_ASYNC("IotconResource_addChildResource", ResourceAddChildResource);
@@ -127,7 +131,7 @@ void IotconInstance::ConnectionChangedCallback(bool is_connected, void* user_dat
     }
 
     LoggerD("Connection recovered, restoring handles");
-    auto ret = instance->manager_.RestoreHandles();
+    auto ret = IotconServerManager::GetInstance().RestoreHandles();
     if (!ret) {
       LoggerD("Connection recovered, but restoring handles failed");
     }
@@ -146,10 +150,82 @@ common::TizenResult IotconInstance::ResourceGetObserverIds(const picojson::objec
   return common::UnknownError("Not implemented");
 }
 
-common::TizenResult IotconInstance::ResourceNotify(const picojson::object& args,
-                                                   const common::AsyncToken& token) {
+common::TizenResult IotconInstance::ResourceNotify(const picojson::object& args) {
   ScopeLogger();
-  return common::UnknownError("Not implemented");
+
+  CHECK_EXIST(args, kId);
+  CHECK_EXIST(args, kQos);
+  CHECK_EXIST(args, kStates);
+
+  ResourceInfoPtr resource;
+  long long id = GetId(args);
+  auto result = IotconServerManager::GetInstance().GetResourceById(id, &resource);
+
+  if (!result) {
+    LogAndReturnTizenError(result, ("GetResourceById() failed"));
+  }
+
+  auto& qos = GetArg(args, kQos);
+  if (!qos.is<std::string>()) {
+    return common::TypeMismatchError("QOS needs to be a string");
+  }
+
+  // create observers to notify
+  auto& observer_ids = GetArg(args, kObserverIds);
+
+  std::vector<int> observers;
+
+  if (observer_ids.is<picojson::array>()) {
+    // use provided list, make sure that observer exists
+    for (auto& id : observer_ids.get<picojson::array>()) {
+      if (id.is<double>()) {
+        auto v = static_cast<int>(id.get<double>());
+        if (resource->observers.end() != resource->observers.find(v)) {
+          observers.push_back(v);
+        }
+      }
+    }
+  } else {
+    // use own list
+    observers.assign(resource->observers.begin(), resource->observers.end());
+  }
+
+  // create & initialize platform object
+  iotcon_observers_h observers_handle = nullptr;
+  result = IotconUtils::ConvertIotconError(iotcon_observers_create(&observers_handle));
+  if (!result) {
+    LogAndReturnTizenError(result, ("iotcon_observers_create() failed"));
+  }
+
+  SCOPE_EXIT {
+    iotcon_observers_destroy(observers_handle);
+  };
+
+  for (auto& id : observers) {
+    result = IotconUtils::ConvertIotconError(iotcon_observers_add(observers_handle, id));
+    if (!result) {
+      LogAndReturnTizenError(result, ("iotcon_observers_add() failed"));
+    }
+  }
+
+  // create representation from resource and states
+  iotcon_representation_h representation = nullptr;
+
+  result = IotconUtils::RepresentationFromResource(resource, GetArg(args, kStates), &representation);
+  if (!result) {
+    LogAndReturnTizenError(result, ("RepresentationFromResource() failed"));
+  }
+
+  SCOPE_EXIT {
+    iotcon_representation_destroy(representation);
+  };
+
+  result = IotconUtils::ConvertIotconError(iotcon_resource_notify(resource->handle, representation, observers_handle, IotconUtils::ToQos(qos.get<std::string>())));
+  if (!result) {
+    LogAndReturnTizenError(result, ("iotcon_resource_notify() failed"));
+  }
+
+  return common::TizenSuccess();
 }
 
 common::TizenResult IotconInstance::ResourceAddResourceTypes(const picojson::object& args,
@@ -183,7 +259,7 @@ common::TizenResult IotconInstance::ResourceSetRequestListener(const picojson::o
 
   ResourceInfoPtr resource;
   long long id = GetId(args);
-  auto result = manager_.GetResourceById(id, &resource);
+  auto result = IotconServerManager::GetInstance().GetResourceById(id, &resource);
 
   if (!result) {
     return result;
@@ -210,7 +286,7 @@ common::TizenResult IotconInstance::ResourceUnsetRequestListener(const picojson:
   CHECK_EXIST(args, kId);
 
   ResourceInfoPtr resource;
-  auto result = manager_.GetResourceById(GetId(args), &resource);
+  auto result = IotconServerManager::GetInstance().GetResourceById(GetId(args), &resource);
 
   if (!result) {
     return result;
@@ -347,8 +423,8 @@ common::TizenResult IotconInstance::ServerCreateResource(const picojson::object&
   properties |= (explicit_discoverable.is<bool>() ? explicit_discoverable.get<bool>() : false) ? IOTCON_RESOURCE_EXPLICIT_DISCOVERABLE : IOTCON_RESOURCE_NO_PROPERTY;
 
   ResourceInfoPtr resource{new ResourceInfo()};
-  auto ret = manager_.CreateResource(uri_path, resource_interfaces, resource_types,
-                                     properties, resource);
+  auto ret = IotconServerManager::GetInstance().CreateResource(uri_path, resource_interfaces, resource_types,
+                                                               properties, resource);
   if (!ret) {
     return ret;
   }
@@ -356,7 +432,7 @@ common::TizenResult IotconInstance::ServerCreateResource(const picojson::object&
   LoggerD("RESOURCE\nid: %lld\nhandle: %p", resource->id, resource->handle);
 
   picojson::value result = picojson::value(picojson::object());
-  ret = IotconUtils::ResourceToJson(resource, manager_, &(result.get<picojson::object>()));
+  ret = IotconUtils::ResourceToJson(resource, &(result.get<picojson::object>()));
   if (!ret) {
     return ret;
   }
@@ -369,7 +445,7 @@ common::TizenResult IotconInstance::ServerRemoveResource(const picojson::object&
 
   CHECK_EXIST(args, kId);
 
-  return manager_.DestroyResource(GetId(args));
+  return IotconServerManager::GetInstance().DestroyResource(GetId(args));
 }
 
 common::TizenResult IotconInstance::GetTimeout(const picojson::object& args) {
index 556d0c9..57b9c19 100644 (file)
@@ -32,8 +32,7 @@ class IotconInstance : public common::TizenInstance {
   static void ConnectionChangedCallback(bool is_connected, void* user_data);
 
   common::TizenResult ResourceGetObserverIds(const picojson::object& args);
-  common::TizenResult ResourceNotify(const picojson::object& args,
-                                     const common::AsyncToken& token);
+  common::TizenResult ResourceNotify(const picojson::object& args);
   common::TizenResult ResourceAddResourceTypes(const picojson::object& args,
                                                const common::AsyncToken& token);
   common::TizenResult ResourceAddResourceInterfaces(const picojson::object& args,
@@ -72,8 +71,6 @@ class IotconInstance : public common::TizenInstance {
   common::TizenResult ServerRemoveResource(const picojson::object& args);
   common::TizenResult GetTimeout(const picojson::object& args);
   common::TizenResult SetTimeout(const picojson::object& args);
-
-  IotconServerManager manager_;
 };
 
 }  // namespace iotcon
index 1852349..19ae602 100644 (file)
@@ -35,13 +35,9 @@ long long GetNextId() {
 
 }  // namespace
 
-IotconServerManager::IotconServerManager(IotconInstance* instance)
-      : instance_(instance) {
-  ScopeLogger();
-}
-
-IotconServerManager::~IotconServerManager() {
-  ScopeLogger();
+IotconServerManager& IotconServerManager::GetInstance() {
+  static IotconServerManager instance;
+  return instance;
 }
 
 TizenResult IotconServerManager::RestoreHandles() {
index 4c8bf8a..b15e362 100644 (file)
@@ -33,11 +33,8 @@ class IotconInstance;
 
 class IotconServerManager {
  public:
-  IotconServerManager(IotconInstance* instance);
-  ~IotconServerManager();
+  static IotconServerManager& GetInstance();
 
-  static void RequestHandler(iotcon_resource_h resource,
-                             iotcon_request_h request, void *user_data);
   common::TizenResult RestoreHandles();
   common::TizenResult CreateResource(const std::string& uri_path,
                                      const picojson::array& interfaces_array,
@@ -46,10 +43,18 @@ class IotconServerManager {
                                      ResourceInfoPtr res_pointer);
   common::TizenResult GetResourceById(long long id, ResourceInfoPtr* res_pointer) const;
   common::TizenResult DestroyResource(long long id);
- private:
   common::TizenResult GetResourceByHandle(iotcon_resource_h resource, ResourceInfoPtr* res_pointer) const;
 
-  IotconInstance* instance_;
+ private:
+  IotconServerManager() = default;
+  IotconServerManager(const IotconServerManager&) = delete;
+  IotconServerManager(IotconServerManager&&) = delete;
+  IotconServerManager& operator=(const IotconServerManager&) = delete;
+  IotconServerManager& operator=(IotconServerManager&&) = delete;
+
+  static void RequestHandler(iotcon_resource_h resource,
+                             iotcon_request_h request, void *user_data);
+
   ResourceInfoMap resource_map_;
 };
 
index bc5276c..bfca55c 100644 (file)
@@ -61,6 +61,11 @@ namespace {
   X(IOTCON_INTERFACE_READONLY, "READONLY") \
   XD(IOTCON_INTERFACE_NONE, "unknown")
 
+#define IOTCON_QOS_E \
+  X(IOTCON_QOS_LOW, "LOW") \
+  X(IOTCON_QOS_HIGH, "HIGH") \
+  XD(IOTCON_QOS_LOW, "unknown")
+
 }  // namespace
 
 const std::string kIsDiscoverable = "isDiscoverable";
@@ -204,7 +209,6 @@ TizenResult IotconUtils::ExtractFromResource(const ResourceInfoPtr& pointer,
 }
 
 TizenResult IotconUtils::ResourceToJson(ResourceInfoPtr pointer,
-                                        const IotconServerManager& manager,
                                         picojson::object* res) {
   ScopeLogger();
 
@@ -245,12 +249,12 @@ TizenResult IotconUtils::ResourceToJson(ResourceInfoPtr pointer,
       continue;
     }
     ResourceInfoPtr resource;
-    ret = manager.GetResourceById((*iter), &resource);
+    ret = IotconServerManager::GetInstance().GetResourceById((*iter), &resource);
     if (ret.IsSuccess()) {
       LoggerD("Found children RESOURCE\nid: %lld\nhandle: %p", resource->id, resource->handle);
 
       picojson::value child = picojson::value(picojson::object());
-      ret = IotconUtils::ResourceToJson(resource, manager, &(child.get<picojson::object>()));
+      ret = IotconUtils::ResourceToJson(resource, &(child.get<picojson::object>()));
       if (ret.IsSuccess()) {
         children.push_back(child);
       }
@@ -773,6 +777,330 @@ common::TizenResult IotconUtils::QueryToJson(iotcon_query_h query,
   return TizenSuccess();
 }
 
+common::TizenResult IotconUtils::RepresentationFromResource(const ResourceInfoPtr& resource,
+                                                            const picojson::value& states,
+                                                            iotcon_representation_h* out) {
+  ScopeLogger();
+
+  iotcon_representation_h representation = nullptr;
+
+  auto result = IotconUtils::ConvertIotconError(iotcon_representation_create(&representation));
+  if (!result) {
+    LogAndReturnTizenError(result, ("iotcon_representation_create() failed"));
+  }
+
+  std::unique_ptr<std::remove_pointer<iotcon_representation_h>::type, void(*)(iotcon_representation_h)> ptr{representation, &iotcon_representation_destroy};
+
+  {
+    char* uri_path = nullptr;
+    result = IotconUtils::ConvertIotconError(iotcon_resource_get_uri_path(resource->handle, &uri_path));
+    if (!result) {
+      LogAndReturnTizenError(result, ("iotcon_resource_get_uri_path() failed"));
+    }
+    result = IotconUtils::ConvertIotconError(iotcon_representation_set_uri_path(representation, uri_path));
+    if (!result) {
+      LogAndReturnTizenError(result, ("iotcon_representation_set_uri_path() failed"));
+    }
+  }
+
+  {
+    iotcon_resource_types_h types = nullptr;
+    result = IotconUtils::ConvertIotconError(iotcon_resource_get_types(resource->handle, &types));
+    if (!result) {
+      LogAndReturnTizenError(result, ("iotcon_resource_get_types() failed"));
+    }
+    result = IotconUtils::ConvertIotconError(iotcon_representation_set_resource_types(representation, types));
+    if (!result) {
+      LogAndReturnTizenError(result, ("iotcon_representation_set_resource_types() failed"));
+    }
+  }
+
+  {
+    int intrefaces = IOTCON_INTERFACE_NONE;
+    result = IotconUtils::ConvertIotconError(iotcon_resource_get_interfaces(resource->handle, &intrefaces));
+    if (!result) {
+      LogAndReturnTizenError(result, ("iotcon_resource_get_interfaces() failed"));
+    }
+    result = IotconUtils::ConvertIotconError(iotcon_representation_set_resource_interfaces(representation, intrefaces));
+    if (!result) {
+      LogAndReturnTizenError(result, ("iotcon_representation_set_resource_interfaces() failed"));
+    }
+  }
+
+  {
+    auto& state = states.get(std::to_string(resource->id));
+    if (state.is<picojson::object>()) {
+      iotcon_state_h state_handle = nullptr;
+      result = IotconUtils::StateFromJson(state.get<picojson::object>(), &state_handle);
+      if (!result) {
+        LogAndReturnTizenError(result, ("StateFromJson() failed"));
+      }
+      SCOPE_EXIT {
+        iotcon_state_destroy(state_handle);
+      };
+      result = IotconUtils::ConvertIotconError(iotcon_representation_set_state(representation, state_handle));
+      if (!result) {
+        LogAndReturnTizenError(result, ("iotcon_representation_set_state() failed"));
+      }
+    }
+  }
+
+  {
+    int children = 0;
+    result = IotconUtils::ConvertIotconError(iotcon_resource_get_number_of_children(resource->handle, &children));
+    if (!result) {
+      LogAndReturnTizenError(result, ("iotcon_resource_get_number_of_children() failed"));
+    }
+
+    for (int i = 0; i < children; ++i) {
+      iotcon_resource_h child = nullptr;
+      result = IotconUtils::ConvertIotconError(iotcon_resource_get_nth_child(resource->handle, i, &child));
+      if (!result) {
+        LogAndReturnTizenError(result, ("iotcon_resource_get_nth_child() failed"));
+      }
+
+      ResourceInfoPtr child_resource;
+      result = IotconServerManager::GetInstance().GetResourceByHandle(child, &child_resource);
+      if (!result) {
+        LogAndReturnTizenError(result, ("GetResourceByHandle() failed"));
+      }
+
+      iotcon_representation_h child_representation = nullptr;
+      result = RepresentationFromResource(child_resource, states, &child_representation);
+      if (!result) {
+        LogAndReturnTizenError(result, ("RepresentationFromResource() failed"));
+      }
+      SCOPE_EXIT {
+        iotcon_representation_destroy(child_representation);
+      };
+      result = IotconUtils::ConvertIotconError(iotcon_representation_add_child(representation, child_representation));
+      if (!result) {
+        LogAndReturnTizenError(result, ("iotcon_representation_add_child() failed"));
+      }
+    }
+  }
+
+  *out = ptr.release();
+  return TizenSuccess();
+}
+
+common::TizenResult IotconUtils::StateFromJson(const picojson::object& s,
+                                               iotcon_state_h* out) {
+  ScopeLogger();
+
+  iotcon_state_h state = nullptr;
+
+  auto result = IotconUtils::ConvertIotconError(iotcon_state_create(&state));
+  if (!result) {
+    LogAndReturnTizenError(result, ("iotcon_state_create() failed"));
+  }
+
+  std::unique_ptr<std::remove_pointer<iotcon_state_h>::type, void(*)(iotcon_state_h)> ptr{state, &iotcon_state_destroy};
+
+  for (const auto& property : s) {
+    const auto& key = property.first;
+
+    if (property.second.is<picojson::null>()) {
+      result = IotconUtils::ConvertIotconError(iotcon_state_add_null(state, key.c_str()));
+      if (!result) {
+        LogAndReturnTizenError(result, ("iotcon_state_add_null() failed"));
+      }
+    } else if (property.second.is<bool>()) {
+      result = IotconUtils::ConvertIotconError(iotcon_state_add_bool(state, key.c_str(), property.second.get<bool>()));
+      if (!result) {
+        LogAndReturnTizenError(result, ("iotcon_state_add_bool() failed"));
+      }
+    } else if (property.second.is<double>()) {
+      result = IotconUtils::ConvertIotconError(iotcon_state_add_double(state, key.c_str(), property.second.get<double>()));
+      if (!result) {
+        LogAndReturnTizenError(result, ("iotcon_state_add_double() failed"));
+      }
+    } else if (property.second.is<std::string>()) {
+      const auto& value = property.second.get<std::string>();
+
+      if (0 == value.find(kHexPrefix)) {
+        auto data = value.c_str() + kHexPrefix.length(); // skip prefix
+        auto size = value.length() - kHexPrefix.length();
+        auto length = size / 2;
+        std::unique_ptr<unsigned char[]> hex{new unsigned char[length]};
+        common::tools::HexToBin(data, size, hex.get(), length);
+        result = IotconUtils::ConvertIotconError(iotcon_state_add_byte_str(state, key.c_str(), hex.get(), length));
+        if (!result) {
+          LogAndReturnTizenError(result, ("iotcon_state_add_byte_str() failed"));
+        }
+      } else {
+        result = IotconUtils::ConvertIotconError(iotcon_state_add_str(state, key.c_str(), const_cast<char*>(value.c_str())));
+        if (!result) {
+          LogAndReturnTizenError(result, ("iotcon_state_add_str() failed"));
+        }
+      }
+    } else if (property.second.is<picojson::array>()) {
+      iotcon_list_h list = nullptr;
+      result = StateListFromJson(property.second.get<picojson::array>(), &list);
+      if (!result) {
+        LogAndReturnTizenError(result, ("StateListFromJson() failed"));
+      }
+      if (list) {
+        SCOPE_EXIT {
+          iotcon_list_destroy(list);
+        };
+        result = IotconUtils::ConvertIotconError(iotcon_state_add_list(state, key.c_str(), list));
+        if (!result) {
+          LogAndReturnTizenError(result, ("iotcon_state_add_list() failed"));
+        }
+      }
+    } else if (property.second.is<picojson::object>()) {
+      iotcon_state_h sub_state = nullptr;
+      result = StateFromJson(property.second.get<picojson::object>(), &sub_state);
+      if (!result) {
+        LogAndReturnTizenError(result, ("StateFromJson() failed"));
+      }
+      SCOPE_EXIT {
+        iotcon_state_destroy(sub_state);
+      };
+      result = IotconUtils::ConvertIotconError(iotcon_state_add_state(state, key.c_str(), sub_state));
+      if (!result) {
+        LogAndReturnTizenError(result, ("iotcon_state_add_state() failed"));
+      }
+    }
+  }
+
+  *out = ptr.release();
+  return TizenSuccess();
+}
+
+common::TizenResult IotconUtils::StateListFromJson(const picojson::array& l,
+                                                   iotcon_list_h* out) {
+  ScopeLogger();
+
+  iotcon_list_h list = nullptr;
+  iotcon_type_e type = IOTCON_TYPE_NONE;
+
+  // check first element in array for type
+  if (l.size() > 0) {
+    if (l[0].is<bool>()) {
+      type = IOTCON_TYPE_BOOL;
+    } else if (l[0].is<double>()) {
+      type = IOTCON_TYPE_DOUBLE;
+    } else if (l[0].is<std::string>()) {
+      if (0 == l[0].get<std::string>().find(kHexPrefix)) {
+        type = IOTCON_TYPE_BYTE_STR;
+      } else {
+        type = IOTCON_TYPE_STR;
+      }
+    } else if (l[0].is<picojson::array>()) {
+      type = IOTCON_TYPE_LIST;
+    } else if (l[0].is<picojson::object>()) {
+      type = IOTCON_TYPE_STATE;
+    }
+  }
+
+  if (IOTCON_TYPE_NONE == type) {
+    LoggerD("Empty list");
+    return TizenSuccess();
+  }
+
+  auto result = IotconUtils::ConvertIotconError(iotcon_list_create(type, &list));
+  if (!result) {
+    LogAndReturnTizenError(result, ("iotcon_list_create() failed"));
+  }
+
+  std::unique_ptr<std::remove_pointer<iotcon_list_h>::type, void(*)(iotcon_list_h)> ptr{list, &iotcon_list_destroy};
+
+  int position = 0;
+
+  // we're ignoring values with wrong type
+  for (const auto& v : l) {
+    switch (type) {
+      case IOTCON_TYPE_BOOL:
+        if (v.is<bool>()) {
+          result = IotconUtils::ConvertIotconError(iotcon_list_add_bool(list, v.get<bool>(), position++));
+          if (!result) {
+            LogAndReturnTizenError(result, ("iotcon_list_add_bool() failed"));
+          }
+        }
+        break;
+
+      case IOTCON_TYPE_DOUBLE:
+        if (v.is<double>()) {
+          result = IotconUtils::ConvertIotconError(iotcon_list_add_double(list, v.get<double>(), position++));
+          if (!result) {
+            LogAndReturnTizenError(result, ("iotcon_list_add_double() failed"));
+          }
+        }
+        break;
+
+      case IOTCON_TYPE_BYTE_STR:
+        if (v.is<std::string>()) {
+          const auto& str = v.get<std::string>();
+          if (0 == str.find(kHexPrefix)) {
+            auto data = str.c_str() + kHexPrefix.length(); // skip prefix
+            auto size = str.length() - kHexPrefix.length();
+            auto length = size / 2;
+            std::unique_ptr<unsigned char[]> hex{new unsigned char[length]};
+            common::tools::HexToBin(data, size, hex.get(), length);
+            result = IotconUtils::ConvertIotconError(iotcon_list_add_byte_str(list, hex.get(), length, position++));
+            if (!result) {
+              LogAndReturnTizenError(result, ("iotcon_list_add_byte_str() failed"));
+            }
+          }
+        }
+        break;
+
+      case IOTCON_TYPE_STR:
+        if (v.is<std::string>()) {
+          result = IotconUtils::ConvertIotconError(iotcon_list_add_str(list, const_cast<char*>(v.get<std::string>().c_str()), position++));
+          if (!result) {
+            LogAndReturnTizenError(result, ("iotcon_list_add_str() failed"));
+          }
+        }
+        break;
+
+      case IOTCON_TYPE_LIST:
+        if (v.is<picojson::array>()) {
+          iotcon_list_h sub_list = nullptr;
+          result = StateListFromJson(v.get<picojson::array>(), &sub_list);
+          if (!result) {
+            LogAndReturnTizenError(result, ("StateListFromJson() failed"));
+          }
+          SCOPE_EXIT {
+            iotcon_list_destroy(sub_list);
+          };
+          result = IotconUtils::ConvertIotconError(iotcon_list_add_list(list, sub_list, position++));
+          if (!result) {
+            LogAndReturnTizenError(result, ("iotcon_list_add_list() failed"));
+          }
+        }
+        break;
+
+      case IOTCON_TYPE_STATE:
+        if (v.is<picojson::object>()) {
+          iotcon_state_h state = nullptr;
+          result = StateFromJson(v.get<picojson::object>(), &state);
+          if (!result) {
+            LogAndReturnTizenError(result, ("StateFromJson() failed"));
+          }
+          SCOPE_EXIT {
+            iotcon_state_destroy(state);
+          };
+          result = IotconUtils::ConvertIotconError(iotcon_list_add_state(list, state, position++));
+          if (!result) {
+            LogAndReturnTizenError(result, ("iotcon_list_add_state() failed"));
+          }
+        }
+        break;
+
+      default:
+        // should not happen
+        LoggerE("Unexpected type: %d", type);
+        return common::UnknownError("Unexpected list type");
+    }
+  }
+
+  *out = ptr.release();
+  return TizenSuccess();
+}
+
 common::TizenResult IotconUtils::ConvertIotconError(int error) {
   switch (error) {
     case IOTCON_ERROR_NONE:
@@ -864,6 +1192,12 @@ iotcon_interface_e IotconUtils::ToInterface(const std::string& e) {
   IOTCON_INTERFACE_E
 }
 
+iotcon_qos_e IotconUtils::ToQos(const std::string& e) {
+  ScopeLogger();
+
+  IOTCON_QOS_E
+}
+
 #undef X
 #undef XD
 
index 6861103..3351d34 100644 (file)
@@ -66,8 +66,6 @@ struct ResourceInfo {
 typedef std::shared_ptr<ResourceInfo> ResourceInfoPtr;
 typedef std::map<long long, ResourceInfoPtr> ResourceInfoMap;
 
-class IotconServerManager;
-
 class IotconUtils {
  public:
   static common::TizenResult ArrayToInterfaces(const picojson::array& interfaces, int* res);
@@ -79,7 +77,6 @@ class IotconUtils {
                                                  int* ifaces,
                                                  int* properties);
   static common::TizenResult ResourceToJson(ResourceInfoPtr pointer,
-                                            const IotconServerManager& manager,
                                             picojson::object* res);
 
   static common::TizenResult RequestToJson(iotcon_request_h request,
@@ -95,6 +92,15 @@ class IotconUtils {
   static common::TizenResult QueryToJson(iotcon_query_h query,
                                          picojson::object* out);
 
+  static common::TizenResult RepresentationFromResource(const ResourceInfoPtr& resource,
+                                                        const picojson::value& states,
+                                                        iotcon_representation_h* representation);
+
+  static common::TizenResult StateFromJson(const picojson::object& state,
+                                           iotcon_state_h* out);
+  static common::TizenResult StateListFromJson(const picojson::array& list,
+                                               iotcon_list_h* out);
+
   static common::TizenResult ConvertIotconError(int error);
   static std::string FromConnectivityType(iotcon_connectivity_type_e e);
   static std::string FromRequestType(iotcon_request_type_e e);
@@ -102,6 +108,7 @@ class IotconUtils {
   static std::string FromInterface(iotcon_interface_e e);
 
   static iotcon_interface_e ToInterface(const std::string& e);
+  static iotcon_qos_e ToQos(const std::string& e);
 };
 
 } // namespace iotcon