Release 4.0.0-preview1-00051
[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 _ConnectionTypeChanged = null;
92         private EventHandler _IPAddressChanged = null;
93         private EventHandler _EthernetCableStateChanged = null;
94         private EventHandler _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 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 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 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 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             return System.Net.IPAddress.Parse(result);;
417         }
418
419         internal IEnumerable<System.Net.IPAddress> GetAllIPv6Addresses(ConnectionType type)
420         {
421             Log.Debug(Globals.LogTag, "GetAllIPv6Addresses");
422             List<System.Net.IPAddress> ipList = new List<System.Net.IPAddress>();
423             Interop.Connection.IPv6AddressCallback callback = (IntPtr ipv6Address, IntPtr userData) =>
424             {
425                 if (ipv6Address != IntPtr.Zero)
426                 {
427                     string ipv6 = Marshal.PtrToStringAnsi(ipv6Address);
428                     ipList.Add(System.Net.IPAddress.Parse(ipv6));
429                     return true;
430                 }
431                 return false;
432             };
433
434             int ret = Interop.Connection.GetAllIPv6Addresses(GetHandle(), (int)type, callback, IntPtr.Zero);
435             if (ret != (int)ConnectionError.None)
436             {
437                 Log.Error(Globals.LogTag, "Failed to get all IPv6 addresses, Error - " + (ConnectionError)ret);
438                 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");
439                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
440                 ConnectionErrorFactory.ThrowConnectionException(ret);
441             }
442
443             return ipList;
444         }
445
446         internal string GetProxy(AddressFamily family)
447         {
448             Log.Debug(Globals.LogTag, "GetProxy " + family);
449             IntPtr ip;
450             int ret = Interop.Connection.GetProxy(GetHandle(), (int)family, out ip);
451             if ((ConnectionError)ret != ConnectionError.None)
452             {
453                 Log.Error(Globals.LogTag, "It failed to get proxy, " + (ConnectionError)ret);
454                 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");
455                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
456                 ConnectionErrorFactory.ThrowConnectionException(ret);
457             }
458
459             string result = Marshal.PtrToStringAnsi(ip);
460             Interop.Libc.Free(ip);
461             return result;
462         }
463
464         internal string GetMacAddress(ConnectionType type)
465         {
466             Log.Debug(Globals.LogTag, "GetMacAddress " + type);
467             IntPtr mac;
468             int ret = Interop.Connection.GetMacAddress(GetHandle(), (int)type, out mac);
469             if ((ConnectionError)ret != ConnectionError.None)
470             {
471                 Log.Error(Globals.LogTag, "It failed to get mac address, " + (ConnectionError)ret);
472                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.ethernet");
473                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
474                 ConnectionErrorFactory.ThrowConnectionException(ret);
475             }
476
477             string result = Marshal.PtrToStringAnsi(mac);
478             Interop.Libc.Free(mac);
479             return result;
480         }
481
482         internal long GetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
483         {
484             Log.Debug(Globals.LogTag, "GetStatistics " + connectionType + ", " + statisticsType);
485             long size;
486             int ret = Interop.Connection.GetStatistics(GetHandle(), (int)connectionType,
487                     (int)statisticsType, out size);
488             if ((ConnectionError)ret != ConnectionError.None)
489             {
490                 Log.Error(Globals.LogTag, "It failed to get statistics, " + (ConnectionError)ret);
491                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
492                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
493                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
494                 ConnectionErrorFactory.ThrowConnectionException(ret);
495             }
496             return size;
497         }
498
499         internal void ResetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
500         {
501             Log.Debug(Globals.LogTag, "ResetStatistics " + connectionType + ", " + statisticsType);
502             int ret = Interop.Connection.ResetStatistics(GetHandle(), (int)connectionType,
503                     (int)statisticsType);
504             if ((ConnectionError)ret != ConnectionError.None)
505             {
506                 Log.Error(Globals.LogTag, "It failed to reset statistics, " + (ConnectionError)ret);
507                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
508                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
509                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
510                 ConnectionErrorFactory.ThrowConnectionException(ret);
511             }
512         }
513
514         internal void AddRoute(AddressFamily family, string interfaceName, System.Net.IPAddress address, System.Net.IPAddress gateway)
515         {
516             if (interfaceName != null && address != null && gateway != null)
517             {
518                 Log.Debug(Globals.LogTag, "AddRoute " + family + ", " + interfaceName + ", " + address + ", " + gateway);
519                 int ret = Interop.Connection.AddRoute(GetHandle(), family, interfaceName, address.ToString(), gateway.ToString());
520                 if ((ConnectionError)ret != ConnectionError.None)
521                 {
522                     Log.Error(Globals.LogTag, "It failed to add route to the routing table, " + (ConnectionError)ret);
523                     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");
524                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
525                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
526                     ConnectionErrorFactory.ThrowConnectionException(ret);
527                 }
528             }
529
530             else
531             {
532                 throw new ArgumentNullException("Arguments are null");
533             }
534         }
535
536         internal void RemoveRoute(AddressFamily family, string interfaceName, System.Net.IPAddress address, System.Net.IPAddress gateway)
537         {
538             if (interfaceName != null && address != null && gateway != null)
539             {
540                 Log.Debug(Globals.LogTag, "RemoveRoute " + family + ", " + interfaceName + ", " + address + ", " + gateway);
541                 int ret = Interop.Connection.RemoveRoute(GetHandle(), family, interfaceName, address.ToString(), gateway.ToString());
542                 if ((ConnectionError)ret != ConnectionError.None)
543                 {
544                     Log.Error(Globals.LogTag, "It failed to remove route from the routing table, " + (ConnectionError)ret);
545                     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");
546                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
547                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
548                     ConnectionErrorFactory.ThrowConnectionException(ret);
549                 }
550             }
551
552             else
553             {
554                 throw new ArgumentNullException("Arguments are null");
555             }
556         }
557
558         internal ConnectionType ConnectionType
559         {
560             get
561             {
562                 Log.Debug(Globals.LogTag, "get ConnectionType");
563                 int type = 0;
564                 int ret = Interop.Connection.GetType(GetHandle(), out type);
565                 if ((ConnectionError)ret != ConnectionError.None)
566                 {
567                     Log.Error(Globals.LogTag, "It failed to get connection type, " + (ConnectionError)ret);
568                     ConnectionErrorFactory.ThrowConnectionException(ret);
569                 }
570                 return (ConnectionType)type;
571             }
572         }
573
574         internal CellularState CellularState
575         {
576             get
577             {
578                 Log.Debug(Globals.LogTag, "get CellularState");
579                 int type = 0;
580                 int ret = Interop.Connection.GetCellularState(GetHandle(), out type);
581                 if ((ConnectionError)ret != ConnectionError.None)
582                 {
583                     Log.Error(Globals.LogTag, "It failed to get cellular state, " + (ConnectionError)ret);
584                     ConnectionErrorFactory.ThrowConnectionException(ret);
585                 }
586                 return (CellularState)type;
587             }
588         }
589
590         internal ConnectionState WiFiState
591         {
592             get
593             {
594                 Log.Debug(Globals.LogTag, "get WiFiState");
595                 int type = 0;
596                 int ret = Interop.Connection.GetWiFiState(GetHandle(), out type);
597                 if ((ConnectionError)ret != ConnectionError.None)
598                 {
599                     Log.Error(Globals.LogTag, "It failed to get wifi state, " + (ConnectionError)ret);
600                     ConnectionErrorFactory.ThrowConnectionException(ret);
601                 }
602                 return (ConnectionState)type;
603             }
604         }
605
606         internal ConnectionState BluetoothState
607         {
608             get
609             {
610                 Log.Debug(Globals.LogTag, "get BluetoothState");
611                 int type = 0;
612                 int ret = Interop.Connection.GetBtState(GetHandle(), out type);
613                 if ((ConnectionError)ret != ConnectionError.None)
614                 {
615                     Log.Error(Globals.LogTag, "It failed to get bluetooth state, " + (ConnectionError)ret);
616                     ConnectionErrorFactory.ThrowConnectionException(ret);
617                 }
618                 return (ConnectionState)type;
619             }
620         }
621
622         internal ConnectionState EthernetState
623         {
624             get
625             {
626                 Log.Debug(Globals.LogTag, "get ConnectionType");
627                 int type = 0;
628                 int ret = Interop.Connection.GetEthernetState(GetHandle(), out type);
629                 if ((ConnectionError)ret != ConnectionError.None)
630                 {
631                     Log.Error(Globals.LogTag, "It failed to get ethernet state, " + (ConnectionError)ret);
632                     ConnectionErrorFactory.ThrowConnectionException(ret);
633                 }
634                 return (ConnectionState)type;
635             }
636         }
637
638         internal EthernetCableState EthernetCableState
639         {
640             get
641             {
642                 Log.Debug(Globals.LogTag, "get EthernetCableState");
643                 int type = 0;
644                 int ret = Interop.Connection.GetEthernetCableState(GetHandle(), out type);
645                 if ((ConnectionError)ret != ConnectionError.None)
646                 {
647                     Log.Error(Globals.LogTag, "It failed to get ethernet cable state, " + (ConnectionError)ret);
648                     ConnectionErrorFactory.ThrowConnectionException(ret);
649                 }
650                 return (EthernetCableState)type;
651             }
652         }
653
654         internal IntPtr CreateCellularProfile(ConnectionProfileType type, string keyword)
655         {
656             Log.Debug(Globals.LogTag, "CreateCellularProfile, " + type + ", " + keyword);
657             if (keyword != null)
658             {
659                 IntPtr handle = IntPtr.Zero;
660                 int ret = Interop.ConnectionProfile.Create((int)type, keyword, out handle);
661                 if ((ConnectionError)ret != ConnectionError.None)
662                 {
663                     Log.Error(Globals.LogTag, "It failed to Create profile, " + (ConnectionError)ret);
664                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
665                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
666                     ConnectionErrorFactory.ThrowConnectionException(ret);
667                 }
668
669                 return handle;
670             }
671
672             else
673             {
674                 throw new ArgumentNullException("Keyword is null");
675             }
676         }
677
678         internal void AddCellularProfile(CellularProfile profile)
679         {
680
681             Log.Debug(Globals.LogTag, "AddCellularProfile");
682             if (profile != null)
683             {
684                 if (profile.Type == ConnectionProfileType.Cellular)
685                 {
686                     int ret = Interop.Connection.AddProfile(GetHandle(), profile.ProfileHandle);
687                     if ((ConnectionError)ret != ConnectionError.None)
688                     {
689                         Log.Error(Globals.LogTag, "Failed to add cellular profile, " + (ConnectionError)ret);
690                         ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
691                         ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.profile)");
692                         ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
693                         ConnectionErrorFactory.ThrowConnectionException(ret);
694                     }
695                 }
696
697                 else
698                 {
699                     throw new ArgumentException("Profile type is not cellular");
700                 }
701             }
702
703             else
704             {
705                 throw new ArgumentNullException("Profile is null");
706             }
707         }
708
709         internal void RemoveProfile(ConnectionProfile profile)
710         {
711             Log.Debug(Globals.LogTag, "RemoveProfile");
712             if (profile != null)
713             {
714                 int ret = Interop.Connection.RemoveProfile(GetHandle(), profile.ProfileHandle);
715                 if ((ConnectionError)ret != ConnectionError.None)
716                 {
717                     Log.Error(Globals.LogTag, "It failed to remove profile, " + (ConnectionError)ret);
718                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
719                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
720                     ConnectionErrorFactory.ThrowConnectionException(ret);
721                 }
722             }
723
724             else
725             {
726                 throw new ArgumentNullException("Profile is null");
727             }
728         }
729
730         internal void UpdateProfile(ConnectionProfile profile)
731         {
732             Log.Debug(Globals.LogTag, "UpdateProfile");
733             if (profile != null)
734             {
735                 int ret = Interop.Connection.UpdateProfile(GetHandle(), profile.ProfileHandle);
736                 if ((ConnectionError)ret != ConnectionError.None)
737                 {
738                     Log.Error(Globals.LogTag, "It failed to update profile, " + (ConnectionError)ret);
739                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.ethernet");
740                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
741                     ConnectionErrorFactory.ThrowConnectionException(ret);
742                 }
743             }
744
745             else
746             {
747                 throw new ArgumentNullException("Profile is null");
748             }
749         }
750
751         internal ConnectionProfile GetCurrentProfile()
752         {
753             Log.Debug(Globals.LogTag, "GetCurrentProfile");
754             IntPtr ProfileHandle;
755             int ret = Interop.Connection.GetCurrentProfile(GetHandle(), out ProfileHandle);
756             if ((ConnectionError)ret != ConnectionError.None)
757             {
758                 Log.Error(Globals.LogTag, "It failed to get current profile, " + (ConnectionError)ret);
759                 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");
760                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
761                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
762                 ConnectionErrorFactory.ThrowConnectionException(ret);
763             }
764
765             ConnectionProfile Profile = new ConnectionProfile(ProfileHandle);
766             return Profile;
767         }
768
769         internal ConnectionProfile GetDefaultCellularProfile(CellularServiceType type)
770         {
771             Log.Debug(Globals.LogTag, "GetDefaultCellularProfile");
772             IntPtr ProfileHandle;
773             int ret = Interop.Connection.GetDefaultCellularServiceProfile(GetHandle(), (int)type, out ProfileHandle);
774             if ((ConnectionError)ret != ConnectionError.None)
775             {
776                 Log.Error(Globals.LogTag, "Error: " + ret);
777                 Log.Error(Globals.LogTag, "It failed to get default cellular profile, " + (ConnectionError)ret);
778                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
779                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
780                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
781                 ConnectionErrorFactory.ThrowConnectionException(ret);
782             }
783
784             CellularProfile Profile = new CellularProfile(ProfileHandle);
785             return Profile;
786         }
787
788         internal Task SetDefaultCellularProfile(CellularServiceType type, ConnectionProfile profile)
789         {
790             Log.Debug(Globals.LogTag, "SetDefaultCellularProfile");
791             if (profile != null)
792             {
793                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
794                 Interop.Connection.ConnectionCallback Callback = (ConnectionError Result, IntPtr Data) =>
795                 {
796                     if (Result != ConnectionError.None)
797                     {
798                         Log.Error(Globals.LogTag, "Error occurs during set default cellular profile, " + Result);
799                         task.SetException(new InvalidOperationException("Error occurs during set default cellular profile, " + Result));
800                     }
801
802                     task.SetResult(true);
803                 };
804
805                 int ret = Interop.Connection.SetDefaultCellularServiceProfileAsync(GetHandle(), (int)type, profile.ProfileHandle, Callback, (IntPtr)0);
806                 if ((ConnectionError)ret != ConnectionError.None)
807                 {
808                     Log.Error(Globals.LogTag, "It failed to set default cellular profile, " + (ConnectionError)ret);
809                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
810                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
811                     ConnectionErrorFactory.ThrowConnectionException(ret);
812                 }
813
814                 return task.Task;
815             }
816
817             else
818             {
819                 throw new ArgumentNullException("Profile is null");
820             }
821         }
822
823
824         internal Task<IEnumerable<ConnectionProfile>> GetProfileListAsync(ProfileListType type)
825         {
826             Log.Debug(Globals.LogTag, "GetProfileListAsync");
827             var task = new TaskCompletionSource<IEnumerable<ConnectionProfile>>();
828
829             List<ConnectionProfile> Result = new List<ConnectionProfile>();
830             IntPtr iterator;
831             int ret = Interop.Connection.GetProfileIterator(GetHandle(), (int)type, out iterator);
832             if ((ConnectionError)ret != ConnectionError.None)
833             {
834                 Log.Error(Globals.LogTag, "It failed to get profile iterator, " + (ConnectionError)ret);
835                 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");
836                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
837                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
838                 ConnectionErrorFactory.ThrowConnectionException(ret);
839             }
840
841             while (Interop.Connection.HasNextProfileIterator(iterator))
842             {
843                 IntPtr nextH;
844                 IntPtr profileH;
845                 Interop.Connection.GetNextProfileIterator(iterator, out nextH);
846                 Interop.ConnectionProfile.Clone(out profileH, nextH);
847
848                 int profileType;
849                 Interop.ConnectionProfile.GetType(profileH, out profileType);
850
851                 if ((ConnectionProfileType)profileType == ConnectionProfileType.WiFi)
852                 {
853                     WiFiProfile cur = new WiFiProfile(profileH);
854                     Result.Add(cur);
855                 }
856                 else if ((ConnectionProfileType)profileType == ConnectionProfileType.Cellular)
857                 {
858                     CellularProfile cur = new CellularProfile(profileH);
859                     Result.Add(cur);
860                 }
861                 else {
862                     ConnectionProfile cur = new ConnectionProfile(profileH);
863                     Result.Add(cur);
864                 }
865             }
866             Interop.Connection.DestroyProfileIterator(iterator);
867             task.SetResult(Result);
868             return task.Task;
869         }
870
871         internal Task OpenProfileAsync(ConnectionProfile profile)
872         {
873             Log.Debug(Globals.LogTag, "OpenProfileAsync");
874             if (profile != null)
875             {
876                 Log.Debug(Globals.LogTag, "OpenProfileAsync " + profile.Name);
877                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
878                 Interop.Connection.ConnectionCallback Callback = (ConnectionError Result, IntPtr Data) =>
879                 {
880                     Log.Debug(Globals.LogTag, "Connected " + profile.Name);
881                     if (Result != ConnectionError.None)
882                     {
883                         Log.Error(Globals.LogTag, "Error occurs during connecting profile, " + Result);
884                         task.SetException(new InvalidOperationException("Error occurs during connecting profile, " + Result));
885                     }
886
887                     task.SetResult(true);
888                 };
889
890                 int ret = Interop.Connection.OpenProfile(GetHandle(), profile.ProfileHandle, Callback, IntPtr.Zero);
891                 if ((ConnectionError)ret != ConnectionError.None)
892                 {
893                     Log.Error(Globals.LogTag, "It failed to connect profile, " + (ConnectionError)ret);
894                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth");
895                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
896                     ConnectionErrorFactory.ThrowConnectionException(ret);
897                 }
898
899                 return task.Task;
900             }
901
902             else
903             {
904                 throw new ArgumentNullException("Profile is null");
905             }
906         }
907
908         internal Task CloseProfileAsync(ConnectionProfile profile)
909         {
910             Log.Debug(Globals.LogTag, "CloseProfileAsync");
911             if (profile != null)
912             {
913                 Log.Debug(Globals.LogTag, "CloseProfileAsync " + profile.Name);
914                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
915                 Interop.Connection.ConnectionCallback Callback = (ConnectionError Result, IntPtr Data) =>
916                 {
917                     if (Result != ConnectionError.None)
918                     {
919                         Log.Error(Globals.LogTag, "Error occurs during disconnecting profile, " + Result);
920                         task.SetException(new InvalidOperationException("Error occurs during disconnecting profile, " + Result));
921                     }
922
923                     task.SetResult(true);
924                 };
925
926                 int ret = Interop.Connection.CloseProfile(GetHandle(), profile.ProfileHandle, Callback, IntPtr.Zero);
927                 if ((ConnectionError)ret != ConnectionError.None)
928                 {
929                     Log.Error(Globals.LogTag, "It failed to disconnect profile, " + (ConnectionError)ret);
930                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth");
931                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
932                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
933                     ConnectionErrorFactory.ThrowConnectionException(ret);
934                 }
935
936                 return task.Task;
937             }
938
939             else
940             {
941                 throw new ArgumentNullException("Profile is null");
942             }
943         }
944     }
945 }