Update network account database when a default profile is changed.
[platform/framework/native/net.git] / src / FNet_SystemNetConnection.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17 /**
18  * @file                        FNet_SystemNetConnection.cpp
19  * @brief               This is the implementation file for _SystemNetConnection class.
20  * @version     3.0
21  *
22  * This file contains the implementation of _SystemNetConnection class.
23  */
24
25 #include <pthread.h>
26 #include <net_connection.h>
27 #include <FNetNetConnectionInfo.h>
28 #include <FBaseRtMutexGuard.h>
29 #include <FBaseSysLog.h>
30 #include <FBase_StringConverter.h>
31 #include <FIo_DirectoryImpl.h>
32 #include "FNet_NetTypes.h"
33 #include "FNet_SystemNetConnection.h"
34 #include "FNet_NetConnectionInfoImpl.h"
35 #include "FNet_DefaultSystemNetConnection.h"
36 #include "FNet_PsSystemNetConnection.h"
37 #include "FNet_WifiSystemNetConnection.h"
38 #include "FNet_WifiDirectSystemNetConnection.h"
39 #include "FNet_UsbSystemNetConnection.h"
40 #include "FNet_NetAccountDatabase.h"
41 #include "FNet_NetAccountManagerImpl.h"
42 #include "FNet_NetConnectionEvent.h"
43 #include "FNet_NetConnectionEventArg.h"
44 #include "FNet_NetUtility.h"
45
46 using namespace std;
47 using namespace Tizen::Base;
48 using namespace Tizen::Base::Collection;
49 using namespace Tizen::Base::Runtime;
50 using namespace Tizen::Io;
51
52 namespace Tizen { namespace Net {
53
54 bool _SystemNetConnection::__isInitialized = false;
55 HashMap* _SystemNetConnection::__pPsSystemConnectionMap = null;
56 _DefaultSystemNetConnection* _SystemNetConnection::__pDefaultConnection = null;
57 _WifiSystemNetConnection* _SystemNetConnection::__pWifiConnection = null;
58 _WifiDirectSystemNetConnection* _SystemNetConnection::__pWifiDirectConnection = null;
59 _UsbSystemNetConnection* _SystemNetConnection::__pUsbConnection = null;
60
61 _SystemNetConnection::_SystemNetConnection(void)
62         : _bearerType(NET_BEARER_NONE)
63         , _connectionState(NET_CONNECTION_STATE_NONE)
64         , _pConnectionInfo(null)
65         , _pEventList(null)
66         , _pLock(null)
67         , _refCount(0)
68 {
69 }
70
71 _SystemNetConnection::~_SystemNetConnection(void)
72 {
73 }
74
75 result
76 _SystemNetConnection::Initialize(const String& name)
77 {
78         result r = E_SUCCESS;
79
80         unique_ptr<_NetConnectionInfoImpl> pConnectionInfo(new (std::nothrow) _NetConnectionInfoImpl());
81         SysTryReturnResult(NID_NET, pConnectionInfo != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
82
83         unique_ptr<ArrayList> pEventList(new (std::nothrow) ArrayList());
84         SysTryReturnResult(NID_NET, pEventList != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
85
86         r = pEventList->Construct();
87         SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.");
88
89         unique_ptr<Mutex> pLock(new (std::nothrow) Mutex());
90         SysTryReturnResult(NID_NET, pLock != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
91
92         r = pLock->Create(name);
93         SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.");
94
95         _name = name;
96         _pConnectionInfo = move(pConnectionInfo);
97         _pEventList = move(pEventList);
98         _pLock = move(pLock);
99
100         return r;
101 }
102
103 void
104 _SystemNetConnection::Deinitialize(void)
105 {
106         _bearerType = NET_BEARER_NONE;
107         _connectionState = NET_CONNECTION_STATE_NONE;
108         _name.Clear();
109         _pConnectionInfo.reset(null);
110         _pEventList.reset(null);
111         _pLock.reset(null);
112         _refCount = 0;
113 }
114
115 result
116 _SystemNetConnection::AddEvent(_NetConnectionEvent& event)
117 {
118         result r = E_SUCCESS;
119         bool isFound = false;
120
121         SysAssertf(_pEventList != null, "Not yet constructed. Construct() should be called before use.");
122
123         MutexGuard locked(*_pLock);
124
125         isFound = _pEventList->Contains(event);
126         if (!isFound)
127         {
128                 r = _pEventList->Add(event);
129         }
130
131         locked.Unlock();
132
133         return r;
134 }
135
136 result
137 _SystemNetConnection::RemoveEvent(_NetConnectionEvent& event)
138 {
139         result r = E_SUCCESS;
140         bool isFound = false;
141
142         SysAssertf(_pEventList != null, "Not yet constructed. Construct() should be called before use.");
143
144         MutexGuard locked(*_pLock);
145
146         isFound = _pEventList->Contains(event);
147         if (isFound)
148         {
149                 event.SetConnectionState(NET_CONNECTION_STATE_NONE);
150                 r = _pEventList->Remove(event, false);
151         }
152
153         locked.Unlock();
154
155         return r;
156 }
157
158 result
159 _SystemNetConnection::Start(_NetConnectionEvent& event)
160 {
161         result r = E_SUCCESS;
162
163         SysAssertf(_pEventList != null, "Not yet constructed. Construct() should be called before use.");
164
165         MutexGuard locked(*_pLock);
166
167         if (_connectionState == NET_CONNECTION_STATE_STARTED)
168         {
169                 SysLog(NID_NET, "[%ls] is already connected.", _name.GetPointer());
170
171                 if (event.GetConnectionState() != NET_CONNECTION_STATE_STARTED)
172                 {
173                         unique_ptr<_NetConnectionEventArg> pEventArg(new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, E_SUCCESS));
174                         SysTryReturnResult(NID_NET, pEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
175
176                         event.SetConnectionState(NET_CONNECTION_STATE_STARTED);
177                         r = event.FireAsync(*pEventArg);
178                         SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.");
179
180                         _refCount++;
181                         pEventArg.release();
182                 }
183         }
184         else
185         {
186                 SysLogException(NID_NET, E_INVALID_CONNECTION,
187                                 "[%s] %ls is NOT connected.", GetErrorMessage(E_INVALID_CONNECTION), _name.GetPointer());
188                 r = E_INVALID_CONNECTION;
189         }
190
191         locked.Unlock();
192
193         return r;
194 }
195
196 result
197 _SystemNetConnection::Stop(_NetConnectionEvent& event, bool waitingEvent)
198 {
199         result r = E_SUCCESS;
200
201         SysAssertf(_pEventList != null, "Not yet constructed. Construct() should be called before use.");
202
203         MutexGuard locked(*_pLock);
204
205         if ((event.GetConnectionState() != NET_CONNECTION_STATE_STOPPED) &&
206                 (event.GetConnectionState() != NET_CONNECTION_STATE_NONE))
207         {
208                 if (waitingEvent)
209                 {
210                         unique_ptr<_NetConnectionEventArg> pEventArg(new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STOPPED, E_SUCCESS));
211                         SysTryReturnResult(NID_NET, pEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
212
213                         event.SetConnectionState(NET_CONNECTION_STATE_STOPPED);
214                         r = event.FireAsync(*pEventArg);
215                         SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.");
216
217                         pEventArg.release();
218                 }
219
220                 _refCount--;
221         }
222
223         locked.Unlock();
224
225         return r;
226 }
227
228 void
229 _SystemNetConnection::HandleStartResponse(result error, void* pData)
230 {
231         SysLog(NID_NET, "[%ls] Ignore HandleStartResponse(%s,0x%x).", _name.GetPointer(), GetErrorMessage(error), pData);
232 }
233
234 void
235 _SystemNetConnection::HandleStopResponse(void)
236 {
237         SysLog(NID_NET, "[%ls] Ignore HandleStopResponse.", _name.GetPointer());
238 }
239
240 void
241 _SystemNetConnection::HandleStartEvent(void)
242 {
243         _NetConnectionEvent* pEvent = null;
244         _NetConnectionEventArg* pEventArg = null;
245
246         if (_connectionState == NET_CONNECTION_STATE_STARTED)
247         {
248                 SysLog(NID_NET, "[%ls] Ignore HandleStartEvent() because this instance is in started state.", _name.GetPointer());
249                 return;
250         }
251
252         SysLog(NID_NET, "[%ls] Notify started event.", _name.GetPointer());
253
254         MutexGuard locked(*_pLock);
255
256         unique_ptr<IEnumerator> pEnum(_pEventList->GetEnumeratorN());
257         if (pEnum != null)
258         {
259                 while (pEnum->MoveNext() == E_SUCCESS)
260                 {
261                         pEvent = dynamic_cast<_NetConnectionEvent*>(pEnum->GetCurrent());
262                         if (pEvent != null)
263                         {
264                                 if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
265                                 {
266                                         pEvent->SetConnectionState(NET_CONNECTION_STATE_STARTED);
267                                         pEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, E_SUCCESS);
268                                         if (pEventArg != null)
269                                         {
270                                                 pEvent->FireAsync(*pEventArg);
271                                         }
272                                 }
273                         }
274                 }
275         }
276
277         locked.Unlock();
278 }
279
280 void
281 _SystemNetConnection::HandleStopEvent(result error)
282 {
283         _NetConnectionEvent* pEvent = null;
284         _NetConnectionEventArg* pEventArg = null;
285
286         if ((_connectionState == NET_CONNECTION_STATE_NONE) || (_connectionState == NET_CONNECTION_STATE_STOPPED))
287         {
288                 SysLog(NID_NET, "[%ls] Ignore HandleStopEvent(%s) because this instance is in stopped state.", _name.GetPointer(), GetErrorMessage(error));
289                 return;
290         }
291
292         SysLog(NID_NET, "[%ls] Notify stopped event.", _name.GetPointer());
293
294         MutexGuard locked(*_pLock);
295
296         _refCount = 0;
297
298         unique_ptr<IEnumerator> pEnum(_pEventList->GetEnumeratorN());
299         if (pEnum != null)
300         {
301                 while (pEnum->MoveNext() == E_SUCCESS)
302                 {
303                         pEvent = dynamic_cast<_NetConnectionEvent*>(pEnum->GetCurrent());
304                         if (pEvent != null)
305                         {
306                                 if ((pEvent->GetConnectionState() != NET_CONNECTION_STATE_NONE) &&
307                                         (pEvent->GetConnectionState() != NET_CONNECTION_STATE_STOPPED))
308                                 {
309                                         pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
310                                         pEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STOPPED, error);
311                                         if (pEventArg != null)
312                                         {
313                                                 pEvent->FireAsync(*pEventArg);
314                                         }
315                                 }
316                         }
317                 }
318         }
319
320         locked.Unlock();
321 }
322
323 NetConnectionState
324 _SystemNetConnection::QueryConnectionState(String& devName) const
325 {
326         if (_pConnectionInfo != null)
327         {
328                 devName = _pConnectionInfo->GetDeviceName();
329         }
330
331         SysLog(NID_NET, "QueryConnectionState() has done with state:%d, devName:%ls", _connectionState, devName.GetPointer());
332
333         return _connectionState;
334 }
335
336 NetBearerType
337 _SystemNetConnection::GetBearerType(void) const
338 {
339         return _bearerType;
340 }
341
342 NetConnectionState
343 _SystemNetConnection::GetConnectionState(void) const
344 {
345         return _connectionState;
346 }
347
348 String
349 _SystemNetConnection::GetProxyAddress(void) const
350 {
351         String proxyAddress;
352
353         if (_pConnectionInfo != null)
354         {
355                 proxyAddress = _pConnectionInfo->GetProxyAddress();
356         }
357
358         SysLog(NID_NET, "GetProxyAddress() has done with proxy:%ls", proxyAddress.GetPointer());
359
360         return proxyAddress;
361 }
362
363 void
364 _SystemNetConnection::GetConnectionInfo(NetConnectionInfo& netConnectionInfo)
365 {
366         _NetConnectionInfoImpl* pSource = _pConnectionInfo.get();
367         _NetConnectionInfoImpl* pDestnation = _NetConnectionInfoImpl::GetInstance(netConnectionInfo);
368
369         SysTryReturnVoidResult(NID_NET, ((pSource != null) && (pDestnation != null)), E_INVALID_ARG,
370                         "[%s] Invalid argument is used. The impl instance is null. [0x%x] [0x%x]", GetErrorMessage(E_INVALID_ARG), pSource, pDestnation);
371
372         MutexGuard locked(*_pLock);
373
374         pDestnation->CopyFrom(pSource);
375
376         locked.Unlock();
377 }
378
379 void
380 _SystemNetConnection::InitializeNetworkFramework(void)
381 {
382         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
383
384         if (!__isInitialized)
385         {
386                 ClearLastResult();
387                 pthread_once(&onceBlock, InitializeNetworkFrameworkOnce);
388                 result r = GetLastResult();
389                 if (r != E_SUCCESS)
390                 {
391                         onceBlock = PTHREAD_ONCE_INIT;
392                 }
393         }
394 }
395
396 void
397 _SystemNetConnection::InitializeNetworkFrameworkOnce(void)
398 {
399         result r = E_SUCCESS;
400
401         __pPsSystemConnectionMap = new (std::nothrow) HashMap();
402         SysTryReturnVoidResult(NID_NET, __pPsSystemConnectionMap != null, E_OUT_OF_MEMORY,
403                         "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
404
405         r = __pPsSystemConnectionMap->Construct();
406         r = TransExceptionsExclusive(r, E_SYSTEM, E_OUT_OF_MEMORY);
407         SysTryReturnVoidResult(NID_NET, r == E_SUCCESS, r,
408                         "[%s] A system error has been occurred. Failed to initialize the HashMap.", GetErrorMessage(r));
409
410         r = _NetAccountDatabase::InitializeRepository();
411         r = TransExceptionsExclusive(r, E_SYSTEM, E_OUT_OF_MEMORY);
412         SysTryReturnVoidResult(NID_NET, r == E_SUCCESS, r,
413                         "[%s] A system error has been occurred. Failed to initialize the network database.", GetErrorMessage(r));
414
415         __isInitialized = true;
416 }
417
418 _SystemNetConnection*
419 _SystemNetConnection::GetPsInstance(NetAccountId netAccountId)
420 {
421         result r = E_SUCCESS;
422         _PsSystemNetConnection* pConnection = null;
423         String profileName;
424
425         r = _NetAccountDatabase::GetProfileName(netAccountId, profileName);
426         SysTryReturn(NID_NET, r == E_SUCCESS, null, E_INVALID_ACCOUNT,
427                         "[%s] Invalid network account. accountId=%d", GetErrorMessage(E_INVALID_ACCOUNT), netAccountId);
428
429         Mutex* pLock = _NetUtility::GetLock();
430         MutexGuard locked(*pLock);
431
432         pConnection = dynamic_cast<_PsSystemNetConnection*>(__pPsSystemConnectionMap->GetValue(profileName));
433         if (pConnection == null)
434         {
435                 pConnection = new (std::nothrow) _PsSystemNetConnection();
436                 SysTryReturn(NID_NET, pConnection != null, null, E_OUT_OF_MEMORY,
437                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
438
439                 r = pConnection->Construct(profileName);
440                 if (r != E_SUCCESS)
441                 {
442                         SysLogException(NID_NET, r, "[%s] Propagating.", GetErrorMessage(r));
443
444                         delete pConnection;
445                         pConnection = null;
446                 }
447                 else
448                 {
449                         r = __pPsSystemConnectionMap->Add(pConnection->__profileName, *pConnection);
450                         if (r != E_SUCCESS)
451                         {
452                                 SysLogException(NID_NET, r, "[%s] Propagating.", GetErrorMessage(r));
453
454                                 delete pConnection;
455                                 pConnection = null;
456                         }
457                 }
458         }
459
460         locked.Unlock();
461
462         return pConnection;
463 }
464
465 _SystemNetConnection*
466 _SystemNetConnection::GetDefaultInstance(void)
467 {
468         result r = E_SUCCESS;
469
470         Mutex* pLock = _NetUtility::GetLock();
471         MutexGuard locked(*pLock);
472
473         if (__pDefaultConnection == null)
474         {
475                 unique_ptr<_DefaultSystemNetConnection> pDefaultConnection(new (std::nothrow) _DefaultSystemNetConnection());
476                 SysTryReturn(NID_NET, pDefaultConnection != null, null, E_OUT_OF_MEMORY,
477                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
478
479                 r = pDefaultConnection->Construct();
480                 SysTryReturn(NID_NET, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
481
482                 __pDefaultConnection = pDefaultConnection.release();
483         }
484
485         locked.Unlock();
486
487         return __pDefaultConnection;
488 }
489
490 _SystemNetConnection*
491 _SystemNetConnection::GetWifiInstance(void)
492 {
493         result r = E_SUCCESS;
494
495         Mutex* pLock = _NetUtility::GetLock();
496         MutexGuard locked(*pLock);
497
498         if (__pWifiConnection == null)
499         {
500                 unique_ptr<_WifiSystemNetConnection> pWifiConnection(new (std::nothrow) _WifiSystemNetConnection());
501                 SysTryReturn(NID_NET, pWifiConnection != null, null, E_OUT_OF_MEMORY,
502                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
503
504                 r = pWifiConnection->Construct();
505                 SysTryReturn(NID_NET, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
506
507                 __pWifiConnection = pWifiConnection.release();
508         }
509
510         locked.Unlock();
511
512         return __pWifiConnection;
513 }
514
515 _SystemNetConnection*
516 _SystemNetConnection::GetWifiDirectInstance(void)
517 {
518         result r = E_SUCCESS;
519
520         Mutex* pLock = _NetUtility::GetLock();
521         MutexGuard locked(*pLock);
522
523         // ToDo - Should be changed similar with other instance. (After resolving circular dependency.)
524         if (__pWifiDirectConnection == null)
525         {
526                 __pWifiDirectConnection = new (std::nothrow) _WifiDirectSystemNetConnection();
527                 SysTryReturn(NID_NET, __pWifiDirectConnection != null, null, E_OUT_OF_MEMORY,
528                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
529
530                 r = __pWifiDirectConnection->Construct();
531                 if (r != E_SUCCESS)
532                 {
533                         SysLogException(NID_NET, r, "[%s] Propagating.", GetErrorMessage(r));
534
535                         delete __pWifiDirectConnection;
536                         __pWifiDirectConnection = null;
537                 }
538         }
539
540         locked.Unlock();
541
542         return __pWifiDirectConnection;
543 }
544
545 _SystemNetConnection*
546 _SystemNetConnection::GetUsbInstance(void)
547 {
548         result r = E_SUCCESS;
549
550         Mutex* pLock = _NetUtility::GetLock();
551         MutexGuard locked(*pLock);
552
553         if (__pUsbConnection == null)
554         {
555                 unique_ptr<_UsbSystemNetConnection> pUsbConnection(new (std::nothrow) _UsbSystemNetConnection());
556                 SysTryReturn(NID_NET, pUsbConnection != null, null, E_OUT_OF_MEMORY,
557                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
558
559                 r = pUsbConnection->Construct();
560                 SysTryReturn(NID_NET, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
561
562                 __pUsbConnection = pUsbConnection.release();
563         }
564
565         locked.Unlock();
566
567         return __pUsbConnection;
568 }
569
570 #if 0
571 result
572 _SystemNetConnection::ConvertError(int ret)
573 {
574         result r = E_SUCCESS;
575
576         switch (ret)
577         {
578         case NET_ERR_NONE:
579                 r = E_SUCCESS;
580                 break;
581
582         case NET_ERR_TIME_OUT:
583                 r = E_TIMEOUT;
584                 break;
585
586         case NET_ERR_NO_SERVICE:
587                 r = E_NETWORK_UNAVAILABLE;
588                 break;
589
590         case NET_ERR_NO_ACTIVE_CONNECTIONS:
591                 r = E_SERVICE_UNAVAILABLE;
592                 break;
593
594         case NET_ERR_CONNECTION_LOGIN_FAILED:
595         case NET_ERR_CONNECTION_AUTH_FAILED:
596         case NET_ERR_CONNECTION_INVALID_KEY:
597                 r = E_AUTHENTICATION;
598                 break;
599
600         case NET_ERR_NOT_SUPPORTED:
601         case NET_ERR_SECURITY_RESTRICTED:
602                 r = E_UNSUPPORTED_OPERATION;
603                 break;
604
605         case NET_ERR_CONNECTION_OUT_OF_RANGE:
606         case NET_ERR_CONNECTION_PIN_MISSING:
607         case NET_ERR_CONNECTION_CONNECT_FAILED:
608         case NET_ERR_OPERATION_ABORTED:
609         case NET_ERR_ACCESS_DENIED:
610                 r = E_NETWORK_FAILED;
611                 break;
612
613         case NET_ERR_CONNECTION_DHCP_FAILED:
614                 r = E_DHCP;
615                 break;
616
617         case NET_ERR_WIFI_DRIVER_FAILURE:
618                 r = E_LINK;
619                 break;
620
621         default:
622                 r = E_SYSTEM;
623                 break;
624         }
625
626         return r;
627 }
628 #endif
629
630 } } // Tizen::Net