[Tizen.Network.WiFi] Use lock on checking if instance is null (#119)
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.WiFi / Tizen.Network.WiFi / WiFiManagerImpl.cs
index f64c917..ec52dc9 100755 (executable)
 
 using System;
 using System.Collections.Generic;
+using System.Threading;
 using System.Threading.Tasks;
+using System.Runtime.InteropServices;
 
 namespace Tizen.Network.WiFi
 {
     static internal class Globals
     {
         internal const string LogTag = "Tizen.Network.WiFi";
-        internal static bool s_isInitialize = false;
+    }
+
+    internal class HandleHolder
+    {
+        private SafeWiFiManagerHandle _handle;
 
-        internal static bool IsInitialize
+        internal HandleHolder()
         {
-            get
-            {
-                if (!Globals.s_isInitialize)
-                {
-                    WiFiManagerImpl.Instance.Initialize();
-                }
-                return Globals.s_isInitialize;
-            }
+            _handle = WiFiManagerImpl.Instance.Initialize();
+            Log.Debug(Globals.LogTag, "Handle: " + _handle);
+        }
+
+        internal SafeWiFiManagerHandle GetSafeHandle()
+        {
+            Log.Debug(Globals.LogTag, "Handleholder safehandle = " + _handle);
+            return _handle;
         }
     }
 
-    internal partial class WiFiManagerImpl : IDisposable
+    internal partial class WiFiManagerImpl
     {
-        private static WiFiManagerImpl _instance;
+        private static readonly Lazy<WiFiManagerImpl> _instance =
+            new Lazy<WiFiManagerImpl>(() => new WiFiManagerImpl());
         private Dictionary<IntPtr, Interop.WiFi.VoidCallback> _callback_map = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
         private int _requestId = 0;
         private string _macAddress;
-        private bool disposed = false;
 
         internal string MacAddress
         {
@@ -53,7 +59,7 @@ namespace Tizen.Network.WiFi
                 if (String.IsNullOrEmpty(_macAddress))
                 {
                     string address;
-                    int ret = Interop.WiFi.GetMacAddress(out address);
+                    int ret = Interop.WiFi.GetMacAddress(GetSafeHandle(), out address);
                     if (ret != (int)WiFiError.None)
                     {
                         Log.Error(Globals.LogTag, "Failed to get mac address, Error - " + (WiFiError)ret);
@@ -67,12 +73,13 @@ namespace Tizen.Network.WiFi
                 return _macAddress;
             }
         }
+
         internal string InterfaceName
         {
             get
             {
                 string name;
-                int ret = Interop.WiFi.GetNetworkInterfaceName(out name);
+                int ret = Interop.WiFi.GetNetworkInterfaceName(GetSafeHandle(), out name);
                 if (ret != (int)WiFiError.None)
                 {
                     Log.Error(Globals.LogTag, "Failed to get interface name, Error - " + (WiFiError)ret);
@@ -81,12 +88,13 @@ namespace Tizen.Network.WiFi
                 return name;
             }
         }
+
         internal WiFiConnectionState ConnectionState
         {
             get
             {
                 int state;
-                int ret = Interop.WiFi.GetConnectionState(out state);
+                int ret = Interop.WiFi.GetConnectionState(GetSafeHandle(), out state);
                 if (ret != (int)WiFiError.None)
                 {
                     Log.Error(Globals.LogTag, "Failed to get connection state, Error - " + (WiFiError)ret);
@@ -95,12 +103,13 @@ namespace Tizen.Network.WiFi
                 return (WiFiConnectionState)state;
             }
         }
-        internal bool IsActivated
+
+        internal bool IsActive
         {
             get
             {
                 bool active;
-                int ret = Interop.WiFi.IsActivated(out active);
+                int ret = Interop.WiFi.IsActive(GetSafeHandle(), out active);
                 if (ret != (int)WiFiError.None)
                 {
                     Log.Error(Globals.LogTag, "Failed to get isActive, Error - " + (WiFiError)ret);
@@ -113,111 +122,76 @@ namespace Tizen.Network.WiFi
         {
             get
             {
-                if (_instance == null)
-                {
-                    _instance = new WiFiManagerImpl();
-                }
-
-                return _instance;
+               return _instance.Value;
             }
         }
 
-        private WiFiManagerImpl()
+        private static ThreadLocal<HandleHolder> s_threadName = new ThreadLocal<HandleHolder>(() =>
         {
-        }
+            Log.Info(Globals.LogTag, "In threadlocal delegate");
+            return new HandleHolder();
+        });
 
-        ~WiFiManagerImpl()
-        {
-            Dispose(false);
-        }
-
-        public void Dispose()
+        private WiFiManagerImpl()
         {
-            Dispose(true);
-            GC.SuppressFinalize(this);
+            Log.Info(Globals.LogTag, "WiFiManagerImpl constructor");
         }
 
-        private void Dispose(bool disposing)
+        internal SafeWiFiManagerHandle GetSafeHandle()
         {
-            if (disposed)
-                return;
-
-            if (disposing)
-            {
-                // Free managed objects.
-            }
-            //Free unmanaged objects
-            deinitialize();
-            RemoveAllRegisteredEvent();
-            disposed = true;
+            return s_threadName.Value.GetSafeHandle();
         }
 
-        internal void Initialize()
+        internal SafeWiFiManagerHandle Initialize()
         {
-            int ret = Interop.WiFi.Initialize();
+            SafeWiFiManagerHandle handle;
+            int ret = Interop.WiFi.Initialize(out handle);
             if (ret != (int)WiFiError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to initialize wifi, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, "http://tizen.org/privilege/network.get");
             }
-            Globals.s_isInitialize = true;
-            string address;
-            ret = Interop.WiFi.GetMacAddress(out address);
-            if (ret != (int)WiFiError.None)
-            {
-                Log.Error(Globals.LogTag, "Failed to get mac address, Error - " + (WiFiError)ret);
-                _macAddress = "";
-            }
-            _macAddress = address;
+            return handle;
         }
 
-        private void deinitialize()
+        internal IEnumerable<WiFiAP> GetFoundAPs()
         {
-            int ret = Interop.WiFi.Deinitialize();
-            if (ret != (int)WiFiError.None)
-            {
-                Log.Error(Globals.LogTag, "Failed to deinitialize wifi, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
-            }
-            Globals.s_isInitialize = false;
-        }
-
-        internal IEnumerable<WiFiAp> GetFoundAps()
-        {
-            List<WiFiAp> apList = new List<WiFiAp>();
+            Log.Debug(Globals.LogTag, "GetFoundAPs");
+            List<WiFiAP> apList = new List<WiFiAP>();
             Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
             {
                 if (apHandle != IntPtr.Zero)
                 {
                     IntPtr clonedHandle;
-                    Interop.WiFi.Ap.Clone(out clonedHandle, apHandle);
-                    WiFiAp apItem = new WiFiAp(clonedHandle);
+                    Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
+                    WiFiAP apItem = new WiFiAP(clonedHandle);
                     apList.Add(apItem);
                     return true;
                 }
                 return false;
             };
 
-            int ret = Interop.WiFi.GetForeachFoundAps(callback, IntPtr.Zero);
+            int ret = Interop.WiFi.GetForeachFoundAPs(GetSafeHandle(), callback, IntPtr.Zero);
             if (ret != (int)WiFiError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to get all APs, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
             }
 
             return apList;
         }
 
-        internal IEnumerable<WiFiAp> GetFoundSpecificAps()
+        internal IEnumerable<WiFiAP> GetFoundSpecificAPs()
         {
-            List<WiFiAp> apList = new List<WiFiAp>();
+            Log.Debug(Globals.LogTag, "GetFoundSpecificAPs");
+            List<WiFiAP> apList = new List<WiFiAP>();
             Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
             {
                 if (apHandle != IntPtr.Zero)
                 {
                     IntPtr clonedHandle;
-                    Interop.WiFi.Ap.Clone(out clonedHandle, apHandle);
-                    WiFiAp apItem = new WiFiAp(clonedHandle);
+                    Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
+                    WiFiAP apItem = new WiFiAP(clonedHandle);
                     apList.Add(apItem);
                     return true;
                 }
@@ -225,11 +199,11 @@ namespace Tizen.Network.WiFi
 
             };
 
-            int ret = Interop.WiFi.GetForeachFoundSpecificAps(callback, IntPtr.Zero);
+            int ret = Interop.WiFi.GetForeachFoundSpecificAPs(GetSafeHandle(), callback, IntPtr.Zero);
             if (ret != (int)WiFiError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to get specific APs, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
             }
 
             return apList;
@@ -237,6 +211,7 @@ namespace Tizen.Network.WiFi
 
         internal IEnumerable<WiFiConfiguration> GetWiFiConfigurations()
         {
+            Log.Debug(Globals.LogTag, "GetWiFiConfigurations");
             List<WiFiConfiguration> configList = new List<WiFiConfiguration>();
             Interop.WiFi.HandleCallback callback = (IntPtr configHandle, IntPtr userData) =>
             {
@@ -251,11 +226,11 @@ namespace Tizen.Network.WiFi
                 return false;
             };
 
-            int ret = Interop.WiFi.Config.GetForeachConfiguration(callback, IntPtr.Zero);
+            int ret = Interop.WiFi.Config.GetForeachConfiguration(GetSafeHandle(), callback, IntPtr.Zero);
             if (ret != (int)WiFiError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to get configurations, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.profile");
             }
 
             return configList;
@@ -263,42 +238,46 @@ namespace Tizen.Network.WiFi
 
         internal void SaveWiFiNetworkConfiguration(WiFiConfiguration config)
         {
+            Log.Debug(Globals.LogTag, "SaveWiFiNetworkConfiguration");
+            if (config == null)
+            {
+                throw new ArgumentNullException("WiFi configuration is null");
+            }
+
             IntPtr configHandle = config.GetHandle();
-            int ret = Interop.WiFi.Config.SaveConfiguration(configHandle);
+            int ret = Interop.WiFi.Config.SaveConfiguration(GetSafeHandle(), configHandle);
             if (ret != (int)WiFiError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to save configuration, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.profile");
             }
         }
 
-        internal WiFiAp GetConnectedAp()
+        internal WiFiAP GetConnectedAP()
         {
+            Log.Debug(Globals.LogTag, "GetConnectedAP");
             IntPtr apHandle;
-
-            int ret = Interop.WiFi.GetConnectedAp(out apHandle);
+            int ret = Interop.WiFi.GetConnectedAP(GetSafeHandle(), out apHandle);
             if (ret != (int)WiFiError.None)
             {
-                Log.Error(Globals.LogTag, "Failed to connect with AP, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                if (ret == (int)WiFiError.NoConnectionError)
+                {
+                    Log.Error(Globals.LogTag, "No connection " + (WiFiError)ret);
+                    return null;
+                }
+                else
+                {
+                    Log.Error(Globals.LogTag, "Failed to get connected AP, Error - " + (WiFiError)ret);
+                    WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
+                }
             }
-            WiFiAp ap = new WiFiAp(apHandle);
+            WiFiAP ap = new WiFiAP(apHandle);
             return ap;
         }
 
-        internal void RemoveAp(WiFiAp ap)
-        {
-            IntPtr apHandle = ap.GetHandle();
-            int ret = Interop.WiFi.RemoveAp(apHandle);
-            if (ret != (int)WiFiError.None)
-            {
-                Log.Error(Globals.LogTag, "Failed to remove with AP, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
-            }
-        }
-
         internal Task ActivateAsync()
         {
+            Log.Debug(Globals.LogTag, "ActivateAsync");
             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
             IntPtr id;
             lock (_callback_map)
@@ -312,24 +291,28 @@ namespace Tizen.Network.WiFi
                         Log.Error(Globals.LogTag, "Error occurs during WiFi activating, " + (WiFiError)error);
                         task.SetException(new InvalidOperationException("Error occurs during WiFi activating, " + (WiFiError)error));
                     }
-                    task.SetResult(true);
+                    else
+                    {
+                        task.SetResult(true);
+                    }
                     lock (_callback_map)
                     {
                         _callback_map.Remove(key);
                     }
                 };
             }
-            int ret = Interop.WiFi.Activate(_callback_map[id], id);
+            int ret = Interop.WiFi.Activate(GetSafeHandle(), _callback_map[id], id);
             if (ret != (int)WiFiError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
             }
             return task.Task;
         }
 
         internal Task ActivateWithWiFiPickerTestedAsync()
         {
+            Log.Debug(Globals.LogTag, "ActivateWithWiFiPickerTestedAsync");
             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
             IntPtr id;
             lock (_callback_map)
@@ -343,24 +326,28 @@ namespace Tizen.Network.WiFi
                         Log.Error(Globals.LogTag, "Error occurs during WiFi activating, " + (WiFiError)error);
                         task.SetException(new InvalidOperationException("Error occurs during WiFi activating, " + (WiFiError)error));
                     }
-                    task.SetResult(true);
+                    else
+                    {
+                        task.SetResult(true);
+                    }
                     lock (_callback_map)
                     {
                         _callback_map.Remove(key);
                     }
                 };
             }
-            int ret = Interop.WiFi.ActivateWithWiFiPickerTested(_callback_map[id], id);
+            int ret = Interop.WiFi.ActivateWithWiFiPickerTested(GetSafeHandle(), _callback_map[id], id);
             if (ret != (int)WiFiError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
             }
             return task.Task;
         }
 
         internal Task DeactivateAsync()
         {
+            Log.Debug(Globals.LogTag, "DeactivateAsync");
             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
             IntPtr id;
             lock (_callback_map)
@@ -374,24 +361,28 @@ namespace Tizen.Network.WiFi
                         Log.Error(Globals.LogTag, "Error occurs during WiFi deactivating, " + (WiFiError)error);
                         task.SetException(new InvalidOperationException("Error occurs during WiFi deactivating, " + (WiFiError)error));
                     }
-                    task.SetResult(true);
+                    else
+                    {
+                        task.SetResult(true);
+                    }
                     lock (_callback_map)
                     {
                         _callback_map.Remove(key);
                     }
                 };
             }
-            int ret = Interop.WiFi.Deactivate(_callback_map[id], id);
+            int ret = Interop.WiFi.Deactivate(GetSafeHandle(), _callback_map[id], id);
             if (ret != (int)WiFiError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to deactivate wifi, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
             }
             return task.Task;
         }
 
         internal Task ScanAsync()
         {
+            Log.Debug(Globals.LogTag, "ScanAsync");
             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
             IntPtr id;
             lock (_callback_map)
@@ -405,24 +396,28 @@ namespace Tizen.Network.WiFi
                         Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
                         task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
                     }
-                    task.SetResult(true);
+                    else
+                    {
+                        task.SetResult(true);
+                    }
                     lock (_callback_map)
                     {
                         _callback_map.Remove(key);
                     }
                 };
             }
-            int ret = Interop.WiFi.Scan(_callback_map[id], id);
+            int ret = Interop.WiFi.Scan(GetSafeHandle(), _callback_map[id], id);
             if (ret != (int)WiFiError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to scan all AP, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
             }
             return task.Task;
         }
 
