Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 48 additions & 78 deletions src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiManagerImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,97 +181,67 @@ internal SafeWiFiManagerHandle GetSafeHandle()
}


internal IEnumerable<WiFiAP> GetFoundAPs()
// Shared "native foreach -> List<T>" collector for the GetFound*/
// GetWiFiConfigurations methods. Each call site supplies only what
// differs: the operation name and privilege (for CheckReturnValue),
// the native foreach function, and how to wrap a native item handle
// into its managed type.
private List<T> EnumerateForeach<T>(string opName, string privilege,
Func<SafeWiFiManagerHandle, Interop.WiFi.HandleCallback, IntPtr, int> nativeForeach,
Func<IntPtr, T> wrap)
{
Log.Info(Globals.LogTag, "GetFoundAPs");
List<WiFiAP> apList = new List<WiFiAP>();
Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
Log.Info(Globals.LogTag, opName);
List<T> list = new List<T>();
Interop.WiFi.HandleCallback callback = (IntPtr handle, IntPtr userData) =>
{
if (apHandle != IntPtr.Zero)
if (handle != IntPtr.Zero)
{
IntPtr clonedHandle;
Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
WiFiAP apItem = new WiFiAP(clonedHandle);
apList.Add(apItem);
list.Add(wrap(handle));
return true;
}
return false;
};

int ret = Interop.WiFi.GetForeachFoundAPs(GetSafeHandle(), callback, IntPtr.Zero);
CheckReturnValue(ret, "GetForeachFoundAPs", PrivilegeNetworkGet);

return apList;
int ret = nativeForeach(GetSafeHandle(), callback, IntPtr.Zero);
CheckReturnValue(ret, opName, privilege);
return list;
}
Comment on lines +189 to 224

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Propagating managed exceptions through native code boundaries (P/Invoke) can lead to undefined behavior, native crashes, or silent failures. Since the wrap delegate can throw exceptions (e.g., if cloning fails or during object construction), it is highly recommended to catch any exceptions inside the callback, stop the iteration, and safely rethrow the captured exception after the native foreach method returns.

        private List<T> EnumerateForeach<T>(string opName, string privilege,
            Func<SafeWiFiManagerHandle, Interop.WiFi.HandleCallback, IntPtr, int> nativeForeach,
            Func<IntPtr, T> wrap)
        {
            Log.Info(Globals.LogTag, opName);
            List<T> list = new List<T>();
            Exception capturedException = null;
            Interop.WiFi.HandleCallback callback = (IntPtr handle, IntPtr userData) =>
            {
                if (handle != IntPtr.Zero)
                {
                    try
                    {
                        list.Add(wrap(handle));
                    }
                    catch (Exception ex)
                    {
                        capturedException = ex;
                        return false;
                    }
                    return true;
                }
                return false;
            };

            int ret = nativeForeach(GetSafeHandle(), callback, IntPtr.Zero);
            if (capturedException != null)
            {
                throw capturedException;
            }
            CheckReturnValue(ret, opName, privilege);
            return list;
        }


internal IEnumerable<WiFiAP> GetFoundSpecificAPs()
{
Log.Info(Globals.LogTag, "GetFoundSpecificAPs");
List<WiFiAP> apList = new List<WiFiAP>();
Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
{
if (apHandle != IntPtr.Zero)
internal IEnumerable<WiFiAP> GetFoundAPs() =>
EnumerateForeach("GetForeachFoundAPs", PrivilegeNetworkGet,
(wifi, cb, ud) => Interop.WiFi.GetForeachFoundAPs(wifi, cb, ud),
apHandle =>
{
IntPtr clonedHandle;
Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
WiFiAP apItem = new WiFiAP(clonedHandle);
apList.Add(apItem);
return true;
}
return false;

};

int ret = Interop.WiFi.GetForeachFoundSpecificAPs(GetSafeHandle(), callback, IntPtr.Zero);
CheckReturnValue(ret, "GetForeachFoundSpecificAPs", PrivilegeNetworkGet);

return apList;
}

internal IEnumerable<WiFiAP> GetFoundBssids()
{
Log.Info(Globals.LogTag, "GetFoundBssids");
List<WiFiAP> apList = new List<WiFiAP>();
Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
{
if (apHandle != IntPtr.Zero)
Interop.WiFi.AP.Clone(out IntPtr clonedHandle, apHandle);
return new WiFiAP(clonedHandle);
});
Comment on lines +229 to +237

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The return value of Interop.WiFi.AP.Clone is ignored. If cloning fails, it may return a non-zero error code and leave clonedHandle as IntPtr.Zero or invalid, which will cause downstream failures when the WiFiAP instance is used. It is safer to check the return value and throw an exception if cloning fails.

                apHandle =>
                {
                    int ret = Interop.WiFi.AP.Clone(out IntPtr clonedHandle, apHandle);
                    if (ret != (int)WiFiError.None)
                    {
                        WiFiErrorFactory.ThrowWiFiException(ret, "Failed to clone AP handle");
                    }
                    return new WiFiAP(clonedHandle);
                });


