P2P: Add p2p_unauthorize command
authorSudhakar Swaminathan <Sudhakar.Swaminathan@Atheros.com>
Thu, 25 Nov 2010 11:09:50 +0000 (13:09 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 25 Nov 2010 11:09:50 +0000 (13:09 +0200)
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
src/p2p/p2p.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/wpa_cli.c

index 02fa35f..a088826 100644 (file)
@@ -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);
index 7c7f6c7..bab4939 100644 (file)
@@ -617,6 +617,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()
  * Returns: 0 on success, -1 on failure
index cfb8e9f..2a635dd 100644 (file)
@@ -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;
index ad9c849..a641858 100644 (file)
@@ -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);
+}
index d0221f2..7f59453 100644 (file)
@@ -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 */
index 7de05ee..2e2d3ab 100644 (file)
@@ -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,
+         "<address> = unauthorize a peer" },
        { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
          "[<duration> <interval>] [<duration> <interval>] = request GO "
          "presence" },