[WiFi] Fixes for design issues reported in confluence
[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                 _network.Dispose();
108                 _security.Dispose();
109                 Interop.WiFi.AP.Destroy(_apHandle);
110                 _apHandle = IntPtr.Zero;
111             }
112             disposed = true;
113         }
114
115         private void createHandle(string id, bool hidden)
116         {
117             int ret = -1;
118             if (hidden)
119             {
120                 ret = Interop.WiFi.AP.CreateHiddenAP(WiFiManagerImpl.Instance.GetHandle(), id, out _apHandle);
121             }
122             else
123             {
124                 ret = Interop.WiFi.AP.Create(WiFiManagerImpl.Instance.GetHandle(), id, out _apHandle);
125             }
126
127             if (ret != (int)WiFiError.None)
128             {
129                 Log.Error(Globals.LogTag, "Failed to create handle, Error - " + (WiFiError)ret);
130                 WiFiErrorFactory.ThrowWiFiException(ret);
131             }
132         }
133
134         private void Initialize()
135         {
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             int ret = Interop.WiFi.AP.Refresh(_apHandle);
146             if (ret != (int)WiFiError.None)
147             {
148                 Log.Error(Globals.LogTag, "Failed to refresh ap handle, Error - " + (WiFiError)ret);
149                 WiFiErrorFactory.ThrowWiFiException(ret, _apHandle);
150             }
151         }
152
153         internal IntPtr GetHandle()
154         {
155             return _apHandle;
156         }
157
158         /// <summary>
159         /// Connects the access point asynchronously.
160         /// </summary>
161         /// <returns> A task indicating whether the Connect method is done or not.</returns>
162         public Task ConnectAsync()
163         {
164             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
165             IntPtr id;
166             lock (_callback_map)
167             {
168                 id = (IntPtr)_requestId++;
169                 _callback_map[id] = (error, key) =>
170                 {
171                     Log.Debug(Globals.LogTag, "Connecting finished : " + (WiFiError)error);
172                     if (error != (int)WiFiError.None)
173                     {
174                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
175                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
176                     }
177                     task.SetResult(true);
178                     lock (_callback_map)
179                     {
180                         _callback_map.Remove(key);
181                     }
182                 };
183             }
184             int ret = Interop.WiFi.Connect(WiFiManagerImpl.Instance.GetHandle(), _apHandle, _callback_map[id], id);
185             if (ret != (int)WiFiError.None)
186             {
187                 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
188                 WiFiErrorFactory.ThrowWiFiException(ret);
189             }
190             return task.Task;
191         }
192
193         /// <summary>
194         /// Connects the access point with WPS PBC asynchronously.
195         /// </summary>
196         /// <returns> A task indicating whether the ConnectByWpsPbs method is done or not.</returns>
197         public Task ConnectByWpsPbcAsync()
198         {
199             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
200             IntPtr id;
201             lock (_callback_map)
202             {
203                 id = (IntPtr)_requestId++;
204                 _callback_map[id] = (error, key) =>
205                 {
206                     Log.Debug(Globals.LogTag, "Connecting by WPS PBC finished");
207                     if (error != (int)WiFiError.None)
208                     {
209                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
210                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
211                     }
212                     task.SetResult(true);
213                     lock (_callback_map)
214                     {
215                         _callback_map.Remove(key);
216                     }
217                 };
218             }
219             int ret = Interop.WiFi.ConnectByWpsPbc(WiFiManagerImpl.Instance.GetHandle(), _apHandle, _callback_map[id], id);
220             if (ret != (int)WiFiError.None)
221             {
222                 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
223                 WiFiErrorFactory.ThrowWiFiException(ret);
224             }
225             return task.Task;
226         }
227
228         /// <summary>
229         /// Connects the access point with WPS PIN asynchronously.
230         /// </summary>
231         /// <returns> A task indicating whether the ConnectByWpsPin method is done or not.</returns>
232         /// <param name="pin">The WPS PIN is a non-null string with length greater than 0 and less than or equal to 8.</param>
233         public Task ConnectByWpsPinAsync(string pin)
234         {
235             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
236             IntPtr id;
237             lock (_callback_map)
238             {
239                 id = (IntPtr)_requestId++;
240                 _callback_map[id] = (error, key) =>
241                 {
242                     Log.Debug(Globals.LogTag, "Connecting by WPS PIN finished");
243                     if (error != (int)WiFiError.None)
244                     {
245                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
246                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
247                     }
248                     task.SetResult(true);
249                     lock (_callback_map)
250                     {
251                         _callback_map.Remove(key);
252                     }
253                 };
254             }
255             int ret = Interop.WiFi.ConnectByWpsPin(WiFiManagerImpl.Instance.GetHandle(), _apHandle, pin, _callback_map[id], id);
256             if (ret != (int)WiFiError.None)
257             {
258                 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
259                 WiFiErrorFactory.ThrowWiFiException(ret);
260             }
261             return task.Task;
262         }
263
264         /// <summary>
265         /// Disconnects the access point asynchronously.
266         /// </summary>
267         /// <returns> A task indicating whether the Disconnect method is done or not.</returns>
268         public Task DisconnectAsync()
269         {
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.GetHandle(), _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             int ret = Interop.WiFi.RemoveAP(WiFiManagerImpl.Instance.GetHandle(), _apHandle);
306             if (ret != (int)WiFiError.None)
307             {
308                 Log.Error(Globals.LogTag, "Failed to remove with AP, Error - " + (WiFiError)ret);
309                 WiFiErrorFactory.ThrowWiFiException(ret);
310             }
311         }
312     }
313 }