diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 6c7b56150..75c78ee0a 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -2884,6 +2884,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); wpa_s->force_long_sd = 0; p2p_flush(wpa_s->global->p2p); + } else if (os_strcmp(buf, "P2P_CANCEL") == 0) { + if (wpas_p2p_cancel(wpa_s)) + reply_len = -1; } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) { if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0) reply_len = -1; diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 4a17a79f1..63b7ea938 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -3628,3 +3628,37 @@ void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s) p2p_update_channel_list(wpa_s->global->p2p, &chan); } + + +int wpas_p2p_cancel(struct wpa_supplicant *wpa_s) +{ + struct wpa_global *global = wpa_s->global; + int found = 0; + + wpa_printf(MSG_DEBUG, "P2P: Request to cancel group formation"); + + if (wpa_s->pending_interface_name[0] && + !is_zero_ether_addr(wpa_s->pending_interface_addr)) + found = 1; + + wpas_p2p_stop_find(wpa_s); + + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { + if (wpa_s == global->p2p_group_formation && + wpa_s->p2p_in_provisioning) { + wpa_printf(MSG_DEBUG, "P2P: Interface %s in group " + "formation found - cancelling", + wpa_s->ifname); + found = 1; + wpas_p2p_group_delete(wpa_s); + break; + } + } + + if (!found) { + wpa_printf(MSG_DEBUG, "P2P: No ongoing group formation found"); + return -1; + } + + return 0; +} diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index e5b2964ae..9b76b4a6e 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -116,5 +116,6 @@ void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s); void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s); int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s); void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s); +int wpas_p2p_cancel(struct wpa_supplicant *wpa_s); #endif /* P2P_SUPPLICANT_H */ diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 00fb0dcca..587b8af0e 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -2055,6 +2055,13 @@ static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_ctrl_command(ctrl, "P2P_CANCEL"); +} + + static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -2407,6 +2414,8 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { " = set a P2P parameter" }, { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none, "= flush P2P state" }, + { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none, + "= cancel P2P group formation" }, { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none, "[ ] [ ] = request GO " "presence" },