Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restyle [linux] Add WiFi support in ConnectivityManager. #1976

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
208 changes: 208 additions & 0 deletions src/platform/Linux/ConnectivityManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
#include <platform/internal/GenericConnectivityManagerImpl_Thread.ipp>
#endif

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
#include <platform/internal/GenericConnectivityManagerImpl_WiFi.ipp>
#endif

using namespace ::chip;
using namespace ::chip::TLV;
using namespace ::chip::DeviceLayer::Internal;
Expand All @@ -52,6 +56,19 @@ CHIP_ERROR ConnectivityManagerImpl::_Init()
GenericConnectivityManagerImpl_Thread<ConnectivityManagerImpl>::_Init();
#endif

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
mConnectivityFlag = 0;
mWpaSupplicant.state = GDBusWpaSupplicant::INIT;
mWpaSupplicant.scanState = GDBusWpaSupplicant::WIFI_SCANNING_IDLE;
mWpaSupplicant.proxy = NULL;
mWpaSupplicant.iface = NULL;
mWpaSupplicant.interfacePath = NULL;
mWpaSupplicant.networkPath = NULL;

wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, "fi.w1.wpa_supplicant1",
"/fi/w1/wpa_supplicant1", NULL, _OnWpaProxyReady, NULL);
#endif

SuccessOrExit(err);

exit:
Expand All @@ -66,5 +83,196 @@ void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
#endif
}

#if CHIP_DEVICE_CONFIG_ENABLE_WPA

uint16_t ConnectivityManagerImpl::mConnectivityFlag;
struct GDBusWpaSupplicant ConnectivityManagerImpl::mWpaSupplicant;

bool ConnectivityManagerImpl::_HaveIPv4InternetConnectivity(void)
{
return ((mConnectivityFlag & kFlag_HaveIPv4InternetConnectivity) != 0);
}

bool ConnectivityManagerImpl::_HaveIPv6InternetConnectivity(void)
{
return ((mConnectivityFlag & kFlag_HaveIPv6InternetConnectivity) != 0);
}

bool ConnectivityManagerImpl::_IsWiFiStationConnected(void)
{
bool ret = false;
const gchar * state = NULL;

if (mWpaSupplicant.state != GDBusWpaSupplicant::WPA_INTERFACE_CONNECTED)
{
ChipLogProgress(DeviceLayer, "wpa_supplicant: _IsWiFiStationConnected: interface not connected");
return false;
}

state = wpa_fi_w1_wpa_supplicant1_interface_get_state(mWpaSupplicant.iface);
ChipLogProgress(DeviceLayer, "wpa_supplicant: wpa_fi_w1_wpa_supplicant1_interface_get_state: %s", state);

if (g_strcmp0(state, "completed") == 0)
{
ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi already connected");
SetFlag(mConnectivityFlag, kFlag_HaveIPv4InternetConnectivity, true);
SetFlag(mConnectivityFlag, kFlag_HaveIPv6InternetConnectivity, true);
ret = true;
}

return ret;
}

bool ConnectivityManagerImpl::_CanStartWiFiScan()
{
return mWpaSupplicant.state == GDBusWpaSupplicant::WPA_INTERFACE_CONNECTED &&
mWpaSupplicant.scanState == GDBusWpaSupplicant::WIFI_SCANNING_IDLE;
}

void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data)
{
GError * err = NULL;
WpaFiW1Wpa_supplicant1Interface * iface = wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus_finish(res, &err);

if (mWpaSupplicant.iface)
{
g_object_unref(mWpaSupplicant.iface);
mWpaSupplicant.iface = NULL;
}

if (iface != NULL && err == NULL)
{
mWpaSupplicant.iface = iface;
mWpaSupplicant.state = GDBusWpaSupplicant::WPA_INTERFACE_CONNECTED;
ChipLogProgress(DeviceLayer, "wpa_supplicant: connected to wpa_supplicant interface proxy: %p", iface);
}
else
{
if (err != NULL)
ChipLogProgress(DeviceLayer, "wpa_supplicant: failed to create wpa_supplicant1 interface proxy %s: %s",
mWpaSupplicant.interfacePath, err->message);
else
ChipLogProgress(DeviceLayer, "wpa_supplicant: failed to create wpa_supplicant1 interface proxy %s",
mWpaSupplicant.interfacePath);

mWpaSupplicant.state = GDBusWpaSupplicant::WPA_NOT_CONNECTED;
}

if (err != NULL)
g_error_free(err);
}

void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsyncResult * res, gpointer user_data)
{
GError * err = NULL;

gboolean result =
wpa_fi_w1_wpa_supplicant1_call_get_interface_finish(mWpaSupplicant.proxy, &mWpaSupplicant.interfacePath, res, &err);
if (result)
{
mWpaSupplicant.state = GDBusWpaSupplicant::WPA_GOT_INTERFACE_PATH;
ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi interface: %s", mWpaSupplicant.interfacePath);

wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, "fi.w1.wpa_supplicant1",
mWpaSupplicant.interfacePath, NULL, _OnWpaInterfaceProxyReady, NULL);
}
else
{
if (err != NULL)
ChipLogProgress(DeviceLayer, "wpa_supplicant: can't find interface %s: %s", CHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME,
err->message);
else
ChipLogProgress(DeviceLayer, "wpa_supplicant: can't find interface %s", CHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME);

mWpaSupplicant.state = GDBusWpaSupplicant::WPA_NO_INTERFACE_PATH;

if (mWpaSupplicant.interfacePath)
{
g_free(mWpaSupplicant.interfacePath);
mWpaSupplicant.interfacePath = NULL;
}
}

if (err != NULL)
g_error_free(err);
}

