[Iotcon] Added options attribute of RemoteResource 24/83324/3
authorPiotr Kosko <p.kosko@samsung.com>
Wed, 10 Aug 2016 06:02:46 +0000 (08:02 +0200)
committerPiotr Kosko <p.kosko@samsung.com>
Thu, 18 Aug 2016 05:47:09 +0000 (07:47 +0200)
[Feature] Added missing attribute of RemoteResource interface.

[Verification] Code compiles without errors.
  Feature was checked in chrome console with below code:

function Create_Resource() {
    var uriPath, dict, resourceTypes, resourceInterfaces;

    SERVER = tizen.iotcon.getServer();
    uriPath = "/door";
    resourceTypes = ["core.door", "oic.r.door"];
    resourceInterfaces = ["oic.if.baseline", "oic.if.ll"];
    dict = {
        isObservable : true,
        isDiscoverable : true
    };

    RESOURCE = SERVER.createResource(uriPath, resourceTypes, resourceInterfaces, dict);
};

function Remove_Resource() {
    SERVER.removeResource(RESOURCE);

};

onError = function(error) {
    console.log("Error occured: " + error.name);
};

onFoundSuccess = function(resource) {
    r = resource;
    console.log("success");
    // default value
    console.log('expected null ---- > ' + JSON.stringify(r.options));
    // ignoring change with incorrect value
    r.options = 'abc';
    console.log('expected null ---- > ' + JSON.stringify(r.options));
    // changing with correct value is possible
    r.options = [new tizen.IotconOption(2200, "abcd")];
    console.log('expected [{"id":2200,"data":"abcd"}] ---- > ' + JSON.stringify(r.options));
    // member is nullable, could change it to null
    r.options = null;
    console.log('expected null ---- > ' + JSON.stringify(r.options));
};

Create_Resource();
client = tizen.iotcon.getClient();
client.findResource(null, "core.door", "ALL", onFoundSuccess, onError);

Change-Id: I3898c04b37ed0a71bfd9b51373031e7118bd2851
Signed-off-by: Piotr Kosko <p.kosko@samsung.com>
src/iotcon/iotcon_api.js
src/iotcon/iotcon_instance.cc
src/iotcon/iotcon_instance.h
src/iotcon/iotcon_utils.cc

index 55e19bb..2f05b70 100644 (file)
@@ -563,7 +563,7 @@ function State(key, state) {
   });
 }
 