-        internal Task ScanSpecificApAsync(string essid)
+        internal Task ScanSpecificAPAsync(string essid)
         {
+            Log.Debug(Globals.LogTag, "ScanSpecificAPAsync " + essid);
             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
             IntPtr id;
             lock (_callback_map)
@@ -436,146 +431,21 @@ namespace Tizen.Network.WiFi
                         Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
                         task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
                     }
-                    task.SetResult(true);
-                    lock (_callback_map)
-                    {
-                        _callback_map.Remove(key);
-                    }
-                };
-            }
-            int ret = Interop.WiFi.ScanSpecificAp(essid, _callback_map[id], id);
-            if (ret != (int)WiFiError.None)
-            {
-                Log.Error(Globals.LogTag, "Failed to scan with specific AP, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
-            }
-            return task.Task;
-        }
-
-        internal Task ConnectAsync(WiFiAp ap)
-        {
-            TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
-            IntPtr id;
-            lock (_callback_map)
-            {
-                id = (IntPtr)_requestId++;
-                _callback_map[id] = (error, key) =>
-                {
-                    Log.Debug(Globals.LogTag, "Connecting finished : " + (WiFiError)error);
-                    if (error != (int)WiFiError.None)
-                    {
-                        Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
-                        task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
-                    }
-                    task.SetResult(true);
-                    lock (_callback_map)
-                    {
-                        _callback_map.Remove(key);
-                    }
-                };
-            }
-            IntPtr apHandle = ap.GetHandle();
-            int ret = Interop.WiFi.Connect(apHandle, _callback_map[id], id);
-            if (ret != (int)WiFiError.None)
-            {
-                Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
-            }
-            return task.Task;
-        }
-
-        internal Task DisconnectAsync(WiFiAp ap)
-        {
-            TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
-            IntPtr id;
-            lock (_callback_map)
-            {
-                id = (IntPtr)_requestId++;
-                _callback_map[id] = (error, key) =>
-                {
-                    Log.Debug(Globals.LogTag, "Disconnecting finished");
-                    if (error != (int)WiFiError.None)
-                    {
-                        Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
-                        task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
-                    }
-                    task.SetResult(true);
-                    lock (_callback_map)
-                    {
-                        _callback_map.Remove(key);
-                    }
-                };
-            }
-            IntPtr apHandle = ap.GetHandle();
-            int ret = Interop.WiFi.Disconnect(apHandle, _callback_map[id], id);
-            if (ret != (int)WiFiError.None)
-            {
-                Log.Error(Globals.LogTag, "Failed to disconnect wifi, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
-            }
-            return task.Task;
-        }
-
-        internal Task ConnectByWpsPbcAsync(WiFiAp ap)
-        {
-            TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
-            IntPtr id;
-            lock (_callback_map)
-            {
-                id = (IntPtr)_requestId++;
-                _callback_map[id] = (error, key) =>
-                {
-                    Log.Debug(Globals.LogTag, "Connecting by WPS PBC finished");
-                    if (error != (int)WiFiError.None)
-                    {
-                        Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
-                        task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
-                    }
-                    task.SetResult(true);
-                    lock (_callback_map)
-                    {
-                        _callback_map.Remove(key);
-                    }
-                };
-            }
-            IntPtr apHandle = ap.GetHandle();
-            int ret = Interop.WiFi.ConnectByWpsPbc(apHandle, _callback_map[id], id);
-            if (ret != (int)WiFiError.None)
-            {
-                Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
-            }
-            return task.Task;
-        }
-
-        internal Task ConnectByWpsPinAsync(WiFiAp ap, string pin)
-        {
-            TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
-            IntPtr id;
-            lock (_callback_map)
-            {
-                id = (IntPtr)_requestId++;
-                _callback_map[id] = (error, key) =>
-                {
-                    Log.Debug(Globals.LogTag, "Connecting by WPS PIN finished");
-                    if (error != (int)WiFiError.None)
+                    else
                     {
-                        Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
-                        task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
+                        task.SetResult(true);
                     }
-                    task.SetResult(true);
                     lock (_callback_map)
                     {
                         _callback_map.Remove(key);
                     }
                 };
             }
-            IntPtr apHandle = ap.GetHandle();
-            int ret = Interop.WiFi.ConnectByWpsPin(apHandle, pin, _callback_map[id], id);
+            int ret = Interop.WiFi.ScanSpecificAP(GetSafeHandle(), essid, _callback_map[id], id);
             if (ret != (int)WiFiError.None)
             {
-                Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
-                WiFiErrorFactory.ThrowWiFiException(ret);
+                Log.Error(Globals.LogTag, "Failed to scan with specific AP, Error - " + (WiFiError)ret);
+                WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
             }
             return task.Task;
         }