'iotcon_instance.h',
'iotcon_server_manager.cc',
'iotcon_server_manager.h',
+ 'iotcon_client_manager.cc',
+ 'iotcon_client_manager.h',
'iotcon_utils.cc',
'iotcon_utils.h',
],
};
var presenceEventListener = createListener('PresenceEventListener', function(response) {
- return new PresenceResponse(native.getResultObject(response));
+ return new PresenceResponse(response.data);
});
Client.prototype.addPresenceEventListener = function() {
nullable: true
}, {
name: 'resourceType',
- type: types.STRING
+ type: types.STRING,
+ nullable: true
}, {
name: 'connectivityType',
type: types.ENUM,
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "iotcon/iotcon_client_manager.h"
+
+#include "common/logger.h"
+
+namespace extension {
+namespace iotcon {
+
+using common::TizenResult;
+using common::TizenSuccess;
+
+namespace {
+
+long long GetPresenceNextId() {
+ static long long id = 0;
+ return ++id;
+}
+
+} // namespace
+
+IotconClientManager& IotconClientManager::GetInstance() {
+ static IotconClientManager instance;
+ return instance;
+}
+
+TizenResult IotconClientManager::RestoreHandles() {
+ ScopeLogger();
+
+ for (const auto& it : presence_map_) {
+ LoggerD("Restoring handle for presence event with id: %lld", it.first);
+
+ PresenceEventPtr presence = it.second;
+ char* host = nullptr;
+ char* resource_type = nullptr;
+ iotcon_connectivity_type_e con_type = IOTCON_CONNECTIVITY_IPV4;
+
+ auto res = IotconUtils::ExtractFromPresenceEvent(presence, &host,
+ &con_type, &resource_type);
+ if (!res){
+ return res;
+ }
+
+ const iotcon_presence_h old_handle = presence->handle;
+ int ret = iotcon_add_presence_cb(host, con_type, resource_type,
+ PresenceHandler, this,&(presence->handle));
+ if (IOTCON_ERROR_NONE != ret || nullptr == presence->handle) {
+ LogAndReturnTizenError(IotconUtils::ConvertIotconError(ret),
+ ("iotcon_add_presence_cb() failed: %d (%s)",
+ ret, get_error_message(ret)));
+ }
+ if (old_handle) {
+ LoggerD("destroy handle which is currently invalid: %p", old_handle);
+ iotcon_remove_presence_cb(old_handle);
+ }
+ LoggerD("new handle: %p", (presence->handle));
+ }
+
+ return TizenSuccess();
+}
+
+void IotconClientManager::PresenceHandler(iotcon_presence_h presence,
+ iotcon_error_e err,
+ iotcon_presence_response_h response,
+ void *user_data) {
+ ScopeLogger();
+
+ if(IOTCON_ERROR_NONE != err) {
+ LoggerE("Error in presence event callback!");
+ return;
+ }
+ auto that = static_cast<IotconClientManager*>(user_data);
+
+ for (const auto& p : that->presence_map_) {
+ if (p.second->presence_listener && p.second->handle == presence) {
+ picojson::value value{picojson::object{}};
+ auto& obj = value.get<picojson::object>();
+ auto ret = IotconUtils::PresenceResponseToJson(response,
+ &obj);
+ if (!ret) {
+ LoggerE("PresenceResponseToJson() failed");
+ return;
+ }
+ // call listener
+ p.second->presence_listener(TizenSuccess(), value);
+ }
+ }
+};
+
+common::TizenResult IotconClientManager::AddPresenceEventListener(
+ const char* host, const iotcon_connectivity_type_e con_type_e,
+ const char* resource_type, PresenceEventPtr presence) {
+ ScopeLogger();
+
+ auto result = IotconUtils::ConvertIotconError(iotcon_add_presence_cb(
+ host, con_type_e, resource_type, PresenceHandler, this,
+ &(presence->handle)));
+
+ // storing PresenceEvent into map
+ presence->id = GetPresenceNextId();
+ presence_map_.insert(std::make_pair(presence->id, presence));
+
+ return TizenSuccess();
+}
+
+common::TizenResult IotconClientManager::RemovePresenceEventListener(long long id) {
+ auto it = presence_map_.find(id);
+ if (it == presence_map_.end()) {
+ return LogAndCreateTizenError(AbortError, "Presence callback with specified ID does not exist");
+ }
+
+ auto result = IotconUtils::ConvertIotconError(iotcon_remove_presence_cb(it->second->handle));
+
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_remove_presence_cb failed"));
+ }
+
+ presence_map_.erase(id);
+
+ return TizenSuccess();
+}
+
+} // namespace iotcon
+} // namespace extension
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WEBAPI_PLUGINS_IOTCON_CLIENT_MANAGER_H__
+#define WEBAPI_PLUGINS_IOTCON_CLIENT_MANAGER_H__
+
+#include <memory>
+#include <map>
+#include <string>
+#include <iotcon.h>
+
+#include "iotcon/iotcon_utils.h"
+
+#include "common/tizen_result.h"
+
+namespace extension {
+namespace iotcon {
+
+class IotconClientManager {
+ public:
+ static IotconClientManager& GetInstance();
+
+ common::TizenResult RestoreHandles();
+ common::TizenResult AddPresenceEventListener(const char* host,
+ const iotcon_connectivity_type_e con_type_e,
+ const char* resource_type,
+ PresenceEventPtr presence);
+ common::TizenResult RemovePresenceEventListener(long long id);
+
+ private:
+ IotconClientManager() = default;
+ IotconClientManager(const IotconClientManager&) = delete;
+ IotconClientManager(IotconClientManager&&) = delete;
+ IotconClientManager& operator=(const IotconClientManager&) = delete;
+ IotconClientManager& operator=(IotconClientManager&&) = delete;
+
+ static void PresenceHandler(iotcon_presence_h resource,
+ iotcon_error_e err,
+ iotcon_presence_response_h response,
+ void *user_data);
+
+ PresenceMap presence_map_;
+};
+
+} // namespace iotcon
+} // namespace extension
+
+#endif // WEBAPI_PLUGINS_IOTCON_CLIENT_MANAGER_H__
#include "iotcon/iotcon_instance.h"
#include <thread>
+#include <iotcon-internal.h>
#include "common/logger.h"
#include "common/scope_exit.h"
#include "common/tools.h"
#include "iotcon/iotcon_utils.h"
+#include "iotcon/iotcon_server_manager.h"
+#include "iotcon/iotcon_client_manager.h"
namespace extension {
namespace iotcon {
common::PostCallback fun;
} CallbackData;
-const std::string kTimeout = "timeout";
-
#define CHECK_EXIST(args, name) \
if (args.end() == args.find(name)) { \
return common::TypeMismatchError(std::string(name) + " is required argument"); \
const common::ListenerToken kResourceRequestListenerToken{"ResourceRequestListener"};
const common::ListenerToken kFindResourceListenerToken{"FindResourceListener"};
+const common::ListenerToken kPresenceEventListenerToken{"PresenceEventListener"};
const std::string kObserverIds = "observerIds";
const std::string kQos = "qos";
const std::string kType = "type";
const std::string kInterface = "iface";
+const std::string kTimeout = "timeout";
} // namespace
IotconInstance::IotconInstance() {
} else {
LoggerD("Iotcon connection changed callback is registered");
}
+
+ ret = iotcon_start_presence(0);
+ if (IOTCON_ERROR_NONE != ret) {
+ LoggerE("Could not start presence: %s",
+ get_error_message(ret));
+ } else {
+ LoggerD("Iotcon iotcon_start_presence");
+ }
}
}
if (!ret) {
LoggerD("Connection recovered, but restoring handles failed");
}
+
+ ret = IotconClientManager::GetInstance().RestoreHandles();
+ if (!ret) {
+ LoggerD("Connection recovered, but restoring presence failed");
+ }
}
}
IotconInstance::~IotconInstance() {
ScopeLogger();
+ iotcon_stop_presence();
iotcon_remove_connection_changed_cb(ConnectionChangedCallback, this);
iotcon_disconnect();
}
common::TizenResult IotconInstance::ClientAddPresenceEventListener(const picojson::object& args) {
ScopeLogger();
- return common::UnknownError("Not implemented");
+
+ CHECK_EXIST(args, kHostAddress);
+ CHECK_EXIST(args, kResourceType);
+ CHECK_EXIST(args, kConnectivityType);
+
+ char* host = nullptr;
+ if (args.find(kHostAddress)->second.is<std::string>()) {
+ host = const_cast<char*>(args.find(kHostAddress)->second.get<std::string>().c_str());
+ }
+
+ 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());
+ }
+
+ auto& con_type = GetArg(args, kConnectivityType);
+ if (!con_type.is<std::string>()) {
+ return common::TypeMismatchError("connectivityType needs to be a string");
+ }
+ iotcon_connectivity_type_e con_type_e = IotconUtils::ToConnectivityType(
+ con_type.get<std::string>());
+
+ PresenceEventPtr presence{new PresenceEvent()};
+ auto ret = IotconClientManager::GetInstance().AddPresenceEventListener(
+ host, con_type_e, resource_type, presence);
+ if (!ret) {
+ return ret;
+ }
+
+ long long id = presence->id;
+
+ presence->presence_listener = [this, id](const common::TizenResult&, 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)}));
+ obj.insert(std::make_pair("data", v));
+
+ Post(kPresenceEventListenerToken, common::TizenSuccess{response});
+ };
+
+ return common::TizenSuccess(picojson::value{static_cast<double>(id)});
}
common::TizenResult IotconInstance::ClientRemovePresenceEventListener(const picojson::object& args) {
ScopeLogger();
- return common::UnknownError("Not implemented");
+
+ CHECK_EXIST(args, kId);
+
+ auto ret = IotconClientManager::GetInstance().RemovePresenceEventListener(GetId(args));
+
+ if (!ret) {
+ return ret;
+ }
+
+ return common::TizenSuccess();
}
-void IotconPDeviceInfoCb(iotcon_device_info_h device_info,
+void IotconDeviceInfoCb(iotcon_device_info_h device_info,
iotcon_error_e result, void *user_data) {
ScopeLogger();
if (IOTCON_ERROR_NONE != result) {
ret = IotconUtils::ConvertIotconError(result);
} else {
- auto ret = IotconUtils::DeviceInfoToJson(device_info,&v.get<picojson::object>());
+ ret = IotconUtils::DeviceInfoToJson(device_info,&v.get<picojson::object>());
}
data->fun(ret, v);
CallbackData* data = new CallbackData{SimplePost(token)};
auto result = IotconUtils::ConvertIotconError(
- iotcon_get_device_info(host.c_str(), con_type_e, IotconPDeviceInfoCb,
+ iotcon_get_device_info(host.c_str(), con_type_e, IotconDeviceInfoCb,
data));
if (!result) {
#include "common/tizen_instance.h"
-#include "iotcon/iotcon_server_manager.h"
+#include <iotcon.h>
namespace extension {
namespace iotcon {
X(IOTCON_QOS_HIGH, "HIGH") \
XD(IOTCON_QOS_LOW, "unknown")
+#define IOTCON_PRESENCE_RESULT_E \
+ X(IOTCON_PRESENCE_OK, "OK") \
+ X(IOTCON_PRESENCE_STOPPED, "STOPPED") \
+ XD(IOTCON_PRESENCE_TIMEOUT, "TIMEOUT")
+
+#define IOTCON_PRESENCE_TRIGGER_E \
+ X(IOTCON_PRESENCE_RESOURCE_CREATED, "CREATED") \
+ X(IOTCON_PRESENCE_RESOURCE_UPDATED, "UPDATED") \
+ XD(IOTCON_PRESENCE_RESOURCE_DESTROYED, "DESTROYED")
+
} // namespace
const std::string kIsDiscoverable = "isDiscoverable";
const std::string kOicDeviceId = "oicDeviceId";
const std::string kDataModelVersion = "dataModelVersion";
+const std::string kResultType = "resultType";
+const std::string kTriggerType = "triggerType";
+
using common::TizenResult;
using common::TizenSuccess;
return TizenSuccess();
}
+common::TizenResult IotconUtils::PresenceResponseToJson(
+ iotcon_presence_response_h presence, picojson::object* out) {
+ ScopeLogger();
+
+ {
+ // hostAddress
+ char* host = nullptr;
+ auto result = ConvertIotconError(iotcon_presence_response_get_host_address(presence,
+ &host));
+ if (!result || !host) {
+ LogAndReturnTizenError(result, ("iotcon_presence_response_get_host_address() failed"));
+ }
+ out->insert(std::make_pair(kHostAddress, picojson::value{std::string(host)}));
+ }
+
+ {
+ // connectivityType
+ iotcon_connectivity_type_e con_type = IOTCON_CONNECTIVITY_IPV4;
+ auto result = ConvertIotconError(iotcon_presence_response_get_connectivity_type(presence,
+ &con_type));
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_presence_response_get_connectivity_type() failed"));
+ }
+ out->insert(std::make_pair(kConnectivityType, picojson::value{
+ FromConnectivityType(con_type)}));
+ }
+
+ {
+ // resourceType
+ char* resource_type = nullptr;
+ auto result = ConvertIotconError(iotcon_presence_response_get_resource_type(presence,
+ &resource_type));
+ if (!result || !resource_type) {
+ LoggerE("iotcon_presence_response_get_resource_type() failed");
+ out->insert(std::make_pair(kResourceType, picojson::value()));
+ } else {
+ out->insert(std::make_pair(kResourceType, picojson::value{std::string(resource_type)}));
+ }
+ }
+
+ // resultType
+ iotcon_presence_result_e result_type = IOTCON_PRESENCE_OK;
+ {
+ auto result = ConvertIotconError(iotcon_presence_response_get_result(presence,
+ &result_type));
+ if (!result) {
+ LogAndReturnTizenError(result, ("iotcon_presence_response_get_result() failed"));
+ }
+
+ out->insert(std::make_pair(kResultType, picojson::value{
+ FromPresenceResponseResultType(result_type)}));
+ }
+
+ {
+ // triggerType
+ iotcon_presence_trigger_e trigger_type = IOTCON_PRESENCE_RESOURCE_CREATED;
+ if (IOTCON_PRESENCE_OK == result_type) {
+ auto result = ConvertIotconError(iotcon_presence_response_get_trigger(presence,
+ &trigger_type));
+ if (!result) {
+ LoggerE("iotcon_presence_response_get_trigger() failed");
+ out->insert(std::make_pair(kTriggerType, picojson::value()));
+ } else {
+ out->insert(std::make_pair(kTriggerType, picojson::value{FromPresenceTriggerType(
+ trigger_type)}));
+ }
+ } else {
+ out->insert(std::make_pair(kTriggerType, picojson::value()));
+ }
+
+ }
+
+ return TizenSuccess();
+}
+
+common::TizenResult IotconUtils::ExtractFromPresenceEvent(const PresenceEventPtr& pointer,
+ char** host,
+ iotcon_connectivity_type_e* con_type,
+ char** resource_type) {
+ ScopeLogger();
+
+ auto result = ConvertIotconError(iotcon_presence_get_host_address(pointer->handle,
+ host));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering presence host address failed"));
+ }
+
+ result = ConvertIotconError(iotcon_presence_get_connectivity_type(pointer->handle,
+ con_type));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering presence connectivity type failed"));
+ }
+
+ result = ConvertIotconError(iotcon_presence_get_resource_type(pointer->handle,
+ resource_type));
+ if (!result) {
+ LogAndReturnTizenError(result, ("Gathering presence resource type failed"));
+ }
+
+ return TizenSuccess();
+}
+
common::TizenResult IotconUtils::PlatformInfoGetProperty(iotcon_platform_info_h platform,
iotcon_platform_info_e property_e,
const std::string& name,
}
}
+std::string IotconUtils::FromPresenceResponseResultType(iotcon_presence_result_e e) {
+ ScopeLogger();
+
+ switch (e) {
+ IOTCON_PRESENCE_RESULT_E
+ }
+}
+
+std::string IotconUtils::FromPresenceTriggerType(iotcon_presence_trigger_e e) {
+ ScopeLogger();
+
+ switch (e) {
+ IOTCON_PRESENCE_TRIGGER_E
+ }
+}
+
#undef X
#undef XD
extern const std::string kIsSecure;
extern const std::string kIsExplicitDiscoverable;
extern const std::string kResourceTypes;
+extern const std::string kResourceType;
extern const std::string kResourceInterfaces;
extern const std::string kResourceChildren;
extern const std::string kUriPath;
extern const std::string kResourceType;
class ResourceInfo;
+class PresenceEvent;
+
typedef std::shared_ptr<ResourceInfo> ResourceInfoPtr;
typedef std::map<long long, ResourceInfoPtr> ResourceInfoMap;
+typedef std::shared_ptr<PresenceEvent> PresenceEventPtr;
+typedef std::map<long long, PresenceEventPtr> PresenceMap;
struct ResourceInfo {
long long id;
}
};
+struct PresenceEvent {
+ long long id;
+ iotcon_presence_h handle;
+ common::PostCallback presence_listener;
+};
+
class IotconUtils {
public:
static void PropertiesToJson(int properties, picojson::object* res);
picojson::array* out);
static common::TizenResult QueryToJson(iotcon_query_h query,
picojson::object* out);
+ static common::TizenResult PresenceResponseToJson(iotcon_presence_response_h presence,
+ picojson::object* out);
+ static common::TizenResult ExtractFromPresenceEvent(const PresenceEventPtr& pointer,
+ char** host,
+ iotcon_connectivity_type_e* con_type,
+ char** resource_type);
static common::TizenResult PlatformInfoToJson(iotcon_platform_info_h platform,
picojson::object* out);
static common::TizenResult PlatformInfoGetProperty(iotcon_platform_info_h platform,
static std::string FromRequestType(iotcon_request_type_e e);
static std::string FromObserveType(iotcon_observe_type_e e);
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 iotcon_interface_e ToInterface(const std::string& e);
static iotcon_connectivity_type_e ToConnectivityType(const std::string& e);