2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 * @file FNet_PsSystemNetConnection.cpp
19 * @brief This is the implementation file for _PsSystemNetConnection class.
22 * This file contains the implementation of _PsSystemNetConnection class.
25 #include <net_connection.h>
26 #include <FNetNetConnectionInfo.h>
27 #include <FBaseSysLog.h>
28 #include <FBase_StringConverter.h>
29 #include "FNet_NetTypes.h"
30 #include "FNet_NetConnectionInfoImpl.h"
31 #include "FNet_PsSystemNetConnection.h"
32 #include "FNet_NetAccountDatabase.h"
33 #include "FNet_NetAccountManagerImpl.h"
34 #include "FNet_NetConnectionEvent.h"
35 #include "FNet_NetConnectionEventArg.h"
36 #include "FNet_NetUtility.h"
39 using namespace Tizen::Base;
40 using namespace Tizen::Base::Collection;
41 using namespace Tizen::Base::Runtime;
43 namespace Tizen { namespace Net {
46 PsOpenCallback(connection_error_e res, void* pUserData)
48 _PsSystemNetConnection* pConnection = static_cast<_PsSystemNetConnection*>(pUserData);
49 NetConnectionState connectionState = pConnection->GetConnectionState();
50 bool isConnected = false;
51 char* pProfileName = null;
52 char* pProfileDisplayName = null;
53 int ret = CONNECTION_ERROR_NONE;
54 connection_profile_h profileHandle = pConnection->GetProfileHandle();
55 connection_profile_state_e state = CONNECTION_PROFILE_STATE_DISCONNECTED;
57 ret = connection_profile_refresh(profileHandle);
58 SysLog(NID_NET, "The return value from connection_profile_refresh() is %d", ret);
59 ret = connection_profile_get_id(profileHandle, &pProfileName);
60 SysLog(NID_NET, "The return value from connection_profile_get_id() is %d", ret);
61 ret = connection_profile_get_name(profileHandle, &pProfileDisplayName);
62 SysLog(NID_NET, "The return value from connection_profile_get_name() is %d", ret);
63 ret = connection_profile_get_state(profileHandle, &state);
64 SysLog(NID_NET, "The return value from connection_profile_get_state() is %d", ret);
66 SysSecureLog(NID_NET, "PsOpenCallback() has been called with res:%d, state:%d, name:[%s][%s]", res, state, pProfileDisplayName, pProfileName);
68 if ((res == CONNECTION_ERROR_NONE) && (state == CONNECTION_PROFILE_STATE_CONNECTED))
70 SysLog(NID_NET, "Profile[%s] is connected.", pProfileName);
75 SysLog(NID_NET, "Profile[%s] is disconnected.", pProfileName);
80 free(pProfileDisplayName);
82 if (connectionState != NET_CONNECTION_STATE_STARTING)
84 SysLog(NID_NET, "Ignore open response because it is in state[%d].", connectionState);
90 pConnection->HandleStartResponse(E_SUCCESS, profileHandle);
94 pConnection->HandleStartResponse(E_NETWORK_FAILED, null);
99 PsCloseCallback(connection_error_e res, void* pUserData)
101 _PsSystemNetConnection* pConnection = static_cast<_PsSystemNetConnection*>(pUserData);
102 NetConnectionState connectionState = pConnection->GetConnectionState();
103 bool isConnected = false;
104 char* pProfileName = null;
105 char* pProfileDisplayName = null;
106 int ret = CONNECTION_ERROR_NONE;
107 connection_profile_h profileHandle = pConnection->GetProfileHandle();
108 connection_profile_state_e state = CONNECTION_PROFILE_STATE_DISCONNECTED;
110 ret = connection_profile_refresh(profileHandle);
111 SysLog(NID_NET, "The return value from connection_profile_refresh() is %d", ret);
112 ret = connection_profile_get_id(profileHandle, &pProfileName);
113 SysLog(NID_NET, "The return value from connection_profile_get_id() is %d", ret);
114 ret = connection_profile_get_name(profileHandle, &pProfileDisplayName);
115 SysLog(NID_NET, "The return value from connection_profile_get_name() is %d", ret);
116 ret = connection_profile_get_state(profileHandle, &state);
117 SysLog(NID_NET, "The return value from connection_profile_get_state() is %d", ret);
119 SysSecureLog(NID_NET, "PsCloseCallback() has been called with res:%d, state:%d, name:[%s][%s]", res, state, pProfileDisplayName, pProfileName);
121 if ((res == CONNECTION_ERROR_NONE) && (state == CONNECTION_PROFILE_STATE_CONNECTED))
123 SysLog(NID_NET, "Profile[%s] is connected.", pProfileName);
128 SysLog(NID_NET, "Profile[%s] is disconnected.", pProfileName);
133 free(pProfileDisplayName);
135 if (connectionState != NET_CONNECTION_STATE_STOPPING)
137 SysLog(NID_NET, "Ignore close response because it is in state[%d].", connectionState);
141 pConnection->HandleStopResponse();
145 PsStateChangedCallback(connection_profile_state_e state, void* pUserData)
147 _PsSystemNetConnection* pConnection = static_cast<_PsSystemNetConnection*>(pUserData);
148 NetConnectionState connectionState = pConnection->GetConnectionState();
149 bool isConnected = false;
150 char* pProfileName = null;
151 char* pProfileDisplayName = null;
152 int ret = CONNECTION_ERROR_NONE;
153 connection_profile_h profileHandle = pConnection->GetProfileHandle();
155 ret = connection_profile_refresh(profileHandle);
156 SysLog(NID_NET, "The return value from connection_profile_refresh() is %d", ret);
157 ret = connection_profile_get_id(profileHandle, &pProfileName);
158 SysLog(NID_NET, "The return value from connection_profile_get_id() is %d", ret);
159 ret = connection_profile_get_name(profileHandle, &pProfileDisplayName);
160 SysLog(NID_NET, "The return value from connection_profile_get_name() is %d", ret);
162 SysSecureLog(NID_NET, "PsStateChangedCallback() has been called with state:%d, name:[%s][%s]", state, pProfileDisplayName, pProfileName);
164 if (state == CONNECTION_PROFILE_STATE_CONNECTED)
166 SysLog(NID_NET, "Profile[%s] is connected.", pProfileName);
171 SysLog(NID_NET, "Profile[%s] is disconnected.", pProfileName);
176 free(pProfileDisplayName);
178 if ((connectionState == NET_CONNECTION_STATE_STARTING) || (connectionState == NET_CONNECTION_STATE_STOPPING))
180 SysLog(NID_NET, "Ignore (not requested) event because it is in state[%d].", connectionState);
187 SysLog(NID_NET, "Ignore started event.");
192 pConnection->HandleStopEvent(E_NETWORK_FAILED);
196 _PsSystemNetConnection::_PsSystemNetConnection(void)
197 : __pConnectionHandle(null)
198 , __pProfileHandle(null)
202 _PsSystemNetConnection::~_PsSystemNetConnection(void)
207 _PsSystemNetConnection::Construct(const String& profileName)
209 SysLog(NID_NET, "Construct()has been called with profileName:%ls", profileName.GetPointer());
211 result r = E_SUCCESS;
212 unique_ptr<void, _ConnectionDeleter> pConnectionHandle;
213 unique_ptr<void, _ProfileDeleter> pProfileHandle;
214 int ret = CONNECTION_ERROR_NONE;
215 connection_h connectionHandle = null;
216 connection_profile_h profileHandle = null;
218 SysAssertf(__pConnectionHandle == null,
219 "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
221 r = _SystemNetConnection::Initialize(L"PS");
222 SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.");
224 ret = connection_create(&connectionHandle);
225 SysTryCatch(NID_NET, ret == CONNECTION_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
226 "[%s] A system error has been occurred. The return value from connection_create() is %d", GetErrorMessage(E_SYSTEM), ret);
227 pConnectionHandle.reset(connectionHandle);
229 profileHandle = _NetAccountManagerImpl::GetPsProfileHandleN(profileName);
230 SysTryCatch(NID_NET, profileHandle != null, r = GetLastResult(), GetLastResult(),
231 "[%s] Propagating.", GetErrorMessage(GetLastResult()));
232 pProfileHandle.reset(profileHandle);
234 ret = connection_profile_set_state_changed_cb(profileHandle, PsStateChangedCallback, this);
235 SysTryCatch(NID_NET, ret == CONNECTION_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
236 "[%s] A system error has been occurred. The return value from connection_profile_set_state_changed_cb() is %d", GetErrorMessage(E_SYSTEM), ret);
238 __profileName = profileName;
239 __pConnectionHandle = move(pConnectionHandle);
240 __pProfileHandle = move(pProfileHandle);
245 _SystemNetConnection::Deinitialize();
251 _PsSystemNetConnection::Start(_NetConnectionEvent& event)
253 result r = E_SUCCESS;
254 _NetConnectionEventArg* pEventArg = null;
256 SysAssertf(__pConnectionHandle != null,
257 "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
259 MutexGuard locked(*_pLock);
261 if (_connectionState == NET_CONNECTION_STATE_STARTED)
264 SysLog(NID_NET, "PS connection[%ls] is already started.", __profileName.GetPointer());
266 if (event.GetConnectionState() != NET_CONNECTION_STATE_STARTED)
268 pEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, E_SUCCESS);
269 SysTryReturnResult(NID_NET, pEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
271 event.SetConnectionState(NET_CONNECTION_STATE_STARTED);
272 event.FireAsync(*pEventArg);
277 else if ((_connectionState == NET_CONNECTION_STATE_STARTING) || (_connectionState == NET_CONNECTION_STATE_STOPPING))
280 SysLog(NID_NET, "PS connection[%ls] is waiting response.", __profileName.GetPointer());
282 if (event.GetConnectionState() != NET_CONNECTION_STATE_STARTING)
284 event.SetConnectionState(NET_CONNECTION_STATE_STARTING);
291 SysLog(NID_NET, "PS connection[%ls] is not active, so start now.", __profileName.GetPointer());
293 int ret = CONNECTION_ERROR_NONE;
295 ret = connection_open_profile(__pConnectionHandle.get(), __pProfileHandle.get(), PsOpenCallback, this);
296 SysTryReturnResult(NID_NET, ret == CONNECTION_ERROR_NONE, E_SYSTEM,
297 "A system error has been occurred. The return value from connection_open_profile() is %d", ret);
299 _connectionState = NET_CONNECTION_STATE_STARTING;
300 event.SetConnectionState(NET_CONNECTION_STATE_STARTING);
310 _PsSystemNetConnection::Stop(_NetConnectionEvent& event, bool waitingEvent)
312 result r = E_SUCCESS;
313 _NetConnectionEventArg* pEventArg = null;
315 SysAssertf(__pConnectionHandle != null,
316 "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
318 MutexGuard locked(*_pLock);
320 if ((event.GetConnectionState() == NET_CONNECTION_STATE_STARTED) ||
321 (event.GetConnectionState() == NET_CONNECTION_STATE_STARTING))
323 if (_connectionState == NET_CONNECTION_STATE_STARTED)
328 SysLog(NID_NET, "PS connection[%ls] is used by others[%d].", __profileName.GetPointer(), _refCount-1);
332 pEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STOPPED, E_SUCCESS);
333 SysTryReturnResult(NID_NET, pEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
335 event.SetConnectionState(NET_CONNECTION_STATE_STOPPED);
336 event.FireAsync(*pEventArg);
343 SysLog(NID_NET, "PS connection[%ls] is not used any longer, so stop it.", __profileName.GetPointer());
345 int ret = CONNECTION_ERROR_NONE;
347 ret = connection_close_profile(__pConnectionHandle.get(), __pProfileHandle.get(), PsCloseCallback, this);
348 SysTryReturnResult(NID_NET, ret == CONNECTION_ERROR_NONE, E_SYSTEM,
349 "A system error has been occurred. The return value from connection_close_profile() is %d", ret);
351 _connectionState = NET_CONNECTION_STATE_STOPPING;
354 event.SetConnectionState(NET_CONNECTION_STATE_STOPPING);
357 else if ((_connectionState == NET_CONNECTION_STATE_STOPPING) ||
358 (_connectionState == NET_CONNECTION_STATE_STARTING))
362 event.SetConnectionState(NET_CONNECTION_STATE_STOPPING);
368 SysLog(NID_NET, "PS connection[%ls] is already stopped.", __profileName.GetPointer());
372 pEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STOPPED, E_SUCCESS);
373 SysTryReturnResult(NID_NET, pEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
375 event.SetConnectionState(NET_CONNECTION_STATE_STOPPED);
376 event.FireAsync(*pEventArg);
386 _PsSystemNetConnection::HandleStartResponse(result error, void* pData)
388 IEnumerator* pEnum = null;
389 _NetConnectionEvent* pEvent = null;
390 _NetConnectionEventArg* pStartEventArg = null;
391 _NetConnectionEventArg* pStopEventArg = null;
393 if (_connectionState != NET_CONNECTION_STATE_STARTING)
395 SysLog(NID_NET, "Ignore _PsSystemNetConnection::HandleStartResponse() because this is NOT in starting state.");
399 MutexGuard locked(*_pLock);
401 if (error == E_SUCCESS)
403 _bearerType = NET_BEARER_PS;
404 _connectionState = NET_CONNECTION_STATE_STARTED;
405 _pConnectionInfo->Update(pData);
409 _bearerType = NET_BEARER_NONE;
410 _connectionState = NET_CONNECTION_STATE_STOPPED;
411 _pConnectionInfo->Clear();
415 pEnum = _pEventList->GetEnumeratorN();
418 while (pEnum->MoveNext() == E_SUCCESS)
420 pEvent = dynamic_cast<_NetConnectionEvent*>(pEnum->GetCurrent());
423 if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
425 if (error == E_SUCCESS)
427 pEvent->SetConnectionState(NET_CONNECTION_STATE_STARTED);
431 pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
434 pStartEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, error);
435 if (pStartEventArg != null)
437 pEvent->FireAsync(*pStartEventArg);
438 SysLog(NID_NET, "Fire Start event on event[0x%x].", pEvent);
441 else if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STOPPING)
443 if (error != E_SUCCESS)
445 pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
446 pStopEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STOPPED, E_SUCCESS);
447 if (pStopEventArg != null)
449 pEvent->FireAsync(*pStopEventArg);
459 if ((_connectionState == NET_CONNECTION_STATE_STARTED) && (_refCount == 0))
461 SysLog(NID_NET, "Connection is started, but not used any more, so stop it.");
463 int ret = CONNECTION_ERROR_NONE;
464 bool isSuccess = false;
466 ret = connection_close_profile(__pConnectionHandle.get(), __pProfileHandle.get(), PsCloseCallback, this);
467 if (ret == CONNECTION_ERROR_NONE)
469 _connectionState = NET_CONNECTION_STATE_STOPPING;
473 if (isSuccess == false)
475 _connectionState = NET_CONNECTION_STATE_STOPPED;
477 pEnum = _pEventList->GetEnumeratorN();
480 while (pEnum->MoveNext() == E_SUCCESS)
482 pEvent = dynamic_cast<_NetConnectionEvent*>(pEnum->GetCurrent());
485 if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STOPPING)
487 pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
488 pStopEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STOPPED, E_SUCCESS);
489 if (pStopEventArg != null)
491 pEvent->FireAsync(*pStopEventArg);
506 _PsSystemNetConnection::HandleStopResponse(void)
508 IEnumerator* pEnum = null;
509 _NetConnectionEvent* pEvent = null;
510 _NetConnectionEventArg* pEventArg = null;
512 if (_connectionState != NET_CONNECTION_STATE_STOPPING)
514 SysLog(NID_NET, "Ignore _PsSystemNetConnection::HandleStopResponse() because this is NOT in stopping state.");
518 MutexGuard locked(*_pLock);
520 _bearerType = NET_BEARER_NONE;
521 _connectionState = NET_CONNECTION_STATE_STOPPED;
522 _pConnectionInfo->Clear();
524 pEnum = _pEventList->GetEnumeratorN();
527 while (pEnum->MoveNext() == E_SUCCESS)
529 pEvent = dynamic_cast<_NetConnectionEvent*>(pEnum->GetCurrent());
532 if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STOPPING)
534 pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
535 pEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STOPPED, E_SUCCESS);
536 if (pEventArg != null)
538 pEvent->FireAsync(*pEventArg);
549 SysLog(NID_NET, "Connection is stopped, but another start request is found, so start the connection.");
551 int ret = CONNECTION_ERROR_NONE;
552 bool isSuccess = false;
554 ret = connection_open_profile(__pConnectionHandle.get(), __pProfileHandle.get(), PsOpenCallback, this);
555 SysLog(NID_NET, "Invoke connection_open_profile() ret[%d].", ret);
556 if (ret == CONNECTION_ERROR_NONE)
558 _connectionState = NET_CONNECTION_STATE_STARTING;
562 if (isSuccess == false)
566 pEnum = _pEventList->GetEnumeratorN();
569 while (pEnum->MoveNext() == E_SUCCESS)
571 pEvent = dynamic_cast<_NetConnectionEvent*>(pEnum->GetCurrent());
574 if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
576 pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
577 pEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, E_NETWORK_FAILED);
578 if (pEventArg != null)
580 pEvent->FireAsync(*pEventArg);
595 _PsSystemNetConnection::HandleStartEvent(void)
597 SysLogException(NID_NET, E_INVALID_OPERATION,
598 "[%s] _PsSystemNetConnection.HandleStartEvent() is NOT allowed.", GetErrorMessage(E_INVALID_OPERATION));
602 _PsSystemNetConnection::HandleStopEvent(result error)
604 IEnumerator* pEnum = null;
605 _NetConnectionEvent* pEvent = null;
606 _NetConnectionEventArg* pStartEventArg = null;
607 _NetConnectionEventArg* pStopEventArg = null;
608 _NetConnectionEventArg* pStopEventArg2 = null;
610 if ((_connectionState == NET_CONNECTION_STATE_NONE) || (_connectionState == NET_CONNECTION_STATE_STOPPED))
612 SysLog(NID_NET, "Ignore _PsSystemNetConnection::HandleStopEvent() because this is already in stopped state.");
616 MutexGuard locked(*_pLock);
618 _bearerType = NET_BEARER_NONE;
619 _connectionState = NET_CONNECTION_STATE_STOPPED;
620 _pConnectionInfo->Clear();
623 pEnum = _pEventList->GetEnumeratorN();
626 while (pEnum->MoveNext() == E_SUCCESS)
628 pEvent = dynamic_cast<_NetConnectionEvent*>(pEnum->GetCurrent());
631 if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
633 pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
634 pStartEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, error);
635 if (pStartEventArg != null)
637 pEvent->FireAsync(*pStartEventArg);
640 else if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STARTED)
642 pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
643 pStopEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STOPPED, error);
644 if (pStopEventArg != null)
646 pEvent->FireAsync(*pStopEventArg);
649 else if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STOPPING)
651 pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
652 pStopEventArg2 = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STOPPED, E_SUCCESS);
653 if (pStopEventArg2 != null)
655 pEvent->FireAsync(*pStopEventArg2);
668 _PsSystemNetConnection::QueryConnectionState(String& devName) const
670 NetConnectionState state = _connectionState;
671 int ret = CONNECTION_ERROR_NONE;
672 connection_profile_h profileHandle = _NetAccountManagerImpl::GetPsProfileHandleN(__profileName);
673 connection_profile_state_e profileState = CONNECTION_PROFILE_STATE_DISCONNECTED;
675 if (profileHandle != null)
677 ret = connection_profile_get_state(profileHandle, &profileState);
678 if ((ret == CONNECTION_ERROR_NONE) && (profileState == CONNECTION_PROFILE_STATE_CONNECTED))
680 char* pDevName = null;
682 ret = connection_profile_get_network_interface_name(profileHandle, &pDevName);
683 if ((ret == CONNECTION_ERROR_NONE) && (pDevName != null))
685 devName = String(pDevName);
689 state = NET_CONNECTION_STATE_STARTED;
692 connection_profile_destroy(profileHandle);
695 SysLog(NID_NET, "QueryConnectionState() has done with state:%d, devName:%ls", state, devName.GetPointer());
701 _PsSystemNetConnection::GetProfileHandle(void)
703 return __pProfileHandle.get();