Commit f8623283 authored by Dmitry Shmidt's avatar Dmitry Shmidt
Browse files

Accumulative patch from commit b618a469c42120e984ab1c85ed6058504d1fca78


  Author: Jouni Malinen <jouni@qca.qualcomm.com>
  Date:   Sat Feb 16 19:54:09 2013 +0200
    Interworking: Select highest priority cred if multiple matches

Interworking: Select highest priority cred if multiple matches
GAS server: Fix a regression in GAS server callback
hostapd: Fix Max SP Length derivation from QoS Info
nl80211: Configure STA Capabilities and Extended Capabilities
Synchronize with wireless-testing.git include/uapi/linux/nl80211.h
WPS: Fix build without CONFIG_WPS_NFC
WPS: Add support for NFC handover select generation with wpa_supplicant
WPS: Update NFC connection handover documentation
WPS: Add support for config token generation with wpa_supplicant
WPS: Allow password token to be written with nfcpy
WPS: Use pre-configured NFC password token instead of overriding it
TDLS: Pass peer's Capability and Ext Capability info during sta_add
TDLS: Pass peer's HT Capability and QOS information during sta_add
nl80211: Add debug prints for STA add/set operations
TDLS: Fix add/set STA operation
Synchronize with wireless-testing.git include/uapi/linux/nl80211.h
WPS: Allow Device Password to be changed from M1 to M2
WPS: Fix wps_reg nfc-pw option
TDLS: Tear down peers when disconnecting from the AP
P2P: Do not use old scan result data for peer discovery
Use more accurate timestamps for scan results
P2P: Postpone P2P-DEVICE-FOUND if config_methods not known
P2P: Do not allow peer update to clear config_methods
WPS: Report NFC connection handover completion differently
P2P: Avoid concurrent scans during all steps of group formation
P2P: Cancel group formation timeout on group removal (on client)
WPS: Change listen time to match nfcpy default (250 ms)
WPS: Report only the carrier record from NFC to wpa_supplicant
WPS: Fetch only the carrier record from wpa_supplicant for NFC
WPS: Update nfcpy script to support AP mode NFC connection handover
WPS: Add command for fetching carrier record for NFC handover
WPS: Clean up debug prints with nfcpy
WPS: Remove 0.5 sec extra wait from NFC handover with nfcpy
WPS: Use alternating poll/listen for NFC peer discovery with nfcpy
WPS: Configure logging to show nfcpy log message
WPS: Add an example python script for NFC operations with hostapd
hostapd: Do not change HT40 capability due to OBSS scan
dbus: Add missing signal description for WPS (7)
EAP peer: Add Session-Id derivation to more EAP methods
EAP peer: Add Session-Id derivation
EAP-IKEV2 server: Fix invalid memory freeing operation
eap_proxy: Add a dummy implementation for compilation testing
eap_proxy: Add mechanism for allowing EAP methods to be offloaded
Android: Allow setgroups to be overridden from build configuration
P2P: Send p2p_stop_find event on failure to start pending p2p_find
P2P: Fix GO Probe Response IEs when Wi-Fi Display is enabled
Capability matching for 60 GHz band
nl80211: Add ctrl_iface message for AP mode connection rejection
P2P: Allow local configuration to use 5 GHz band 40 MHz channels
Fix BSS RANGE command for no exact id match cases

