From 57b38882e5f6fffa96c3397ba2c2436a872354df Mon Sep 17 00:00:00 2001 From: Purushottam Kushwaha Date: Wed, 13 Apr 2016 11:00:08 +0530 Subject: [PATCH] P2P: Add P2P_GROUP_MEMBER command to fetch client interface address This allows local GO to fetch the P2P Interface Address of a P2P Client in the group based on the P2P Device Address for the client. This command should be sent only on a group interface (the same peer may be in multiple concurrent groups). Usage: P2P_GROUP_MEMBER Output: Signed-off-by: Purushottam Kushwaha --- src/p2p/p2p.h | 10 ++++++++++ src/p2p/p2p_group.c | 14 ++++++++++++++ wpa_supplicant/ctrl_iface.c | 27 +++++++++++++++++++++++++++ wpa_supplicant/wpa_cli.c | 10 ++++++++++ 4 files changed, 61 insertions(+) diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 0feafd3..186af36 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -2133,6 +2133,16 @@ int p2p_client_limit_reached(struct p2p_group *group); const u8 * p2p_iterate_group_members(struct p2p_group *group, void **next); /** + * p2p_group_get_client_interface_addr - Get P2P Interface Address of a client in a group + * @group: P2P group context from p2p_group_init() + * @dev_addr: P2P Device Address of the client + * Returns: P2P Interface Address of the client if found or %NULL if no match + * found + */ +const u8 * p2p_group_get_client_interface_addr(struct p2p_group *group, + const u8 *dev_addr); + +/** * p2p_group_get_dev_addr - Get a P2P Device Address of a client in a group * @group: P2P group context from p2p_group_init() * @addr: P2P Interface Address of the client diff --git a/src/p2p/p2p_group.c b/src/p2p/p2p_group.c index eac73ef..3aed6bd 100644 --- a/src/p2p/p2p_group.c +++ b/src/p2p/p2p_group.c @@ -850,6 +850,20 @@ static struct p2p_group_member * p2p_group_get_client(struct p2p_group *group, } +const u8 * p2p_group_get_client_interface_addr(struct p2p_group *group, + const u8 *dev_addr) +{ + struct p2p_group_member *m; + + if (!group) + return NULL; + m = p2p_group_get_client(group, dev_addr); + if (m) + return m->addr; + return NULL; +} + + static struct p2p_group_member * p2p_group_get_client_iface( struct p2p_group *group, const u8 *interface_addr) { diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 3c97819..9251ceb 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5834,6 +5834,29 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) } +static int p2p_ctrl_group_member(struct wpa_supplicant *wpa_s, const char *cmd, + char *buf, size_t buflen) +{ + u8 dev_addr[ETH_ALEN]; + struct wpa_ssid *ssid; + int res; + const u8 *iaddr; + + ssid = wpa_s->current_ssid; + if (!wpa_s->global->p2p || !ssid || ssid->mode != WPAS_MODE_P2P_GO || + hwaddr_aton(cmd, dev_addr)) + return -1; + + iaddr = p2p_group_get_client_interface_addr(wpa_s->p2p_group, dev_addr); + if (!iaddr) + return -1; + res = os_snprintf(buf, buflen, MACSTR, MAC2STR(iaddr)); + if (os_snprintf_error(buflen, res)) + return -1; + return res; +} + + static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) { @@ -8808,6 +8831,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) { if (p2p_ctrl_group_add(wpa_s, buf + 14)) reply_len = -1; + } else if (os_strncmp(buf, "P2P_GROUP_MEMBER ", 17) == 0) { + reply_len = p2p_ctrl_group_member(wpa_s, buf + 17, reply, + reply_size); } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) { if (p2p_ctrl_prov_disc(wpa_s, buf + 14)) reply_len = -1; @@ -9552,6 +9578,7 @@ static char * wpas_global_ctrl_iface_redir_p2p(struct wpa_global *global, "P2P_LISTEN ", "P2P_GROUP_REMOVE ", "P2P_GROUP_ADD ", + "P2P_GROUP_MEMBER ", "P2P_PROV_DISC ", "P2P_SERV_DISC_REQ ", "P2P_SERV_DISC_CANCEL_REQ ", diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 7099fb3..ca2673b 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -2175,6 +2175,13 @@ static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, } +static int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv); +} + + static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -3253,6 +3260,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { " = remove P2P group interface (terminate group if GO)" }, { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none, "[ht40] = add a new P2P group (local end as GO)" }, + { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL, + cli_cmd_flag_none, + " = Get peer interface address on local GO using peer Device Address" }, { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, wpa_cli_complete_p2p_peer, cli_cmd_flag_none, " = request provisioning discovery" }, -- 2.1.4