-function prepareResourceInfo(that){
+function prepareResourceInfo(that, notIncludeOptions){
   var callArgs = {};
   callArgs.id = that[kIdKey];
   if (!callArgs.id) {
@@ -580,6 +580,9 @@ function prepareResourceInfo(that){
     callArgs.isExplicitDiscoverable = that.isExplicitDiscoverable;
     callArgs.resourceTypes = that.resourceTypes;
     callArgs.resourceInterfaces = that.resourceInterfaces;
+    if (!notIncludeOptions) {
+      callArgs.options = that.options;
+    }
   } else {
     console.log("Already stored in C++, all needed info is id");
   }
@@ -602,8 +605,7 @@ function RemoteResource(data) {
   Object.defineProperties(this, {
     cachedRepresentation: {
       get: function() {
-        var callArgs = {};
-        callArgs.id = this[kIdKey];
+        var callArgs = prepareResourceInfo(this);
         var result = native.callSync('IotconRemoteResource_getCachedRepresentation', callArgs);
         if (native.isSuccess(result)) {
           return createRepresentation(native.getResultObject(result));
@@ -615,8 +617,40 @@ function RemoteResource(data) {
       enumerable: true
     },
     options: {
-      value: null,
-      writable: true,
+      get: function() {
+        var options_ = null;
+        var callArgs = prepareResourceInfo(this, true);
+        var result = native.callSync('IotconRemoteResource_getOptions', callArgs);
+        if (native.isSuccess(result)) {
+          var data = native.getResultObject(result);
+          options_ = [];
+          for (var i = 0; i < data.length; ++i) {
+            options_.push(new IotconOption(data[i].id, data[i].data));
+          }
+        }
+        return options_;
+      }.bind(this),
+      set: function(val) {
+        // array or null are only acceptable values
+        if (!T.isArray(val) && null != val) {
+          return;
+        }
+        // check types of array values
+        if (T.isArray(val)) {
+          for (var i = 0; i < val.length; ++i) {
+            if (!(val[i] instanceof tizen.IotconOption)) {
+              return;
+            }
+          }
+        }
+
+        var callArgs = prepareResourceInfo(this, true);
+        callArgs['options'] = val;
+        var result = native.callSync('IotconRemoteResource_setOptions', callArgs);
+        if (native.isSuccess(result)) {
+          manageId(this, native.getResultObject(result));
+        }
+      }.bind(this),
       enumerable: true
     }
   });
index 29af641..46b5f4d 100644 (file)
@@ -108,6 +108,8 @@ IotconInstance::IotconInstance() {
   REGISTER_SYNC("IotconResource_unsetRequestListener", ResourceUnsetRequestListener);
   REGISTER_SYNC("IotconResponse_send", ResponseSend);
   REGISTER_SYNC("IotconRemoteResource_getCachedRepresentation", RemoteResourceGetCachedRepresentation);
+  REGISTER_SYNC("IotconRemoteResource_getOptions", RemoteResourceGetOptions);
+  REGISTER_SYNC("IotconRemoteResource_setOptions", RemoteResourceSetOptions);
   REGISTER_SYNC("IotconRemoteResource_setStateChangeListener", RemoteResourceSetStateChangeListener);
   REGISTER_SYNC("IotconRemoteResource_unsetStateChangeListener", RemoteResourceUnsetStateChangeListener);
   REGISTER_SYNC("IotconRemoteResource_startCaching", RemoteResourceStartCaching);
@@ -523,7 +525,65 @@ common::TizenResult IotconInstance::RemoteResourceGetCachedRepresentation(const
     }
     return common::TizenSuccess{repr_json};
   }
-  return common::UnknownError("Failed to gather cached representation");
+  return common::AbortError("Failed to gather cached representation");
+}
+
+common::TizenResult IotconInstance::RemoteResourceGetOptions(const picojson::object& args) {
+  ScopeLogger();
+
+  FoundRemoteInfoPtr ptr;
+  auto res = IotconUtils::RemoteResourceFromJson(args, &ptr);
+  if (!res) {
+    LogAndReturnTizenError(res, ("Failed to build resource using json data"));
+  }
+
+  iotcon_options_h options = nullptr;
+  res = IotconUtils::ConvertIotconError(
+      iotcon_remote_resource_get_options(ptr->handle, &options));
+  if (!res) {
+    LogAndReturnTizenError(res, ("Gathering options failed"));
+  }
+
+  if (options) {
+    picojson::array options_array;
+    res = IotconUtils::OptionsToJson(options, &options_array);
+    if (!res) {
+      LogAndReturnTizenError(res, ("OptionsToJson() failed"));
+    }
+    return common::TizenSuccess{picojson::value(options_array)};
+  }
+
+  return common::AbortError("Failed to gather options");
+}
+
+common::TizenResult IotconInstance::RemoteResourceSetOptions(const picojson::object& args) {
+  ScopeLogger();
+  CHECK_EXIST(args, kOptions);
+
+  FoundRemoteInfoPtr ptr;
+  auto res = IotconUtils::RemoteResourceFromJson(args, &ptr);
+  if (!res) {
+    LogAndReturnTizenError(res, ("Failed to build resource using json data"));
+  }
+
+  // default value would be null (if provided value is not an array)
+  iotcon_options_h options = nullptr;
+  const auto& options_it = args.find(kOptions);
+  if (options_it->second.is<picojson::array>()) {
+    // if it is an array use provided values
+    const auto& options_array = options_it->second.get<picojson::array>();
+    res = IotconUtils::OptionsFromJson(options_array, &options);
+    if (!res) {
+      return res;
+    }
+  }
+
+  res = IotconUtils::ConvertIotconError(iotcon_remote_resource_set_options(ptr->handle, options));
+  if (!res) {
+    LogAndReturnTizenError(res, ("iotcon_response_set_options() failed"));
+  }
+
+  return common::TizenSuccess{IotconClientManager::GetInstance().StoreRemoteResource(ptr)};
 }
 
 common::TizenResult IotconInstance::RemoteResourceMethodGet(const picojson::object& args,
index 5af4f6f..48340ed 100644 (file)
@@ -45,6 +45,8 @@ class IotconInstance : public common::TizenInstance {
   common::TizenResult ResourceUnsetRequestListener(const picojson::object& args);
   common::TizenResult ResponseSend(const picojson::object& args);
   common::TizenResult RemoteResourceGetCachedRepresentation(const picojson::object& args);
+  common::TizenResult RemoteResourceGetOptions(const picojson::object& args);
+  common::TizenResult RemoteResourceSetOptions(const picojson::object& args);
   common::TizenResult RemoteResourceMethodGet(const picojson::object& args,
                                               const common::AsyncToken& token);
   common::TizenResult RemoteResourceMethodPut(const picojson::object& args,
index c167418..15fc29f 100644 (file)
@@ -406,6 +406,12 @@ TizenResult IotconUtils::ExtractFromRemoteResource(RemoteResourceInfo* resource)
     //LogAndReturnTizenError(result, ("Gathering cached representation failed"));
   }
 
+  result = ConvertIotconError(
+      iotcon_remote_resource_get_options(resource->resource, &resource->options));
+  if (!result) {
+    LogAndReturnTizenError(result, ("Gathering options failed"));
+  }
+
   return TizenSuccess();
 }
 
@@ -451,6 +457,15 @@ TizenResult IotconUtils::RemoteResourceToJson(iotcon_remote_resource_h handle,
     res->insert(std::make_pair(kRepresentation, repr_json));
   }
 
+  if (remote_res.options) {
+    picojson::array options;
+    result = OptionsToJson(remote_res.options, &options);
+    if (!result) {
+      LogAndReturnTizenError(result, ("OptionsToJson() failed"));
+    }
+    res->insert(std::make_pair(kOptions, picojson::value(options)));
+  }
+
   return TizenSuccess();
 }
 
@@ -517,6 +532,21 @@ common::TizenResult IotconUtils::RemoteResourceFromJson(const picojson::object&
     LogAndReturnTizenError(res, ("creating handle failed"));
   }
 
+  // options is optional nullable. if it's not present, just ignore it
+  auto options_it = source.find(kOptions);
+  if (source.end() != options_it) {
+    const auto& options_array = options_it->second.get<picojson::array>();
+    iotcon_options_h options = nullptr;
+    res = IotconUtils::OptionsFromJson(options_array, &options);
+    if (!res) {
+      return res;
+    }
+    res = IotconUtils::ConvertIotconError(iotcon_remote_resource_set_options((*ptr)->handle, options));
+    if (!res) {
+      LogAndReturnTizenError(res, ("iotcon_response_set_options() failed"));
+    }
+  }
+
   return TizenSuccess();
 }
 
@@ -1493,7 +1523,7 @@ common::TizenResult IotconUtils::StateListFromJson(const picojson::array& l,
       default:
         // should not happen
         LoggerE("Unexpected type: %d", type);
-        return common::UnknownError("Unexpected list type");
+        return common::AbortError("Unexpected list type");
     }
   }