From c64e3a08a92cdc0765b004a028e8e1071b1087db Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 1 Jan 2014 18:44:44 +0200 Subject: [PATCH] P2P: Send received Presence Response information to ctrl_iface monitors The P2P_PRESENCE_REQ command did not give any easily available indication of the response received from the GO. Make this more useful by providing such response (if received) as a ctrl_iface monitor event (P2P-PRESENCE-RESPONSE). Signed-hostap: Jouni Malinen --- src/common/wpa_ctrl.h | 1 + src/p2p/p2p.c | 5 +++++ src/p2p/p2p.h | 11 +++++++++ wpa_supplicant/README-P2P | 6 +++-- wpa_supplicant/p2p_supplicant.c | 37 ++++++++++++++++++++++++++++--- wpa_supplicant/wpa_supplicant_i.h | 1 + 6 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index 1c9588164..030df130d 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -147,6 +147,7 @@ extern "C" { #define P2P_EVENT_INVITATION_RESULT "P2P-INVITATION-RESULT " #define P2P_EVENT_FIND_STOPPED "P2P-FIND-STOPPED " #define P2P_EVENT_PERSISTENT_PSK_FAIL "P2P-PERSISTENT-PSK-FAIL id=" +#define P2P_EVENT_PRESENCE_RESPONSE "P2P-PRESENCE-RESPONSE " /* parameters: */ #define ESS_DISASSOC_IMMINENT "ESS-DISASSOC-IMMINENT " diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 23b74c0eb..2a13736cd 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -3770,6 +3770,11 @@ static void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, return; } + if (p2p->cfg->presence_resp) { + p2p->cfg->presence_resp(p2p->cfg->cb_ctx, sa, *msg.status, + msg.noa, msg.noa_len); + } + if (*msg.status) { p2p_dbg(p2p, "P2P Presence Request was rejected: status %u", *msg.status); diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index bff78ef99..f35a2363e 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -778,6 +778,17 @@ struct p2p_config { * or 0 if not. */ int (*go_connected)(void *ctx, const u8 *dev_addr); + + /** + * presence_resp - Callback on Presence Response + * @ctx: Callback context from cb_ctx + * @src: Source address (GO's P2P Interface Address) + * @status: Result of the request (P2P_SC_*) + * @noa: Returned NoA value + * @noa_len: Length of the NoA buffer in octets + */ + void (*presence_resp)(void *ctx, const u8 *src, u8 status, + const u8 *noa, size_t noa_len); }; diff --git a/wpa_supplicant/README-P2P b/wpa_supplicant/README-P2P index ffc2baf06..08d39e246 100644 --- a/wpa_supplicant/README-P2P +++ b/wpa_supplicant/README-P2P @@ -418,9 +418,11 @@ p2p_presence_req [ ] [ ] Send a P2P Presence Request to the GO (this is only available when acting as a P2P client). If no duration/interval pairs are given, the request indicates that this client has no special needs for GO -presence. the first parameter pair gives the preferred duration and +presence. The first parameter pair gives the preferred duration and interval values in microseconds. If the second pair is included, that -indicates which value would be acceptable. +indicates which value would be acceptable. This command returns OK +immediately and the response from the GO is indicated in a +P2P-PRESENCE-RESPONSE event message. Parameters diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index c01c68401..a71cbbec9 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -489,6 +489,8 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s, os_free(wpa_s->go_params); wpa_s->go_params = NULL; + wpa_s->waiting_presence_resp = 0; + wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network"); if (ssid && (ssid->p2p_group || ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION || @@ -3364,6 +3366,28 @@ int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s) } +static void wpas_presence_resp(void *ctx, const u8 *src, u8 status, + const u8 *noa, size_t noa_len) +{ + struct wpa_supplicant *wpa_s, *intf = ctx; + char hex[100]; + + for (wpa_s = intf->global->ifaces; wpa_s; wpa_s = wpa_s->next) { + if (wpa_s->waiting_presence_resp) + break; + } + if (!wpa_s) { + wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No group interface was waiting for presence response"); + return; + } + wpa_s->waiting_presence_resp = 0; + + wpa_snprintf_hex(hex, sizeof(hex), noa, noa_len); + wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PRESENCE_RESPONSE "src=" MACSTR + " status=%u noa=%s", MAC2STR(src), status, hex); +} + + /** * wpas_p2p_init - Initialize P2P module for %wpa_supplicant * @global: Pointer to global data from wpa_supplicant_init() @@ -3409,6 +3433,7 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) p2p.invitation_result = wpas_invitation_result; p2p.get_noa = wpas_get_noa; p2p.go_connected = wpas_go_connected; + p2p.presence_resp = wpas_presence_resp; os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN); os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN); @@ -5434,6 +5459,8 @@ done: int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1, u32 interval1, u32 duration2, u32 interval2) { + int ret; + if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) return -1; @@ -5442,9 +5469,13 @@ int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1, wpa_s->current_ssid->mode != WPAS_MODE_INFRA) return -1; - return p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid, - wpa_s->own_addr, wpa_s->assoc_freq, - duration1, interval1, duration2, interval2); + ret = p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid, + wpa_s->own_addr, wpa_s->assoc_freq, + duration1, interval1, duration2, interval2); + if (ret == 0) + wpa_s->waiting_presence_resp = 1; + + return ret; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 29ed02418..2e3f24494 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -663,6 +663,7 @@ struct wpa_supplicant { unsigned int p2p_go_vht:1; unsigned int user_initiated_pd:1; unsigned int p2p_go_group_formation_completed:1; + unsigned int waiting_presence_resp; int p2p_first_connection_timeout; int p2p_persistent_go_freq; int p2p_persistent_id;