2 * Copyright (c) 2018 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 Tizen.Applications;
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;
39 private static TaskCompletionSource<WiFiAP> wpsWithoutSsidTask = null;
40 private static Dictionary<IntPtr, TaskCompletionSource<bool>> _wpsTaskMap = new Dictionary<IntPtr, TaskCompletionSource<bool>>();
41 private TizenSynchronizationContext context = new TizenSynchronizationContext();
42 private static TizenSynchronizationContext s_context = new TizenSynchronizationContext();
45 /// The network information of the access point (AP).
47 /// <since_tizen> 3 </since_tizen>
48 /// <value>The WiFiNetwork instance containing the network information of the AP.</value>
49 public WiFiNetwork NetworkInformation
58 /// The security information of the access point (AP).
60 /// <since_tizen> 3 </since_tizen>
61 /// <value>The WiFiSecurity instance containing security information of the AP.</value>
62 public WiFiSecurity SecurityInformation
70 internal WiFiAP(IntPtr handle)
72 Log.Debug(Globals.LogTag, "New WiFiAP. Handle: " + handle);
78 /// Creates an object for the access point.
80 /// <since_tizen> 3 </since_tizen>
81 /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
82 /// <feature>http://tizen.org/feature/network.wifi</feature>
83 /// <privilege>http://tizen.org/privilege/network.get</privilege>
84 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
85 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
86 /// <exception cref="ArgumentNullException">Thrown when the ESSID is passed as null.</exception>
87 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
88 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
89 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
90 public WiFiAP(string essid)
92 Log.Debug(Globals.LogTag, "New WiFiAP. Essid: " + essid);
93 createHandle(essid, true);
98 /// Creates an object for the hidden access point.
100 /// <since_tizen> 3 </since_tizen>
101 /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
102 /// <param name="hidden">The value to set a hidden AP.</param>
103 /// <feature>http://tizen.org/feature/network.wifi</feature>
104 /// <privilege>http://tizen.org/privilege/network.get</privilege>
105 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
106 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
107 /// <exception cref="ArgumentNullException">Thrown when the ESSID is passed as null.</exception>
108 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
109 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
110 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
111 public WiFiAP(string essid, bool hidden)
113 createHandle(essid, hidden);
118 /// Destroy the WiFiAP object
126 /// A method to destroy the managed WiFiAP objects.
128 /// <since_tizen> 3 </since_tizen>
129 public void Dispose()
132 GC.SuppressFinalize(this);
135 private void Dispose(bool disposing)
140 Log.Info(Globals.LogTag, "WiFiAP Handle HashCode: " + _apHandle.GetHashCode());
141 int ret = Interop.WiFi.AP.Destroy(_apHandle);
142 if (ret == (int)WiFiError.None)
144 _apHandle = IntPtr.Zero;
149 private void createHandle(string id, bool hidden)
154 throw new ArgumentNullException("Essid is null");
159 ret = Interop.WiFi.AP.CreateHiddenAP(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
163 ret = Interop.WiFi.AP.Create(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
166 if (ret != (int)WiFiError.None)
168 Log.Error(Globals.LogTag, "Failed to create handle, Error - " + (WiFiError)ret);
169 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
173 private void Initialize()
175 Interop.WiFi.SafeWiFiAPHandle apHandle = new Interop.WiFi.SafeWiFiAPHandle(_apHandle);
176 _network = new WiFiNetwork(apHandle);
177 _security = new WiFiSecurity(apHandle);
181 /// Refreshes the access point information.
183 /// <since_tizen> 3 </since_tizen>
184 /// <feature>http://tizen.org/feature/network.wifi</feature>
185 /// <privilege>http://tizen.org/privilege/network.get</privilege>
186 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
187 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
188 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
189 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
190 public void Refresh()
192 Log.Debug(Globals.LogTag, "Refresh");
195 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
197 int ret = Interop.WiFi.AP.Refresh(_apHandle);
198 if (ret != (int)WiFiError.None)
200 Log.Error(Globals.LogTag, "Failed to refresh ap handle, Error - " + (WiFiError)ret);
201 if (ret == (int)WiFiError.InvalidParameterError)
203 throw new InvalidOperationException("Invalid handle");
205 WiFiErrorFactory.ThrowWiFiException(ret, _apHandle, "http://tizen.org/privilege/network.get");
210 /// Connects the access point asynchronously.
212 /// <since_tizen> 3 </since_tizen>
213 /// <returns> A task indicating whether the connect method is done or not.</returns>
215 /// This method must be called from MainThread.
217 /// <feature>http://tizen.org/feature/network.wifi</feature>
218 /// <privilege>http://tizen.org/privilege/network.set</privilege>
219 /// <privilege>http://tizen.org/privilege/network.get</privilege>
220 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
221 /// <exception cref="NowInProgressException">Thrown when the Wi-Fi connection is now in progress.</exception>
222 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
223 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
224 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
225 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
226 /// <exception cref="InvalidKeyException">Thrown when the key is wrong.</exception>
227 public Task ConnectAsync()
229 Log.Info(Globals.LogTag, "ConnectAsync HashCode: " + _apHandle.GetHashCode());
232 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
234 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
238 id = (IntPtr)_requestId++;
239 _callback_map[id] = (error, key) =>
241 Log.Info(Globals.LogTag, "ConnectAsync done " + (WiFiError)error);
242 if (error != (int)WiFiError.None)
244 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
245 task.SetException(WiFiErrorFactory.GetException(error, "Error occurs during WiFi connecting"));
249 task.SetResult(true);
253 _callback_map.Remove(key);
260 Log.Info(Globals.LogTag, "Interop.WiFi.Connect");
263 int ret = Interop.WiFi.Connect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
264 if (ret != (int)WiFiError.None)
266 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
267 if (ret == (int)WiFiError.InvalidParameterError)
269 throw new InvalidOperationException("Invalid handle");
271 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
276 Log.Error(Globals.LogTag, "Exception on ConnectAsync\n" + e);
277 task.SetException(e);
285 /// Connects the access point with the WPS asynchronously.
287 /// <since_tizen> 3 </since_tizen>
288 /// <param name="info">A WpsInfo instance which is type of WpsPbcInfo or WpsPinInfo.</param>
289 /// <returns>A task indicating whether the ConnectWps method is done or not.</returns>
291 /// This method must be called from MainThread.
293 /// <feature>http://tizen.org/feature/network.wifi</feature>
294 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
295 /// <privilege>http://tizen.org/privilege/network.get</privilege>
296 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
297 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
298 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
299 /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
300 /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is an empty string or more than 7 characters.</exception>
301 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
302 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
303 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
304 /// <exception cref="NowInProgressException">Thrown when the Wi-Fi connection is now in progress.</exception>
305 /// <exception cref="TimeoutException">Thrown when the timeout of WPS connection is expired.</exception>
306 public Task ConnectWpsAsync(WpsInfo info)
308 Log.Info(Globals.LogTag, "ConnectWpsAsync");
311 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
314 TaskCompletionSource<bool> wpsTask = new TaskCompletionSource<bool>();
315 _wpsTaskMap[_apHandle] = wpsTask;
320 id = (IntPtr)_requestId++;
321 _callback_map[id] = (error, key) =>
323 Log.Info(Globals.LogTag, "ConnectWpsAsync done");
324 if (error != (int)WiFiError.None)
326 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
327 wpsTask.SetException(WiFiErrorFactory.GetException(error, "Error occurs during WiFi connecting"));
328 Log.Info(Globals.LogTag, "Remove task for ConnectWpsAsync");
329 _wpsTaskMap.Remove(_apHandle);
333 wpsTask.SetResult(true);
334 Log.Info(Globals.LogTag, "Remove task for ConnectWpsAsync");
335 _wpsTaskMap.Remove(_apHandle);
339 _callback_map.Remove(key);
349 if (info.GetType() == typeof(WpsPbcInfo))
351 Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPb");
352 ret = Interop.WiFi.ConnectByWpsPbc(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
354 else if (info.GetType() == typeof(WpsPinInfo))
356 WpsPinInfo pinInfo = (WpsPinInfo)info;
357 if (pinInfo.GetWpsPin() == null)
359 throw new ArgumentNullException("Wps pin should not be null");
362 if (pinInfo.GetWpsPin().Length == 0 || pinInfo.GetWpsPin().Length > 8)
364 throw new ArgumentOutOfRangeException("Wps pin should not be empty or more than 7 characters");
367 Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPin");
368 ret = Interop.WiFi.ConnectByWpsPin(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, pinInfo.GetWpsPin(), _callback_map[id], id);
371 if (ret != (int)WiFiError.None)
373 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
374 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
379 Log.Error(Globals.LogTag, "Exception on ConnectWpsAsync\n" + e);
380 wpsTask.SetException(e);
381 Log.Info(Globals.LogTag, "Remove task for ConnectWpsAsync");
382 _wpsTaskMap.Remove(_apHandle);
390 /// Connects the access point with WPS without SSID asynchronously.
392 /// <since_tizen> 3 </since_tizen>
393 /// <param name="info">A WpsInfo instance which is of type WpsPbcInfo or WpsPinInfo.</param>
394 /// <returns>A task which contains Connected access point information.</returns>
396 /// If WpsPinInfo is used, its object has to be constructed with a pin which must be 4 or 8 characters long. \n
397 /// This method must be called from MainThread.
399 /// <feature>http://tizen.org/feature/network.wifi</feature>
400 /// <privilege>http://tizen.org/privilege/network.set</privilege>
401 /// <privilege>http://tizen.org/privilege/network.get</privilege>
402 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
403 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
404 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
405 /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
406 /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is not of 4 or 8 characters long.</exception>
407 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
408 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
409 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
410 /// <exception cref="NowInProgressException">Thrown when the Wi-Fi connection is now in progress.</exception>
411 /// <exception cref="TimeoutException">Thrown when the timeout of WPS connection is expired.</exception>
412 public static Task<WiFiAP> ConnectWpsWithoutSsidAsync(WpsInfo info)
414 Log.Info(Globals.LogTag, "ConnectWpsWithoutSsidAsync");
415 wpsWithoutSsidTask = new TaskCompletionSource<WiFiAP>();
419 id = (IntPtr)s_requestId++;
420 s_callbackMap[id] = (error, key) =>
422 Log.Info(Globals.LogTag, "ConnectWpsWithoutSsidAsync done");
423 if (error != (int)WiFiError.None)
425 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
426 wpsWithoutSsidTask.SetException(WiFiErrorFactory.GetException(error, "Error occurs during WiFi connecting"));
427 wpsWithoutSsidTask = null;
428 Log.Info(Globals.LogTag, "task is null");
432 WiFiAP ap = WiFiManagerImpl.Instance.GetConnectedAP();
433 wpsWithoutSsidTask.SetResult(ap);
434 wpsWithoutSsidTask = null;
435 Log.Info(Globals.LogTag, "task is null");
439 s_callbackMap.Remove(key);
444 s_context.Post((x) =>
449 if (info.GetType() == typeof(WpsPbcInfo))
451 Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPbcWithoutSsid");
452 ret = Interop.WiFi.ConnectByWpsPbcWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), s_callbackMap[id], id);
454 else if (info.GetType() == typeof(WpsPinInfo))
456 WpsPinInfo pinInfo = (WpsPinInfo)info;
457 if (pinInfo.GetWpsPin() == null)
459 throw new ArgumentNullException("Wps pin should not be null");
462 if (pinInfo.GetWpsPin().Length != 4 && pinInfo.GetWpsPin().Length != 8)
464 throw new ArgumentOutOfRangeException("Wps pin should be of 4 or 8 characters long");
467 Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPinWithoutSsid");
468 ret = Interop.WiFi.ConnectByWpsPinWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), pinInfo.GetWpsPin(), s_callbackMap[id], id);
471 if (ret != (int)WiFiError.None)
473 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
474 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
479 Log.Error(Globals.LogTag, "Exception on ConnectWpsWithoutSsidAsync\n" + e);
480 wpsWithoutSsidTask.SetException(e);
481 wpsWithoutSsidTask = null;
482 Log.Info(Globals.LogTag, "task is null");
486 return wpsWithoutSsidTask.Task;
490 /// Stops ongoing WPS provisioning
492 /// <since_tizen> 5 </since_tizen>
493 /// <feature>http://tizen.org/feature/network.wifi</feature>
494 /// <privilege>http://tizen.org/privilege/network.set</privilege>
495 /// <privilege>http://tizen.org/privilege/network.get</privilege>
496 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
497 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
498 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
499 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
500 public static void CancelWps()
502 Log.Debug(Globals.LogTag, "CancelWps");
503 int ret = Interop.WiFi.CancelWps(WiFiManagerImpl.Instance.GetSafeHandle());
504 if (ret != (int)WiFiError.None)
506 Log.Error(Globals.LogTag, "Failed to cancel Wps, Error - " + (WiFiError)ret);
507 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
510 // Cancel awaiting tasks
511 if (wpsWithoutSsidTask != null)
513 Log.Info(Globals.LogTag, "Cancel ConnectWpsWithoutSsidAsync()");
514 wpsWithoutSsidTask.SetCanceled();
516 foreach (var item in _wpsTaskMap)
518 Log.Info(Globals.LogTag, "Cancel ConnectWpsAsync() by " + item.Key.GetHashCode());
519 item.Value.SetCanceled();
527 /// Disconnects the access point asynchronously.
529 /// <since_tizen> 3 </since_tizen>
530 /// <returns> A task indicating whether the disconnect method is done or not.</returns>
532 /// This method must be called from MainThread.
534 /// <feature>http://tizen.org/feature/network.wifi</feature>
535 /// <privilege>http://tizen.org/privilege/network.set</privilege>
536 /// <privilege>http://tizen.org/privilege/network.get</privilege>
537 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
538 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
539 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
540 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
541 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
542 public Task DisconnectAsync()
544 Log.Debug(Globals.LogTag, "DisconnectAsync");
547 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
549 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
553 id = (IntPtr)_requestId++;
554 _callback_map[id] = (error, key) =>
556 Log.Info(Globals.LogTag, "DisconnectAsync done");
557 if (error != (int)WiFiError.None)
559 Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
560 task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
564 task.SetResult(true);
568 _callback_map.Remove(key);
575 Log.Info(Globals.LogTag, "Interop.WiFi.Disconnect");
578 int ret = Interop.WiFi.Disconnect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
579 if (ret != (int)WiFiError.None)
581 Log.Error(Globals.LogTag, "Failed to disconnect wifi, Error - " + (WiFiError)ret);
582 if (ret == (int)WiFiError.InvalidParameterError)
584 throw new InvalidOperationException("Invalid handle");
586 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
591 Log.Error(Globals.LogTag, "Exception on Disconnect\n" + e);
592 task.SetException(e);
600 /// Deletes the information of a stored access point and disconnects it when the AP is connected.
601 /// 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.
603 /// <since_tizen> 3 </since_tizen>
604 /// <feature>http://tizen.org/feature/network.wifi</feature>
605 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
606 /// <privilege>http://tizen.org/privilege/network.get</privilege>
607 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
608 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
609 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
610 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
611 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
612 public void ForgetAP()
614 Log.Debug(Globals.LogTag, "ForgetAP");
617 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
619 int ret = Interop.WiFi.RemoveAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
620 if (ret != (int)WiFiError.None)
622 Log.Error(Globals.LogTag, "Failed to forget AP, Error - " + (WiFiError)ret);
623 if (ret == (int)WiFiError.InvalidParameterError)
625 throw new InvalidOperationException("Invalid handle");
627 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
632 /// Deletes the information of a stored access point and disconnects it when the AP is connected asyncronously.
633 /// 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.
635 /// <returns> A task indicating whether the disconnect method is done or not.</returns>
637 /// This method must be called from MainThread.
639 /// <since_tizen> 5 </since_tizen>
640 /// <feature>http://tizen.org/feature/network.wifi</feature>
641 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
642 /// <privilege>http://tizen.org/privilege/network.get</privilege>
643 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
644 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
645 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
646 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
647 public Task ForgetAPAsync()
649 Log.Debug(Globals.LogTag, "ForgetAPAsync");
652 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
654 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
658 id = (IntPtr)_requestId++;
659 _callback_map[id] = (error, key) =>
661 Log.Info(Globals.LogTag, "ForgetAPAsync done");
662 if (error != (int)WiFiError.None)
664 Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
665 task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
669 task.SetResult(true);
673 _callback_map.Remove(key);
680 Log.Info(Globals.LogTag, "Interop.WiFi.ForgetAP");
683 int ret = Interop.WiFi.ForgetAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
684 if (ret != (int)WiFiError.None)
686 Log.Error(Globals.LogTag, "Failed to forget wifi, Error - " + (WiFiError)ret);
687 if (ret == (int)WiFiError.InvalidParameterError)
689 throw new InvalidOperationException("Invalid handle");
691 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
696 Log.Error(Globals.LogTag, "Exception on ForgetAPAsync\n" + e);
697 task.SetException(e);
705 /// Update the information of a stored access point.
706 /// When a AP information is changed, the change will not be applied until this method is called.
708 /// <since_tizen> 5 </since_tizen>
709 /// <feature>http://tizen.org/feature/network.wifi</feature>
710 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
711 /// <privilege>http://tizen.org/privilege/network.get</privilege>
712 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
713 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
714 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
715 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
716 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
719 Log.Debug(Globals.LogTag, "Update");
722 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
724 int ret = Interop.WiFi.UpdateAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
725 if (ret != (int)WiFiError.None)
727 Log.Error(Globals.LogTag, "Failed to update AP, Error - " + (WiFiError)ret);
728 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
734 /// An abstract class which is used to represent the WPS information of the access point.
736 /// <since_tizen> 3 </since_tizen>
737 public abstract class WpsInfo
742 /// A class which is used to represent WPS PBC information of the access point.
744 /// <since_tizen> 3 </since_tizen>
745 public class WpsPbcInfo : WpsInfo
750 /// A class which is used to represent WPS PIN information of the access point.
752 /// <since_tizen> 3 </since_tizen>
753 public class WpsPinInfo : WpsInfo
762 /// A public constructor which instantiates WpsPinInfo class with the given pin.
764 /// <since_tizen> 3 </since_tizen>
765 /// <param name="pin">WPS Pin of the access point.</param>
767 /// Pin should not be null or empty. It should be of less than 8 characters.
769 public WpsPinInfo(string pin)
774 internal string GetWpsPin()