From 9d562b7946b6485dd88d303d82cdb21821f618ea Mon Sep 17 00:00:00 2001 From: Sudhakar Swaminathan Date: Thu, 25 Nov 2010 13:09:50 +0200 Subject: [PATCH] P2P: Add p2p_unauthorize command This can be used to remove authorization from a previous p2p_connect commands that has not yet resulted in completed GO Negotiation. --- src/p2p/p2p.c | 29 +++++++++++++++++++++++++++++ src/p2p/p2p.h | 13 +++++++++++++ wpa_supplicant/ctrl_iface.c | 3 +++ wpa_supplicant/p2p_supplicant.c | 15 +++++++++++++++ wpa_supplicant/p2p_supplicant.h | 1 + wpa_supplicant/wpa_cli.c | 24 ++++++++++++++++++++++++ 6 files changed, 85 insertions(+) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 02fa35ffb..a088826b6 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1925,6 +1925,35 @@ void p2p_flush(struct p2p_data *p2p) } +int p2p_unauthorize(struct p2p_data *p2p, const u8 *addr) +{ + struct p2p_device *dev; + + dev = p2p_get_device(p2p, addr); + if (dev == NULL) + return -1; + + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unauthorizing " MACSTR, + MAC2STR(addr)); + + if (p2p->go_neg_peer == dev) + p2p->go_neg_peer = NULL; + + dev->wps_method = WPS_NOT_READY; + dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; + dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; + + /* Check if after_scan_tx is for this peer. If so free it */ + if (p2p->after_scan_tx && + os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) { + os_free(p2p->after_scan_tx); + p2p->after_scan_tx = NULL; + } + + return 0; +} + + int p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name) { os_free(p2p->cfg->dev_name); diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 7c7f6c754..bab4939a2 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -616,6 +616,19 @@ void p2p_deinit(struct p2p_data *p2p); */ void p2p_flush(struct p2p_data *p2p); +/** + * p2p_unauthorize - Unauthorize the specified peer device + * @p2p: P2P module context from p2p_init() + * @addr: P2P peer entry to be unauthorized + * Returns: 0 on success, -1 on failure + * + * This command removes any connection authorization from the specified P2P + * peer device address. This can be used, e.g., to cancel effect of a previous + * p2p_authorize() or p2p_connect() call that has not yet resulted in completed + * GO Negotiation. + */ +int p2p_unauthorize(struct p2p_data *p2p, const u8 *addr); + /** * p2p_set_dev_name - Set device name * @p2p: P2P module context from p2p_init() diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index cfb8e9f83..2a635dd36 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -2990,6 +2990,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_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) { + if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0) + reply_len = -1; } else if (os_strcmp(buf, "P2P_CANCEL") == 0) { if (wpas_p2p_cancel(wpa_s)) reply_len = -1; diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index ad9c849c4..a64185894 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -3985,3 +3985,18 @@ void wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s, return; p2p_set_best_channels(p2p, freq_24, freq_5, freq_overall); } + + +int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr) +{ + u8 peer[ETH_ALEN]; + struct p2p_data *p2p = wpa_s->global->p2p; + + if (p2p == NULL || (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)) + return -1; + + if (hwaddr_aton(addr, peer)) + return -1; + + return p2p_unauthorize(p2p, peer); +} diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index d0221f221..7f5945318 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -120,5 +120,6 @@ int wpas_p2p_cancel(struct wpa_supplicant *wpa_s); void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s); void wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s, int freq_24, int freq_5, int freq_overall); +int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr); #endif /* P2P_SUPPLICANT_H */ diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 7de05eeb3..2e2d3ab12 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -2044,6 +2044,28 @@ static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, } +static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char cmd[100]; + int res; + + if (argc != 1) { + printf("Invalid P2P_UNAUTHORIZE command: needs one argument " + "(peer address)\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]); + + if (res < 0 || (size_t) res >= sizeof(cmd)) + return -1; + + cmd[sizeof(cmd) - 1] = '\0'; + return wpa_ctrl_command(ctrl, cmd); +} + + static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -2407,6 +2429,8 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { "= flush P2P state" }, { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none, "= cancel P2P group formation" }, + { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none, + "
= unauthorize a peer" }, { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none, "[ ] [ ] = request GO " "presence" },