Merge "[Calendar] Fix spelling error"
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Connection / Tizen.Network.Connection / ConnectionInternalManager.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 using System.Text;
21 using System.Threading.Tasks;
22 using System.Runtime.InteropServices;
23 using System.Collections;
24 using System.Threading;
25
26 namespace Tizen.Network.Connection
27 {
28     class HandleHolder : IDisposable
29     {
30         private IntPtr Handle;
31         private bool disposed = false;
32
33         public HandleHolder()
34         {
35             Log.Debug(Globals.LogTag, "Handle: " + Handle);
36             int ret = Interop.Connection.Create(out Handle);
37             if(ret != (int)ConnectionError.None)
38             {
39                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
40                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
41                 ConnectionErrorFactory.ThrowConnectionException(ret);
42             }
43         }
44
45         ~HandleHolder()
46         {
47             Dispose(false);
48         }
49
50         internal IntPtr GetHandle()
51         {
52             Log.Debug(Globals.LogTag, "handleholder handle = " + Handle);
53             return Handle;
54         }
55         public void Dispose()
56         {
57             Dispose(true);
58             GC.SuppressFinalize(this);
59         }
60
61         private void Dispose(bool disposing)
62         {
63             Log.Debug(Globals.LogTag, ">>> HandleHolder Dispose with " + disposing);
64             Log.Debug(Globals.LogTag, ">>> Handle: " + Handle);
65             if (disposed)
66                 return;
67
68             if (disposing)
69             {
70                 // Free managed objects.
71                 Destroy();
72             }
73             disposed = true;
74         }
75
76         private void Destroy()
77         {
78             Interop.Connection.Destroy(Handle);
79             if (Handle != IntPtr.Zero)
80             {
81                 Handle = IntPtr.Zero;
82             }
83         }
84     }
85
86     internal class ConnectionInternalManager
87     {
88         private bool disposed = false;
89         private static ConnectionInternalManager s_instance = null;
90
91         private EventHandler<ConnectionTypeEventArgs> _ConnectionTypeChanged = null;
92         private EventHandler<AddressEventArgs> _IPAddressChanged = null;
93         private EventHandler<EthernetCableStateEventArgs> _EthernetCableStateChanged = null;
94         private EventHandler<AddressEventArgs> _ProxyAddressChanged = null;
95
96         private Interop.Connection.ConnectionAddressChangedCallback _connectionAddressChangedCallback;
97         private Interop.Connection.ConnectionTypeChangedCallback _connectionTypeChangedCallback;
98         private Interop.Connection.ConnectionAddressChangedCallback _proxyAddressChangedCallback;
99
100         internal static ConnectionInternalManager Instance
101         {
102             get
103             {
104                 if (s_instance == null)
105                 {
106                     s_instance = new ConnectionInternalManager();
107                 }
108
109                 return s_instance;
110             }
111         }
112
113         private static ThreadLocal<HandleHolder> s_threadName = new ThreadLocal<HandleHolder>(() =>
114         {
115             Log.Info(Globals.LogTag, "In threadlocal delegate");
116             return new HandleHolder();
117         });
118
119         private ConnectionInternalManager()
120         {
121
122         }
123
124         ~ConnectionInternalManager()
125         {
126             Dispose(false);
127         }
128
129         public void Dispose()
130         {
131             Dispose(true);
132             GC.SuppressFinalize(this);
133         }
134
135         private void Dispose(bool disposing)
136         {
137             Log.Debug(Globals.LogTag, ">>> ConnectionInternalManager Dispose with disposing " + disposing + ", disposed " + disposed);
138             Log.Debug(Globals.LogTag, ">>> Handle: " + GetHandle());
139             if (disposed)
140                 return;
141
142             if (disposing)
143             {
144                 // Free managed objects.
145             }
146
147             UnregisterEvents();
148             disposed = true;
149         }
150
151         internal IntPtr GetHandle()
152         {
153             return s_threadName.Value.GetHandle();
154         }
155
156         internal event EventHandler<ConnectionTypeEventArgs> ConnectionTypeChanged
157         {
158             add
159             {
160                 if (_ConnectionTypeChanged == null)
161                 {
162                     ConnectionTypeChangedStart();
163                 }
164
165                 _ConnectionTypeChanged += value;
166             }
167             remove
168             {
169                 _ConnectionTypeChanged -= value;
170                 if (_ConnectionTypeChanged == null)
171                 {
172                     ConnectionTypeChangedStop();
173                 }
174             }
175         }
176
177         private void ConnectionTypeChangedStart()
178         {
179             _connectionTypeChangedCallback = (ConnectionType type, IntPtr user_data) =>
180             {
181                 if (_ConnectionTypeChanged != null)
182                 {
183                     _ConnectionTypeChanged(null, new ConnectionTypeEventArgs(type));
184                 }
185             };
186
187             int ret = Interop.Connection.SetTypeChangedCallback(GetHandle(), _connectionTypeChangedCallback, IntPtr.Zero);
188             if ((ConnectionError)ret != ConnectionError.None)
189             {
190                 Log.Error(Globals.LogTag, "It failed to register connection type changed callback, " + (ConnectionError)ret);
191                 ConnectionErrorFactory.ThrowConnectionException(ret);
192             }
193         }
194
195         private void ConnectionTypeChangedStop()
196         {
197             int ret = Interop.Connection.UnsetTypeChangedCallback(GetHandle());
198             if ((ConnectionError)ret != ConnectionError.None)
199             {
200                 Log.Error(Globals.LogTag, "It failed to unregister connection type changed callback, " + (ConnectionError)ret);
201                 ConnectionErrorFactory.ThrowConnectionException(ret);
202             }
203         }
204
205         internal event EventHandler<EthernetCableStateEventArgs> EthernetCableStateChanged
206         {
207             add
208             {
209                 if (_EthernetCableStateChanged == null)
210                 {
211                     EthernetCableStateChangedStart();
212                 }
213                 _EthernetCableStateChanged += value;
214             }
215             remove
216             {
217                 _EthernetCableStateChanged -= value;
218                 if (_EthernetCableStateChanged == null)
219                 {
220                     EthernetCableStateChangedStop();
221                 }
222             }
223         }
224
225         private void EthernetCableStateChangedStart()
226         {
227             int ret = Interop.Connection.SetEthernetCableStateChagedCallback(GetHandle(), EthernetCableStateChangedCallback, IntPtr.Zero);
228             if ((ConnectionError)ret != ConnectionError.None)
229             {
230                 Log.Error(Globals.LogTag, "It failed to register ethernet cable state changed callback, " + (ConnectionError)ret);
231                 ConnectionErrorFactory.ThrowConnectionException(ret);
232             }
233         }
234
235         private void EthernetCableStateChangedStop()
236         {
237             int ret = Interop.Connection.UnsetEthernetCableStateChagedCallback(GetHandle());
238             if ((ConnectionError)ret != ConnectionError.None)
239             {
240                 Log.Error(Globals.LogTag, "It failed to unregister ethernet cable state changed callback, " + (ConnectionError)ret);
241                 ConnectionErrorFactory.ThrowConnectionException(ret);
242             }
243         }
244
245         private void EthernetCableStateChangedCallback(EthernetCableState state, IntPtr user_data)
246         {
247             if (_EthernetCableStateChanged != null)
248             {
249                 _EthernetCableStateChanged(null, new EthernetCableStateEventArgs(state));
250             }
251         }
252
253         internal event EventHandler<AddressEventArgs> IPAddressChanged
254         {
255             add
256             {
257                 if (_IPAddressChanged == null)
258                 {
259                     IPAddressChangedStart();
260                 }
261                 _IPAddressChanged += value;
262             }
263
264             remove
265             {
266                 _IPAddressChanged -= value;
267                 if (_IPAddressChanged == null)
268                 {
269                     IPAddressChangedStop();
270                 }
271             }
272         }
273
274         private void IPAddressChangedStart()
275         {
276             _connectionAddressChangedCallback = (IntPtr IPv4, IntPtr IPv6, IntPtr UserData) =>
277             {
278                 if (_IPAddressChanged != null)
279                 {
280                     string ipv4 = Marshal.PtrToStringAnsi(IPv4);
281                     string ipv6 = Marshal.PtrToStringAnsi(IPv6);
282
283                     if ((string.IsNullOrEmpty(ipv4) == false) || (string.IsNullOrEmpty(ipv6) == false))
284                     {
285                         _IPAddressChanged(null, new AddressEventArgs(ipv4, ipv6));
286                     }
287                 }
288             };
289
290             int ret = Interop.Connection.SetIPAddressChangedCallback(GetHandle(), _connectionAddressChangedCallback, IntPtr.Zero);
291             if ((ConnectionError)ret != ConnectionError.None)
292             {
293                 Log.Error(Globals.LogTag, "It failed to register callback for changing IP address, " + (ConnectionError)ret);
294             }
295         }
296
297         private void IPAddressChangedStop()
298         {
299             int ret = Interop.Connection.UnsetIPAddressChangedCallback(GetHandle());
300             if ((ConnectionError)ret != ConnectionError.None)
301             {
302                 Log.Error(Globals.LogTag, "It failed to unregister callback for changing IP address, " + (ConnectionError)ret);
303             }
304         }
305
306         internal event EventHandler<AddressEventArgs> ProxyAddressChanged
307         {
308             add
309             {
310                 //Console.WriteLine("ProxyAddressChanged Add **");
311                 if (_ProxyAddressChanged == null)
312                 {
313                     ProxyAddressChangedStart();
314                 }
315
316                 _ProxyAddressChanged += value;
317             }
318             remove
319             {
320                 //Console.WriteLine("ProxyAddressChanged Remove");
321                 _ProxyAddressChanged -= value;
322                 if (_ProxyAddressChanged == null)
323                 {
324                     ProxyAddressChangedStop();
325                 }
326             }
327         }
328
329         private void ProxyAddressChangedStart()
330         {
331             _proxyAddressChangedCallback = (IntPtr IPv4, IntPtr IPv6, IntPtr UserData) =>
332             {
333                 if (_ProxyAddressChanged != null)
334                 {
335                     string ipv4 = Marshal.PtrToStringAnsi(IPv4);
336                     string ipv6 = Marshal.PtrToStringAnsi(IPv6);
337
338                     if ((string.IsNullOrEmpty(ipv4) == false) || (string.IsNullOrEmpty(ipv6) == false))
339                     {
340                         _ProxyAddressChanged(null, new AddressEventArgs(ipv4, ipv6));
341                     }
342                 }
343             };
344
345             int ret = Interop.Connection.SetProxyAddressChangedCallback(GetHandle(), _proxyAddressChangedCallback, IntPtr.Zero);
346             if ((ConnectionError)ret != ConnectionError.None)
347             {
348                 Log.Error(Globals.LogTag, "It failed to register callback for changing proxy address, " + (ConnectionError)ret);
349             }
350         }
351
352         private void ProxyAddressChangedStop()
353         {
354             int ret = Interop.Connection.UnsetProxyAddressChangedCallback(GetHandle());
355             if ((ConnectionError)ret != ConnectionError.None)
356             {
357                 Log.Error(Globals.LogTag, "It failed to unregister callback for changing proxy address, " + (ConnectionError)ret);
358             }
359         }
360
361         private void UnregisterEvents()
362         {
363             if (_ConnectionTypeChanged != null)
364             {
365                 ConnectionTypeChangedStop();
366             }
367             if (_IPAddressChanged != null)
368             {
369                 IPAddressChangedStop();
370             }
371             if (_EthernetCableStateChanged != null)
372             {
373                 EthernetCableStateChangedStop();
374             }
375             if (_ProxyAddressChanged != null)
376             {
377                 ProxyAddressChangedStop();
378             }
379         }
380
381         internal int GetProfileIterator(ProfileListType type, out IntPtr iterator)
382         {
383             return Interop.Connection.GetProfileIterator(GetHandle(), (int)type, out iterator);
384         }
385
386         internal bool HasNext(IntPtr iterator)
387         {
388             return Interop.Connection.HasNextProfileIterator(iterator);
389         }
390
391         internal int NextProfileIterator(IntPtr iterator, out IntPtr profileHandle)
392         {
393             return Interop.Connection.GetNextProfileIterator(iterator, out profileHandle);
394         }
395
396         internal int DestoryProfileIterator(IntPtr iterator)
397         {
398             return Interop.Connection.DestroyProfileIterator(iterator);
399         }
400
401         internal System.Net.IPAddress GetIPAddress(AddressFamily family)
402         {
403             Log.Debug(Globals.LogTag, "GetIPAddress " + family);
404             IntPtr ip;
405             int ret = Interop.Connection.GetIPAddress(GetHandle(), (int)family, out ip);
406             if ((ConnectionError)ret != ConnectionError.None)
407             {
408                 Log.Error(Globals.LogTag, "It failed to get IP address, " + (ConnectionError)ret);
409                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
410                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
411                 ConnectionErrorFactory.ThrowConnectionException(ret);
412             }
413
414             string result = Marshal.PtrToStringAnsi(ip);
415             Interop.Libc.Free(ip);
416             Log.Debug(Globals.LogTag, "IPAddress " + result + " (" + result.Length + ")");
417             if (result.Length == 0)
418             {
419                 if (family == AddressFamily.IPv4)
420                     return System.Net.IPAddress.Parse("0.0.0.0");
421                 else
422                     return System.Net.IPAddress.Parse("::");
423             }
424             return System.Net.IPAddress.Parse(result);
425         }
426
427         internal IEnumerable<System.Net.IPAddress> GetAllIPv6Addresses(ConnectionType type)
428         {
429             Log.Debug(Globals.LogTag, "GetAllIPv6Addresses");
430             List<System.Net.IPAddress> ipList = new List<System.Net.IPAddress>();
431             Interop.Connection.IPv6AddressCallback callback = (IntPtr ipv6Address, IntPtr userData) =>
432             {
433                 if (ipv6Address != IntPtr.Zero)
434                 {
435                     string ipv6 = Marshal.PtrToStringAnsi(ipv6Address);
436                     if (ipv6.Length == 0)
437                         ipList.Add(System.Net.IPAddress.Parse("::"));
438                     else
439                         ipList.Add(System.Net.IPAddress.Parse(ipv6));
440                     return true;
441                 }
442                 return false;
443             };
444
445             int ret = Interop.Connection.GetAllIPv6Addresses(GetHandle(), (int)type, callback, IntPtr.Zero);
446             if (ret != (int)ConnectionError.None)
447             {
448                 Log.Error(Globals.LogTag, "Failed to get all IPv6 addresses, Error - " + (ConnectionError)ret);
449                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
450                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
451                 ConnectionErrorFactory.ThrowConnectionException(ret);
452             }
453
454             return ipList;
455         }
456
457         internal string GetProxy(AddressFamily family)
458         {
459             Log.Debug(Globals.LogTag, "GetProxy " + family);
460             IntPtr ip;
461             int ret = Interop.Connection.GetProxy(GetHandle(), (int)family, out ip);
462             if ((ConnectionError)ret != ConnectionError.None)
463             {
464                 Log.Error(Globals.LogTag, "It failed to get proxy, " + (ConnectionError)ret);
465                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
466                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
467                 ConnectionErrorFactory.ThrowConnectionException(ret);
468             }
469
470             string result = Marshal.PtrToStringAnsi(ip);
471             Interop.Libc.Free(ip);
472             return result;
473         }
474
475         internal string GetMacAddress(ConnectionType type)
476         {
477             Log.Debug(Globals.LogTag, "GetMacAddress " + type);
478             IntPtr mac;
479             int ret = Interop.Connection.GetMacAddress(GetHandle(), (int)type, out mac);
480             if ((ConnectionError)ret != ConnectionError.None)
481             {
482                 Log.Error(Globals.LogTag, "It failed to get mac address, " + (ConnectionError)ret);
483                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.ethernet");
484                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
485                 ConnectionErrorFactory.ThrowConnectionException(ret);
486             }
487
488             string result = Marshal.PtrToStringAnsi(mac);
489             Interop.Libc.Free(mac);
490             return result;
491         }
492
493         internal long GetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
494         {
495             Log.Debug(Globals.LogTag, "GetStatistics " + connectionType + ", " + statisticsType);
496             long size;
497             int ret = Interop.Connection.GetStatistics(GetHandle(), (int)connectionType,
498                     (int)statisticsType, out size);
499             if ((ConnectionError)ret != ConnectionError.None)
500             {
501                 Log.Error(Globals.LogTag, "It failed to get statistics, " + (ConnectionError)ret);
502                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
503                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
504                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
505                 ConnectionErrorFactory.ThrowConnectionException(ret);
506             }
507             return size;
508         }
509
510         internal void ResetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
511         {
512             Log.Debug(Globals.LogTag, "ResetStatistics " + connectionType + ", " + statisticsType);
513             int ret = Interop.Connection.ResetStatistics(GetHandle(), (int)connectionType,
514                     (int)statisticsType);
515             if ((ConnectionError)ret != ConnectionError.None)
516             {
517                 Log.Error(Globals.LogTag, "It failed to reset statistics, " + (ConnectionError)ret);
518                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
519                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
520                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
521                 ConnectionErrorFactory.ThrowConnectionException(ret);
522             }
523         }
524
525         internal void AddRoute(AddressFamily family, string interfaceName, System.Net.IPAddress address, System.Net.IPAddress gateway)
526         {
527             if (interfaceName != null && address != null && gateway != null)
528             {
529                 Log.Debug(Globals.LogTag, "AddRoute " + family + ", " + interfaceName + ", " + address + ", " + gateway);
530                 int ret = Interop.Connection.AddRoute(GetHandle(), family, interfaceName, address.ToString(), gateway.ToString());
531                 if ((ConnectionError)ret != ConnectionError.None)
532                 {
533                     Log.Error(Globals.LogTag, "It failed to add route to the routing table, " + (ConnectionError)ret);
534                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
535                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
536                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
537                     ConnectionErrorFactory.ThrowConnectionException(ret);
538                 }
539             }
540
541             else
542             {
543                 throw new ArgumentNullException("Arguments are null");
544             }
545         }
546
547         internal void RemoveRoute(AddressFamily family, string interfaceName, System.Net.IPAddress address, System.Net.IPAddress gateway)
548         {
549             if (interfaceName != null && address != null && gateway != null)
550             {
551                 Log.Debug(Globals.LogTag, "RemoveRoute " + family + ", " + interfaceName + ", " + address + ", " + gateway);
552                 int ret = Interop.Connection.RemoveRoute(GetHandle(), family, interfaceName, address.ToString(), gateway.ToString());
553                 if ((ConnectionError)ret != ConnectionError.None)
554                 {
555                     Log.Error(Globals.LogTag, "It failed to remove route from the routing table, " + (ConnectionError)ret);
556                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
557                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
558                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
559                     ConnectionErrorFactory.ThrowConnectionException(ret);
560                 }
561             }
562
563             else
564             {
565                 throw new ArgumentNullException("Arguments are null");
566             }
567         }
568
569         internal ConnectionType ConnectionType
570         {
571             get
572             {
573                 Log.Debug(Globals.LogTag, "get ConnectionType");
574                 int type = 0;
575                 int ret = Interop.Connection.GetType(GetHandle(), out type);
576                 if ((ConnectionError)ret != ConnectionError.None)
577                 {
578                     Log.Error(Globals.LogTag, "It failed to get connection type, " + (ConnectionError)ret);
579                     ConnectionErrorFactory.ThrowConnectionException(ret);
580                 }
581                 return (ConnectionType)type;
582             }
583         }
584
585         internal CellularState CellularState
586         {
587             get
588             {
589                 Log.Debug(Globals.LogTag, "get CellularState");
590                 int type = 0;
591                 int ret = Interop.Connection.GetCellularState(GetHandle(), out type);
592                 if ((ConnectionError)ret != ConnectionError.None)
593                 {
594                     Log.Error(Globals.LogTag, "It failed to get cellular state, " + (ConnectionError)ret);
595                     ConnectionErrorFactory.ThrowConnectionException(ret);
596                 }
597                 return (CellularState)type;
598             }
599         }
600
601         internal ConnectionState WiFiState
602         {
603             get
604             {
605                 Log.Debug(Globals.LogTag, "get WiFiState");
606                 int type = 0;
607                 int ret = Interop.Connection.GetWiFiState(GetHandle(), out type);
608                 if ((ConnectionError)ret != ConnectionError.None)
609                 {
610                     Log.Error(Globals.LogTag, "It failed to get wifi state, " + (ConnectionError)ret);
611                     ConnectionErrorFactory.ThrowConnectionException(ret);
612                 }
613                 return (ConnectionState)type;
614             }
615         }
616
617         internal ConnectionState BluetoothState
618         {
619             get
620             {
621                 Log.Debug(Globals.LogTag, "get BluetoothState");
622                 int type = 0;
623                 int ret = Interop.Connection.GetBtState(GetHandle(), out type);
624                 if ((ConnectionError)ret != ConnectionError.None)
625                 {
626                     Log.Error(Globals.LogTag, "It failed to get bluetooth state, " + (ConnectionError)ret);
627                     ConnectionErrorFactory.ThrowConnectionException(ret);
628                 }
629                 return (ConnectionState)type;
630             }
631         }
632
633         internal ConnectionState EthernetState
634         {
635             get
636             {
637                 Log.Debug(Globals.LogTag, "get ConnectionType");
638                 int type = 0;
639                 int ret = Interop.Connection.GetEthernetState(GetHandle(), out type);
640                 if ((ConnectionError)ret != ConnectionError.None)
641                 {
642                     Log.Error(Globals.LogTag, "It failed to get ethernet state, " + (ConnectionError)ret);
643                     ConnectionErrorFactory.ThrowConnectionException(ret);
644                 }
645                 return (ConnectionState)type;
646             }
647         }
648
649         internal EthernetCableState EthernetCableState
650         {
651             get
652             {
653                 Log.Debug(Globals.LogTag, "get EthernetCableState");
654                 int type = 0;
655                 int ret = Interop.Connection.GetEthernetCableState(GetHandle(), out type);
656                 if ((ConnectionError)ret != ConnectionError.None)
657                 {
658                     Log.Error(Globals.LogTag, "It failed to get ethernet cable state, " + (ConnectionError)ret);
659                     ConnectionErrorFactory.ThrowConnectionException(ret);
660                 }
661                 return (EthernetCableState)type;
662             }
663         }
664
665         internal IntPtr CreateCellularProfile(ConnectionProfileType type, string keyword)
666         {
667             Log.Debug(Globals.LogTag, "CreateCellularProfile, " + type + ", " + keyword);
668             if (keyword != null)
669             {
670                 IntPtr handle = IntPtr.Zero;
671                 int ret = Interop.ConnectionProfile.Create((int)type, keyword, out handle);
672                 if ((ConnectionError)ret != ConnectionError.None)
673                 {
674                     Log.Error(Globals.LogTag, "It failed to Create profile, " + (ConnectionError)ret);
675                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
676                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
677                     ConnectionErrorFactory.ThrowConnectionException(ret);
678                 }
679
680                 return handle;
681             }
682
683             else
684             {
685                 throw new ArgumentNullException("Keyword is null");
686             }
687         }
688
689         internal void AddCellularProfile(CellularProfile profile)
690         {
691
692             Log.Debug(Globals.LogTag, "AddCellularProfile");
693             if (profile != null)
694             {
695                 if (profile.Type == ConnectionProfileType.Cellular)
696                 {
697                     int ret = Interop.Connection.AddProfile(GetHandle(), profile.ProfileHandle);
698                     if ((ConnectionError)ret != ConnectionError.None)
699                     {
700                         Log.Error(Globals.LogTag, "Failed to add cellular profile, " + (ConnectionError)ret);
701                         ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
702                         ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.profile)");
703                         ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
704                         ConnectionErrorFactory.ThrowConnectionException(ret);
705                     }
706                 }
707
708                 else
709                 {
710                     throw new ArgumentException("Profile type is not cellular");
711                 }
712             }
713
714             else
715             {
716                 throw new ArgumentNullException("Profile is null");
717             }
718         }
719
720         internal void RemoveProfile(ConnectionProfile profile)
721         {
722             Log.Debug(Globals.LogTag, "RemoveProfile");
723             if (profile != null)
724             {
725                 int ret = Interop.Connection.RemoveProfile(GetHandle(), profile.ProfileHandle);
726                 if ((ConnectionError)ret != ConnectionError.None)
727                 {
728                     Log.Error(Globals.LogTag, "It failed to remove profile, " + (ConnectionError)ret);
729                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
730                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
731                     ConnectionErrorFactory.ThrowConnectionException(ret);
732                 }
733             }
734
735             else
736             {
737                 throw new ArgumentNullException("Profile is null");
738             }
739         }
740
741         internal void UpdateProfile(ConnectionProfile profile)
742         {
743             Log.Debug(Globals.LogTag, "UpdateProfile");
744             if (profile != null)
745             {
746                 int ret = Interop.Connection.UpdateProfile(GetHandle(), profile.ProfileHandle);
747                 if ((ConnectionError)ret != ConnectionError.None)
748                 {
749                     Log.Error(Globals.LogTag, "It failed to update profile, " + (ConnectionError)ret);
750                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.ethernet");
751                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
752                     ConnectionErrorFactory.ThrowConnectionException(ret);
753                 }
754             }
755
756             else
757             {
758                 throw new ArgumentNullException("Profile is null");
759             }
760         }
761
762         internal ConnectionProfile GetCurrentProfile()
763         {
764             Log.Debug(Globals.LogTag, "GetCurrentProfile");
765             IntPtr ProfileHandle;
766             int ret = Interop.Connection.GetCurrentProfile(GetHandle(), out ProfileHandle);
767             if ((ConnectionError)ret != ConnectionError.None)
768             {
769                 Log.Error(Globals.LogTag, "It failed to get current profile, " + (ConnectionError)ret);
770                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
771                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
772                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
773                 ConnectionErrorFactory.ThrowConnectionException(ret);
774             }
775
776             ConnectionProfile Profile = new ConnectionProfile(ProfileHandle);
777             return Profile;
778         }
779
780         internal ConnectionProfile GetDefaultCellularProfile(CellularServiceType type)
781         {
782             Log.Debug(Globals.LogTag, "GetDefaultCellularProfile");
783             IntPtr ProfileHandle;
784             int ret = Interop.Connection.GetDefaultCellularServiceProfile(GetHandle(), (int)type, out ProfileHandle);
785             if ((ConnectionError)ret != ConnectionError.None)
786             {
787                 Log.Error(Globals.LogTag, "Error: " + ret);
788                 Log.Error(Globals.LogTag, "It failed to get default cellular profile, " + (ConnectionError)ret);
789                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
790                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
791                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
792                 ConnectionErrorFactory.ThrowConnectionException(ret);
793             }
794
795             CellularProfile Profile = new CellularProfile(ProfileHandle);
796             return Profile;
797         }
798
799         internal Task SetDefaultCellularProfile(CellularServiceType type, ConnectionProfile profile)
800         {
801             Log.Debug(Globals.LogTag, "SetDefaultCellularProfile");
802             if (profile != null)
803             {
804                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
805                 Interop.Connection.ConnectionCallback Callback = (ConnectionError Result, IntPtr Data) =>
806                 {
807                     if (Result != ConnectionError.None)
808                     {
809                         Log.Error(Globals.LogTag, "Error occurs during set default cellular profile, " + Result);
810                         task.SetException(new InvalidOperationException("Error occurs during set default cellular profile, " + Result));
811                     }
812
813                     task.SetResult(true);
814                 };
815
816                 int ret = Interop.Connection.SetDefaultCellularServiceProfileAsync(GetHandle(), (int)type, profile.ProfileHandle, Callback, (IntPtr)0);
817                 if ((ConnectionError)ret != ConnectionError.None)
818                 {
819                     Log.Error(Globals.LogTag, "It failed to set default cellular profile, " + (ConnectionError)ret);
820                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
821                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
822                     ConnectionErrorFactory.ThrowConnectionException(ret);
823                 }
824
825                 return task.Task;
826             }
827
828             else
829             {
830                 throw new ArgumentNullException("Profile is null");
831             }
832         }
833
834
835         internal Task<IEnumerable<ConnectionProfile>> GetProfileListAsync(ProfileListType type)
836         {
837             Log.Debug(Globals.LogTag, "GetProfileListAsync");
838             var task = new TaskCompletionSource<IEnumerable<ConnectionProfile>>();
839
840             List<ConnectionProfile> Result = new List<ConnectionProfile>();
841             IntPtr iterator;
842             int ret = Interop.Connection.GetProfileIterator(GetHandle(), (int)type, out iterator);
843             if ((ConnectionError)ret != ConnectionError.None)
844             {
845                 Log.Error(Globals.LogTag, "It failed to get profile iterator, " + (ConnectionError)ret);
846                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
847                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
848                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
849                 ConnectionErrorFactory.ThrowConnectionException(ret);
850             }
851
852             while (Interop.Connection.HasNextProfileIterator(iterator))
853             {
854                 IntPtr nextH;
855                 IntPtr profileH;
856                 Interop.Connection.GetNextProfileIterator(iterator, out nextH);
857                 Interop.ConnectionProfile.Clone(out profileH, nextH);
858
859                 int profileType;
860                 Interop.ConnectionProfile.GetType(profileH, out profileType);
861
862                 if ((ConnectionProfileType)profileType == ConnectionProfileType.WiFi)
863                 {
864                     WiFiProfile cur = new WiFiProfile(profileH);
865                     Result.Add(cur);
866                 }
867                 else if ((ConnectionProfileType)profileType == ConnectionProfileType.Cellular)
868                 {
869                     CellularProfile cur = new CellularProfile(profileH);
870                     Result.Add(cur);
871                 }
872                 else {
873                     ConnectionProfile cur = new ConnectionProfile(profileH);
874                     Result.Add(cur);
875                 }
876             }
877             Interop.Connection.DestroyProfileIterator(iterator);
878             task.SetResult(Result);
879             return task.Task;
880         }
881
882         internal Task OpenProfileAsync(ConnectionProfile profile)
883         {
884             Log.Debug(Globals.LogTag, "OpenProfileAsync");
885             if (profile != null)
886             {
887                 Log.Debug(Globals.LogTag, "OpenProfileAsync " + profile.Name);
888                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
889                 Interop.Connection.ConnectionCallback Callback = (ConnectionError Result, IntPtr Data) =>
890                 {
891                     Log.Debug(Globals.LogTag, "Connected " + profile.Name);
892                     if (Result != ConnectionError.None)
893                     {
894                         Log.Error(Globals.LogTag, "Error occurs during connecting profile, " + Result);
895                         task.SetException(new InvalidOperationException("Error occurs during connecting profile, " + Result));
896                     }
897
898                     task.SetResult(true);
899                 };
900
901                 int ret = Interop.Connection.OpenProfile(GetHandle(), profile.ProfileHandle, Callback, IntPtr.Zero);
902                 if ((ConnectionError)ret != ConnectionError.None)
903                 {
904                     Log.Error(Globals.LogTag, "It failed to connect profile, " + (ConnectionError)ret);
905                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth");
906                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
907                     ConnectionErrorFactory.ThrowConnectionException(ret);
908                 }
909
910                 return task.Task;
911             }
912
913             else
914             {
915                 throw new ArgumentNullException("Profile is null");
916             }
917         }
918
919         internal Task CloseProfileAsync(ConnectionProfile profile)
920         {
921             Log.Debug(Globals.LogTag, "CloseProfileAsync");
922             if (profile != null)
923             {
924                 Log.Debug(Globals.LogTag, "CloseProfileAsync " + profile.Name);
925                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
926                 Interop.Connection.ConnectionCallback Callback = (ConnectionError Result, IntPtr Data) =>
927                 {
928                     if (Result != ConnectionError.None)
929                     {
930                         Log.Error(Globals.LogTag, "Error occurs during disconnecting profile, " + Result);
931                         task.SetException(new InvalidOperationException("Error occurs during disconnecting profile, " + Result));
932                     }
933
934                     task.SetResult(true);
935                 };
936
937                 int ret = Interop.Connection.CloseProfile(GetHandle(), profile.ProfileHandle, Callback, IntPtr.Zero);
938                 if ((ConnectionError)ret != ConnectionError.None)
939                 {
940                     Log.Error(Globals.LogTag, "It failed to disconnect profile, " + (ConnectionError)ret);
941                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth");
942                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
943                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
944                     ConnectionErrorFactory.ThrowConnectionException(ret);
945                 }
946
947                 return task.Task;
948             }
949
950             else
951             {
952                 throw new ArgumentNullException("Profile is null");
953             }
954         }
955     }
956 }