*/
#include <net_connection.h>
+#include <wifi.h>
#include <FNetNetConnectionInfo.h>
#include <FBaseRtMutexGuard.h>
#include <FBaseSysLog.h>
+#include <FSysSettingInfo.h>
#include <FBase_StringConverter.h>
+#include <FApp_AppManagerImpl.h>
#include "FNet_NetTypes.h"
#include "FNet_NetConnectionInfoImpl.h"
#include "FNet_WifiSystemNetConnection.h"
#include "FNet_NetConnectionEventArg.h"
using namespace std;
+using namespace Tizen::App;
using namespace Tizen::Base;
using namespace Tizen::Base::Collection;
using namespace Tizen::Base::Runtime;
+using namespace Tizen::System;
namespace Tizen { namespace Net {
+static const char* _WIFI_QS_APP_ID = "net.wifi-qs";
+
void
WifiConnectionTypeChangedCallback(connection_type_e type, void* pUserData)
{
E_SYSTEM, "WIFI profileHandle is not found.");
SysLog(NID_NET, "Wifi is connected.");
- pConnection->HandleStartEvent();
- pConnection->UpdateConnectionInfo(profileHandle);
+
+ if (pConnection->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
+ {
+ pConnection->HandleStartResponse(E_SUCCESS, profileHandle);
+ }
+ else
+ {
+ pConnection->HandleStartEvent();
+ pConnection->UpdateConnectionInfo(profileHandle);
+ }
connection_profile_destroy(profileHandle);
}
else
{
SysLog(NID_NET, "Wifi is not connected.");
- pConnection->HandleStopEvent(E_NETWORK_FAILED);
- pConnection->UpdateConnectionInfo(null);
+
+ if (pConnection->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
+ {
+ bool isWifiQsRunning = false;
+
+ isWifiQsRunning = _AppManagerImpl::GetInstance()->IsRunning(String(_WIFI_QS_APP_ID));
+
+ if (isWifiQsRunning)
+ {
+ SysLog(NID_NET, "Ignore disconnected event on the starting state because Wi-Fi QuickStart is running.");
+ }
+ else
+ {
+ SysLog(NID_NET, "Failed to connect Wifi.");
+ pConnection->HandleStartResponse(E_NETWORK_FAILED, null);
+ }
+ }
+ else
+ {
+ pConnection->HandleStopEvent(E_NETWORK_FAILED);
+ pConnection->UpdateConnectionInfo(null);
+ }
}
}
+void
+WifiActivatedCallback(wifi_error_e res, void* pUserData)
+{
+ _WifiSystemNetConnection* pConnection = static_cast<_WifiSystemNetConnection*>(pUserData);
+
+ SysLog(NID_NET, "Enter with res[%d].", res);
+
+ if (res != WIFI_ERROR_NONE)
+ {
+ SysLogException(NID_NET, E_NETWORK_FAILED, "[E_NETWORK_FAILED] Failed to activate Wi-Fi.");
+ pConnection->HandleStartResponse(E_NETWORK_FAILED, null);
+ }
+
+ SysLog(NID_NET, "Exit.");
+}
+
_WifiSystemNetConnection::_WifiSystemNetConnection(void)
: __pConnectionHandle(null)
+ , __pTimer(null)
{
}
{
result r = E_SUCCESS;
unique_ptr<void, _ConnectionDeleter> pConnectionHandle;
+ unique_ptr<Timer> pTimer;
+
int ret = CONNECTION_ERROR_NONE;
connection_h connectionHandle = null;
connection_profile_h profileHandle = null;
SysAssertf(__pConnectionHandle == null,
"Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
+ pTimer.reset(new (std::nothrow) Timer());
+ SysTryReturnResult(NID_NET, pTimer != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
+
+ r = pTimer->Construct(*this);
+ SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.");
+
r = _SystemNetConnection::Initialize(L"WIFI");
SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.", GetErrorMessage(r));
+ ret = wifi_initialize();
+ SysTryCatch(NID_NET, ((ret == WIFI_ERROR_NONE) || (ret == WIFI_ERROR_INVALID_OPERATION)),
+ r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] wifi_initialize() failed with ret=[%d]", ret);
+
ret = connection_create(&connectionHandle);
SysTryCatch(NID_NET, ret == CONNECTION_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
"[%s] A system error has been occurred. The return value from connection_create() is %d", GetErrorMessage(E_SYSTEM), ret);
}
__pConnectionHandle = move(pConnectionHandle);
+ __pTimer = move(pTimer);
return r;
return r;
}
+result
+_WifiSystemNetConnection::Start(_NetConnectionEvent& event)
+{
+ SysLog(NID_NET, "Starting WIFI connection.");
+
+ result r = E_SUCCESS;
+
+ SysAssertf(_pEventList != null, "Not yet constructed. Construct() should be called before use.");
+
+ MutexGuard locked(*_pLock);
+
+ if (_connectionState == NET_CONNECTION_STATE_STARTED)
+ {
+ // Already Started
+ SysLog(NID_NET, "WIFI connection is already started.");
+
+ if (event.GetConnectionState() != NET_CONNECTION_STATE_STARTED)
+ {
+ unique_ptr<_NetConnectionEventArg> pEventArg(new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, E_SUCCESS));
+ SysTryReturnResult(NID_NET, pEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
+
+ event.SetConnectionState(NET_CONNECTION_STATE_STARTED);
+ r = event.FireAsync(*pEventArg);
+ SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.", GetErrorMessage(r));
+
+ _refCount++;
+ pEventArg.release();
+ }
+ }
+ else if ((_connectionState == NET_CONNECTION_STATE_STARTING) || (_connectionState == NET_CONNECTION_STATE_STOPPING))
+ {
+ // Waiting Response
+ SysLog(NID_NET, "WIFI connection is waiting response.");
+
+ if (event.GetConnectionState() != NET_CONNECTION_STATE_STARTING)
+ {
+ event.SetConnectionState(NET_CONNECTION_STATE_STARTING);
+ _refCount++;
+ }
+ }
+ else
+ {
+ // None or Stopped
+ SysLog(NID_NET, "WIFI connection is not active.");
+
+ SysTryReturnResult(NID_NET, !event.IsManagedSystemConnection(), E_INVALID_CONNECTION, "Wi-Fi activation is not allowed for a managed network connection.");
+
+ int ret = WIFI_ERROR_NONE;
+ bool isActivated = false;
+
+ ret = wifi_is_activated(&isActivated);
+ SysTryReturnResult(NID_NET, ret == WIFI_ERROR_NONE, E_SYSTEM, "wifi_is_activated() failed with ret=[%d].", ret);
+ SysTryReturnResult(NID_NET, !isActivated, E_INVALID_CONNECTION, "Wi-Fi is already activated, so can't start it.");
+
+ bool isFlightModeEnabled = false;
+ r = SettingInfo::GetValue(L"http://tizen.org/setting/network.flight_mode", isFlightModeEnabled);
+ SysTryReturnResult(NID_NET, r == E_SUCCESS && !isFlightModeEnabled, E_INVALID_CONNECTION, "Flight mode is enabled.");
+
+ r = _AppManagerImpl::GetInstance()->AddAppEventListener(*this);
+ SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM, "Failed to set application event listener.");
+
+ ret = wifi_activate(WifiActivatedCallback, this);
+ if (ret != WIFI_ERROR_NONE)
+ {
+ SysLogException(NID_NET, E_SYSTEM, "[E_SYSTEM] wifi_activate() failed with ret=[%d].", ret);
+
+ _AppManagerImpl::GetInstance()->RemoveAppEventListener(*this);
+
+ return E_SYSTEM;
+ }
+
+ _connectionState = NET_CONNECTION_STATE_STARTING;
+ event.SetConnectionState(NET_CONNECTION_STATE_STARTING);
+ _refCount++;
+ }
+
+ locked.Unlock();
+
+ SysLog(NID_NET, "Exit with result[%s].", GetErrorMessage(r));
+
+ return r;
+}
+
+void
+_WifiSystemNetConnection::HandleStartResponse(result error, void* pData)
+{
+ SysLog(NID_NET, "Start response is received with result[%s].", GetErrorMessage(error));
+
+ IEnumerator* pEnum = null;
+ _NetConnectionEvent* pEvent = null;
+ _NetConnectionEventArg* pStartEventArg = null;
+
+ if (_connectionState != NET_CONNECTION_STATE_STARTING)
+ {
+ SysLog(NID_NET, "Ignore _WifiSystemNetConnection::HandleStartResponse() because this is NOT in starting state.");
+ return;
+ }
+
+ _AppManagerImpl::GetInstance()->RemoveAppEventListener(*this);
+
+ MutexGuard locked(*_pLock);
+
+ if (error == E_SUCCESS)
+ {
+ _bearerType = NET_BEARER_WIFI;
+ _connectionState = NET_CONNECTION_STATE_STARTED;
+ _pConnectionInfo->Update(pData);
+ }
+ else
+ {
+ _bearerType = NET_BEARER_NONE;
+ _connectionState = NET_CONNECTION_STATE_STOPPED;
+ _pConnectionInfo->Clear();
+ _refCount = 0;
+ }
+
+ pEnum = _pEventList->GetEnumeratorN();
+ if (pEnum != null)
+ {
+ while (pEnum->MoveNext() == E_SUCCESS)
+ {
+ pEvent = dynamic_cast<_NetConnectionEvent*>(pEnum->GetCurrent());
+ if (pEvent != null)
+ {
+ if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
+ {
+ if (error == E_SUCCESS)
+ {
+ pEvent->SetConnectionState(NET_CONNECTION_STATE_STARTED);
+ }
+ else
+ {
+ pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
+ }
+
+ pStartEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, error);
+ if (pStartEventArg != null)
+ {
+ pEvent->FireAsync(*pStartEventArg);
+ }
+ }
+ }
+ }
+
+ delete pEnum;
+ }
+
+ locked.Unlock();
+
+ SysLog(NID_NET, "Exit.");
+}
+
+void
+_WifiSystemNetConnection::OnApplicationLaunched(const AppId& appId, int pid)
+{
+ SysLog(NID_NET, "App is launched. appid[%ls] pid[%d].", appId.GetPointer(), pid);
+}
+
+void
+_WifiSystemNetConnection::OnApplicationTerminated(const AppId& appId, int pid)
+{
+ SysLog(NID_NET, "App is terminated. appid[%ls] pid[%d].", appId.GetPointer(), pid);
+
+ if (appId.Equals(String(_WIFI_QS_APP_ID), false))
+ {
+ SysLog(NID_NET, "Wi-Fi QuickStart is terminated before Wi-Fi is connected.");
+ __pTimer->Start(1);
+
+ // ToDo - Remove timer and call HandleStartResponse here (After lockup issue is resolved.)
+// HandleStartResponse(E_NETWORK_FAILED, null);
+ }
+}
+
+void
+_WifiSystemNetConnection::OnTimerExpired(Timer& timer)
+{
+ SysLog(NID_NET, "Timer is expired, so treat as an error.");
+
+ HandleStartResponse(E_NETWORK_FAILED, null);
+}
+
void
_WifiSystemNetConnection::UpdateConnectionInfo(void* pData)
{