From 8f6dc93a7ab3034c3ae04363cca4f923f154ffcb Mon Sep 17 00:00:00 2001
From: Piotr Kosko
Date: Wed, 17 Feb 2016 11:29:56 +0100
Subject: [PATCH] [Iotcon] Added set/unset StateChangeListener
[Verification] Code compiles, adding/removing listener works in chrome console,
listener calls not checked.
Change-Id: I9f91f2a48355b8fa52ff4fe527039b7f770d48c7
Signed-off-by: Piotr Kosko
---
src/iotcon/iotcon_api.js | 48 +++++--------
src/iotcon/iotcon_instance.cc | 69 +++++++++++++++++-
src/iotcon/iotcon_utils.cc | 132 ++++++++++++++++++++++++++++++++++
src/iotcon/iotcon_utils.h | 8 +++
4 files changed, 226 insertions(+), 31 deletions(-)
diff --git a/src/iotcon/iotcon_api.js b/src/iotcon/iotcon_api.js
index dab068b1..2647cabf 100644
--- a/src/iotcon/iotcon_api.js
+++ b/src/iotcon/iotcon_api.js
@@ -518,26 +518,22 @@ Response.prototype.send = function() {
}
};
-function RemoteResponse(request) {
- validator.isConstructorCall(this, tizen.RemoteResponse);
+function RemoteResponse(data) {
+ if (data.representation) {
+ data.representation = createRepresentation(data.representation);
+ } else {
+ data.representation = null;
+ }
- Object.defineProperties(this, {
- result: {
- value: null,
- writable: false,
- enumerable: true
- },
- representation: {
- value: null,
- writable: false,
- enumerable: true
- },
- options: {
- value: null,
- writable: false,
- enumerable: true
+ if (data.options) {
+ var options = [];
+ for (var i = 0; i < data.options.length; ++i) {
+ options.push(new IotconOption(data.options[i].id, data.options[i].data));
}
- });
+ data.options = options;
+ }
+
+ decorateWithData(data, this);
}
function State(key, state) {
@@ -768,11 +764,6 @@ RemoteResource.prototype.setStateChangeListener = function() {
}, {
name: 'successCallback',
type: types.FUNCTION
- }, {
- name: 'errorCallback',
- type: types.FUNCTION,
- optional: true,
- nullable: true
}]);
var callArgs = prepareResourceInfo(this);
@@ -781,12 +772,9 @@ RemoteResource.prototype.setStateChangeListener = function() {
var that = this;
var listener = function(result) {
- if (native.isFailure(result)) {
- native.callIfPossible(args.errorCallback, native.getErrorObject(result));
- } else {
- updateWithInternalData(native.getResultObject(result), that);
- args.successCallback(that);
- }
+ //TODO check what should be updated
+ //updateWithInternalData(result, that);
+ args.successCallback(new RemoteResponse(result.data));
};
var result = native.callSync('IotconRemoteResource_setStateChangeListener', callArgs);
@@ -794,6 +782,7 @@ RemoteResource.prototype.setStateChangeListener = function() {
if (native.isFailure(result)) {
throw native.getErrorObject(result);
} else {
+ manageId(this, native.getResultObject(result));
stateChangeListener.addListener(this[kIdKey], listener);
}
};
@@ -806,6 +795,7 @@ RemoteResource.prototype.unsetStateChangeListener = function() {
if (native.isFailure(result)) {
throw native.getErrorObject(result);
} else {
+ manageId(this, native.getResultObject(result));
stateChangeListener.removeListener(this[kIdKey]);
}
};
diff --git a/src/iotcon/iotcon_instance.cc b/src/iotcon/iotcon_instance.cc
index be20d1e3..d8c1a6af 100644
--- a/src/iotcon/iotcon_instance.cc
+++ b/src/iotcon/iotcon_instance.cc
@@ -45,6 +45,8 @@ const common::ListenerToken kFindResourceListenerToken{"FindResourceListener"};
const common::ListenerToken kPresenceEventListenerToken{"PresenceEventListener"};
const common::ListenerToken kRemoteResourceConnectionChangeListener
{"RemoteResourceConnectionChangeListener"};
+const common::ListenerToken kRemoteResourceStateChangeListener
+ {"RemoteResourceStateChangeListener"};
const std::string kObserverIds = "observerIds";
const std::string kQos = "qos";
@@ -535,14 +537,77 @@ common::TizenResult IotconInstance::RemoteResourceMethodDelete(const picojson::o
return common::UnknownError("Not implemented");
}
+static void ObserveCallback(iotcon_remote_resource_h resource, iotcon_error_e err,
+ int sequence_number, iotcon_response_h response, void *user_data) {
+ ScopeLogger();
+ FoundRemoteInfo* ptr = static_cast(user_data);
+ if (ptr->observe_listener) {
+ picojson::value json_result = picojson::value(picojson::object());
+
+ auto result = IotconUtils::ResponseToJson(response, &json_result.get());
+ if (result) {
+ ptr->observe_listener(common::TizenSuccess(), json_result);
+ } else {
+ LoggerD("Ignoring callback");
+ }
+ }
+}
+
common::TizenResult IotconInstance::RemoteResourceSetStateChangeListener(const picojson::object& args) {
ScopeLogger();
- return common::UnknownError("Not implemented");
+ CHECK_EXIST(args, kQuery);
+ CHECK_EXIST(args, kObservePolicy);
+ FoundRemoteInfoPtr ptr;
+ auto result = IotconUtils::RemoteResourceFromJson(args, &ptr);
+ if (!result) {
+ LogAndReturnTizenError(result, ("Failed to create remote resource handle"));
+ }
+
+ iotcon_query_h query = nullptr;
+ auto query_obj = args.find(kQuery)->second.get();
+ result = IotconUtils::QueryFromJson(query_obj, &query);
+ if (!result){
+ return result;
+ }
+ SCOPE_EXIT {
+ iotcon_query_destroy(query);
+ };
+
+ iotcon_observe_policy_e observe_policy = IotconUtils::ToObservePolicy(
+ args.find(kObservePolicy)->second.get().c_str());
+
+ ptr->observe_listener = [this, ptr](const common::TizenResult& res, const picojson::value& v) {
+ picojson::value response{picojson::object{}};
+ auto& obj = response.get();
+
+ obj.insert(std::make_pair(kId, picojson::value{static_cast(ptr->id)}));
+ obj.insert(std::make_pair("data", v));
+
+ Post(kRemoteResourceStateChangeListener, common::TizenSuccess{response});
+ };
+
+ result = IotconUtils::ConvertIotconError(
+ iotcon_remote_resource_observe_register(ptr->handle, observe_policy, query,
+ ObserveCallback, ptr.get()));
+ if (!result) {
+ return result;
+ }
+ return common::TizenSuccess{IotconClientManager::GetInstance().StoreRemoteResource(ptr)};
}
common::TizenResult IotconInstance::RemoteResourceUnsetStateChangeListener(const picojson::object& args) {
ScopeLogger();
- return common::UnknownError("Not implemented");
+ FoundRemoteInfoPtr ptr;
+ auto result = IotconUtils::RemoteResourceFromJson(args, &ptr);
+ if (!result) {
+ LogAndReturnTizenError(result, ("Failed to create remote resource handle"));
+ }
+ result = IotconUtils::ConvertIotconError(iotcon_remote_resource_observe_deregister(ptr->handle));
+ if (!result) {
+ return result;
+ }
+ ptr->observe_listener = nullptr;
+ return common::TizenSuccess{IotconClientManager::GetInstance().RemoveRemoteResource(ptr)};
}
static void RepresentationChangedCallback(iotcon_remote_resource_h resource,
diff --git a/src/iotcon/iotcon_utils.cc b/src/iotcon/iotcon_utils.cc
index 60e05fcd..d44e8a15 100644
--- a/src/iotcon/iotcon_utils.cc
+++ b/src/iotcon/iotcon_utils.cc
@@ -86,6 +86,11 @@ namespace {
X(IOTCON_RESPONSE_FORBIDDEN, "FORBIDDEN") \
XD(IOTCON_RESPONSE_ERROR, "unknown")
+#define IOTCON_OBSERVE_POLICY_E \
+ X(IOTCON_OBSERVE_IGNORE_OUT_OF_ORDER, "IGNORE_OUT_OF_ORDER") \
+ X(IOTCON_OBSERVE_ACCEPT_OUT_OF_ORDER, "ACCEPT_OUT_OF_ORDER") \
+ XD(IOTCON_OBSERVE_ACCEPT_OUT_OF_ORDER, "unknown")
+
} // namespace
const std::string kIsDiscoverable = "isDiscoverable";
@@ -104,6 +109,7 @@ const std::string kKeepId = "keepId";
const std::string kDeviceId = "deviceId";
const std::string kHostAddress = "hostAddress";
const std::string kConnectivityType = "connectivityType";
+const std::string kObservePolicy = "observePolicy";
const std::string kRepresentation = "representation";
const std::string kRepresentations = "representations";
@@ -1021,6 +1027,118 @@ common::TizenResult IotconUtils::QueryToJson(iotcon_query_h query,
return TizenSuccess();
}
+common::TizenResult IotconUtils::QueryFromJson(const picojson::object& source, iotcon_query_h* res) {
+ ScopeLogger();
+ iotcon_query_h query = nullptr;
+ auto result = ConvertIotconError(iotcon_query_create(&query));
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_query_create() failed"));
+ }
+ std::unique_ptr::type, void(*)(iotcon_query_h)>
+ query_ptr(query, &iotcon_query_destroy); // automatically release the memory
+ {
+ // resourceType
+ auto it = source.find(kResourceType);
+ if (source.end() != it && it->second.is()) {
+ const char* resource_type = it->second.get().c_str();
+ auto result = ConvertIotconError(iotcon_query_set_resource_type(query, resource_type));
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_query_set_resource_type() failed"));
+ }
+ }
+ }
+
+ {
+ // resourceInterface
+ auto it = source.find(kResourceInterface);
+ if (source.end() != it && it->second.is()) {
+ iotcon_interface_e interface = ToInterface(it->second.get());
+ auto result = ConvertIotconError(iotcon_query_set_interface(query, interface));
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_query_set_interface() failed"));
+ }
+ }
+ }
+
+ {
+ // filter
+ auto it = source.find(kFilter);
+ if (source.end() != it) {
+ const auto& filter = IotconUtils::GetArg(source, kFilter);
+ if (filter.is()) {
+ const auto& filter_obj = filter.get();
+ for (const auto it : filter_obj) {
+ if (it.second.is()){
+ const std::string& key = it.first;
+ const std::string& value = it.second.get();
+ LoggerD("key: %s ---- value: %s", key.c_str(), value.c_str());
+
+ auto result = ConvertIotconError(iotcon_query_add(query, key.c_str(), value.c_str()));
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_query_add() failed"));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ *res = query_ptr.release();
+ return TizenSuccess();
+}
+
+common::TizenResult IotconUtils::ResponseToJson(iotcon_response_h handle,
+ picojson::object* res) {
+ ScopeLogger();
+
+ {
+ // ResponseResult result
+ iotcon_response_result_e response = IOTCON_RESPONSE_ERROR;
+ auto result = ConvertIotconError(iotcon_response_get_result(handle, &response));
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_response_get_result() failed"));
+ }
+ std::string result_str = FromResponseResultType(response);
+ res->insert(std::make_pair(kResultType, picojson::value{result_str}));
+ }
+
+ {
+ // Representation representation
+ iotcon_representation_h repr = nullptr;
+ auto result = ConvertIotconError(iotcon_response_get_representation(handle, &repr));
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_response_get_representation() failed"));
+ }
+ picojson::value repr_json{picojson::object{}};
+ result = RepresentationToJson(repr, &repr_json.get());
+ if (!result) {
+ LogAndReturnTizenError(result, ("RepresentationToJson() failed"));
+ }
+ res->insert(std::make_pair(kRepresentation, repr_json));
+ }
+
+ {
+ // IotconOption[]? options
+ iotcon_options_h options = nullptr;
+ auto result = ConvertIotconError(iotcon_response_get_options(handle, &options));
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_response_get_options() failed"));
+ }
+ if (options) {
+ picojson::value opt_json{picojson::array{}};
+ result = OptionsToJson(options, &opt_json.get());
+ if (!result) {
+ LogAndReturnTizenError(result, ("OptionsToJson() failed"));
+ }
+ res->insert(std::make_pair(kOptions, opt_json));
+ } else {
+ res->insert(std::make_pair(kOptions, picojson::value{}));
+ }
+ }
+
+ return TizenSuccess();
+}
+
common::TizenResult IotconUtils::RepresentationFromResource(const ResourceInfoPtr& resource,
const picojson::value& states,
iotcon_representation_h* out) {
@@ -1873,6 +1991,14 @@ std::string IotconUtils::FromPresenceTriggerType(iotcon_presence_trigger_e e) {
}
}
+std::string IotconUtils::FromResponseResultType(iotcon_response_result_e e) {
+ ScopeLogger();
+
+ switch (e) {
+ IOTCON_RESPONSE_RESULT_E
+ }
+}
+
#undef X
#undef XD
@@ -1899,6 +2025,12 @@ iotcon_connectivity_type_e IotconUtils::ToConnectivityType(const std::string& e)
IOTCON_CONNECTIVITY_TYPE_E
}
+iotcon_observe_policy_e IotconUtils::ToObservePolicy(const std::string& e) {
+ ScopeLogger();
+
+ IOTCON_OBSERVE_POLICY_E
+}
+
iotcon_response_result_e IotconUtils::ToResponseResult(const std::string& e) {
IOTCON_RESPONSE_RESULT_E
}
diff --git a/src/iotcon/iotcon_utils.h b/src/iotcon/iotcon_utils.h
index 280b11e4..21dbc5b0 100644
--- a/src/iotcon/iotcon_utils.h
+++ b/src/iotcon/iotcon_utils.h
@@ -58,6 +58,8 @@ extern const std::string kConnectivityType;
extern const std::string kResourceType;
extern const std::string kRepresentation;
extern const std::string kOptions;
+extern const std::string kQuery;
+extern const std::string kObservePolicy;
class ResourceInfo;
class PresenceEvent;
@@ -115,6 +117,7 @@ struct FoundRemoteInfo {
short ref_count; // counter for registered listeners for this handle
//TODO add listeners for each type
common::PostCallback connection_listener;
+ common::PostCallback observe_listener;
FoundRemoteInfo() :
id(0), handle(nullptr), ref_count(1) {} //initialize with 1 (struct is created, so it
//mean that some listener would be created)
@@ -162,6 +165,9 @@ class IotconUtils {
picojson::array* out);
static common::TizenResult QueryToJson(iotcon_query_h query,
picojson::object* out);
+ static common::TizenResult QueryFromJson(const picojson::object& source, iotcon_query_h* res);
+ static common::TizenResult ResponseToJson(iotcon_response_h handle,
+ picojson::object* res);
static common::TizenResult PresenceResponseToJson(iotcon_presence_response_h presence,
picojson::object* out);
static common::TizenResult ExtractFromPresenceEvent(const PresenceEventPtr& pointer,
@@ -201,9 +207,11 @@ class IotconUtils {
static std::string FromInterface(iotcon_interface_e e);
static std::string FromPresenceResponseResultType(iotcon_presence_result_e e);
static std::string FromPresenceTriggerType(iotcon_presence_trigger_e e);
+ static std::string FromResponseResultType(iotcon_response_result_e e);
static iotcon_interface_e ToInterface(const std::string& e);
static iotcon_connectivity_type_e ToConnectivityType(const std::string& e);
+ static iotcon_observe_policy_e ToObservePolicy(const std::string& e);
static iotcon_qos_e ToQos(const std::string& e);
static iotcon_response_result_e ToResponseResult(const std::string& e);
};
--
2.34.1