internal IEnumerable<WiFiAP> GetFoundSpecificAPs() =>
EnumerateForeach("GetForeachFoundSpecificAPs", PrivilegeNetworkGet,
(wifi, cb, ud) => Interop.WiFi.GetForeachFoundSpecificAPs(wifi, cb, ud),
apHandle =>
{
IntPtr clonedHandle;
Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
WiFiAP apItem = new WiFiAP(clonedHandle);
apList.Add(apItem);
return true;
}
return false;
};

int ret = Interop.WiFi.GetForeachFoundBssids(GetSafeHandle(), callback, IntPtr.Zero);
CheckReturnValue(ret, "GetForeachFoundBssids", PrivilegeNetworkGet);

return apList;
}

internal IEnumerable<WiFiConfiguration> GetWiFiConfigurations()
{
Log.Debug(Globals.LogTag, "GetWiFiConfigurations");
List<WiFiConfiguration> configList = new List<WiFiConfiguration>();
Interop.WiFi.HandleCallback callback = (IntPtr configHandle, IntPtr userData) =>
{
if (configHandle != IntPtr.Zero)
Interop.WiFi.AP.Clone(out IntPtr clonedHandle, apHandle);
return new WiFiAP(clonedHandle);
});
Comment on lines +242 to +250

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The return value of Interop.WiFi.AP.Clone is ignored. If cloning fails, it may return a non-zero error code and leave clonedHandle as IntPtr.Zero or invalid, which will cause downstream failures when the WiFiAP instance is used. It is safer to check the return value and throw an exception if cloning fails.

                apHandle =>
                {
                    int ret = Interop.WiFi.AP.Clone(out IntPtr clonedHandle, apHandle);
                    if (ret != (int)WiFiError.None)
                    {
                        WiFiErrorFactory.ThrowWiFiException(ret, "Failed to clone AP handle");
                    }
                    return new WiFiAP(clonedHandle);
                });


internal IEnumerable<WiFiAP> GetFoundBssids() =>
EnumerateForeach("GetForeachFoundBssids", PrivilegeNetworkGet,
(wifi, cb, ud) => Interop.WiFi.GetForeachFoundBssids(wifi, cb, ud),
apHandle =>
{
IntPtr clonedConfig;
Interop.WiFi.Config.Clone(configHandle, out clonedConfig);
WiFiConfiguration configItem = new WiFiConfiguration(clonedConfig);
configList.Add(configItem);
return true;
}
return false;
};

int ret = Interop.WiFi.Config.GetForeachConfiguration(GetSafeHandle(), callback, IntPtr.Zero);
CheckReturnValue(ret, "GetForeachConfiguration", PrivilegeNetworkProfile);
return configList;
}
Interop.WiFi.AP.Clone(out IntPtr clonedHandle, apHandle);
return new WiFiAP(clonedHandle);
});
Comment on lines +255 to +263

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The return value of Interop.WiFi.AP.Clone is ignored. If cloning fails, it may return a non-zero error code and leave clonedHandle as IntPtr.Zero or invalid, which will cause downstream failures when the WiFiAP instance is used. It is safer to check the return value and throw an exception if cloning fails.

                apHandle =>
                {
                    int ret = Interop.WiFi.AP.Clone(out IntPtr clonedHandle, apHandle);
                    if (ret != (int)WiFiError.None)
                    {
                        WiFiErrorFactory.ThrowWiFiException(ret, "Failed to clone AP handle");
                    }
                    return new WiFiAP(clonedHandle);
                });


internal IEnumerable<WiFiConfiguration> GetWiFiConfigurations() =>
EnumerateForeach("GetForeachConfiguration", PrivilegeNetworkProfile,
(wifi, cb, ud) => Interop.WiFi.Config.GetForeachConfiguration(wifi, cb, ud),
configHandle =>
{
Interop.WiFi.Config.Clone(configHandle, out IntPtr clonedConfig);
return new WiFiConfiguration(clonedConfig);
});
Comment on lines +268 to +276

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The return value of Interop.WiFi.Config.Clone is ignored. If cloning fails, it may return a non-zero error code and leave clonedConfig as IntPtr.Zero or invalid, which will cause downstream failures when the WiFiConfiguration instance is used. It is safer to check the return value and throw an exception if cloning fails.

                configHandle =>
                {
                    int ret = Interop.WiFi.Config.Clone(configHandle, out IntPtr clonedConfig);
                    if (ret != (int)WiFiError.None)
                    {
                        WiFiErrorFactory.ThrowWiFiException(ret, "Failed to clone WiFi configuration");
                    }
                    return new WiFiConfiguration(clonedConfig);
                });


internal void SaveWiFiNetworkConfiguration(WiFiConfiguration config)
{
Expand Down
Loading