void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties,
gpointer user_data)
{
if (mWpaSupplicant.interfacePath)
return;

mWpaSupplicant.interfacePath = const_cast<gchar *>(path);
if (mWpaSupplicant.interfacePath)
{
mWpaSupplicant.state = GDBusWpaSupplicant::WPA_GOT_INTERFACE_PATH;
ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi interface added: %s", mWpaSupplicant.interfacePath);

wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, "fi.w1.wpa_supplicant1",
mWpaSupplicant.interfacePath, NULL, _OnWpaInterfaceProxyReady, NULL);
}
}

void ConnectivityManagerImpl::_OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties,
gpointer user_data)
{
if (mWpaSupplicant.interfacePath == NULL)
return;

if (g_strcmp0(mWpaSupplicant.interfacePath, path) == 0)
{
ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi interface removed: %s", path);

mWpaSupplicant.state = GDBusWpaSupplicant::WPA_NO_INTERFACE_PATH;

if (mWpaSupplicant.interfacePath)
{
g_free(mWpaSupplicant.interfacePath);
mWpaSupplicant.interfacePath = NULL;
}

if (mWpaSupplicant.iface)
{
g_object_unref(mWpaSupplicant.iface);
mWpaSupplicant.iface = NULL;
}

mWpaSupplicant.scanState = GDBusWpaSupplicant::WIFI_SCANNING_IDLE;
}
}

void ConnectivityManagerImpl::_OnWpaProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data)
{
GError * err = NULL;

mWpaSupplicant.proxy = wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus_finish(res, &err);
if (mWpaSupplicant.proxy != NULL && err == NULL)
{
mWpaSupplicant.state = GDBusWpaSupplicant::WPA_CONNECTED;
ChipLogProgress(DeviceLayer, "wpa_supplicant: connected to wpa_supplicant proxy: %p", mWpaSupplicant.proxy);

g_signal_connect(mWpaSupplicant.proxy, "interface-added", G_CALLBACK(_OnWpaInterfaceAdded), NULL);

g_signal_connect(mWpaSupplicant.proxy, "interface-removed", G_CALLBACK(_OnWpaInterfaceRemoved), NULL);

wpa_fi_w1_wpa_supplicant1_call_get_interface(mWpaSupplicant.proxy, CHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME, NULL,
_OnWpaInterfaceReady, NULL);
}
else
{
if (err != NULL)
ChipLogProgress(DeviceLayer, "wpa_supplicant: failed to create wpa_supplicant proxy %s", err->message);
else
ChipLogProgress(DeviceLayer, "wpa_supplicant: failed to create wpa_supplicant proxy");

mWpaSupplicant.state = GDBusWpaSupplicant::WPA_NOT_CONNECTED;
}

if (err != NULL)
g_error_free(err);
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA

} // namespace DeviceLayer
} // namespace chip
55 changes: 55 additions & 0 deletions src/platform/Linux/ConnectivityManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,19 @@
#include <platform/internal/GenericConnectivityManagerImpl_NoThread.h>
#endif
#include <platform/internal/GenericConnectivityManagerImpl_NoTunnel.h>
#if CHIP_DEVICE_CONFIG_ENABLE_WPA
#include <platform/internal/GenericConnectivityManagerImpl_WiFi.h>
#else
#include <platform/internal/GenericConnectivityManagerImpl_NoWiFi.h>
#endif
#include <support/FlagUtils.hpp>

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
#include <DBusWpa.h>
#include <DBusWpaInterface.h>
#include <DBusWpaNetwork.h>
#endif

namespace chip {
namespace Inet {
class IPAddress;
Expand All @@ -44,6 +54,33 @@ class IPAddress;
namespace chip {
namespace DeviceLayer {

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
struct GDBusWpaSupplicant
{
enum
{
INIT,
WPA_CONNECTING,
WPA_CONNECTED,
WPA_NOT_CONNECTED,
WPA_NO_INTERFACE_PATH,
WPA_GOT_INTERFACE_PATH,
WPA_INTERFACE_CONNECTED,
} state;

enum
{
WIFI_SCANNING_IDLE,
WIFI_SCANNING,
} scanState;

WpaFiW1Wpa_supplicant1 * proxy;
WpaFiW1Wpa_supplicant1Interface * iface;
gchar * interfacePath;
gchar * networkPath;
};
#endif

/**
* Concrete implementation of the ConnectivityManager singleton object for Linux platforms.
*/
Expand All @@ -59,7 +96,11 @@ class ConnectivityManagerImpl final : public ConnectivityManager,
#else
public Internal::GenericConnectivityManagerImpl_NoThread<ConnectivityManagerImpl>,
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WPA
public Internal::GenericConnectivityManagerImpl_WiFi<ConnectivityManagerImpl>,
#else
public Internal::GenericConnectivityManagerImpl_NoWiFi<ConnectivityManagerImpl>,
#endif
public Internal::GenericConnectivityManagerImpl_NoTunnel<ConnectivityManagerImpl>
{
// Allow the ConnectivityManager interface class to delegate method calls to
Expand All @@ -75,6 +116,20 @@ class ConnectivityManagerImpl final : public ConnectivityManager,
CHIP_ERROR _Init(void);
void _OnPlatformEvent(const ChipDeviceEvent * event);

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
bool _IsWiFiStationConnected(void);
bool _CanStartWiFiScan();
static void _OnWpaProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data);
static void _OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties,
gpointer user_data);
static void _OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, gpointer user_data);
static void _OnWpaInterfaceReady(GObject * source_object, GAsyncResult * res, gpointer user_data);
static void _OnWpaInterfaceProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data);

static uint16_t mConnectivityFlag;
static struct GDBusWpaSupplicant mWpaSupplicant;
#endif

// ===== Members for internal use by the following friends.

friend ConnectivityManager & ConnectivityMgr(void);
Expand Down