Change-Id: Iac9284bba31db40911aecc3adf2843c9b1576db1
Signed-off-by: default avatarDmitry Shmidt <dimitrysh@google.com>
parent 1e1c48d2
......@@ -338,3 +338,17 @@ If the NFC tag contains a password token, the token is added to the
internal Registrar. This allows station Enrollee from which the password
token was received to run through WPS protocol to provision the
credential.
"nfc_get_handover_sel <NDEF> <WPS>" command can be used to build the
contents of a Handover Select Message for connection handover when this
does not depend on the contents of the Handover Request Message. The
first argument selects the format of the output data and the second
argument selects which type of connection handover is requested (WPS =
Wi-Fi handover as specified in WSC 2.0).
"nfc_report_handover <INIT/RESP> WPS <carrier from handover request>
<carrier from handover select>" is used to report completed NFC
connection handover. The first parameter indicates whether the local
device initiated or responded to the connection handover and the carrier
records are the selected carrier from the handover request and select
messages as a hexdump.
......@@ -2627,15 +2627,19 @@ static int hostapd_config_fill(struct hostapd_config *conf,
"wps_nfc_dev_pw_id value", line);
errors++;
}
bss->wps_nfc_pw_from_config = 1;
} else if (os_strcmp(buf, "wps_nfc_dh_pubkey") == 0) {
wpabuf_free(bss->wps_nfc_dh_pubkey);
bss->wps_nfc_dh_pubkey = hostapd_parse_bin(pos);
bss->wps_nfc_pw_from_config = 1;
} else if (os_strcmp(buf, "wps_nfc_dh_privkey") == 0) {
wpabuf_free(bss->wps_nfc_dh_privkey);
bss->wps_nfc_dh_privkey = hostapd_parse_bin(pos);
bss->wps_nfc_pw_from_config = 1;
} else if (os_strcmp(buf, "wps_nfc_dev_pw") == 0) {
wpabuf_free(bss->wps_nfc_dev_pw);
bss->wps_nfc_dev_pw = hostapd_parse_bin(pos);
bss->wps_nfc_pw_from_config = 1;
#endif /* CONFIG_WPS_NFC */
#endif /* CONFIG_WPS */
#ifdef CONFIG_P2P_MANAGER
......
......@@ -352,6 +352,59 @@ static int hostapd_ctrl_iface_wps_nfc_token(struct hostapd_data *hapd,
return -1;
}
static int hostapd_ctrl_iface_nfc_get_handover_sel(struct hostapd_data *hapd,
char *cmd, char *reply,
size_t max_len)
{
struct wpabuf *buf;
int res;
char *pos;
int ndef;
pos = os_strchr(cmd, ' ');
if (pos == NULL)
return -1;
*pos++ = '\0';
if (os_strcmp(cmd, "WPS") == 0)
ndef = 0;
else if (os_strcmp(cmd, "NDEF") == 0)
ndef = 1;
else
return -1;
if (os_strcmp(pos, "WPS-CR") == 0)
buf = hostapd_wps_nfc_hs_cr(hapd, ndef);
else
buf = NULL;
if (buf == NULL)
return -1;
res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
wpabuf_len(buf));
reply[res++] = '\n';
reply[res] = '\0';
wpabuf_free(buf);
return res;
}
static int hostapd_ctrl_iface_nfc_report_handover(struct hostapd_data *hapd,
char *cmd)
{
/*
* Since NFC connection handover provided full WPS Credential, there is
* no need for additional operations within hostapd. Just report this in
* debug log.
*/
wpa_printf(MSG_DEBUG, "NFC: Connection handover reported: %s", cmd);
return 0;
}
#endif /* CONFIG_WPS_NFC */
......@@ -913,6 +966,12 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
} else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) {
reply_len = hostapd_ctrl_iface_wps_nfc_token(
hapd, buf + 14, reply, reply_size);
} else if (os_strncmp(buf, "NFC_GET_HANDOVER_SEL ", 21) == 0) {
reply_len = hostapd_ctrl_iface_nfc_get_handover_sel(
hapd, buf + 21, reply, reply_size);
} else if (os_strncmp(buf, "NFC_REPORT_HANDOVER ", 20) == 0) {
if (hostapd_ctrl_iface_nfc_report_handover(hapd, buf + 20))
reply_len = -1;
#endif /* CONFIG_WPS_NFC */
#endif /* CONFIG_WPS */
#ifdef CONFIG_WNM
......
......@@ -475,6 +475,29 @@ static int hostapd_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl,
}
return wpa_ctrl_command(ctrl, cmd);
}
static int hostapd_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl,
int argc, char *argv[])
{
char cmd[64];
int res;
if (argc != 2) {
printf("Invalid 'nfc_get_handover_sel' command - two arguments "
"are required.\n");
return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "NFC_GET_HANDOVER_SEL %s %s",
argv[0], argv[1]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long NFC_GET_HANDOVER_SEL command.\n");
return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
#endif /* CONFIG_WPS_NFC */
......@@ -796,6 +819,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
{ "wps_nfc_tag_read", hostapd_cli_cmd_wps_nfc_tag_read },
{ "wps_nfc_config_token", hostapd_cli_cmd_wps_nfc_config_token },
{ "wps_nfc_token", hostapd_cli_cmd_wps_nfc_token },
{ "nfc_get_handover_sel", hostapd_cli_cmd_nfc_get_handover_sel },
#endif /* CONFIG_WPS_NFC */
{ "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
{ "wps_config", hostapd_cli_cmd_wps_config },
......
#!/usr/bin/python
#
# Example nfcpy to hostapd wrapper for WPS NFC operations
# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.
import os
import sys
import time
import nfc
import nfc.ndef
import nfc.llcp
import nfc.handover
import logging
logging.basicConfig()
import wpactrl
wpas_ctrl = '/var/run/hostapd'
def wpas_connect():
ifaces = []
if os.path.isdir(wpas_ctrl):
try:
ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
except OSError, error:
print "Could not find hostapd: ", error
return None
if len(ifaces) < 1:
print "No hostapd control interface found"
return None
for ctrl in ifaces:
try:
wpas = wpactrl.WPACtrl(ctrl)
return wpas
except wpactrl.error, error:
print "Error: ", error
pass
return None
def wpas_tag_read(message):
wpas = wpas_connect()
if (wpas == None):
return
print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
def wpas_get_config_token():
wpas = wpas_connect()
if (wpas == None):
return None
return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
def wpas_get_password_token():
wpas = wpas_connect()
if (wpas == None):
return None
return wpas.request("WPS_NFC_TOKEN NDEF").rstrip().decode("hex")
def wpas_get_handover_sel():
wpas = wpas_connect()
if (wpas == None):
return None
return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip().decode("hex")
def wpas_report_handover(req, sel):
wpas = wpas_connect()
if (wpas == None):
return None
return wpas.request("NFC_REPORT_HANDOVER RESP WPS " +
str(req).encode("hex") + " " +
str(sel).encode("hex"))
class HandoverServer(nfc.handover.HandoverServer):
def __init__(self):
super(HandoverServer, self).__init__()
def process_request(self, request):
print "HandoverServer - request received"
print "Parsed handover request: " + request.pretty()
sel = nfc.ndef.HandoverSelectMessage(version="1.2")
for carrier in request.carriers:
print "Remote carrier type: " + carrier.type
if carrier.type == "application/vnd.wfa.wsc":
print "WPS carrier type match - add WPS carrier record"
self.received_carrier = carrier.record
data = wpas_get_handover_sel()
if data is None:
print "Could not get handover select carrier record from hostapd"
continue
print "Handover select carrier record from hostapd:"
print data.encode("hex")
self.sent_carrier = data
message = nfc.ndef.Message(data);
sel.add_carrier(message[0], "active", message[1:])
print "Handover select:"
print sel.pretty()
print str(sel).encode("hex")
print "Sending handover select"
return sel
def wps_handover_resp(peer):
print "Trying to handle WPS handover"
srv = HandoverServer()
nfc.llcp.activate(peer);
try:
print "Trying handover";
srv.start()
print "Wait for disconnect"
while nfc.llcp.connected():
time.sleep(0.1)
print "Disconnected after handover"
except nfc.llcp.ConnectRefused:
print "Handover connection refused"
nfc.llcp.shutdown()
return
if srv.sent_carrier:
wpas_report_handover(srv.received_carrier, srv.sent_carrier)
print "Remove peer"
nfc.llcp.shutdown()
print "Done with handover"
def wps_tag_read(tag):
if len(tag.ndef.message):
message = nfc.ndef.Message(tag.ndef.message)
print "message type " + message.type
for record in message:
print "record type " + record.type
if record.type == "application/vnd.wfa.wsc":
print "WPS tag - send to hostapd"
wpas_tag_read(tag.ndef.message)
break
else:
print "Empty tag"
print "Remove tag"
while tag.is_present:
time.sleep(0.1)
def wps_write_config_tag(clf):
print "Write WPS config token"
data = wpas_get_config_token()
if (data == None):
print "Could not get WPS config token from hostapd"
return
print "Touch an NFC tag"
while True:
tag = clf.poll()
if tag == None:
time.sleep(0.1)
continue
break
print "Tag found - writing"
tag.ndef.message = data
print "Done - remove tag"
while tag.is_present:
time.sleep(0.1)
def wps_write_password_tag(clf):
print "Write WPS password token"
data = wpas_get_password_token()
if (data == None):
print "Could not get WPS password token from hostapd"
return
print "Touch an NFC tag"
while True:
tag = clf.poll()
if tag == None:
time.sleep(0.1)
continue
break
print "Tag found - writing"
tag.ndef.message = data
print "Done - remove tag"
while tag.is_present:
time.sleep(0.1)
def find_peer(clf):
while True:
if nfc.llcp.connected():
print "LLCP connected"
general_bytes = nfc.llcp.startup({})
peer = clf.listen(ord(os.urandom(1)) + 250, general_bytes)
if isinstance(peer, nfc.DEP):
print "listen -> DEP";
if peer.general_bytes.startswith("Ffm"):
print "Found DEP"
return peer
print "mismatch in general_bytes"
print peer.general_bytes
peer = clf.poll(general_bytes)
if isinstance(peer, nfc.DEP):
print "poll -> DEP";
if peer.general_bytes.startswith("Ffm"):
print "Found DEP"
return peer
print "mismatch in general_bytes"
print peer.general_bytes
if peer:
print "Found tag"
return peer
def main():
clf = nfc.ContactlessFrontend()
try:
if len(sys.argv) > 1 and sys.argv[1] == "write-config":
wps_write_config_tag(clf)
raise SystemExit
if len(sys.argv) > 1 and sys.argv[1] == "write-password":
wps_write_password_tag(clf)
raise SystemExit
while True:
print "Waiting for a tag or peer to be touched"
tag = find_peer(clf)
if isinstance(tag, nfc.DEP):
wps_handover_resp(tag)
continue
if tag.ndef:
wps_tag_read(tag)
continue
print "Not an NDEF tag - remove tag"
while tag.is_present:
time.sleep(0.1)
except KeyboardInterrupt:
raise SystemExit
finally:
clf.close()
raise SystemExit
if __name__ == '__main__':
main()
......@@ -365,6 +365,7 @@ struct hostapd_bss_config {
char *model_url;
char *upc;
struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
int wps_nfc_pw_from_config;
int wps_nfc_dev_pw_id;
struct wpabuf *wps_nfc_dh_pubkey;
struct wpabuf *wps_nfc_dh_privkey;
......
......@@ -13,6 +13,7 @@
#include "drivers/driver.h"
#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "common/wpa_ctrl.h"
#include "crypto/random.h"
#include "p2p/p2p.h"
#include "wps/wps.h"
......@@ -393,6 +394,22 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
}
void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
const u8 *addr, int reason_code)
{
switch (reason_code) {
case MAX_CLIENT_REACHED:
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_MAX_STA MACSTR,
MAC2STR(addr));
break;
case BLOCKED_CLIENT:
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_BLOCKED_STA MACSTR,
MAC2STR(addr));
break;
}
}
int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
const u8 *bssid, const u8 *ie, size_t ie_len,
int ssi_signal)
......@@ -828,6 +845,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->ch_switch.ht_enabled,
data->ch_switch.ch_offset);
break;
case EVENT_CONNECT_FAILED_REASON:
if (!data)
break;
hostapd_event_connect_failed_reason(
hapd, data->connect_failed_reason.addr,
data->connect_failed_reason.code);
break;
default:
wpa_printf(MSG_DEBUG, "Unknown event %d", event);
break;
......
......@@ -305,6 +305,8 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
const u8 *ie, size_t ielen, int reassoc);
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr);
void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr);
void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
const u8 *addr, int reason_code);
int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
const u8 *bssid, const u8 *ie, size_t ie_len,
int ssi_signal);
......
......@@ -443,7 +443,6 @@ static void ieee80211n_check_scan(struct hostapd_iface *iface)
iface->conf->channel +
iface->conf->secondary_channel * 4);
iface->conf->secondary_channel = 0;
iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
}
res = ieee80211n_allowed_ht40_channel_pair(iface);
......
......@@ -1601,7 +1601,7 @@ static void handle_action(struct hostapd_data *hapd,
hapd->iface->freq);
}
if (hapd->public_action_cb2) {
hapd->public_action_cb2(hapd->public_action_cb_ctx,
hapd->public_action_cb2(hapd->public_action_cb2_ctx,
(u8 *) mgmt, len,
hapd->iface->freq);
}
......
......@@ -133,8 +133,7 @@ int hostapd_ht_operation_update(struct hostapd_iface *iface)
new_op_mode = 0;
if (iface->num_sta_no_ht)
new_op_mode = OP_MODE_MIXED;
else if ((iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
&& iface->num_sta_ht_20mhz)
else if (iface->conf->secondary_channel && iface->num_sta_ht_20mhz)
new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
else if (iface->olbc_ht)
new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
......
......@@ -1583,8 +1583,25 @@ struct wpabuf * hostapd_wps_nfc_config_token(struct hostapd_data *hapd,
}
struct wpabuf * hostapd_wps_nfc_hs_cr(struct hostapd_data *hapd, int ndef)
{
/*
* Handover Select carrier record for WPS uses the same format as
* configuration token.
*/
return hostapd_wps_nfc_config_token(hapd, ndef);
}
struct wpabuf * hostapd_wps_nfc_token_gen(struct hostapd_data *hapd, int ndef)
{
if (hapd->conf->wps_nfc_pw_from_config) {
return wps_nfc_token_build(ndef,
hapd->conf->wps_nfc_dev_pw_id,
hapd->conf->wps_nfc_dh_pubkey,
hapd->conf->wps_nfc_dev_pw);
}
return wps_nfc_token_gen(ndef, &hapd->conf->wps_nfc_dev_pw_id,
&hapd->conf->wps_nfc_dh_pubkey,
&hapd->conf->wps_nfc_dh_privkey,
......
......@@ -35,6 +35,7 @@ int hostapd_wps_nfc_tag_read(struct hostapd_data *hapd,
const struct wpabuf *data);
struct wpabuf * hostapd_wps_nfc_config_token(struct hostapd_data *hapd,
int ndef);
struct wpabuf * hostapd_wps_nfc_hs_cr(struct hostapd_data *hapd, int ndef);
struct wpabuf * hostapd_wps_nfc_token_gen(struct hostapd_data *hapd, int ndef);
int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd);
void hostapd_wps_nfc_token_disable(struct hostapd_data *hapd);
......
......@@ -218,6 +218,7 @@
/* EIDs defined by IEEE 802.11h - END */
#define WLAN_EID_ERP_INFO 42
#define WLAN_EID_HT_CAP 45
#define WLAN_EID_QOS 46
#define WLAN_EID_RSN 48
#define WLAN_EID_EXT_SUPP_RATES 50
#define WLAN_EID_MOBILITY_DOMAIN 54
......
......@@ -150,6 +150,8 @@ extern "C" {
#define AP_STA_CONNECTED "AP-STA-CONNECTED "
#define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED "
#define AP_REJECTED_MAX_STA "AP-REJECTED-MAX-STA "
#define AP_REJECTED_BLOCKED_STA "AP-REJECTED-BLOCKED-STA "
/* BSS command information masks */
......
......@@ -122,6 +122,13 @@ struct hostapd_hw_modes {
#define IEEE80211_CAP_IBSS 0x0002
#define IEEE80211_CAP_PRIVACY 0x0010
/* DMG (60 GHz) IEEE 802.11ad */
/* type - bits 0..1 */
#define IEEE80211_CAP_DMG_MASK 0x0003
#define IEEE80211_CAP_DMG_IBSS 0x0001 /* Tx by: STA */
#define IEEE80211_CAP_DMG_PBSS 0x0002 /* Tx by: PCP */
#define IEEE80211_CAP_DMG_AP 0x0003 /* Tx by: AP */
#define WPA_SCAN_QUAL_INVALID BIT(0)
#define WPA_SCAN_NOISE_INVALID BIT(1)
#define WPA_SCAN_LEVEL_INVALID BIT(2)
......@@ -180,10 +187,12 @@ struct wpa_scan_res {
* struct wpa_scan_results - Scan results
* @res: Array of pointers to allocated variable length scan result entries
* @num: Number of entries in the scan result array
* @fetch_time: Time when the results were fetched from the driver
*/
struct wpa_scan_results {
struct wpa_scan_res **res;
size_t num;
struct os_time fetch_time;
};
/**
......@@ -902,6 +911,8 @@ struct hostapd_sta_add_params {
u32 flags; /* bitmask of WPA_STA_* flags */
int set; /* Set STA parameters instead of add */
u8 qosinfo;
const u8 *ext_capab;
size_t ext_capab_len;
};
struct hostapd_freq_params {
......@@ -3067,7 +3078,16 @@ enum wpa_event_type {
*
* This event can be used to request a WNM operation to be performed.
*/
EVENT_WNM
EVENT_WNM,
/**
* EVENT_CONNECT_FAILED_REASON - Connection failure reason in AP mode
*
* This event indicates that the driver reported a connection failure
* with the specified client (for example, max client reached, etc.) in
* AP mode.
*/
EVENT_CONNECT_FAILED_REASON
};
......@@ -3692,6 +3712,19 @@ union wpa_event_data {
int ht_enabled;
int ch_offset;
} ch_switch;
/**
* struct connect_failed - Data for EVENT_CONNECT_FAILED_REASON
* @addr: Remote client address
* @code: Reason code for connection failure
*/
struct connect_failed_reason {
u8 addr[ETH_ALEN];
enum {
MAX_CLIENT_REACHED,
BLOCKED_CLIENT
} code;
} connect_failed_reason;
};
/**
......
......@@ -79,6 +79,7 @@ const char * event_to_string(enum wpa_event_type event)
E2S(EAPOL_TX_STATUS);
E2S(CH_SWITCH);
E2S(WNM);
E2S(CONNECT_FAILED_REASON);
}
return "UNKNOWN";
......
......@@ -2162,6 +2162,43 @@ static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
}
static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
struct nlattr **tb)
{
union wpa_event_data data;
u32 reason;
wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
return;
os_memset(&data, 0, sizeof(data));
os_memcpy(data.connect_failed_reason.addr,
nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
switch (reason) {
case NL80211_CONN_FAIL_MAX_CLIENTS:
wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
data.connect_failed_reason.code = MAX_CLIENT_REACHED;
break;
case NL80211_CONN_FAIL_BLOCKED_CLIENT:
wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
" tried to connect",
MAC2STR(data.connect_failed_reason.addr));
data.connect_failed_reason.code = BLOCKED_CLIENT;
break;
default:
wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
"%u", reason);
return;
}
wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
}
static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
int wds)
{
......@@ -2299,6 +2336,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
case NL80211_CMD_TDLS_OPER:
nl80211_tdls_oper_event(drv, tb);
break;
case NL80211_CMD_CONN_FAILED:
nl80211_connect_failed_event(drv, tb);
break;
default:
wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
"(cmd=%d)", cmd);
......@@ -5798,6 +5838,8 @@ static int wpa_driver_nl80211_sta_add(void *priv,
if (!msg)
return -ENOMEM;
wpa_printf(MSG_DEBUG, "nl80211: %s STA " MACSTR,
params->set ? "Set" : "Add", MAC2STR(params->addr));
nl80211_cmd(drv, msg, 0, params->set ? NL80211_CMD_SET_STATION :
NL80211_CMD_NEW_STATION);
......@@ -5805,26 +5847,49 @@ static int wpa_driver_nl80211_sta_add(void *priv,
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);
NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,
params->supp_rates);
wpa_hexdump(MSG_DEBUG, " * supported rates", params->supp_rates,
params->supp_rates_len);
if (!params->set) {
wpa_printf(MSG_DEBUG, " * aid=%u", params->aid);
NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
wpa_printf(MSG_DEBUG, " * listen_interval=%u",
params->listen_interval);
NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
params->listen_interval);
}
if (params->ht_capabilities) {
wpa_hexdump(MSG_DEBUG, " * ht_capabilities",
(u8 *) params->ht_capabilities,
sizeof(*params->ht_capabilities));
NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,
sizeof(*params->ht_capabilities),
params->ht_capabilities);
}
if (params->vht_capabilities) {
wpa_hexdump(MSG_DEBUG, " * vht_capabilities",
(u8 *) params->vht_capabilities,
sizeof(*params->vht_capabilities));
NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY,
sizeof(*params->vht_capabilities),
params->vht_capabilities);
}
wpa_printf(MSG_DEBUG, " * capability=0x%x", params->capability);
NLA_PUT_U16(msg, NL80211_ATTR_STA_CAPABILITY, params->capability);
if (params->ext_capab) {
wpa_hexdump(MSG_DEBUG, " * ext_capab",
params->ext_capab, params->ext_capab_len);
NLA_PUT(msg, NL80211_ATTR_STA_EXT_CAPABILITY,
params->ext_capab_len, params->ext_capab);
}
os_memset(&upd, 0, sizeof(upd));
upd.mask = sta_flags_nl80211(params->flags);
upd.set = upd.mask;
wpa_printf(MSG_DEBUG, " * flags set=0x%x mask=0x%x",
upd.set, upd.mask);
NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
if (params->flags & WPA_STA_WMM) {
......@@ -5832,10 +5897,11 @@ static int wpa_driver_nl80211_sta_add(void *priv,
if (!wme)
goto nla_put_failure;
wpa_printf(MSG_DEBUG, " * qosinfo=0x%x", params->qosinfo);
NLA_PUT_U8(wme, NL80211_STA_WME_UAPSD_QUEUES,
params->qosinfo & WMM_QOSINFO_STA_AC_MASK);
NLA_PUT_U8(wme, NL80211_STA_WME_MAX_SP,
(params->qosinfo > WMM_QOSINFO_STA_SP_SHIFT) &
(params->qosinfo >> WMM_QOSINFO_STA_SP_SHIFT) &
WMM_QOSINFO_STA_SP_MASK);
if (nla_put_nested(msg, NL80211_ATTR_STA_WME, wme) < 0)
goto nla_put_failure;
......
......@@ -1318,11 +1318,12 @@ static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx)
if (drv->pending_p2p_scan && drv->p2p) {
#ifdef CONFIG_P2P
size_t i;
struct os_time now;
os_get_time(&now);
for (i = 0; i < drv->num_scanres; i++) {
struct wpa_scan_res *bss = drv->scanres[i];
if (p2p_scan_res_handler(drv->p2p, bss->bssid,
bss->freq, bss->age,
bss->level,
bss->freq, &now, bss->level,
(const u8 *) (bss + 1),
bss->ie_len) > 0)
return;
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment