Fix memory leak
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.WiFi / Tizen.Network.WiFi / WiFiAP.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.Threading.Tasks;
19 using System.Collections.Generic;
20
21 namespace Tizen.Network.WiFi
22 {
23     /// <summary>
24     /// A class for managing the network information of the access point(AP).
25     /// </summary>
26     public class WiFiAP : IDisposable
27     {
28         private IntPtr _apHandle = IntPtr.Zero;
29         private Dictionary<IntPtr, Interop.WiFi.VoidCallback> _callback_map = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
30         private int _requestId = 0;
31         private WiFiNetwork _network;
32         private WiFiSecurity _security;
33         private bool _disposed = false;
34
35         /// <summary>
36         /// The network information of the access point(AP).
37         /// </summary>
38         public WiFiNetwork NetworkInformation
39         {
40             get
41             {
42                 return _network;
43             }
44         }
45
46         /// <summary>
47         /// The security information of the access point(AP).
48         /// </summary>
49         public WiFiSecurity SecurityInformation
50         {
51             get
52             {
53                 return _security;
54             }
55         }
56
57         internal WiFiAP(IntPtr handle)
58         {
59             Log.Debug(Globals.LogTag, "New WiFiAP. Handle: " + handle);
60             _apHandle = handle;
61             Initialize();
62         }
63
64         /// <summary>
65         /// Creates an object for the access point.
66         /// </summary>
67         /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
68         public WiFiAP(string essid)
69         {
70             Log.Debug(Globals.LogTag, "New WiFiAP. Essid: " + essid);
71             createHandle(essid, true);
72             Initialize();
73         }
74
75         /// <summary>
76         /// Creates an object for the hidden access point.
77         /// </summary>
78         /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
79         /// <param name="hidden">The value to set hidden AP</param>
80         public WiFiAP(string essid, bool hidden)
81         {
82             createHandle(essid, hidden);
83             Initialize();
84         }
85
86         ~WiFiAP()
87         {
88             Dispose(false);
89         }
90
91         /// <summary>
92         /// A method to destroy the managed WiFiAP objects.
93         /// </summary>
94         public void Dispose()
95         {
96             Dispose(true);
97             GC.SuppressFinalize(this);
98         }
99
100         private void Dispose(bool disposing)
101         {
102             if (_disposed)
103                 return;
104
105             if (disposing)
106             {
107                 Interop.WiFi.AP.Destroy(_apHandle);
108                 _apHandle = IntPtr.Zero;
109             }
110             _disposed = true;
111         }
112
113         private void createHandle(string id, bool hidden)
114         {
115             int ret = -1;
116             if (hidden)
117             {
118                 ret = Interop.WiFi.AP.CreateHiddenAP(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
119             }
120
121             else
122             {
123                 ret = Interop.WiFi.AP.Create(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
124             }
125
126             if (ret != (int)WiFiError.None)
127             {
128                 Log.Error(Globals.LogTag, "Failed to create handle, Error - " + (WiFiError)ret);
129                 WiFiErrorFactory.ThrowWiFiException(ret);
130             }
131         }
132
133         private void Initialize()
134         {
135             Interop.WiFi.SafeWiFiAPHandle apHandle = new Interop.WiFi.SafeWiFiAPHandle(_apHandle);
136             _network = new WiFiNetwork(apHandle);
137             _security = new WiFiSecurity(apHandle);
138         }
139
140         /// <summary>
141         /// Refreshes the access point information.
142         /// </summary>
143         public void Refresh()
144         {
145             Log.Debug(Globals.LogTag, "Refresh");
146             int ret = Interop.WiFi.AP.Refresh(_apHandle);
147             if (ret != (int)WiFiError.None)
148             {
149                 Log.Error(Globals.LogTag, "Failed to refresh ap handle, Error - " + (WiFiError)ret);
150                 WiFiErrorFactory.ThrowWiFiException(ret, _apHandle);
151             }
152         }
153
154         /// <summary>
155         /// Connects the access point asynchronously.
156         /// </summary>
157         /// <returns> A task indicating whether the Connect method is done or not.</returns>
158         public Task ConnectAsync()
159         {
160             Log.Debug(Globals.LogTag, "ConnectAsync");
161             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
162             IntPtr id;
163             lock (_callback_map)
164             {
165                 id = (IntPtr)_requestId++;
166                 _callback_map[id] = (error, key) =>
167                 {
168                     Log.Debug(Globals.LogTag, "Connecting finished : " + (WiFiError)error);
169                     if (error != (int)WiFiError.None)
170                     {
171                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
172                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
173                     }
174                     task.SetResult(true);
175                     lock (_callback_map)
176                     {
177                         _callback_map.Remove(key);
178                     }
179                 };
180             }
181             int ret = Interop.WiFi.Connect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
182             if (ret != (int)WiFiError.None)
183             {
184                 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
185                 WiFiErrorFactory.ThrowWiFiException(ret);
186             }
187             return task.Task;
188         }
189
190         /// <summary>
191         /// Connects the access point with WPS PBC asynchronously.
192         /// </summary>
193         /// <returns> A task indicating whether the ConnectByWpsPbs method is done or not.</returns>
194         public Task ConnectByWpsPbcAsync()
195         {
196             Log.Debug(Globals.LogTag, "ConnectByWpsPbcAsync");
197             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
198             IntPtr id;
199             lock (_callback_map)
200             {
201                 id = (IntPtr)_requestId++;
202                 _callback_map[id] = (error, key) =>
203                 {
204                     Log.Debug(Globals.LogTag, "Connecting by WPS PBC finished");
205                     if (error != (int)WiFiError.None)
206                     {
207                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
208                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
209                     }
210                     task.SetResult(true);
211                     lock (_callback_map)
212                     {
213                         _callback_map.Remove(key);
214                     }
215                 };
216             }
217             int ret = Interop.WiFi.ConnectByWpsPbc(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
218             if (ret != (int)WiFiError.None)
219             {
220                 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
221                 WiFiErrorFactory.ThrowWiFiException(ret);
222             }
223             return task.Task;
224         }
225
226         /// <summary>
227         /// Connects the access point with WPS PIN asynchronously.
228         /// </summary>
229         /// <returns> A task indicating whether the ConnectByWpsPin method is done or not.</returns>
230         /// <param name="pin">The WPS PIN is a non-null string with length greater than 0 and less than or equal to 8.</param>
231         public Task ConnectByWpsPinAsync(string pin)
232         {
233             Log.Debug(Globals.LogTag, "ConnectByWpsPinAsync");
234             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
235             IntPtr id;
236             lock (_callback_map)
237             {
238                 id = (IntPtr)_requestId++;
239                 _callback_map[id] = (error, key) =>
240                 {
241                     Log.Debug(Globals.LogTag, "Connecting by WPS PIN finished");
242                     if (error != (int)WiFiError.None)
243                     {
244                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
245                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
246                     }
247                     task.SetResult(true);
248                     lock (_callback_map)
249                     {
250                         _callback_map.Remove(key);
251                     }
252                 };
253             }
254             int ret = Interop.WiFi.ConnectByWpsPin(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, pin, _callback_map[id], id);
255             if (ret != (int)WiFiError.None)
256             {
257                 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
258                 WiFiErrorFactory.ThrowWiFiException(ret);
259             }
260             return task.Task;
261         }
262
263         /// <summary>
264         /// Disconnects the access point asynchronously.
265         /// </summary>
266         /// <returns> A task indicating whether the Disconnect method is done or not.</returns>
267         public Task DisconnectAsync()
268         {
269             Log.Debug(Globals.LogTag, "DisconnectAsync");
270             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
271             IntPtr id;
272             lock (_callback_map)
273             {
274                 id = (IntPtr)_requestId++;
275                 _callback_map[id] = (error, key) =>
276                 {
277                     Log.Debug(Globals.LogTag, "Disconnecting finished");
278                     if (error != (int)WiFiError.None)
279                     {
280                         Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
281                         task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
282                     }
283                     task.SetResult(true);
284                     lock (_callback_map)
285                     {
286                         _callback_map.Remove(key);
287                     }
288                 };
289             }
290             int ret = Interop.WiFi.Disconnect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
291             if (ret != (int)WiFiError.None)
292             {
293                 Log.Error(Globals.LogTag, "Failed to disconnect wifi, Error - " + (WiFiError)ret);
294                 WiFiErrorFactory.ThrowWiFiException(ret);
295             }
296             return task.Task;
297         }
298
299         /// <summary>
300         /// Deletes the information of stored access point and disconnects it when it is connected.<br>
301         /// If an AP is connected, then connection information will be stored. This information is used when a connection to that AP is established automatically.
302         /// </summary>
303         public void RemoveAP()
304         {
305             Log.Debug(Globals.LogTag, "RemoveAP");
306             int ret = Interop.WiFi.RemoveAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
307             if (ret != (int)WiFiError.None)
308             {
309                 Log.Error(Globals.LogTag, "Failed to remove with AP, Error - " + (WiFiError)ret);
310                 WiFiErrorFactory.ThrowWiFiException(ret);
311             }
312         }
313     }
314 }