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;
20 using System.ComponentModel;
22 namespace Tizen.Network.WiFi
25 /// A class for managing the network information of the access point (AP).
27 /// <since_tizen> 3 </since_tizen>
28 public class WiFiAP : IDisposable
30 private IntPtr _apHandle = IntPtr.Zero;
31 private Dictionary<IntPtr, Interop.WiFi.VoidCallback> _callback_map = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
32 private static Dictionary<IntPtr, Interop.WiFi.VoidCallback> s_callbackMap = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
33 private int _requestId = 0;
34 private static int s_requestId = 0;
35 private WiFiNetwork _network;
36 private WiFiSecurity _security;
37 private bool _disposed = false;
40 /// The network information of the access point (AP).
42 /// <since_tizen> 3 </since_tizen>
43 /// <value>The WiFiNetwork instance containing the network information of the AP.</value>
44 public WiFiNetwork NetworkInformation
53 /// The security information of the access point (AP).
55 /// <since_tizen> 3 </since_tizen>
56 /// <value>The WiFiSecurity instance containing security information of the AP.</value>
57 public WiFiSecurity SecurityInformation
65 internal WiFiAP(IntPtr handle)
67 Log.Debug(Globals.LogTag, "New WiFiAP. Handle: " + handle);
73 /// Creates an object for the access point.
75 /// <since_tizen> 3 </since_tizen>
76 /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
77 /// <feature>http://tizen.org/feature/network.wifi</feature>
78 /// <privilege>http://tizen.org/privilege/network.get</privilege>
79 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
80 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
81 /// <exception cref="ArgumentNullException">Thrown when the ESSID is passed as null.</exception>
82 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
83 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
84 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
85 public WiFiAP(string essid)
87 Log.Debug(Globals.LogTag, "New WiFiAP. Essid: " + essid);
88 createHandle(essid, true);
93 /// Creates an object for the hidden access point.
95 /// <since_tizen> 3 </since_tizen>
96 /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
97 /// <param name="hidden">The value to set a hidden AP.</param>
98 /// <feature>http://tizen.org/feature/network.wifi</feature>
99 /// <privilege>http://tizen.org/privilege/network.get</privilege>
100 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
101 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
102 /// <exception cref="ArgumentNullException">Thrown when the ESSID is passed as null.</exception>
103 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
104 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
105 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
106 public WiFiAP(string essid, bool hidden)
108 createHandle(essid, hidden);
113 /// Destroy the WiFiAP object
121 /// A method to destroy the managed WiFiAP objects.
123 /// <since_tizen> 3 </since_tizen>
124 public void Dispose()
127 GC.SuppressFinalize(this);
130 private void Dispose(bool disposing)
137 Interop.WiFi.AP.Destroy(_apHandle);
138 _apHandle = IntPtr.Zero;
143 private void createHandle(string id, bool hidden)
148 throw new ArgumentNullException("Essid is null");
153 ret = Interop.WiFi.AP.CreateHiddenAP(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
158 ret = Interop.WiFi.AP.Create(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
161 if (ret != (int)WiFiError.None)
163 Log.Error(Globals.LogTag, "Failed to create handle, Error - " + (WiFiError)ret);
164 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
168 private void Initialize()
170 Interop.WiFi.SafeWiFiAPHandle apHandle = new Interop.WiFi.SafeWiFiAPHandle(_apHandle);
171 _network = new WiFiNetwork(apHandle);
172 _security = new WiFiSecurity(apHandle);
176 /// Refreshes the access point information.
178 /// <since_tizen> 3 </since_tizen>
179 /// <feature>http://tizen.org/feature/network.wifi</feature>
180 /// <privilege>http://tizen.org/privilege/network.get</privilege>
181 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
182 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
183 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
184 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
185 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
186 public void Refresh()
188 Log.Debug(Globals.LogTag, "Refresh");
191 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
193 int ret = Interop.WiFi.AP.Refresh(_apHandle);
194 if (ret != (int)WiFiError.None)
196 Log.Error(Globals.LogTag, "Failed to refresh ap handle, Error - " + (WiFiError)ret);
197 WiFiErrorFactory.ThrowWiFiException(ret, _apHandle, "http://tizen.org/privilege/network.get");
202 /// Connects the access point asynchronously.
204 /// <since_tizen> 3 </since_tizen>
205 /// <returns> A task indicating whether the connect method is done or not.</returns>
206 /// <feature>http://tizen.org/feature/network.wifi</feature>
207 /// <privilege>http://tizen.org/privilege/network.set</privilege>
208 /// <privilege>http://tizen.org/privilege/network.get</privilege>
209 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
210 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
211 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
212 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
213 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
214 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
215 public Task ConnectAsync()
217 Log.Debug(Globals.LogTag, "ConnectAsync");
220 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
222 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
226 id = (IntPtr)_requestId++;
227 _callback_map[id] = (error, key) =>
229 Log.Debug(Globals.LogTag, "Connecting finished : " + (WiFiError)error);
230 if (error != (int)WiFiError.None)
232 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
233 task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
237 task.SetResult(true);
241 _callback_map.Remove(key);
246 int ret = Interop.WiFi.Connect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
247 if (ret != (int)WiFiError.None)
249 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
250 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
257 /// Connects the access point with the WPS asynchronously.
259 /// <since_tizen> 3 </since_tizen>
260 /// <param name="info">A WpsInfo instance which is type of WpsPbcInfo or WpsPinInfo.</param>
261 /// <returns>A task indicating whether the ConnectWps method is done or not.</returns>
262 /// <feature>http://tizen.org/feature/network.wifi</feature>
263 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
264 /// <privilege>http://tizen.org/privilege/network.get</privilege>
265 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
266 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
267 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
268 /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
269 /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is an empty string or more than 7 characters.</exception>
270 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
271 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
272 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
273 public Task ConnectWpsAsync(WpsInfo info)
275 Log.Debug(Globals.LogTag, "ConnectWpsAsync");
278 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
280 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
284 id = (IntPtr)_requestId++;
285 _callback_map[id] = (error, key) =>
287 Log.Debug(Globals.LogTag, "Connecting by WPS finished");
288 if (error != (int)WiFiError.None)
290 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
291 task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
295 task.SetResult(true);
299 _callback_map.Remove(key);
305 if (info.GetType() == typeof(WpsPbcInfo))
307 ret = Interop.WiFi.ConnectByWpsPbc(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
310 else if (info.GetType() == typeof(WpsPinInfo))
312 WpsPinInfo pinInfo = (WpsPinInfo)info;
313 if (pinInfo.GetWpsPin() == null)
315 throw new ArgumentNullException("Wps pin should not be null");
318 if (pinInfo.GetWpsPin().Length == 0 || pinInfo.GetWpsPin().Length > 8)
320 throw new ArgumentOutOfRangeException("Wps pin should not be empty or more than 7 characters");
323 ret = Interop.WiFi.ConnectByWpsPin(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, pinInfo.GetWpsPin(), _callback_map[id], id);
326 if (ret != (int)WiFiError.None)
328 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
329 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
336 /// Connects the access point with WPS without SSID asynchronously.
338 /// <since_tizen> 3 </since_tizen>
339 /// <param name="info">A WpsInfo instance which is of type WpsPbcInfo or WpsPinInfo.</param>
340 /// <returns>A task which contains Connected access point information.</returns>
342 /// If WpsPinInfo is used, its object has to be constructed with a pin which must be 4 or 8 characters long.
344 /// <feature>http://tizen.org/feature/network.wifi</feature>
345 /// <privilege>http://tizen.org/privilege/network.set</privilege>
346 /// <privilege>http://tizen.org/privilege/network.get</privilege>
347 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
348 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
349 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
350 /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
351 /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is not of 4 or 8 characters long.</exception>
352 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
353 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
354 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
355 public static Task<WiFiAP> ConnectWpsWithoutSsidAsync(WpsInfo info)
357 TaskCompletionSource<WiFiAP> task = new TaskCompletionSource<WiFiAP>();
361 id = (IntPtr)s_requestId++;
362 s_callbackMap[id] = (error, key) =>
364 Log.Debug(Globals.LogTag, "Connecting by WPS finished");
365 if (error != (int)WiFiError.None)
367 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
368 task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
372 WiFiAP ap = WiFiManagerImpl.Instance.GetConnectedAP();
377 s_callbackMap.Remove(key);
383 if (info.GetType() == typeof(WpsPbcInfo))
385 ret = Interop.WiFi.ConnectByWpsPbcWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), s_callbackMap[id], id);
388 else if (info.GetType() == typeof(WpsPinInfo))
390 WpsPinInfo pinInfo = (WpsPinInfo)info;
391 if (pinInfo.GetWpsPin() == null)
393 throw new ArgumentNullException("Wps pin should not be null");
396 if (pinInfo.GetWpsPin().Length != 4 && pinInfo.GetWpsPin().Length != 8)
398 throw new ArgumentOutOfRangeException("Wps pin should be of 4 or 8 characters long");
401 ret = Interop.WiFi.ConnectByWpsPinWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), pinInfo.GetWpsPin(), s_callbackMap[id], id);
404 if (ret != (int)WiFiError.None)
406 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
407 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
414 /// Disconnects the access point asynchronously.
416 /// <since_tizen> 3 </since_tizen>
417 /// <returns> A task indicating whether the disconnect method is done or not.</returns>
418 /// <feature>http://tizen.org/feature/network.wifi</feature>
419 /// <privilege>http://tizen.org/privilege/network.set</privilege>
420 /// <privilege>http://tizen.org/privilege/network.get</privilege>
421 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
422 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
423 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
424 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
425 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
426 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
427 public Task DisconnectAsync()
429 Log.Debug(Globals.LogTag, "DisconnectAsync");
432 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
434 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
438 id = (IntPtr)_requestId++;
439 _callback_map[id] = (error, key) =>
441 Log.Debug(Globals.LogTag, "Disconnecting finished");
442 if (error != (int)WiFiError.None)
444 Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
445 task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
449 task.SetResult(true);
453 _callback_map.Remove(key);
457 int ret = Interop.WiFi.Disconnect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
458 if (ret != (int)WiFiError.None)
460 Log.Error(Globals.LogTag, "Failed to disconnect wifi, Error - " + (WiFiError)ret);
461 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
467 /// Deletes the information of a stored access point and disconnects it when the AP is connected.
468 /// 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.
470 /// <since_tizen> 3 </since_tizen>
471 /// <feature>http://tizen.org/feature/network.wifi</feature>
472 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
473 /// <privilege>http://tizen.org/privilege/network.get</privilege>
474 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
475 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
476 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
477 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
478 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
479 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
480 public void ForgetAP()
482 Log.Debug(Globals.LogTag, "ForgetAP");
485 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
487 int ret = Interop.WiFi.RemoveAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
488 if (ret != (int)WiFiError.None)
490 Log.Error(Globals.LogTag, "Failed to forget AP, Error - " + (WiFiError)ret);
491 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
497 /// An abstract class which is used to represent the WPS information of the access point.
499 /// <since_tizen> 3 </since_tizen>
500 public abstract class WpsInfo
505 /// A class which is used to represent WPS PBC information of the access point.
507 /// <since_tizen> 3 </since_tizen>
508 public class WpsPbcInfo : WpsInfo
513 /// A class which is used to represent WPS PIN information of the access point.
515 /// <since_tizen> 3 </since_tizen>
516 public class WpsPinInfo : WpsInfo
525 /// A public constructor which instantiates WpsPinInfo class with the given pin.
527 /// <since_tizen> 3 </since_tizen>
528 /// <param name="pin">WPS Pin of the access point.</param>
530 /// Pin should not be null or empty. It should be of less than 8 characters.
532 public WpsPinInfo(string pin)
537 internal string GetWpsPin()