From 1507c074fc30b6a5b1a129c44a6dd13601e5bfb4 Mon Sep 17 00:00:00 2001 From: Jakub Skowron Date: Mon, 14 Nov 2016 19:37:44 +0100 Subject: [PATCH] [Iotcon] implement add/removeGeneratedPinListener Added iotcon_manager and implemented methods tizen.iotcon.add/removeGeneratedPinListener using native iotcon_add/remove_generated_pin_cb() Change-Id: I60767a8f0ed7ef8fb5378e2ad77d8059be45f18c Signed-off-by: Jakub Skowron --- src/iotcon/iotcon.gyp | 2 + src/iotcon/iotcon_api.js | 36 +++++++++++++ src/iotcon/iotcon_instance.cc | 26 ++++++++++ src/iotcon/iotcon_instance.h | 2 + src/iotcon/iotcon_manager.cc | 97 +++++++++++++++++++++++++++++++++++ src/iotcon/iotcon_manager.h | 54 +++++++++++++++++++ 6 files changed, 217 insertions(+) create mode 100644 src/iotcon/iotcon_manager.cc create mode 100644 src/iotcon/iotcon_manager.h diff --git a/src/iotcon/iotcon.gyp b/src/iotcon/iotcon.gyp index c45581fa..0fa85ed4 100644 --- a/src/iotcon/iotcon.gyp +++ b/src/iotcon/iotcon.gyp @@ -15,6 +15,8 @@ 'iotcon_extension.h', 'iotcon_instance.cc', 'iotcon_instance.h', + 'iotcon_manager.cc', + 'iotcon_manager.h', 'iotcon_server_manager.cc', 'iotcon_server_manager.h', 'iotcon_client_manager.cc', diff --git a/src/iotcon/iotcon_api.js b/src/iotcon/iotcon_api.js index c8ea7862..1afe4a0a 100644 --- a/src/iotcon/iotcon_api.js +++ b/src/iotcon/iotcon_api.js @@ -1384,6 +1384,42 @@ Iotcon.prototype.setTimeout = function() { } }; +var generatedPinListener = createListener( 'GeneratedPinListener' /* kGeneratedPinToken in iotcon_instance.cc */, + function(response) { return response.pin; } ); + +Iotcon.prototype.addGeneratedPinListener = function() { + var args = validator.validateMethod(arguments, [{ + name: 'successCallback', + type: types.FUNCTION + }]); + + var result = native.callSync('Iotcon_addGeneratedPinListener', {}); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } else { + var watchId = native.getResultObject(result); + generatedPinListener.addListener(watchId, args.successCallback); + return watchId; + } +}; + +Iotcon.prototype.removeGeneratedPinListener = function() { + var args = validator.validateMethod(arguments, [{ + name: 'watchId', + type: types.LONG + }]); + + var result = native.callSync('Iotcon_removeGeneratedPinListener', { watchId: args.watchId }); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } else { + generatedPinListener.removeListener(args.watchId); + } +}; + + // Exports tizen.IotconOption = IotconOption; tizen.Representation = Representation; diff --git a/src/iotcon/iotcon_instance.cc b/src/iotcon/iotcon_instance.cc index 41aa17e0..73bdb1e4 100644 --- a/src/iotcon/iotcon_instance.cc +++ b/src/iotcon/iotcon_instance.cc @@ -23,6 +23,7 @@ #include "common/tools.h" #include "iotcon/iotcon_utils.h" +#include "iotcon/iotcon_manager.h" #include "iotcon/iotcon_server_manager.h" #include "iotcon/iotcon_client_manager.h" @@ -70,6 +71,7 @@ void RemoteResourceResponseCallback(iotcon_remote_resource_h resource, } } +const common::ListenerToken kGeneratedPinToken{"GeneratedPinListener"}; const common::ListenerToken kResourceRequestListenerToken{"ResourceRequestListener"}; const common::ListenerToken kFindResourceListenerToken{"FindResourceListener"}; const common::ListenerToken kPresenceEventListenerToken{"PresenceEventListener"}; @@ -131,6 +133,8 @@ IotconInstance::IotconInstance() : initialized_(false), presence_started_(false) REGISTER_SYNC("Iotcon_initialize", Initialize); REGISTER_SYNC("Iotcon_getTimeout", GetTimeout); REGISTER_SYNC("Iotcon_setTimeout", SetTimeout); + REGISTER_SYNC("Iotcon_addGeneratedPinListener", AddGeneratedPinListener); + REGISTER_SYNC("Iotcon_removeGeneratedPinListener", RemoveGeneratedPinListener); REGISTER_SYNC("IotconServer_createResource", ServerCreateResource); REGISTER_SYNC("IotconServer_removeResource", ServerRemoveResource); REGISTER_SYNC("IotconServer_startPresence", ServerStartPresence); @@ -1624,6 +1628,28 @@ common::TizenResult IotconInstance::SetTimeout(const picojson::object& args) { return common::TizenSuccess(); } +common::TizenResult IotconInstance::AddGeneratedPinListener(const picojson::object& args) { + ScopeLogger(); + + auto listener = [this](const char* pin, long watchId) { + picojson::object obj; + obj[kId] = picojson::value{(double)watchId}; + obj["pin"] = picojson::value{pin}; + this->Post(kGeneratedPinToken, common::TizenSuccess{ picojson::value{obj} }); + }; + + return IotconManager::GetInstance().addGeneratedPinListener(listener); +} + +common::TizenResult IotconInstance::RemoveGeneratedPinListener(const picojson::object& args) { + ScopeLogger(); + + CHECK_EXIST(args, "watchId"); + long watchId = args.find("watchId")->second.get(); + + return IotconManager::GetInstance().removeGeneratedPinListener(watchId); +} + common::PostCallback IotconInstance::PostForMethodCall(const common::AsyncToken& token, const FoundRemoteInfoPtr& resource) { ScopeLogger(); diff --git a/src/iotcon/iotcon_instance.h b/src/iotcon/iotcon_instance.h index 4a0201b9..2d44f5c9 100644 --- a/src/iotcon/iotcon_instance.h +++ b/src/iotcon/iotcon_instance.h @@ -78,6 +78,8 @@ class IotconInstance : public common::TizenInstance { common::TizenResult Initialize(const picojson::object& args); common::TizenResult GetTimeout(const picojson::object& args); common::TizenResult SetTimeout(const picojson::object& args); + common::TizenResult AddGeneratedPinListener(const picojson::object& args); + common::TizenResult RemoveGeneratedPinListener(const picojson::object& args); common::PostCallback PostForMethodCall(const common::AsyncToken& token, const FoundRemoteInfoPtr& resource); diff --git a/src/iotcon/iotcon_manager.cc b/src/iotcon/iotcon_manager.cc new file mode 100644 index 00000000..d0f6c499 --- /dev/null +++ b/src/iotcon/iotcon_manager.cc @@ -0,0 +1,97 @@ +/* + * 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. + */ + +#include + +#include + +#include "iotcon/iotcon_manager.h" +#include "iotcon/iotcon_utils.h" +#include "common/logger.h" + +namespace extension { +namespace iotcon { + +IotconManager::IotconManager() : nextWatchId(1) { +} + +IotconManager& IotconManager::GetInstance() { + static IotconManager instance; + return instance; +} + +common::TizenResult IotconManager::addGeneratedPinListener(std::function listener) { + ScopeLogger(); + using namespace std::placeholders; + + //generate id + long watchId = nextWatchId++; + + std::function listener_with_id = std::bind(listener, _1, watchId); + + iotcon_generated_pin_cb callback = IotconManager::ListenerHandler; + + { + std::lock_guard mutex_lock{listeners_mutex}; + if( listeners.empty() ) { + /* user_data is not used */ + auto result = IotconUtils::ConvertIotconError( iotcon_add_generated_pin_cb(callback, nullptr) ); + if( !result ) { + return result; + } + } + + //store listener in map + this->listeners[watchId] = listener_with_id; + } + + return common::TizenSuccess{ picojson::value{(double)watchId} }; +} + +common::TizenResult IotconManager::removeGeneratedPinListener(long watchId) { + std::lock_guard mutex_guard{listeners_mutex}; + + auto it = listeners.find(watchId); + if( it == listeners.end() ) { + return LogAndCreateTizenError(AbortError, "Listener with specified ID does not exist"); + } + + listeners.erase(it); + + // If we deleted last listener, unregister our handler + if( listeners.empty() ) { + auto result = IotconUtils::ConvertIotconError( iotcon_remove_generated_pin_cb(IotconManager::ListenerHandler) ); + if (!result) { + return result; + } + } + + return common::TizenSuccess{}; +} + +void IotconManager::ListenerHandler(const char* pin, void *user_data) { + ScopeLogger(); + /* user_data is not used */ + + auto& instance = IotconManager::GetInstance(); + std::unique_lock mutex_guard{instance.listeners_mutex}; + for( auto& listener : instance.listeners ) { + listener.second(pin); + } +}; + +} // namespace iotcon +} // namespace extension diff --git a/src/iotcon/iotcon_manager.h b/src/iotcon/iotcon_manager.h new file mode 100644 index 00000000..2d9876e7 --- /dev/null +++ b/src/iotcon/iotcon_manager.h @@ -0,0 +1,54 @@ +/* + * 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 IOTCON_MANAGER_H_ +#define IOTCON_MANAGER_H_ + +#include +#include +#include + +#include "common/tizen_result.h" + +namespace extension { +namespace iotcon { + +class IotconManager { + public: + static IotconManager& GetInstance(); + + common::TizenResult addGeneratedPinListener(std::function listener); + common::TizenResult removeGeneratedPinListener(long watchId); + + private: + static void ListenerHandler(const char* pin, void *user_data); + + IotconManager(); + IotconManager(const IotconManager&) = delete; + IotconManager(IotconManager&&) = delete; + IotconManager& operator=(const IotconManager&) = delete; + IotconManager& operator=(IotconManager&&) = delete; + + long nextWatchId; + std::map > listeners; + std::mutex listeners_mutex; +}; + +} // namespace iotcon +} // namespace extension + + +#endif /* IOTCON_MANAGER_H_ */ -- 2.34.1