[Feature] Added findResource of Client interface.
[Verification] Code compiles.
Code below works and successCallback is called two times:
var server = tizen.iotcon.getServer();
var dict = {
resourceInterfaces : ["DEFAULT", "LINK"],
isObservable : true,
isDiscoverable : true
};
server.createResource("/a/door2", ["core.door"], dict);
var dict = {
resourceInterfaces : ["DEFAULT", "LINK"],
isObservable : true,
isDiscoverable : true
};
server.createResource("/a/door3", ["core.door"], dict);
var client = tizen.iotcon.getClient();
client.findResource(null, "core.door", "ALL",
function(v){console.log("success for address: " + v.hostAddress + " and uri: " + v.uriPath)},
function(e){console.log("error " + JSON.stringify(e))},false);
Change-Id: I1b7c5fb102ba0e440651b392c0cdeabf85713e43
Signed-off-by: Piotr Kosko <p.kosko@samsung.com>
var callArgs = {};
callArgs.id = this[kIdKey];
var result = native.callSync('IotconRemoteResource_getCachedRepresentation', callArgs);
- return createRepresentation(native.getResultObject(result));
+ if (native.isSuccess(result)) {
+ return createRepresentation(native.getResultObject(result));
+ }
+ // TODO check what should be returned
+ console.log("returning empty Object");
+ return {};
}.bind(this),
set: function() {},
enumerable: true
function Client() {
}
+var findResourceListener = createListener('FindResourceListener');
+var globalFindResourceId = 0;
+
Client.prototype.findResource = function() {
var args = validator.validateMethod(arguments, [{
name: 'hostAddress',
type: types.FUNCTION,
optional: true,
nullable: true
+ }, {
+ name: 'isSecure',
+ type: types.BOOLEAN
}]);
var callArgs = {};
+ callArgs.id = ++globalFindResourceId;
callArgs.hostAddress = args.hostAddress;
callArgs.resourceType = args.resourceType;
callArgs.connectivityType = args.connectivityType;
+ callArgs.isSecure = args.isSecure;
var callback = function(result) {
if (native.isFailure(result)) {
}
};
- var result = native.call('IotconClient_findResource', callArgs, callback);
-
+ var result = native.callSync('IotconClient_findResource', callArgs);
if (native.isFailure(result)) {
throw native.getErrorObject(result);
+ } else {
+ findResourceListener.addListener(callArgs.id, callback);
}
};
#include "common/logger.h"
#include "common/scope_exit.h"
+#include "common/tools.h"
#include "iotcon/iotcon_utils.h"
}
const common::ListenerToken kResourceRequestListenerToken{"ResourceRequestListener"};
+const common::ListenerToken kFindResourceListenerToken{"FindResourceListener"};
const std::string kObserverIds = "observerIds";
const std::string kQos = "qos";
REGISTER_SYNC("Iotcon_setTimeout", SetTimeout);
REGISTER_SYNC("IotconServer_createResource", ServerCreateResource);
REGISTER_SYNC("IotconServer_removeResource", ServerRemoveResource);
+ REGISTER_SYNC("IotconClient_findResource", ClientFindResource);
#undef REGISTER_SYNC
REGISTER_ASYNC("IotconRemoteResource_methodPut", RemoteResourceMethodPut);
REGISTER_ASYNC("IotconRemoteResource_methodPost", RemoteResourceMethodPost);
REGISTER_ASYNC("IotconRemoteResource_methodDelete", RemoteResourceMethodDelete);
- REGISTER_ASYNC("IotconClient_findResource", ClientFindResource);
REGISTER_ASYNC("IotconClient_getDeviceInfo", ClientGetDeviceInfo);
REGISTER_ASYNC("IotconClient_getPlatformInfo", ClientGetPlatformInfo);
return common::UnknownError("Not implemented");
}
-common::TizenResult IotconInstance::ClientFindResource(const picojson::object& args,
- const common::AsyncToken& token) {
+void IotconInstance::ResourceFoundCallback(iotcon_remote_resource_h resource,
+ iotcon_error_e result, void *user_data) {
ScopeLogger();
- return common::UnknownError("Not implemented");
+ CallbackData* data = static_cast<CallbackData*>(user_data);
+ auto ret = IotconUtils::ConvertIotconError(result);
+ if (!ret) {
+ data->fun(ret, picojson::value{});
+ return;
+ }
+
+ picojson::value json_result = picojson::value(picojson::object());
+
+ ret = IotconUtils::RemoteResourceToJson(resource, &(json_result.get<picojson::object>()));
+ if (!ret) {
+ data->fun(ret, picojson::value{});
+ return;
+ }
+ data->fun(ret, json_result);
+}
+
+common::TizenResult IotconInstance::ClientFindResource(const picojson::object& args) {
+ ScopeLogger();
+
+ CHECK_EXIST(args, kHostAddress);
+ char* host_address = nullptr;
+ if (args.find(kHostAddress)->second.is<std::string>()) {
+ host_address = const_cast<char*>(args.find(kHostAddress)->second.get<std::string>().c_str());
+ }
+
+ CHECK_EXIST(args, kResourceType);
+ char* resource_type = nullptr;
+ if (args.find(kResourceType)->second.is<std::string>()) {
+ resource_type = const_cast<char*>(args.find(kResourceType)->second.get<std::string>().c_str());
+ }
+
+ CHECK_EXIST(args, kConnectivityType);
+ iotcon_connectivity_type_e connectivity_type = IotconUtils::ToConnectivityType(
+ args.find(kConnectivityType)->second.get<std::string>());
+ CHECK_EXIST(args, kIsSecure);
+ bool is_secure = args.find(kIsSecure)->second.get<bool>();
+
+ long long id = GetId(args);
+ auto response = [this, id](const common::TizenResult& res, const picojson::value& v) {
+ picojson::value response{picojson::object{}};
+ auto& obj = response.get<picojson::object>();
+
+ obj.insert(std::make_pair(kId, picojson::value{static_cast<double>(id)}));
+ if(res) {
+ common::tools::ReportSuccess(v, obj);
+ } else {
+ common::tools::ReportError(res, &obj);
+ }
+
+ Post(kFindResourceListenerToken, common::TizenSuccess{response});
+ };
+ CallbackData* data = new CallbackData{response};
+
+ LoggerD("Running find with:\nhost_address: %s,\nconnectivity_type: %d,\nresource_type: %s,\nis_secure: %d",
+ host_address, connectivity_type, resource_type, is_secure);
+ auto result = IotconUtils::ConvertIotconError(
+ iotcon_find_resource(host_address, connectivity_type, resource_type,
+ is_secure, ResourceFoundCallback, data));
+ if (!result) {
+ delete data;
+ LogAndReturnTizenError(result);
+ } else {
+ int timeout = 60; //default value set much bigger than default value for iotcon = 30s
+ auto result = IotconUtils::ConvertIotconError(iotcon_get_timeout(&timeout));
+ if (!result) {
+ LoggerE("iotcon_get_timeout - function call failed, using default value %d", timeout);
+ } else {
+ timeout = timeout + 1; //add one extra second to prevent too fast delete
+ }
+ // adding listener to delete data, when find would be finished
+ std::thread([data, timeout]() {
+ std::this_thread::sleep_for(std::chrono::seconds(timeout));
+ LoggerD("Deleting resource find data: %p", data);
+ delete data;
+ }).detach();
+ }
+
+ return common::TizenSuccess();
}
common::TizenResult IotconInstance::ClientAddPresenceEventListener(const picojson::object& args) {
virtual ~IotconInstance();
private:
static void ConnectionChangedCallback(bool is_connected, void* user_data);
+ static void ResourceFoundCallback(iotcon_remote_resource_h resource,
+ iotcon_error_e result, void *user_data);
common::TizenResult ResourceGetObserverIds(const picojson::object& args);
common::TizenResult ResourceNotify(const picojson::object& args);
common::TizenResult RemoteResourceStopCaching(const picojson::object& args);
common::TizenResult RemoteResourceSetConnectionChangeListener(const picojson::object& args);
common::TizenResult RemoteResourceUnsetConnectionChangeListener(const picojson::object& args);
- common::TizenResult ClientFindResource(const picojson::object& args,
- const common::AsyncToken& token);
+ common::TizenResult ClientFindResource(const picojson::object& args);
common::TizenResult ClientAddPresenceEventListener(const picojson::object& args);
common::TizenResult ClientRemovePresenceEventListener(const picojson::object& args);
common::TizenResult ClientGetDeviceInfo(const picojson::object& args,
const std::string kUriPath = "uriPath";
const std::string kStates = "states";
const std::string kId = "id";
-
+const std::string kDeviceId = "deviceId";
const std::string kHostAddress = "hostAddress";
const std::string kConnectivityType = "connectivityType";
+
const std::string kRepresentation = "representation";
const std::string kRepresentations = "representations";
const std::string kRequestType = "type";
using common::TizenResult;
using common::TizenSuccess;
+
+void IotconUtils::PropertiesToJson(int properties, picojson::object* res) {
+ bool value = properties & IOTCON_RESOURCE_OBSERVABLE;
+ res->insert(std::make_pair(kIsObservable, picojson::value(value)));
+ value = properties & IOTCON_RESOURCE_DISCOVERABLE;
+ res->insert(std::make_pair(kIsDiscoverable, picojson::value(value)));
+ value = properties & IOTCON_RESOURCE_ACTIVE;
+ res->insert(std::make_pair(kIsActive, picojson::value(value)));
+ value = properties & IOTCON_RESOURCE_SLOW;
+ res->insert(std::make_pair(kIsSlow, picojson::value(value)));
+ value = properties & IOTCON_RESOURCE_SECURE;
+ res->insert(std::make_pair(kIsSecure, picojson::value(value)));
+ value = properties & IOTCON_RESOURCE_EXPLICIT_DISCOVERABLE;
+ res->insert(std::make_pair(kIsExplicitDiscoverable, picojson::value(value)));
+}
+
TizenResult IotconUtils::ArrayToInterfaces(const picojson::array& interfaces, int* res) {
ScopeLogger();
res->insert(std::make_pair(kResourceInterfaces,
picojson::value(InterfacesToArray(ifaces))));
- bool value = properties & IOTCON_RESOURCE_OBSERVABLE;
- res->insert(std::make_pair(kIsObservable, picojson::value(value)));
- value = properties & IOTCON_RESOURCE_DISCOVERABLE;
- res->insert(std::make_pair(kIsDiscoverable, picojson::value(value)));
- value = properties & IOTCON_RESOURCE_ACTIVE;
- res->insert(std::make_pair(kIsActive, picojson::value(value)));
- value = properties & IOTCON_RESOURCE_SLOW;
- res->insert(std::make_pair(kIsSlow, picojson::value(value)));
- value = properties & IOTCON_RESOURCE_SECURE;
- res->insert(std::make_pair(kIsSecure, picojson::value(value)));
- value = properties & IOTCON_RESOURCE_EXPLICIT_DISCOVERABLE;
- res->insert(std::make_pair(kIsExplicitDiscoverable, picojson::value(value)));
+ IotconUtils::PropertiesToJson(properties, res);
picojson::array children;
for (const auto& child_resource : pointer->children) {
return TizenSuccess();
}
+TizenResult IotconUtils::ExtractFromRemoteResource(RemoteResourceInfo* resource) {
+ ScopeLogger();
+
+ auto result = ConvertIotconError(
+ iotcon_remote_resource_get_uri_path(resource->resource, &resource->uri_path));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering uri path failed"));
+ }
+
+ result = ConvertIotconError(
+ iotcon_remote_resource_get_connectivity_type(resource->resource, &resource->connectivity_type));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering connectivity type failed"));
+ }
+
+ result = ConvertIotconError(
+ iotcon_remote_resource_get_host_address(resource->resource, &resource->host_address));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering host address failed"));
+ }
+
+ result = ConvertIotconError(
+ iotcon_remote_resource_get_device_id(resource->resource, &resource->device_id));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering host address failed"));
+ }
+
+ result = ConvertIotconError(
+ iotcon_remote_resource_get_types(resource->resource, &resource->types));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering types failed"));
+ }
+
+ result = ConvertIotconError(
+ iotcon_remote_resource_get_interfaces(resource->resource, &resource->ifaces));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering interfaces failed"));
+ }
+
+ result = ConvertIotconError(
+ iotcon_remote_resource_get_properties(resource->resource, &resource->properties));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering properties failed"));
+ }
+
+ result = ConvertIotconError(
+ iotcon_remote_resource_get_options(resource->resource, &resource->options));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering options failed"));
+ }
+
+ result = ConvertIotconError(
+ iotcon_remote_resource_get_cached_representation(resource->resource, &resource->representation));
+ if (!result) {
+ LoggerD("Gathering cached representation failed");
+ //TODO check: native method returns error here, now ignoring fail instead of returning error
+ //LogAndReturnTizenError(result, ("Gathering cached representation failed"));
+ }
+
+ return TizenSuccess();
+}
+
+TizenResult IotconUtils::RemoteResourceToJson(iotcon_remote_resource_h handle,
+ picojson::object* res) {
+ ScopeLogger();
+
+ RemoteResourceInfo remote_res;
+ remote_res.resource = handle;
+ auto result = ExtractFromRemoteResource(&remote_res);
+ if (!result){
+ return result;
+ }
+ res->insert(std::make_pair(kUriPath, picojson::value(remote_res.uri_path)));
+ res->insert(std::make_pair(kConnectivityType, picojson::value(
+ FromConnectivityType(remote_res.connectivity_type))));
+ res->insert(std::make_pair(kHostAddress, picojson::value(remote_res.host_address)));
+ res->insert(std::make_pair(kDeviceId, picojson::value(remote_res.device_id)));
+
+ if (remote_res.types) {
+ picojson::array types;
+ iotcon_resource_types_foreach(remote_res.types, ResourceTypeIterator, &types);
+ res->insert(std::make_pair(kResourceTypes, picojson::value(types)));
+ }
+
+ res->insert(std::make_pair(kResourceInterfaces,
+ picojson::value(InterfacesToArray(remote_res.ifaces))));
+
+ IotconUtils::PropertiesToJson(remote_res.properties, res);
+
+ if (remote_res.options) {
+ picojson::value opt_json{picojson::array{}};
+ result = OptionsToJson(remote_res.options, &opt_json.get<picojson::array>());
+ if (!result) {
+ LogAndReturnTizenError(result, ("OptionsToJson() failed"));
+ }
+ res->insert(std::make_pair(kOptions, opt_json));
+ }
+
+ if (remote_res.representation) {
+ picojson::value repr_json{picojson::object{}};
+ result = RepresentationToJson(remote_res.representation, &repr_json.get<picojson::object>());
+ if (!result) {
+ LogAndReturnTizenError(result, ("RepresentationToJson() failed"));
+ }
+ res->insert(std::make_pair(kRepresentation, repr_json));
+ }
+
+ return TizenSuccess();
+}
+
common::TizenResult IotconUtils::RequestToJson(iotcon_request_h request,
picojson::object* out) {
ScopeLogger();
extern const std::string kUriPath;
extern const std::string kStates;
extern const std::string kId;
+extern const std::string kDeviceId;
extern const std::string kHostAddress;
extern const std::string kConnectivityType;
+extern const std::string kResourceType;
class ResourceInfo;
typedef std::shared_ptr<ResourceInfo> ResourceInfoPtr;
}
};
+struct RemoteResourceInfo {
+ iotcon_remote_resource_h resource;
+ char* uri_path;
+ iotcon_connectivity_type_e connectivity_type;
+ char* host_address;
+ char* device_id;
+ iotcon_resource_types_h types;
+ int ifaces;
+ int properties; // to check if observable
+ iotcon_options_h options;
+ iotcon_representation_h representation;
+ RemoteResourceInfo() :
+ resource(nullptr), uri_path(nullptr),
+ connectivity_type(IOTCON_CONNECTIVITY_ALL), host_address(nullptr),
+ device_id(nullptr), types(nullptr), ifaces(0),
+ properties(0), options(nullptr), representation(nullptr) {}
+ ~RemoteResourceInfo() {
+ //according to native description, must not release any handles
+ }
+};
+
class IotconUtils {
public:
+ static void PropertiesToJson(int properties, picojson::object* res);
static common::TizenResult ArrayToInterfaces(const picojson::array& interfaces, int* res);
static picojson::array InterfacesToArray(int interfaces);
static common::TizenResult ArrayToTypes(const picojson::array& types, iotcon_resource_types_h* res);
int* properties);
static common::TizenResult ResourceToJson(ResourceInfoPtr pointer,
picojson::object* res);
+ static common::TizenResult ExtractFromRemoteResource(RemoteResourceInfo* resource);
+ static common::TizenResult RemoteResourceToJson(iotcon_remote_resource_h handle,
+ picojson::object* res);
static common::TizenResult RequestToJson(iotcon_request_h request,
picojson::object* out);