diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index ae496ff54..f9e504357 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -377,7 +377,10 @@ struct wpa_config { * stations in the group. As a P2P client, this means no GO seen in * scan results. The maximum idle time is specified in seconds with 0 * indicating no time limit, i.e., the P2P group remains in active - * state indefinitely until explicitly removed. + * state indefinitely until explicitly removed. As a P2P client, the + * maximum idle time of P2P_MAX_CLIENT_IDLE seconds is enforced, i.e., + * this parameter is mainly meant for GO use and for P2P client, it can + * only be used to reduce the default timeout to smaller value. */ unsigned int p2p_group_idle; diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 80f7afdfd..7cf37d079 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -45,6 +45,14 @@ */ #define P2P_MAX_JOIN_SCAN_ATTEMPTS 10 +#ifndef P2P_MAX_CLIENT_IDLE +/* + * How many seconds to try to reconnect to the GO when connection in P2P client + * role has been lost. + */ +#define P2P_MAX_CLIENT_IDLE 10 +#endif /* P2P_MAX_CLIENT_IDLE */ + static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx); static struct wpa_supplicant * @@ -3743,11 +3751,19 @@ int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period, } +static int wpas_p2p_is_client(struct wpa_supplicant *wpa_s) +{ + return wpa_s->current_ssid != NULL && + wpa_s->current_ssid->p2p_group && + wpa_s->current_ssid->mode == WPAS_MODE_INFRA; +} + + static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; - if (wpa_s->conf->p2p_group_idle == 0) { + if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) { wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - " "disabled"); return; @@ -3762,17 +3778,24 @@ static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx) static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s) { - eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL); - if (wpa_s->conf->p2p_group_idle == 0) - return; + unsigned int timeout; + eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL); if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group) return; + timeout = wpa_s->conf->p2p_group_idle; + if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA && + (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE)) + timeout = P2P_MAX_CLIENT_IDLE; + + if (timeout == 0) + return; + wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds", - wpa_s->conf->p2p_group_idle); - eloop_register_timeout(wpa_s->conf->p2p_group_idle, 0, - wpas_p2p_group_idle_timeout, wpa_s, NULL); + timeout); + eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout, + wpa_s, NULL); }