P2P: Add p2p_prov_disc auto mechanism
wpa_supplicant can now be requested to automatically figure out whether the indicated peer is operating as a GO and if so, use join-a-group style PD instead of pre-GO Negotiation PD. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
25a94f525c
commit
0918c4bf3b
6 changed files with 86 additions and 14 deletions
|
@ -101,7 +101,7 @@ Flush P2P peer table and state.
|
||||||
|
|
||||||
Group Formation
|
Group Formation
|
||||||
|
|
||||||
p2p_prov_disc <peer device address> <display|keypad|pbc> [join]
|
p2p_prov_disc <peer device address> <display|keypad|pbc> [join|auto]
|
||||||
|
|
||||||
Send P2P provision discovery request to the specified peer. The
|
Send P2P provision discovery request to the specified peer. The
|
||||||
parameters for this command are the P2P device address of the peer and
|
parameters for this command are the P2P device address of the peer and
|
||||||
|
@ -112,7 +112,10 @@ to enter a PIN that we display.
|
||||||
|
|
||||||
The optional "join" parameter can be used to indicate that this command
|
The optional "join" parameter can be used to indicate that this command
|
||||||
is requesting an already running GO to prepare for a new client. This is
|
is requesting an already running GO to prepare for a new client. This is
|
||||||
mainly used with "display" to request it to display a PIN.
|
mainly used with "display" to request it to display a PIN. The "auto"
|
||||||
|
parameter can be used to request wpa_supplicant to automatically figure
|
||||||
|
out whether the peer device is operating as a GO and if so, use
|
||||||
|
join-a-group style PD instead of GO Negotiation style PD.
|
||||||
|
|
||||||
p2p_connect <peer device address> <pbc|pin|PIN#> [display|keypad]
|
p2p_connect <peer device address> <pbc|pin|PIN#> [display|keypad]
|
||||||
[persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>]
|
[persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>]
|
||||||
|
|
|
@ -2946,8 +2946,9 @@ static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
{
|
{
|
||||||
u8 addr[ETH_ALEN];
|
u8 addr[ETH_ALEN];
|
||||||
char *pos;
|
char *pos;
|
||||||
|
enum wpas_p2p_prov_disc_use use = WPAS_P2P_PD_FOR_GO_NEG;
|
||||||
|
|
||||||
/* <addr> <config method> [join] */
|
/* <addr> <config method> [join|auto] */
|
||||||
|
|
||||||
if (hwaddr_aton(cmd, addr))
|
if (hwaddr_aton(cmd, addr))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2957,8 +2958,12 @@ static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
return -1;
|
return -1;
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
return wpas_p2p_prov_disc(wpa_s, addr, pos,
|
if (os_strstr(pos, " join") != NULL)
|
||||||
os_strstr(pos, "join") != NULL);
|
use = WPAS_P2P_PD_FOR_JOIN;
|
||||||
|
else if (os_strstr(pos, " auto") != NULL)
|
||||||
|
use = WPAS_P2P_PD_AUTO;
|
||||||
|
|
||||||
|
return wpas_p2p_prov_disc(wpa_s, addr, pos, use);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -692,7 +692,8 @@ DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
|
||||||
os_strcmp(config_method, "pushbutton"))
|
os_strcmp(config_method, "pushbutton"))
|
||||||
return wpas_dbus_error_invalid_args(message, NULL);
|
return wpas_dbus_error_invalid_args(message, NULL);
|
||||||
|
|
||||||
if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method, 0) < 0)
|
if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method,
|
||||||
|
WPAS_P2P_PD_FOR_GO_NEG) < 0)
|
||||||
return wpas_dbus_error_unknown_error(message,
|
return wpas_dbus_error_unknown_error(message,
|
||||||
"Failed to send provision discovery request");
|
"Failed to send provision discovery request");
|
||||||
|
|
||||||
|
|
|
@ -1821,6 +1821,7 @@ void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
|
||||||
{
|
{
|
||||||
struct wpa_supplicant *wpa_s = ctx;
|
struct wpa_supplicant *wpa_s = ctx;
|
||||||
unsigned int generated_pin = 0;
|
unsigned int generated_pin = 0;
|
||||||
|
char params[20];
|
||||||
|
|
||||||
if (wpa_s->pending_pd_before_join &&
|
if (wpa_s->pending_pd_before_join &&
|
||||||
(os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
|
(os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
|
||||||
|
@ -1832,14 +1833,22 @@ void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wpa_s->pending_pd_use == AUTO_PD_JOIN ||
|
||||||
|
wpa_s->pending_pd_use == AUTO_PD_GO_NEG)
|
||||||
|
os_snprintf(params, sizeof(params), " peer_go=%d",
|
||||||
|
wpa_s->pending_pd_use == AUTO_PD_JOIN);
|
||||||
|
else
|
||||||
|
params[0] = '\0';
|
||||||
|
|
||||||
if (config_methods & WPS_CONFIG_DISPLAY)
|
if (config_methods & WPS_CONFIG_DISPLAY)
|
||||||
wpas_prov_disc_local_keypad(wpa_s, peer, "");
|
wpas_prov_disc_local_keypad(wpa_s, peer, params);
|
||||||
else if (config_methods & WPS_CONFIG_KEYPAD) {
|
else if (config_methods & WPS_CONFIG_KEYPAD) {
|
||||||
generated_pin = wps_generate_pin();
|
generated_pin = wps_generate_pin();
|
||||||
wpas_prov_disc_local_display(wpa_s, peer, "", generated_pin);
|
wpas_prov_disc_local_display(wpa_s, peer, params,
|
||||||
|
generated_pin);
|
||||||
} else if (config_methods & WPS_CONFIG_PUSHBUTTON)
|
} else if (config_methods & WPS_CONFIG_PUSHBUTTON)
|
||||||
wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP MACSTR,
|
wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP MACSTR
|
||||||
MAC2STR(peer));
|
"%s", MAC2STR(peer), params);
|
||||||
|
|
||||||
wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
|
wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
|
||||||
P2P_PROV_DISC_SUCCESS,
|
P2P_PROV_DISC_SUCCESS,
|
||||||
|
@ -2595,6 +2604,13 @@ static void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s)
|
||||||
" for join operationg - stop join attempt",
|
" for join operationg - stop join attempt",
|
||||||
MAC2STR(wpa_s->pending_join_iface_addr));
|
MAC2STR(wpa_s->pending_join_iface_addr));
|
||||||
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
|
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
|
||||||
|
if (wpa_s->p2p_auto_pd) {
|
||||||
|
wpa_s->p2p_auto_pd = 0;
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
|
||||||
|
" p2p_dev_addr=" MACSTR " status=N/A",
|
||||||
|
MAC2STR(wpa_s->pending_join_dev_addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
wpa_msg(wpa_s->parent, MSG_INFO,
|
wpa_msg(wpa_s->parent, MSG_INFO,
|
||||||
P2P_EVENT_GROUP_FORMATION_FAILURE);
|
P2P_EVENT_GROUP_FORMATION_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -2702,6 +2718,25 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
|
||||||
if (scan_res)
|
if (scan_res)
|
||||||
wpas_p2p_scan_res_handler(wpa_s, scan_res);
|
wpas_p2p_scan_res_handler(wpa_s, scan_res);
|
||||||
|
|
||||||
|
if (wpa_s->p2p_auto_pd) {
|
||||||
|
int join = wpas_p2p_peer_go(wpa_s,
|
||||||
|
wpa_s->pending_join_dev_addr);
|
||||||
|
wpa_s->p2p_auto_pd = 0;
|
||||||
|
wpa_s->pending_pd_use = join ? AUTO_PD_JOIN : AUTO_PD_GO_NEG;
|
||||||
|
wpa_printf(MSG_DEBUG, "P2P: Auto PD with " MACSTR " join=%d",
|
||||||
|
MAC2STR(wpa_s->pending_join_dev_addr), join);
|
||||||
|
if (p2p_prov_disc_req(wpa_s->global->p2p,
|
||||||
|
wpa_s->pending_join_dev_addr,
|
||||||
|
wpa_s->pending_pd_config_methods, join,
|
||||||
|
0) < 0) {
|
||||||
|
wpa_s->p2p_auto_pd = 0;
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
|
||||||
|
" p2p_dev_addr=" MACSTR " status=N/A",
|
||||||
|
MAC2STR(wpa_s->pending_join_dev_addr));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (wpa_s->p2p_auto_join) {
|
if (wpa_s->p2p_auto_join) {
|
||||||
if (!wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr)) {
|
if (!wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr)) {
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be "
|
wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be "
|
||||||
|
@ -2898,6 +2933,7 @@ static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
|
||||||
MAC2STR(iface_addr), MAC2STR(dev_addr),
|
MAC2STR(iface_addr), MAC2STR(dev_addr),
|
||||||
auto_join ? " (auto_join)" : "");
|
auto_join ? " (auto_join)" : "");
|
||||||
|
|
||||||
|
wpa_s->p2p_auto_pd = 0;
|
||||||
wpa_s->p2p_auto_join = !!auto_join;
|
wpa_s->p2p_auto_join = !!auto_join;
|
||||||
os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN);
|
os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN);
|
||||||
os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN);
|
os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN);
|
||||||
|
@ -3666,10 +3702,12 @@ void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
|
|
||||||
int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
||||||
const char *config_method, int join)
|
const char *config_method,
|
||||||
|
enum wpas_p2p_prov_disc_use use)
|
||||||
{
|
{
|
||||||
u16 config_methods;
|
u16 config_methods;
|
||||||
|
|
||||||
|
wpa_s->pending_pd_use = NORMAL_PD;
|
||||||
if (os_strncmp(config_method, "display", 7) == 0)
|
if (os_strncmp(config_method, "display", 7) == 0)
|
||||||
config_methods = WPS_CONFIG_DISPLAY;
|
config_methods = WPS_CONFIG_DISPLAY;
|
||||||
else if (os_strncmp(config_method, "keypad", 6) == 0)
|
else if (os_strncmp(config_method, "keypad", 6) == 0)
|
||||||
|
@ -3682,16 +3720,30 @@ int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use == WPAS_P2P_PD_AUTO) {
|
||||||
|
os_memcpy(wpa_s->pending_join_dev_addr, peer_addr, ETH_ALEN);
|
||||||
|
wpa_s->pending_pd_config_methods = config_methods;
|
||||||
|
wpa_s->p2p_auto_pd = 1;
|
||||||
|
wpa_s->p2p_auto_join = 0;
|
||||||
|
wpa_s->pending_pd_before_join = 0;
|
||||||
|
wpas_p2p_stop_find(wpa_s);
|
||||||
|
wpa_s->p2p_join_scan_count = 0;
|
||||||
|
wpas_p2p_join_scan(wpa_s, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) {
|
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) {
|
||||||
return wpa_drv_p2p_prov_disc_req(wpa_s, peer_addr,
|
return wpa_drv_p2p_prov_disc_req(wpa_s, peer_addr,
|
||||||
config_methods, join);
|
config_methods,
|
||||||
|
use == WPAS_P2P_PD_FOR_JOIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
|
if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr,
|
return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr,
|
||||||
config_methods, join, 0);
|
config_methods, use == WPAS_P2P_PD_FOR_JOIN,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,14 @@ struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
|
||||||
int group_formation);
|
int group_formation);
|
||||||
void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
||||||
int registrar);
|
int registrar);
|
||||||
|
enum wpas_p2p_prov_disc_use {
|
||||||
|
WPAS_P2P_PD_FOR_GO_NEG,
|
||||||
|
WPAS_P2P_PD_FOR_JOIN,
|
||||||
|
WPAS_P2P_PD_AUTO
|
||||||
|
};
|
||||||
int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
||||||
const char *config_method, int join);
|
const char *config_method,
|
||||||
|
enum wpas_p2p_prov_disc_use use);
|
||||||
void wpas_send_action_tx_status(struct wpa_supplicant *wpa_s, const u8 *dst,
|
void wpas_send_action_tx_status(struct wpa_supplicant *wpa_s, const u8 *dst,
|
||||||
const u8 *data, size_t data_len,
|
const u8 *data, size_t data_len,
|
||||||
enum p2p_send_action_result result);
|
enum p2p_send_action_result result);
|
||||||
|
|
|
@ -477,6 +477,10 @@ struct wpa_supplicant {
|
||||||
int pending_join_wps_method;
|
int pending_join_wps_method;
|
||||||
int p2p_join_scan_count;
|
int p2p_join_scan_count;
|
||||||
int force_long_sd;
|
int force_long_sd;
|
||||||
|
u16 pending_pd_config_methods;
|
||||||
|
enum {
|
||||||
|
NORMAL_PD, AUTO_PD_GO_NEG, AUTO_PD_JOIN
|
||||||
|
} pending_pd_use;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Whether cross connection is disallowed by the AP to which this
|
* Whether cross connection is disallowed by the AP to which this
|
||||||
|
@ -509,6 +513,7 @@ struct wpa_supplicant {
|
||||||
|
|
||||||
unsigned int p2p_cb_on_scan_complete:1;
|
unsigned int p2p_cb_on_scan_complete:1;
|
||||||
unsigned int p2p_auto_join:1;
|
unsigned int p2p_auto_join:1;
|
||||||
|
unsigned int p2p_auto_pd:1;
|
||||||
unsigned int p2p_persistent_group:1;
|
unsigned int p2p_persistent_group:1;
|
||||||
int p2p_go_intent;
|
int p2p_go_intent;
|
||||||
int p2p_connect_freq;
|
int p2p_connect_freq;
|
||||||
|
|
Loading…
Reference in a new issue