diff options
| author | Jouni Malinen <j@w1.fi> | 2014-01-01 23:30:23 +0200 |
|---|---|---|
| committer | Steve Kondik <shade@chemlab.org> | 2014-06-12 14:07:59 -0700 |
| commit | eb8a1b7990db7f4464740306b978f56bdcefc5a3 (patch) | |
| tree | 75e5ff057aa60a0c787924d3024189b76d601b3d | |
| parent | 3e3b81fe1013768dc989a6ed719be63b3998851d (diff) | |
| download | android_external_wpa_supplicant_8-eb8a1b7990db7f4464740306b978f56bdcefc5a3.tar.gz android_external_wpa_supplicant_8-eb8a1b7990db7f4464740306b978f56bdcefc5a3.tar.bz2 android_external_wpa_supplicant_8-eb8a1b7990db7f4464740306b978f56bdcefc5a3.zip | |
nl80211: Initial support for vendor commands and events
Print into the debug log the list of vendor commands and events that the
driver supports. In addition, add a generic handler for vendor events.
This can be extended for each vendor/subcmd.
Signed-hostap: Jouni Malinen <j@w1.fi>
Git-commit: 17b79e65a9491a02a3d28411f1432481e8af564b
Git-repo : git://w1.fi/srv/git/hostap.git
Change-Id: Ic649ebc25a30f0a6e3bfaae58fb917217f28f3c6
| -rw-r--r-- | src/drivers/driver_nl80211.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 7be46ff4..3437cd78 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -477,6 +477,11 @@ static const char * nl80211_command_to_string(enum nl80211_commands cmd) C2S(NL80211_CMD_FT_EVENT) C2S(NL80211_CMD_CRIT_PROTOCOL_START) C2S(NL80211_CMD_CRIT_PROTOCOL_STOP) + C2S(NL80211_CMD_GET_COALESCE) + C2S(NL80211_CMD_SET_COALESCE) + C2S(NL80211_CMD_CHANNEL_SWITCH) + C2S(NL80211_CMD_VENDOR) + C2S(NL80211_CMD_SET_QOS_MAP) default: return "NL80211_CMD_UNKNOWN"; } @@ -2607,6 +2612,48 @@ static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb, } +static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv, + struct nlattr **tb) +{ + u32 vendor_id, subcmd, wiphy = 0; + int wiphy_idx; + u8 *data = NULL; + size_t len = 0; + + if (!tb[NL80211_ATTR_VENDOR_ID] || + !tb[NL80211_ATTR_VENDOR_SUBCMD]) + return; + + vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]); + subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]); + + if (tb[NL80211_ATTR_WIPHY]) + wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]); + + wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u", + wiphy, vendor_id, subcmd); + + if (tb[NL80211_ATTR_VENDOR_DATA]) { + data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]); + len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]); + wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len); + } + + wiphy_idx = nl80211_get_wiphy_index(drv->first_bss); + if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) { + wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)", + wiphy, wiphy_idx); + return; + } + + switch (vendor_id) { + default: + wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event"); + break; + } +} + + static void do_process_drv_event(struct i802_bss *bss, int cmd, struct nlattr **tb) { @@ -2769,6 +2816,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, case NL80211_CMD_STOP_AP: nl80211_stop_ap(drv, tb); break; + case NL80211_CMD_VENDOR: + nl80211_vendor_event(drv, tb); + break; default: wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event " "(cmd=%d)", cmd); @@ -3345,6 +3395,38 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg) } } + if (tb[NL80211_ATTR_VENDOR_DATA]) { + struct nlattr *nl; + int rem; + + nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) { + struct nl80211_vendor_cmd_info *vinfo; + if (nla_len(nl) != sizeof(vinfo)) { + wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info"); + continue; + } + vinfo = nla_data(nl); + wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u", + vinfo->vendor_id, vinfo->subcmd); + } + } + + if (tb[NL80211_ATTR_VENDOR_EVENTS]) { + struct nlattr *nl; + int rem; + + nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) { + struct nl80211_vendor_cmd_info *vinfo; + if (nla_len(nl) != sizeof(vinfo)) { + wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info"); + continue; + } + vinfo = nla_data(nl); + wpa_printf(MSG_DEBUG, "nl80211: Supported vendor event: vendor_id=0x%x subcmd=%u", + vinfo->vendor_id, vinfo->subcmd); + } + } + return NL_SKIP; } @@ -3584,6 +3666,16 @@ static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global) /* Continue without regulatory events */ } + ret = nl_get_multicast_id(global, "nl80211", "vendor"); + if (ret >= 0) + ret = nl_socket_add_membership(global->nl_event, ret); + if (ret < 0) { + wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast " + "membership for vendor events: %d (%s)", + ret, strerror(-ret)); + /* Continue without vendor events */ + } + nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, |
