From ac130279343c113d7a55ea243eaed9adc57c9e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfonso=20S=C3=A1nchez-Beato?= Date: Tue, 19 Jun 2018 14:44:36 +0200 Subject: [PATCH] platform: add methods to retrieve current WoWLAN state --- src/platform/nm-linux-platform.c | 8 ++++ src/platform/nm-platform.c | 10 +++++ src/platform/nm-platform.h | 2 + src/platform/wifi/wifi-utils-nl80211.c | 61 ++++++++++++++++++++++++-- src/platform/wifi/wifi-utils-private.h | 3 ++ src/platform/wifi/wifi-utils.c | 9 ++++ src/platform/wifi/wifi-utils.h | 2 + 7 files changed, 92 insertions(+), 3 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 9bd662a18c..33a05ab126 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -6092,6 +6092,13 @@ wifi_indicate_addressing_running (NMPlatform *platform, int ifindex, gboolean ru wifi_utils_indicate_addressing_running (wifi_data, running); } +static NMSettingWirelessWakeOnWLan +wifi_get_wake_on_wlan (NMPlatform *platform, int ifindex) +{ + WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); + return wifi_utils_get_wake_on_wlan (wifi_data); +} + static gboolean wifi_set_wake_on_wlan (NMPlatform *platform, int ifindex, NMSettingWirelessWakeOnWLan wowl) @@ -7238,6 +7245,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->wifi_set_powersave = wifi_set_powersave; platform_class->wifi_find_frequency = wifi_find_frequency; platform_class->wifi_indicate_addressing_running = wifi_indicate_addressing_running; + platform_class->wifi_get_wake_on_wlan = wifi_get_wake_on_wlan; platform_class->wifi_set_wake_on_wlan = wifi_set_wake_on_wlan; platform_class->mesh_get_channel = mesh_get_channel; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index f75019e8ba..96bb2928ef 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -2888,6 +2888,16 @@ nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gbo klass->wifi_indicate_addressing_running (self, ifindex, running); } +NMSettingWirelessWakeOnWLan +nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex) +{ + _CHECK_SELF (self, klass, FALSE); + + g_return_val_if_fail (ifindex > 0, FALSE); + + return klass->wifi_get_wake_on_wlan (self, ifindex); +} + gboolean nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl) { diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 866df7362e..84d10d2af0 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -868,6 +868,7 @@ typedef struct { void (*wifi_set_powersave) (NMPlatform *, int ifindex, guint32 powersave); guint32 (*wifi_find_frequency) (NMPlatform *, int ifindex, const guint32 *freqs); void (*wifi_indicate_addressing_running) (NMPlatform *, int ifindex, gboolean running); + NMSettingWirelessWakeOnWLan (*wifi_get_wake_on_wlan) (NMPlatform *, int ifindex); gboolean (*wifi_set_wake_on_wlan) (NMPlatform *, int ifindex, NMSettingWirelessWakeOnWLan wowl); guint32 (*mesh_get_channel) (NMPlatform *, int ifindex); @@ -1247,6 +1248,7 @@ void nm_platform_wifi_set_mode (NMPlatform *self, int ifindex, NM void nm_platform_wifi_set_powersave (NMPlatform *self, int ifindex, guint32 powersave); guint32 nm_platform_wifi_find_frequency (NMPlatform *self, int ifindex, const guint32 *freqs); void nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gboolean running); +NMSettingWirelessWakeOnWLan nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex); gboolean nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl); guint32 nm_platform_mesh_get_channel (NMPlatform *self, int ifindex); diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index 6c2ff3f579..c6e77b1103 100644 --- a/src/platform/wifi/wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -271,6 +271,59 @@ nla_put_failure: return FALSE; } +static int +nl80211_get_wake_on_wlan_handler (struct nl_msg *msg, void *arg) +{ + NMSettingWirelessWakeOnWLan* wowl = arg; + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG]; + struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); + + nla_parse (attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) + return NL_SKIP; + + nla_parse (trig, MAX_NL80211_WOWLAN_TRIG, + nla_data (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + nla_len (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + NULL); + + if (trig[NL80211_WOWLAN_TRIG_ANY]) + *wowl = NM_FLAGS_SET (*wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY); + if (trig[NL80211_WOWLAN_TRIG_DISCONNECT]) + *wowl = NM_FLAGS_SET (*wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT); + if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT]) + *wowl = NM_FLAGS_SET (*wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC); + if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) + *wowl = NM_FLAGS_SET (*wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE); + if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) + *wowl = NM_FLAGS_SET (*wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST); + if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) + *wowl = NM_FLAGS_SET (*wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE); + if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) + *wowl = NM_FLAGS_SET (*wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE); + if (trig[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) + *wowl = NM_FLAGS_SET (*wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP); + + return NL_SKIP; +} + +static NMSettingWirelessWakeOnWLan +wifi_nl80211_get_wake_on_wlan (WifiData *data) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + NMSettingWirelessWakeOnWLan wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE; + nm_auto_nlmsg struct nl_msg *msg = NULL; + + msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0); + + nl80211_send_and_recv (nl80211, msg, nl80211_get_wake_on_wlan_handler, &wowl); + + return wowl; +} + static gboolean wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) { @@ -282,11 +335,11 @@ wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) return TRUE; - msg = nl80211_alloc_msg(nl80211, NL80211_CMD_SET_WOWLAN, 0); + msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_WOWLAN, 0); if (!msg) return FALSE; - triggers = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); + triggers = nla_nest_start (msg, NL80211_ATTR_WOWLAN_TRIGGERS); if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY)) NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_ANY); @@ -306,7 +359,8 @@ wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) nla_nest_end(msg, triggers); err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); - return err ? FALSE : TRUE; + + return err >= 0; nla_put_failure: return FALSE; @@ -887,6 +941,7 @@ wifi_nl80211_init (int ifindex) .get_mode = wifi_nl80211_get_mode, .set_mode = wifi_nl80211_set_mode, .set_powersave = wifi_nl80211_set_powersave, + .get_wake_on_wlan = wifi_nl80211_get_wake_on_wlan, .set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan, .get_freq = wifi_nl80211_get_freq, .find_freq = wifi_nl80211_find_freq, diff --git a/src/platform/wifi/wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h index 627108cbca..dc5dec05cc 100644 --- a/src/platform/wifi/wifi-utils-private.h +++ b/src/platform/wifi/wifi-utils-private.h @@ -34,6 +34,9 @@ typedef struct { /* Set power saving mode on an interface */ gboolean (*set_powersave) (WifiData *data, guint32 powersave); + /* Get WakeOnWLAN configuration on an interface */ + NMSettingWirelessWakeOnWLan (*get_wake_on_wlan) (WifiData *data); + /* Set WakeOnWLAN mode on an interface */ gboolean (*set_wake_on_wlan) (WifiData *data, NMSettingWirelessWakeOnWLan wowl); diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c index b3dd92bab0..778cbd90b7 100644 --- a/src/platform/wifi/wifi-utils.c +++ b/src/platform/wifi/wifi-utils.c @@ -112,6 +112,15 @@ wifi_utils_set_powersave (WifiData *data, guint32 powersave) return data->klass->set_powersave ? data->klass->set_powersave (data, powersave) : TRUE; } +NMSettingWirelessWakeOnWLan +wifi_utils_get_wake_on_wlan (WifiData *data) +{ + g_return_val_if_fail (data != NULL, FALSE); + + return data->klass->get_wake_on_wlan ? + data->klass->get_wake_on_wlan (data) : NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE; +} + gboolean wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) { diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h index c69561def4..e454b71740 100644 --- a/src/platform/wifi/wifi-utils.h +++ b/src/platform/wifi/wifi-utils.h @@ -67,6 +67,8 @@ gboolean wifi_utils_get_wowlan (WifiData *data); gboolean wifi_utils_set_powersave (WifiData *data, guint32 powersave); +NMSettingWirelessWakeOnWLan wifi_utils_get_wake_on_wlan (WifiData *data); + gboolean wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl); /* OLPC Mesh-only functions */