Merge "[WiFi] Fix XML documentation warnings"
[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     /// <since_tizen> 3 </since_tizen>
27     public class WiFiAP : IDisposable
28     {
29         private IntPtr _apHandle = IntPtr.Zero;
30         private Dictionary<IntPtr, Interop.WiFi.VoidCallback> _callback_map = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
31         private static Dictionary<IntPtr, Interop.WiFi.VoidCallback> s_callbackMap = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
32         private int _requestId = 0;
33         private static int s_requestId = 0;
34         private WiFiNetwork _network;
35         private WiFiSecurity _security;
36         private bool _disposed = false;
37
38         /// <summary>
39         /// The network information of the access point (AP).
40         /// </summary>
41         /// <since_tizen> 3 </since_tizen>
42         /// <value>The WiFiNetwork instance containing the network information of the AP.</value>
43         public WiFiNetwork NetworkInformation
44         {
45             get
46             {
47                 return _network;
48             }
49         }
50
51         /// <summary>
52         /// The security information of the access point (AP).
53         /// </summary>
54         /// <since_tizen> 3 </since_tizen>
55         /// <value>The WiFiSecurity instance containing security information of the AP.</value>
56         public WiFiSecurity SecurityInformation
57         {
58             get
59             {
60                 return _security;
61             }
62         }
63
64         internal WiFiAP(IntPtr handle)
65         {
66             Log.Debug(Globals.LogTag, "New WiFiAP. Handle: " + handle);
67             _apHandle = handle;
68             Initialize();
69         }
70
71         /// <summary>
72         /// Creates an object for the access point.
73         /// </summary>
74         /// <since_tizen> 3 </since_tizen>
75         /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
76         /// <feature>http://tizen.org/feature/network.wifi</feature>
77         /// <privilege>http://tizen.org/privilege/network.get</privilege>
78         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
79         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
80         /// <exception cref="ArgumentNullException">Thrown when the ESSID is passed as null.</exception>
81         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
82         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
83         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
84         public WiFiAP(string essid)
85         {
86             Log.Debug(Globals.LogTag, "New WiFiAP. Essid: " + essid);
87             createHandle(essid, true);
88             Initialize();
89         }
90
91         /// <summary>
92         /// Creates an object for the hidden access point.
93         /// </summary>
94         /// <since_tizen> 3 </since_tizen>
95         /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
96         /// <param name="hidden">The value to set a hidden AP.</param>
97         /// <feature>http://tizen.org/feature/network.wifi</feature>
98         /// <privilege>http://tizen.org/privilege/network.get</privilege>
99         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
100         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
101         /// <exception cref="ArgumentNullException">Thrown when the ESSID is passed as null.</exception>
102         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
103         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
104         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
105         public WiFiAP(string essid, bool hidden)
106         {
107             createHandle(essid, hidden);
108             Initialize();
109         }
110
111         /// <summary>
112         /// Destroy the WiFiAP object
113         /// </summary>
114         ~WiFiAP()
115         {
116             Dispose(false);
117         }
118
119         /// <summary>
120         /// A method to destroy the managed WiFiAP objects.
121         /// </summary>
122         /// <since_tizen> 3 </since_tizen>
123         public void Dispose()
124         {
125             Dispose(true);
126             GC.SuppressFinalize(this);
127         }
128
129         private void Dispose(bool disposing)
130         {
131             if (_disposed)
132                 return;
133
134             if (disposing)
135             {
136                 Interop.WiFi.AP.Destroy(_apHandle);
137                 _apHandle = IntPtr.Zero;
138             }
139             _disposed = true;
140         }
141
142         private void createHandle(string id, bool hidden)
143         {
144             int ret = -1;
145             if (id == null)
146             {
147                 throw new ArgumentNullException("Essid is null");
148             }
149
150             if (hidden)
151             {
152                 ret = Interop.WiFi.AP.CreateHiddenAP(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
153             }
154
155             else
156             {
157                 ret = Interop.WiFi.AP.Create(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
158             }
159
160             if (ret != (int)WiFiError.None)
161             {
162                 Log.Error(Globals.LogTag, "Failed to create handle, Error - " + (WiFiError)ret);
163                 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
164             }
165         }
166
167         private void Initialize()
168         {
169             Interop.WiFi.SafeWiFiAPHandle apHandle = new Interop.WiFi.SafeWiFiAPHandle(_apHandle);
170             _network = new WiFiNetwork(apHandle);
171             _security = new WiFiSecurity(apHandle);
172         }
173
174         /// <summary>
175         /// Refreshes the access point information.
176         /// </summary>
177         /// <since_tizen> 3 </since_tizen>
178         /// <feature>http://tizen.org/feature/network.wifi</feature>
179         /// <privilege>http://tizen.org/privilege/network.get</privilege>
180         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
181         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
182         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
183         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
184         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
185         public void Refresh()
186         {
187             Log.Debug(Globals.LogTag, "Refresh");
188             if (_disposed)
189             {
190                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
191             }
192             int ret = Interop.WiFi.AP.Refresh(_apHandle);
193             if (ret != (int)WiFiError.None)
194             {
195                 Log.Error(Globals.LogTag, "Failed to refresh ap handle, Error - " + (WiFiError)ret);
196                 WiFiErrorFactory.ThrowWiFiException(ret, _apHandle, "http://tizen.org/privilege/network.get");
197             }
198         }
199
200         /// <summary>
201         /// Connects the access point asynchronously.
202         /// </summary>
203         /// <since_tizen> 3 </since_tizen>
204         /// <returns> A task indicating whether the connect method is done or not.</returns>
205         /// <feature>http://tizen.org/feature/network.wifi</feature>
206         /// <privilege>http://tizen.org/privilege/network.set</privilege>
207         /// <privilege>http://tizen.org/privilege/network.get</privilege>
208         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
209         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
210         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
211         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
212         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
213         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
214         public Task ConnectAsync()
215         {
216             Log.Debug(Globals.LogTag, "ConnectAsync");
217             if (_disposed)
218             {
219                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
220             }
221             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
222             IntPtr id;
223             lock (_callback_map)
224             {
225                 id = (IntPtr)_requestId++;
226                 _callback_map[id] = (error, key) =>
227                 {
228                     Log.Debug(Globals.LogTag, "Connecting finished : " + (WiFiError)error);
229                     if (error != (int)WiFiError.None)
230                     {
231                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
232                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
233                     }
234                     else
235                     {
236                         task.SetResult(true);
237                     }
238                     lock (_callback_map)
239                     {
240                         _callback_map.Remove(key);
241                     }
242                 };
243             }
244
245             int ret = Interop.WiFi.Connect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
246             if (ret != (int)WiFiError.None)
247             {
248                 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
249                 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
250             }
251
252             return task.Task;
253         }
254
255         /// <summary>
256         /// Connects the access point with the WPS asynchronously.
257         /// </summary>
258         /// <since_tizen> 3 </since_tizen>
259         /// <param name="info">A WpsInfo instance which is type of WpsPbcInfo or WpsPinInfo.</param>
260         /// <returns>A task indicating whether the ConnectWps method is done or not.</returns>
261         /// <feature>http://tizen.org/feature/network.wifi</feature>
262         /// <privilege>http://tizen.org/privilege/network.profile</privilege>
263         /// <privilege>http://tizen.org/privilege/network.get</privilege>
264         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
265         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
266         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
267         /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
268         /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is an empty string or more than 7 characters.</exception>
269         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
270         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
271         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
272         public Task ConnectWpsAsync(WpsInfo info)
273         {
274             Log.Debug(Globals.LogTag, "ConnectWpsAsync");
275             if (_disposed)
276             {
277                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
278             }
279             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
280             IntPtr id;
281             lock (_callback_map)
282             {
283                 id = (IntPtr)_requestId++;
284                 _callback_map[id] = (error, key) =>
285                 {
286                     Log.Debug(Globals.LogTag, "Connecting by WPS finished");
287                     if (error != (int)WiFiError.None)
288                     {
289                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
290                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
291                     }
292                     else
293                     {
294                         task.SetResult(true);
295                     }
296                     lock (_callback_map)
297                     {
298                         _callback_map.Remove(key);
299                     }
300                 };
301             }
302
303             int ret = -1;
304             if (info.GetType() == typeof(WpsPbcInfo))
305             {
306                 ret = Interop.WiFi.ConnectByWpsPbc(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
307             }
308
309             else if (info.GetType() == typeof(WpsPinInfo))
310             {
311                 WpsPinInfo pinInfo = (WpsPinInfo)info;
312                 if (pinInfo.GetWpsPin() == null)
313                 {
314                     throw new ArgumentNullException("Wps pin should not be null");
315                 }
316
317                 if (pinInfo.GetWpsPin().Length == 0 || pinInfo.GetWpsPin().Length > 8)
318                 {
319                     throw new ArgumentOutOfRangeException("Wps pin should not be empty or more than 7 characters");
320                 }
321
322                 ret = Interop.WiFi.ConnectByWpsPin(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, pinInfo.GetWpsPin(), _callback_map[id], id);
323             }
324
325             if (ret != (int)WiFiError.None)
326             {
327                 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
328                 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
329             }
330
331             return task.Task;
332         }
333
334         /// <summary>
335         /// Connects the access point with WPS without SSID asynchronously.
336         /// </summary>
337         /// <since_tizen> 3 </since_tizen>
338         /// <param name="info">A WpsInfo instance which is of type WpsPbcInfo or WpsPinInfo.</param>
339         /// <returns>A task which contains Connected access point information.</returns>
340         /// <remarks>
341         /// If WpsPinInfo is used, its object has to be constructed with a pin which must be 4 or 8 characters long.
342         /// </remarks>
343         /// <feature>http://tizen.org/feature/network.wifi</feature>
344         /// <privilege>http://tizen.org/privilege/network.set</privilege>
345         /// <privilege>http://tizen.org/privilege/network.get</privilege>
346         /// <privilege>http://tizen.org/privilege/network.profile</privilege>
347         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
348         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
349         /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
350         /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is not of 4 or 8 characters long.</exception>
351         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
352         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
353         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
354         public static Task<WiFiAP> ConnectWpsWithoutSsidAsync(WpsInfo info)
355         {
356             TaskCompletionSource<WiFiAP> task = new TaskCompletionSource<WiFiAP>();
357             IntPtr id;
358             lock (s_callbackMap)
359             {
360                 id = (IntPtr)s_requestId++;
361                 s_callbackMap[id] = (error, key) =>
362                 {
363                     Log.Debug(Globals.LogTag, "Connecting by WPS finished");
364                     if (error != (int)WiFiError.None)
365                     {
366                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
367                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
368                     }
369                     else
370                     {
371                         WiFiAP ap = WiFiManagerImpl.Instance.GetConnectedAP();
372                         task.SetResult(ap);
373                     }
374                     lock (s_callbackMap)
375                     {
376                         s_callbackMap.Remove(key);
377                     }
378                 };
379             }
380
381             int ret = -1;
382             if (info.GetType() == typeof(WpsPbcInfo))
383             {
384                 ret = Interop.WiFi.ConnectByWpsPbcWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), s_callbackMap[id], id);   
385             }
386
387             else if (info.GetType() == typeof(WpsPinInfo))
388             {
389                 WpsPinInfo pinInfo = (WpsPinInfo)info;
390                 if (pinInfo.GetWpsPin() == null)
391                 {
392                     throw new ArgumentNullException("Wps pin should not be null");
393                 }
394
395                 if (pinInfo.GetWpsPin().Length != 4 && pinInfo.GetWpsPin().Length != 8)
396                 {
397                     throw new ArgumentOutOfRangeException("Wps pin should be of 4 or 8 characters long");
398                 }
399
400                 ret = Interop.WiFi.ConnectByWpsPinWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), pinInfo.GetWpsPin(), s_callbackMap[id], id);
401             }
402
403             if (ret != (int)WiFiError.None)
404             {
405                 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
406                 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
407             }
408
409             return task.Task;
410         }
411
412         /// <summary>
413         /// Disconnects the access point asynchronously.
414         /// </summary>
415         /// <since_tizen> 3 </since_tizen>
416         /// <returns> A task indicating whether the disconnect method is done or not.</returns>
417         /// <feature>http://tizen.org/feature/network.wifi</feature>
418         /// <privilege>http://tizen.org/privilege/network.set</privilege>
419         /// <privilege>http://tizen.org/privilege/network.get</privilege>
420         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
421         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
422         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
423         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
424         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
425         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
426         public Task DisconnectAsync()
427         {
428             Log.Debug(Globals.LogTag, "DisconnectAsync");
429             if (_disposed)
430             {
431                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
432             }
433             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
434             IntPtr id;
435             lock (_callback_map)
436             {
437                 id = (IntPtr)_requestId++;
438                 _callback_map[id] = (error, key) =>
439                 {
440                     Log.Debug(Globals.LogTag, "Disconnecting finished");
441                     if (error != (int)WiFiError.None)
442                     {
443                         Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
444                         task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
445                     }
446                     else
447                     {
448                         task.SetResult(true);
449                     }
450                     lock (_callback_map)
451                     {
452                         _callback_map.Remove(key);
453                     }
454                 };
455             }
456             int ret = Interop.WiFi.Disconnect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
457             if (ret != (int)WiFiError.None)
458             {
459                 Log.Error(Globals.LogTag, "Failed to disconnect wifi, Error - " + (WiFiError)ret);
460                 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
461             }
462             return task.Task;
463         }
464
465         /// <summary>
466         /// Deletes the information of a stored access point and disconnects it when the AP is connected.
467         /// If an AP is connected, then the connection information will be stored. This information is used when a connection to that AP is established automatically.
468         /// </summary>
469         /// <since_tizen> 3 </since_tizen>
470         /// <feature>http://tizen.org/feature/network.wifi</feature>
471         /// <privilege>http://tizen.org/privilege/network.profile</privilege>
472         /// <privilege>http://tizen.org/privilege/network.get</privilege>
473         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
474         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
475         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
476         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
477         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
478         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
479         public void ForgetAP()
480         {
481             Log.Debug(Globals.LogTag, "ForgetAP");
482             if (_disposed)
483             {
484                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
485             }
486             int ret = Interop.WiFi.RemoveAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
487             if (ret != (int)WiFiError.None)
488             {
489                 Log.Error(Globals.LogTag, "Failed to forget AP, Error - " + (WiFiError)ret);
490                 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
491             }
492         }
493     }
494
495     /// <summary>
496     /// An abstract class which is used to represent the WPS information of the access point.
497     /// </summary>
498     /// <since_tizen> 3 </since_tizen>
499     public abstract class WpsInfo
500     {
501     }
502
503     /// <summary>
504     /// A class which is used to represent WPS PBC information of the access point.
505     /// </summary>
506     public class WpsPbcInfo : WpsInfo
507     {
508     }
509
510     /// <summary>
511     /// A class which is used to represent WPS PIN information of the access point.
512     /// </summary>
513     public class WpsPinInfo : WpsInfo
514     {
515         private string _pin;
516
517         private WpsPinInfo()
518         {
519         }
520
521         /// <summary>
522         /// A public constructor which instantiates WpsPinInfo class with the given pin.
523         /// </summary>
524         /// <since_tizen> 3 </since_tizen>
525         /// <param name="pin">WPS Pin of the access point.</param>
526         /// <remarks>
527         /// Pin should not be null or empty. It should be of less than 8 characters.
528         /// </remarks>
529         public WpsPinInfo(string pin)
530         {
531             _pin = pin;
532         }
533
534         internal string GetWpsPin()
535         {
536             return _pin;
537         }
538     }
539 }