wpa_supplicant: Add Wake-on-WLAN configuration support

Add a new wowlan_triggers option to wpa_supplicant.conf. The triggers in
this key will be used to configure the kernel wowlan configuration.

For now, support only simple flags. More complex triggers can be added
later on.

Signed-off-by: Eliad Peller <eliadx.peller@intel.com>
This commit is contained in:
Eliad Peller 2014-04-24 08:45:39 +03:00 committed by Jouni Malinen
parent 959214b260
commit e4fa8b120b
7 changed files with 205 additions and 0 deletions

View file

@ -682,6 +682,16 @@ enum hide_ssid {
HIDDEN_SSID_ZERO_CONTENTS
};
struct wowlan_triggers {
u8 any;
u8 disconnect;
u8 magic_pkt;
u8 gtk_rekey_failure;
u8 eap_identity_req;
u8 four_way_handshake;
u8 rfkill_release;
};
struct wpa_driver_ap_params {
/**
* head - Beacon head from IEEE 802.11 header to IEs before TIM IE
@ -1032,6 +1042,8 @@ struct wpa_driver_capa {
*/
const u8 *extended_capa, *extended_capa_mask;
unsigned int extended_capa_len;
struct wowlan_triggers wowlan_triggers;
};
@ -2518,6 +2530,13 @@ struct wpa_driver_ops {
int (*set_qos_map)(void *priv, const u8 *qos_map_set,
u8 qos_map_set_len);
/**
* set_wowlan - Set wake-on-wireless triggers
* @priv: Private driver interface data
* @triggers: wowlan triggers
*/
int (*set_wowlan)(void *priv, const struct wowlan_triggers *triggers);
/**
* signal_poll - Get current connection information
* @priv: Private driver interface data

View file

@ -3697,6 +3697,35 @@ static void wiphy_info_probe_resp_offload(struct wpa_driver_capa *capa,
}
static void wiphy_info_wowlan_triggers(struct wpa_driver_capa *capa,
struct nlattr *tb)
{
struct nlattr *triggers[MAX_NL80211_WOWLAN_TRIG + 1];
if (tb == NULL)
return;
if (nla_parse_nested(triggers, MAX_NL80211_WOWLAN_TRIG,
tb, NULL))
return;
if (triggers[NL80211_WOWLAN_TRIG_ANY])
capa->wowlan_triggers.any = 1;
if (triggers[NL80211_WOWLAN_TRIG_DISCONNECT])
capa->wowlan_triggers.disconnect = 1;
if (triggers[NL80211_WOWLAN_TRIG_MAGIC_PKT])
capa->wowlan_triggers.magic_pkt = 1;
if (triggers[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
capa->wowlan_triggers.gtk_rekey_failure = 1;
if (triggers[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
capa->wowlan_triggers.eap_identity_req = 1;
if (triggers[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
capa->wowlan_triggers.four_way_handshake = 1;
if (triggers[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
capa->wowlan_triggers.rfkill_release = 1;
}
static int wiphy_info_handler(struct nl_msg *msg, void *arg)
{
struct nlattr *tb[NL80211_ATTR_MAX + 1];
@ -3820,6 +3849,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
}
}
wiphy_info_wowlan_triggers(capa,
tb[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]);
return NL_SKIP;
}
@ -12137,6 +12169,57 @@ nla_put_failure:
}
static int nl80211_set_wowlan(void *priv,
const struct wowlan_triggers *triggers)
{
struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
struct nl_msg *msg;
struct nlattr *wowlan_triggers;
int ret;
msg = nlmsg_alloc();
if (!msg)
return -ENOMEM;
wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan");
nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WOWLAN);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
wowlan_triggers = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
if (!wowlan_triggers)
goto nla_put_failure;
if (triggers->any)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
if (triggers->disconnect)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
if (triggers->magic_pkt)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
if (triggers->gtk_rekey_failure)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
if (triggers->eap_identity_req)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
if (triggers->four_way_handshake)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
if (triggers->rfkill_release)
NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
nla_nest_end(msg, wowlan_triggers);
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
if (ret)
wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan failed");
return ret;
nla_put_failure:
nlmsg_free(msg);
return -ENOBUFS;
}
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211",
.desc = "Linux nl80211/cfg80211",
@ -12227,4 +12310,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
#endif /* ANDROID */
.vendor_cmd = nl80211_vendor_cmd,
.set_qos_map = nl80211_set_qos_map,
.set_wowlan = nl80211_set_wowlan,
};