From: Kamil Lysik Date: Wed, 4 Feb 2015 08:55:25 +0000 (+0100) Subject: [NBS] NBS Native implementation X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~472 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4f86536f1b7e164c4734acb7497a4b646b8054dc;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [NBS] NBS Native implementation [Verification] TCT pass: 24/25 Change-Id: I378e81df677ed17863ebb40b8e558c420ab27c9f Signed-off-by: Kamil Lysik --- diff --git a/src/networkbearerselection/networkbearerselection.gyp b/src/networkbearerselection/networkbearerselection.gyp index 54b2c480..c868701f 100644 --- a/src/networkbearerselection/networkbearerselection.gyp +++ b/src/networkbearerselection/networkbearerselection.gyp @@ -9,6 +9,7 @@ 'variables': { 'packages': [ 'icu-i18n', + 'capi-network-connection', ], }, 'sources': [ @@ -17,6 +18,8 @@ 'networkbearerselection_extension.h', 'networkbearerselection_instance.cc', 'networkbearerselection_instance.h', + 'networkbearerselection_manager.cc', + 'networkbearerselection_manager.h', ], 'conditions': [ [ 'tizen == 1', { diff --git a/src/networkbearerselection/networkbearerselection_api.js b/src/networkbearerselection/networkbearerselection_api.js index 16433853..d7374ced 100644 --- a/src/networkbearerselection/networkbearerselection_api.js +++ b/src/networkbearerselection/networkbearerselection_api.js @@ -55,26 +55,26 @@ NetworkBearerSelection.prototype.requestRouteToHost = function(networkType, doma {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} ]); + var id = nextCallbackId(); + var nativeParam = { networkType: args.networkType, - domainName: args.domainName + domainName: args.domainName, + id: id }; - var result = native_.callSync('NetworkBearerSelection_requestRouteToHost', nativeParam); - - if (native_.isFailure(result)) { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - } - - var id = nextCallbackId(); - - native_.addListener('NetworkBearerSelectionCallback_' + id, _networkBearerSelectionCallback); - callbacks[id] = { onsuccess: args.successCallback.onsuccess, ondisconnected: args.successCallback.ondisconnected, onerror: args.errorCallback }; + + native_.addListener('NetworkBearerSelectionCallback_' + id, _networkBearerSelectionCallback); + var result = native_.callSync('NetworkBearerSelection_requestRouteToHost', nativeParam); + + if (native_.isFailure(result)) { + native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } }; NetworkBearerSelection.prototype.releaseRouteToHost = function(networkType, domainName, successCallback, errorCallback) { diff --git a/src/networkbearerselection/networkbearerselection_extension.h b/src/networkbearerselection/networkbearerselection_extension.h index 73011a75..bd5034d0 100644 --- a/src/networkbearerselection/networkbearerselection_extension.h +++ b/src/networkbearerselection/networkbearerselection_extension.h @@ -16,4 +16,4 @@ class NetworkBearerSelectionExtension : public common::Extension { virtual common::Instance* CreateInstance(); }; -#endif // NETWORKBEARERSELECTION_NETWORKBEARERSELECTION_EXTENSION_H_ +#endif // NETWORKBEARERSELECTION_NETWORKBEARERSELECTION_EXTENSION_H_ diff --git a/src/networkbearerselection/networkbearerselection_instance.cc b/src/networkbearerselection/networkbearerselection_instance.cc index 9d5d4cfc..4ac386f3 100644 --- a/src/networkbearerselection/networkbearerselection_instance.cc +++ b/src/networkbearerselection/networkbearerselection_instance.cc @@ -9,6 +9,7 @@ #include "common/picojson.h" #include "common/logger.h" #include "common/platform_exception.h" +#include "common/task-queue.h" namespace extension { namespace networkbearerselection { @@ -17,97 +18,155 @@ namespace { // The privileges that required in NetworkBearerSelection API const std::string kPrivilegeNetworkBearerSelection = ""; -} // namespace +} // namespace using namespace common; using namespace extension::networkbearerselection; NetworkBearerSelectionInstance::NetworkBearerSelectionInstance() { using namespace std::placeholders; - #define REGISTER_SYNC(c,x) \ - RegisterSyncHandler(c, std::bind(&NetworkBearerSelectionInstance::x, this, _1, _2)); - REGISTER_SYNC("NetworkBearerSelection_requestRouteToHost", NetworkBearerSelectionRequestRouteToHost); - REGISTER_SYNC("NetworkBearerSelection_releaseRouteToHost", NetworkBearerSelectionReleaseRouteToHost); - #undef REGISTER_SYNC -} - -NetworkBearerSelectionInstance::~NetworkBearerSelectionInstance() { +#define REGISTER_SYNC(c, x) \ + RegisterSyncHandler( \ + c, std::bind(&NetworkBearerSelectionInstance::x, this, _1, _2)); +#define REGISTER_ASYNC(c, x) \ + RegisterHandler( \ + c, std::bind(&NetworkBearerSelectionInstance::x, this, _1, _2)); + REGISTER_SYNC("NetworkBearerSelection_requestRouteToHost", + NetworkBearerSelectionRequestRouteToHost); + REGISTER_ASYNC("NetworkBearerSelection_releaseRouteToHost", + NetworkBearerSelectionReleaseRouteToHost); +#undef REGISTER_SYNC +#undef REGISTER_ASYNC + + NetworkBearerSelectionManager::GetInstance()->AddListener(this); } +NetworkBearerSelectionInstance::~NetworkBearerSelectionInstance() {} -enum NetworkBearerSelectionCallbacks { - NetworkBearerSelectionRequestRouteToHostCallback, - NetworkBearerSelectionReleaseRouteToHostCallback -}; - -static void ReplyAsync(NetworkBearerSelectionInstance* instance, NetworkBearerSelectionCallbacks cbfunc, - int callbackId, bool isSuccess, picojson::object& param) { - param["callbackId"] = picojson::value(static_cast(callbackId)); - param["status"] = picojson::value(isSuccess ? "success" : "error"); - - // insert result for async callback to param - switch(cbfunc) { - case NetworkBearerSelectionRequestRouteToHostCallback: { - // do something... - break; - } - case NetworkBearerSelectionReleaseRouteToHostCallback: { - // do something... - break; - } - default: { - LoggerE("Invalid Callback Type"); - return; - } +#define CHECK_EXIST(args, name, out) \ + if (!args.contains(name)) { \ + ReportError(TypeMismatchException(name " is required argument"), out); \ + return; \ } - picojson::value result = picojson::value(param); - - instance->PostMessage(result.serialize().c_str()); -} - -#define CHECK_EXIST(args, name, out) \ - if (!args.contains(name)) {\ - ReportError(TypeMismatchException(name" is required argument"), out);\ - return;\ - } - - -void NetworkBearerSelectionInstance::NetworkBearerSelectionRequestRouteToHost(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) +void NetworkBearerSelectionInstance::NetworkBearerSelectionRequestRouteToHost( + const picojson::value& args, + picojson::object& out) { + LoggerD("enter"); CHECK_EXIST(args, "domainName", out) + CHECK_EXIST(args, "id", out) - int callbackId = static_cast(args.get("callbackId").get()); const std::string& domainName = args.get("domainName").get(); + const int listenerId = static_cast(args.get("id").get()); - // implement it + auto get = [=]()->void { + NetworkBearerSelectionManager::GetInstance()->requestRouteToHost( + domainName); + }; - // call ReplyAsync in later (Asynchronously) + listenerMap.insert(std::make_pair(domainName, listenerId)); - // if success - // ReportSuccess(out); - // if error - // ReportError(out); + common::TaskQueue::GetInstance().Async(get); + ReportSuccess(out); } -void NetworkBearerSelectionInstance::NetworkBearerSelectionReleaseRouteToHost(const picojson::value& args, picojson::object& out) { + +void NetworkBearerSelectionInstance::NetworkBearerSelectionReleaseRouteToHost( + const picojson::value& args, + picojson::object& out) { + LoggerD("enter"); CHECK_EXIST(args, "callbackId", out) CHECK_EXIST(args, "domainName", out) - - int callbackId = static_cast(args.get("callbackId").get()); + const double callback_id = args.get("callbackId").get(); const std::string& domainName = args.get("domainName").get(); - // implement it + auto get = [ this, callback_id ](bool status)->void { + LoggerD("enter"); + picojson::value response = picojson::value(picojson::object()); + picojson::object& obj = response.get(); + if (status) + ReportSuccess(obj); + else + ReportError(UnknownException("PLATFORM ERROR"), obj); + obj["callbackId"] = picojson::value(callback_id); + PostMessage(response.serialize().c_str()); + }; + + auto reply = [=](bool status)->void { + LoggerD("enter"); + common::TaskQueue::GetInstance().Async(std::bind(get, status)); + }; + + bool status = + NetworkBearerSelectionManager::GetInstance()->releaseRouteToHost( + domainName, reply); + if (status) { + ReportSuccess(out); + } else { + ReportError(out); + } +} - // call ReplyAsync in later (Asynchronously) +void NetworkBearerSelectionInstance::onNBSSuccess( + const std::string& domain_name) { + LoggerD("enter"); + picojson::value event = picojson::value(picojson::object()); + picojson::object& obj = event.get(); + obj["domainName"] = picojson::value(domain_name); + obj["state"] = picojson::value("Success"); + + auto iterRange = listenerMap.equal_range(domain_name); + for (auto iter = iterRange.first; iter != iterRange.second; ++iter) { + auto listenerId = (*iter).second; + obj["listenerId"] = picojson::value("NetworkBearerSelectionCallback_" + + std::to_string(listenerId)); + obj["id"] = picojson::value(static_cast(listenerId)); + LoggerD("Posting: %s", event.serialize().c_str()); + PostMessage(event.serialize().c_str()); + } +} - // if success - // ReportSuccess(out); - // if error - // ReportError(out); +void NetworkBearerSelectionInstance::onNBSError(const std::string& domain_name, + const std::string& info) { + LoggerD("enter"); + picojson::value event = picojson::value(picojson::object()); + picojson::object& obj = event.get(); + ReportError(UnknownException(info), obj); + obj["domainName"] = picojson::value(domain_name); + obj["state"] = picojson::value("Error"); + + auto iterRange = listenerMap.equal_range(domain_name); + for (auto iter = iterRange.first; iter != iterRange.second; ++iter) { + auto listenerId = (*iter).second; + obj["listenerId"] = picojson::value("NetworkBearerSelectionCallback_" + + std::to_string(listenerId)); + obj["id"] = picojson::value(static_cast(listenerId)); + LoggerD("Posting: %s", event.serialize().c_str()); + PostMessage(event.serialize().c_str()); + } + listenerMap.erase(domain_name); } +void NetworkBearerSelectionInstance::onNBSDisconnect( + const std::string& domain_name) { + LoggerD("enter"); + picojson::value event = picojson::value(picojson::object()); + picojson::object& obj = event.get(); + obj["domainName"] = picojson::value(domain_name); + obj["state"] = picojson::value("Disconnected"); + + auto iterRange = listenerMap.equal_range(domain_name); + for (auto iter = iterRange.first; iter != iterRange.second; ++iter) { + auto listenerId = (*iter).second; + obj["listenerId"] = picojson::value("NetworkBearerSelectionCallback_" + + std::to_string(listenerId)); + obj["id"] = picojson::value(static_cast(listenerId)); + LoggerD("Posting: %s", event.serialize().c_str()); + PostMessage(event.serialize().c_str()); + } + listenerMap.erase(domain_name); +} #undef CHECK_EXIST -} // namespace networkbearerselection -} // namespace extension +} // namespace networkbearerselection +} // namespace extension diff --git a/src/networkbearerselection/networkbearerselection_instance.h b/src/networkbearerselection/networkbearerselection_instance.h index 4aa27494..52319253 100644 --- a/src/networkbearerselection/networkbearerselection_instance.h +++ b/src/networkbearerselection/networkbearerselection_instance.h @@ -6,21 +6,33 @@ #define NETWORKBEARERSELECTION_NETWORKBEARERSELECTION_INSTANCE_H_ #include "common/extension.h" +#include "networkbearerselection_manager.h" +#include namespace extension { namespace networkbearerselection { -class NetworkBearerSelectionInstance : public common::ParsedInstance { +class NetworkBearerSelectionInstance : public common::ParsedInstance, + public NetworkBearerSelectionListener { public: NetworkBearerSelectionInstance(); virtual ~NetworkBearerSelectionInstance(); private: - void NetworkBearerSelectionRequestRouteToHost(const picojson::value& args, picojson::object& out); - void NetworkBearerSelectionReleaseRouteToHost(const picojson::value& args, picojson::object& out); + void NetworkBearerSelectionRequestRouteToHost(const picojson::value& args, + picojson::object& out); + void NetworkBearerSelectionReleaseRouteToHost(const picojson::value& args, + picojson::object& out); + + virtual void onNBSSuccess(const std::string& domain_name); + virtual void onNBSError(const std::string& domain_name, + const std::string& info); + virtual void onNBSDisconnect(const std::string& domain_name); + + std::multimap listenerMap; }; -} // namespace networkbearerselection -} // namespace extension +} // namespace networkbearerselection +} // namespace extension -#endif // NETWORKBEARERSELECTION_NETWORKBEARERSELECTION_INSTANCE_H_ +#endif // NETWORKBEARERSELECTION_NETWORKBEARERSELECTION_INSTANCE_H_ diff --git a/src/networkbearerselection/networkbearerselection_manager.cc b/src/networkbearerselection/networkbearerselection_manager.cc new file mode 100644 index 00000000..316802d7 --- /dev/null +++ b/src/networkbearerselection/networkbearerselection_manager.cc @@ -0,0 +1,408 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "networkbearerselection_manager.h" +#include "common/logger.h" + +#include +#include + +namespace extension { +namespace networkbearerselection { + +namespace { +const char* kPlatformError = "Platform error"; +const char* kInvalidValuesError = "Invalid values error"; +} + +struct NetworkBearerSelectionRequestEvent { + std::string domain_name; + NetworkBearerSelectionRequestEvent(const std::string& dm) : domain_name(dm) {} +}; + +struct NetworkBearerSelectionReleaseEvent { + std::string domain_name; + NetworkBearerSelectionManager::ReleaseReplyCallback callback; + NetworkBearerSelectionReleaseEvent( + const std::string& dm, + const NetworkBearerSelectionManager::ReleaseReplyCallback& cb) + : domain_name(dm), callback(cb) {} +}; + +void NetworkBearerSelectionManager::AddListener( + NetworkBearerSelectionListener* listener) { + m_listeners.push_back(listener); +} + +NetworkBearerSelectionManager* NetworkBearerSelectionManager::GetInstance() { + static NetworkBearerSelectionManager instance; + return &instance; +} + +NetworkBearerSelectionManager::NetworkBearerSelectionManager() + : m_connectionHandle(nullptr), + m_profileHandle(nullptr), + m_connectionState(ConnectionState::Unknown), + m_isConnectionOpen(false) { + int ret = connection_create(&m_connectionHandle); + + if (CONNECTION_ERROR_NONE == ret) { + LoggerD("Client registration success"); + } else { + LoggerE("Client registration failed"); + m_connectionHandle = nullptr; + } +} + +NetworkBearerSelectionManager::~NetworkBearerSelectionManager() { + if (m_connectionHandle != nullptr) { + LoggerD("Client deregistration success"); + if (m_profileHandle) { + connection_profile_destroy(m_profileHandle); + m_profileHandle = nullptr; + } + connection_destroy(m_connectionHandle); + } else { + LoggerE("Client deregistration failed"); + } +} + +void NetworkBearerSelectionManager::connection_state_changed_callback( + connection_profile_state_e state, + void* user_data) { + LoggerD("enter"); + if (user_data != nullptr) { + LoggerD("Callback registration Succeeded"); + if (state == CONNECTION_PROFILE_STATE_ASSOCIATION) { + LoggerD("association state"); + return; + } + NetworkBearerSelectionRequestEvent* event = + static_cast(user_data); + std::string domain_name = event->domain_name; + delete event; + NetworkBearerSelectionManager::GetInstance()->deregistStateChangeListener(domain_name); + if (state == CONNECTION_PROFILE_STATE_DISCONNECTED) { + NetworkBearerSelectionManager::GetInstance()->makeDisconnectCallback( + domain_name); + } + } +} + +void NetworkBearerSelectionManager::connection_profile_opened_callback( + connection_error_e result, + void* user_data) { + LoggerD("enter"); + if (user_data == nullptr) { + LoggerD("Error: null passed in profile open callback"); + return; + } + + NetworkBearerSelectionRequestEvent* event = + static_cast(user_data); + std::string domain_name = event->domain_name; + delete event; + + if (result == CONNECTION_ERROR_NONE) { + LoggerD("Connection open Succeeded"); + if (user_data != nullptr) { + NetworkBearerSelectionManager::GetInstance()->registStateChangeListener( + domain_name); + } + } else { + LoggerD("Connection open Failed"); + NetworkBearerSelectionManager::GetInstance()->makeErrorCallback( + domain_name, kPlatformError); + } +} + +void NetworkBearerSelectionManager::connection_closed_callback( + connection_error_e result, + void* user_data) { + LoggerD("enter"); + if (user_data == nullptr) { + LoggerD("Error: null passed in profile open callback"); + return; + } + + NetworkBearerSelectionReleaseEvent* event = + static_cast(user_data); + std::string domain_name = event->domain_name; + ReleaseReplyCallback callback = event->callback; + delete event; + + if (result == CONNECTION_ERROR_NONE) { + LoggerD("Connection close Succeeded"); + if (user_data != nullptr) { + NetworkBearerSelectionManager::GetInstance()->deregistStateChangeListener( + domain_name); + callback(true); + } + } else { + callback(false); + } +} + +void NetworkBearerSelectionManager::connection_closed_callback2( + connection_error_e result, + void* user_data) { + LoggerD("enter"); + if (result == CONNECTION_ERROR_NONE) { + LoggerD("Connection close Succeeded"); + } +} + +void NetworkBearerSelectionManager::requestRouteToHost( + const std::string& domain_name) { + LoggerD("NetworkBearerSelectionManager::requestRouteToHost"); + connection_profile_h profileHandle; + + if (m_connectionState == ConnectionState::Connected) { + LoggerD("connection is already opened."); + for (std::list::iterator it = m_domainNames.begin(); + it != m_domainNames.end(); + it++) { + if (*it == domain_name) { + LoggerD("Same domain name is exist in list."); + makeSuccessCallback(domain_name); + return; + } + } + } + + if (m_profileHandle) { + connection_profile_destroy(m_profileHandle); + m_profileHandle = nullptr; + } + + if (connection_get_default_cellular_service_profile( + m_connectionHandle, + CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET, + &m_profileHandle) != CONNECTION_ERROR_NONE) { + LoggerE("Fail to get profile handle"); + makeErrorCallback(domain_name, kPlatformError); + return; + } + + char* defaultProfileName_c = nullptr; + std::string defaultProfileName; + + connection_profile_get_name(m_profileHandle, &defaultProfileName_c); + if (defaultProfileName_c == nullptr) { + LoggerE("default profile is not exist."); + makeErrorCallback(domain_name, kPlatformError); + return; + } + defaultProfileName = defaultProfileName_c; + free(defaultProfileName_c); + defaultProfileName_c = nullptr; + + if (connection_get_current_profile(m_connectionHandle, &profileHandle) != + CONNECTION_ERROR_NONE) { + LoggerE("Fail to get current profile handle"); + makeErrorCallback(domain_name, kPlatformError); + return; + } + + char* currentProfileName_c = nullptr; + std::string currentProfileName; + if (connection_profile_get_name(profileHandle, ¤tProfileName_c) != + CONNECTION_ERROR_NONE) { + LoggerE("Fail to get current profile name"); + makeErrorCallback(domain_name, kPlatformError); + return; + } + + if (currentProfileName_c == nullptr) { + LoggerE("current profile is not exist."); + makeErrorCallback(domain_name, kPlatformError); + return; + } + currentProfileName = currentProfileName_c; + free(currentProfileName_c); + currentProfileName_c = nullptr; + + if (defaultProfileName != currentProfileName) { + NetworkBearerSelectionRequestEvent* event = + new NetworkBearerSelectionRequestEvent(domain_name); + if (connection_open_profile(m_connectionHandle, + m_profileHandle, + connection_profile_opened_callback, + event) != CONNECTION_ERROR_NONE) { + LoggerE("Connection open Failed"); + delete event; + makeErrorCallback(domain_name, kPlatformError); + } else { + m_isConnectionOpen = true; + } + } else { + registStateChangeListener(domain_name); + } +} + +bool NetworkBearerSelectionManager::releaseRouteToHost( + const std::string& domain_name, + const ReleaseReplyCallback& reply_cb) { + LoggerD("enter"); + for (std::list::iterator it = m_domainNames.begin(); + it != m_domainNames.end(); + it++) { + if (*it == domain_name) { + LoggerD("Same domain name is exist in list."); + m_domainNames.remove(domain_name); + LoggerD("list size : %i", m_domainNames.size()); + if (m_domainNames.size() == 0) { + if (!m_profileHandle) { + // TODO: ALREADY_IN_USE EXCEPTION + return false; + } + + if (connection_profile_unset_state_changed_cb(m_profileHandle) != + CONNECTION_ERROR_NONE) { + LoggerE("unset callback is failed"); + if (m_profileHandle) { + connection_profile_destroy(m_profileHandle); + m_profileHandle = NULL; + } + return true; + } + + if (m_isConnectionOpen) { + NetworkBearerSelectionReleaseEvent* event = + new NetworkBearerSelectionReleaseEvent(domain_name, reply_cb); + if (connection_close_profile(m_connectionHandle, + m_profileHandle, + connection_closed_callback, + event) != CONNECTION_ERROR_NONE) { + LoggerE("connection close failed"); + delete event; + reply_cb(false); + } else { + m_isConnectionOpen = false; + deregistStateChangeListener(domain_name); + } + } else { + reply_cb(true); + } + } + return true; + } + } + + // TODO: INVALID_ARGUMENT_EXCEPTION + return false; +} + +void NetworkBearerSelectionManager::registStateChangeListener( + const std::string& domain_name) { + LoggerD("enter"); + char* interfaceName = nullptr; + char* hostAddr = nullptr; + struct hostent* host_entry; + + if (connection_profile_get_network_interface_name( + m_profileHandle, &interfaceName) != CONNECTION_ERROR_NONE) { + LoggerD("Fail to get interface name!"); + if (m_profileHandle) { + connection_profile_destroy(m_profileHandle); + m_profileHandle = nullptr; + } + makeErrorCallback(domain_name, kPlatformError); + } else { + LoggerD("Interface name : %s", interfaceName); + } + + LoggerD("Domain name to be resolved: %s", domain_name.c_str()); + + host_entry = gethostbyname(domain_name.c_str()); + + if (!host_entry) { + LoggerD("gethostbyname is failed"); + makeErrorCallback(domain_name, kInvalidValuesError); + if (connection_close_profile(m_connectionHandle, + m_profileHandle, + connection_closed_callback2, + nullptr) != CONNECTION_ERROR_NONE) { + LoggerD("connection close failed"); + makeErrorCallback(domain_name, kPlatformError); + } + if (m_profileHandle) { + connection_profile_destroy(m_profileHandle); + m_profileHandle = nullptr; + } + return; + } + + hostAddr = inet_ntoa(*(struct in_addr*)host_entry->h_addr_list[0]); + LoggerD("hostAddr : %s", hostAddr); + + NetworkBearerSelectionRequestEvent* event = + new NetworkBearerSelectionRequestEvent(domain_name); + if (connection_profile_set_state_changed_cb(m_profileHandle, + connection_state_changed_callback, + event) != CONNECTION_ERROR_NONE) { + LoggerE("Callback register is failed."); + if (m_profileHandle) { + connection_profile_destroy(m_profileHandle); + m_profileHandle = nullptr; + } + delete event; + } else { + if (connection_add_route(m_connectionHandle, interfaceName, hostAddr) != + CONNECTION_ERROR_NONE) { + LoggerE("add route is failed."); + connection_profile_unset_state_changed_cb(m_profileHandle); + makeErrorCallback(domain_name, kPlatformError); + } else { + LoggerD("add route is successed."); + m_domainNames.push_back(domain_name); + makeSuccessCallback(domain_name); + } + } +} + +void NetworkBearerSelectionManager::deregistStateChangeListener( + const std::string& domain_name) { + LoggerD("enter"); + if (m_profileHandle) { + connection_profile_unset_state_changed_cb(m_profileHandle); + connection_profile_destroy(m_profileHandle); + m_profileHandle = NULL; + } + m_domainNames.remove(domain_name); + m_connectionState = ConnectionState::Disconnected; +} + +void NetworkBearerSelectionManager::makeSuccessCallback( + const std::string& domain_name) { + LoggerD("enter"); + for (NetworkBearerSelectionListener* listener : m_listeners) + listener->onNBSSuccess(domain_name); +} + +void NetworkBearerSelectionManager::makeErrorCallback( + const std::string& domain_name, + const char* info) { + LoggerD("enter"); + std::string l_info = info; + makeErrorCallback(domain_name, l_info); +} + +void NetworkBearerSelectionManager::makeErrorCallback( + const std::string& domain_name, + const std::string& info) { + LoggerD("enter"); + for (NetworkBearerSelectionListener* listener : m_listeners) + listener->onNBSError(domain_name, info); +} + +void NetworkBearerSelectionManager::makeDisconnectCallback( + const std::string& domain_name) { + LoggerD("enter"); + for (NetworkBearerSelectionListener* listener : m_listeners) + listener->onNBSDisconnect(domain_name); +} + +} // namespace networkbearerselection +} // namespace extension diff --git a/src/networkbearerselection/networkbearerselection_manager.h b/src/networkbearerselection/networkbearerselection_manager.h new file mode 100644 index 00000000..863a71b7 --- /dev/null +++ b/src/networkbearerselection/networkbearerselection_manager.h @@ -0,0 +1,87 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NETWORKBEARERSELECTION_NETWORKBEARERSELECTION_MANAGER_H_ +#define NETWORKBEARERSELECTION_NETWORKBEARERSELECTION_MANAGER_H_ + +#include +#include +#include +#include +#include + +namespace extension { +namespace networkbearerselection { + +enum class ConnectionState { + Unknown, + Connected, + Disconnected, + ConnectionFailed +}; + +enum class NetworkType { + Cellular, + Unknown +}; + +class NetworkBearerSelectionListener { + public: + virtual void onNBSSuccess(const std::string& domain_name) = 0; + virtual void onNBSError(const std::string& domain_name, + const std::string& info) = 0; + virtual void onNBSDisconnect(const std::string& domain_name) = 0; +}; + +class NetworkBearerSelectionManager { + public: + typedef std::function ReleaseReplyCallback; + void AddListener(NetworkBearerSelectionListener* listener); + + void requestRouteToHost(const std::string& domain_name); + bool releaseRouteToHost(const std::string& domain_name, + const ReleaseReplyCallback& reply_cb); + + static NetworkBearerSelectionManager* GetInstance(); + + NetworkBearerSelectionManager(const NetworkBearerSelectionManager&) = delete; + NetworkBearerSelectionManager& operator=( + const NetworkBearerSelectionManager&) = delete; + + private: + static void connection_state_changed_callback( + connection_profile_state_e state, + void* user_data); + static void connection_profile_opened_callback(connection_error_e result, + void* user_data); + static void connection_closed_callback(connection_error_e result, + void* user_data); + static void connection_closed_callback2(connection_error_e result, + void* user_data); + + void registStateChangeListener(const std::string& domain_name); + void deregistStateChangeListener(const std::string& domain_name); + + void makeSuccessCallback(const std::string& domain_name); + void makeErrorCallback(const std::string& domain_name, const char* info); + void makeErrorCallback(const std::string& domain_name, + const std::string& info); + void makeDisconnectCallback(const std::string& domain_name); + + NetworkBearerSelectionManager(); + ~NetworkBearerSelectionManager(); + + std::list m_listeners; + + connection_h m_connectionHandle; + connection_profile_h m_profileHandle; + std::list m_domainNames; + ConnectionState m_connectionState; + bool m_isConnectionOpen; +}; + +} // namespace networkbearerselection +} // namespace extension + +#endif // NETWORKBEARERSELECTION_NETWORKBEARERSELECTION_MANAGER_H_