2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Threading.Tasks;
19 using System.Collections.Generic;
21 namespace Tizen.Network.WiFi
24 /// A class for managing the network information of the access point (AP).
26 /// <since_tizen> 3 </since_tizen>
27 public class WiFiAP : IDisposable
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;
39 /// The network information of the access point (AP).
41 /// <since_tizen> 3 </since_tizen>
42 /// <value>The WiFiNetwork instance containing the network information of the AP.</value>
43 public WiFiNetwork NetworkInformation
52 /// The security information of the access point (AP).
54 /// <since_tizen> 3 </since_tizen>
55 /// <value>The WiFiSecurity instance containing security information of the AP.</value>
56 public WiFiSecurity SecurityInformation
64 internal WiFiAP(IntPtr handle)
66 Log.Debug(Globals.LogTag, "New WiFiAP. Handle: " + handle);
72 /// Creates an object for the access point.
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)
86 Log.Debug(Globals.LogTag, "New WiFiAP. Essid: " + essid);
87 createHandle(essid, true);
92 /// Creates an object for the hidden access point.
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)
107 createHandle(essid, hidden);
117 /// A method to destroy the managed WiFiAP objects.
119 /// <since_tizen> 3 </since_tizen>
120 public void Dispose()
123 GC.SuppressFinalize(this);
126 private void Dispose(bool disposing)
133 Interop.WiFi.AP.Destroy(_apHandle);
134 _apHandle = IntPtr.Zero;
139 private void createHandle(string id, bool hidden)
144 throw new ArgumentNullException("Essid is null");
149 ret = Interop.WiFi.AP.CreateHiddenAP(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
154 ret = Interop.WiFi.AP.Create(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
157 if (ret != (int)WiFiError.None)
159 Log.Error(Globals.LogTag, "Failed to create handle, Error - " + (WiFiError)ret);
160 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
164 private void Initialize()
166 Interop.WiFi.SafeWiFiAPHandle apHandle = new Interop.WiFi.SafeWiFiAPHandle(_apHandle);
167 _network = new WiFiNetwork(apHandle);
168 _security = new WiFiSecurity(apHandle);
172 /// Refreshes the access point information.
174 /// <since_tizen> 3 </since_tizen>
175 /// <feature>http://tizen.org/feature/network.wifi</feature>
176 /// <privilege>http://tizen.org/privilege/network.get</privilege>
177 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
178 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
179 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
180 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
181 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
182 public void Refresh()
184 Log.Debug(Globals.LogTag, "Refresh");
187 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
189 int ret = Interop.WiFi.AP.Refresh(_apHandle);
190 if (ret != (int)WiFiError.None)
192 Log.Error(Globals.LogTag, "Failed to refresh ap handle, Error - " + (WiFiError)ret);
193 WiFiErrorFactory.ThrowWiFiException(ret, _apHandle, "http://tizen.org/privilege/network.get");
198 /// Connects the access point asynchronously.
200 /// <since_tizen> 3 </since_tizen>
201 /// <returns> A task indicating whether the connect method is done or not.</returns>
202 /// <feature>http://tizen.org/feature/network.wifi</feature>
203 /// <privilege>http://tizen.org/privilege/network.set</privilege>
204 /// <privilege>http://tizen.org/privilege/network.get</privilege>
205 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
206 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
207 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
208 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
209 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
210 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
211 public Task ConnectAsync()
213 Log.Debug(Globals.LogTag, "ConnectAsync");
216 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
218 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
222 id = (IntPtr)_requestId++;
223 _callback_map[id] = (error, key) =>
225 Log.Debug(Globals.LogTag, "Connecting finished : " + (WiFiError)error);
226 if (error != (int)WiFiError.None)
228 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
229 task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
231 task.SetResult(true);
234 _callback_map.Remove(key);
239 int ret = Interop.WiFi.Connect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
240 if (ret != (int)WiFiError.None)
242 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
243 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
250 /// Connects the access point with the WPS asynchronously.
252 /// <since_tizen> 3 </since_tizen>
253 /// <param name="info">A WpsInfo instance which is type of WpsPbcInfo or WpsPinInfo.</param>
254 /// <returns>A task indicating whether the ConnectWps method is done or not.</returns>
255 /// <feature>http://tizen.org/feature/network.wifi</feature>
256 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
257 /// <privilege>http://tizen.org/privilege/network.get</privilege>
258 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
259 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
260 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
261 /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
262 /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is an empty string or more than 7 characters.</exception>
263 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
264 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
265 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
266 public Task ConnectWpsAsync(WpsInfo info)
268 Log.Debug(Globals.LogTag, "ConnectWpsAsync");
271 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
273 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
277 id = (IntPtr)_requestId++;
278 _callback_map[id] = (error, key) =>
280 Log.Debug(Globals.LogTag, "Connecting by WPS finished");
281 if (error != (int)WiFiError.None)
283 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
284 task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
286 task.SetResult(true);
289 _callback_map.Remove(key);
295 if (info.GetType() == typeof(WpsPbcInfo))
297 ret = Interop.WiFi.ConnectByWpsPbc(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
300 else if (info.GetType() == typeof(WpsPinInfo))
302 WpsPinInfo pinInfo = (WpsPinInfo)info;
303 if (pinInfo.GetWpsPin() == null)
305 throw new ArgumentNullException("Wps pin should not be null");
308 if (pinInfo.GetWpsPin().Length == 0 || pinInfo.GetWpsPin().Length > 8)
310 throw new ArgumentOutOfRangeException("Wps pin should not be empty or more than 7 characters");
313 ret = Interop.WiFi.ConnectByWpsPin(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, pinInfo.GetWpsPin(), _callback_map[id], id);
316 if (ret != (int)WiFiError.None)
318 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
319 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
326 /// Connects the access point with WPS without SSID asynchronously.
328 /// <since_tizen> 3 </since_tizen>
329 /// <param name="info">A WpsInfo instance which is of type WpsPbcInfo or WpsPinInfo.</param>
330 /// <returns>A task which contains Connected access point information.</returns>
332 /// If WpsPinInfo is used, its object has to be constructed with a pin which must be 4 or 8 characters long.
334 /// <feature>http://tizen.org/feature/network.wifi</feature>
335 /// <privilege>http://tizen.org/privilege/network.set</privilege>
336 /// <privilege>http://tizen.org/privilege/network.get</privilege>
337 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
338 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
339 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
340 /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
341 /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is not of 4 or 8 characters long.</exception>
342 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
343 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
344 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
345 public static Task<WiFiAP> ConnectWpsWithoutSsidAsync(WpsInfo info)
347 TaskCompletionSource<WiFiAP> task = new TaskCompletionSource<WiFiAP>();
351 id = (IntPtr)s_requestId++;
352 s_callbackMap[id] = (error, key) =>
354 Log.Debug(Globals.LogTag, "Connecting by WPS finished");
355 if (error != (int)WiFiError.None)
357 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
358 task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
360 WiFiAP ap = WiFiManagerImpl.Instance.GetConnectedAP();
364 s_callbackMap.Remove(key);
370 if (info.GetType() == typeof(WpsPbcInfo))
372 ret = Interop.WiFi.ConnectByWpsPbcWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), s_callbackMap[id], id);
375 else if (info.GetType() == typeof(WpsPinInfo))
377 WpsPinInfo pinInfo = (WpsPinInfo)info;
378 if (pinInfo.GetWpsPin() == null)
380 throw new ArgumentNullException("Wps pin should not be null");
383 if (pinInfo.GetWpsPin().Length != 4 && pinInfo.GetWpsPin().Length != 8)
385 throw new ArgumentOutOfRangeException("Wps pin should be of 4 or 8 characters long");
388 ret = Interop.WiFi.ConnectByWpsPinWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), pinInfo.GetWpsPin(), s_callbackMap[id], id);
391 if (ret != (int)WiFiError.None)
393 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
394 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
401 /// Disconnects the access point asynchronously.
403 /// <since_tizen> 3 </since_tizen>
404 /// <returns> A task indicating whether the disconnect method is done or not.</returns>
405 /// <feature>http://tizen.org/feature/network.wifi</feature>
406 /// <privilege>http://tizen.org/privilege/network.set</privilege>
407 /// <privilege>http://tizen.org/privilege/network.get</privilege>
408 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
409 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
410 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
411 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
412 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
413 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
414 public Task DisconnectAsync()
416 Log.Debug(Globals.LogTag, "DisconnectAsync");
419 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
421 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
425 id = (IntPtr)_requestId++;
426 _callback_map[id] = (error, key) =>
428 Log.Debug(Globals.LogTag, "Disconnecting finished");
429 if (error != (int)WiFiError.None)
431 Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
432 task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
434 task.SetResult(true);
437 _callback_map.Remove(key);
441 int ret = Interop.WiFi.Disconnect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
442 if (ret != (int)WiFiError.None)
444 Log.Error(Globals.LogTag, "Failed to disconnect wifi, Error - " + (WiFiError)ret);
445 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
451 /// Deletes the information of a stored access point and disconnects it when the AP is connected.<br>
452 /// 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.
454 /// <since_tizen> 3 </since_tizen>
455 /// <feature>http://tizen.org/feature/network.wifi</feature>
456 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
457 /// <privilege>http://tizen.org/privilege/network.get</privilege>
458 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
459 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
460 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
461 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
462 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
463 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
464 public void ForgetAP()
466 Log.Debug(Globals.LogTag, "ForgetAP");
469 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
471 int ret = Interop.WiFi.RemoveAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
472 if (ret != (int)WiFiError.None)
474 Log.Error(Globals.LogTag, "Failed to forget AP, Error - " + (WiFiError)ret);
475 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
481 /// An abstract class which is used to represent the WPS information of the access point.
483 /// <since_tizen> 3 </since_tizen>
484 public abstract class WpsInfo
489 /// A class which is used to represent WPS PBC information of the access point.
491 public class WpsPbcInfo : WpsInfo
496 /// A class which is used to represent WPS PIN information of the access point.
498 public class WpsPinInfo : WpsInfo
507 /// A public constructor which instantiates WpsPinInfo class with the given pin.
509 /// <since_tizen> 3 </since_tizen>
510 /// <param name="pin">WPS Pin of the access point.</param>
512 /// Pin should not be null or empty. It should be of less than 8 characters.
514 public WpsPinInfo(string pin)
519 internal string GetWpsPin()