P2P: Remove P2P group on driver resource becoming unavailable

Add a new driver event, EVENT_INTERFACE_UNAVAILABLE, for indicating
that the driver is not able to continue operating the virtual
interface in its current mode anymore, e.g., due to operating
channel for GO interface forced to a DFS channel by another virtual
interface.

When this happens for a P2P group interface, the P2P group will
be terminated and P2P-GROUP-REMOVED event shows the reason for
this as follows:
P2P-GROUP-REMOVED wlan0 GO reason=UNAVAILABLE
This commit is contained in:
Jouni Malinen 2010-10-25 19:16:11 +03:00 committed by Jouni Malinen
parent 129eb428b1
commit c973f3868a
5 changed files with 38 additions and 2 deletions

View file

@ -2212,7 +2212,21 @@ enum wpa_event_type {
* e.g., because of a regulatory domain change triggered by scan * e.g., because of a regulatory domain change triggered by scan
* results including an AP advertising a country code. * results including an AP advertising a country code.
*/ */
EVENT_CHANNEL_LIST_CHANGED EVENT_CHANNEL_LIST_CHANGED,
/**
* EVENT_INTERFACE_UNAVAILABLE - Notify that interface is unavailable
*
* This event is used to indicate that the driver cannot maintain this
* interface in its operation mode anymore. The most likely use for
* this is to indicate that AP mode operation is not available due to
* operating channel would need to be changed to a DFS channel when
* the driver does not support radar detection and another virtual
* interfaces caused the operating channel to change. Other similar
* resource conflicts could also trigger this for station mode
* interfaces.
*/
EVENT_INTERFACE_UNAVAILABLE
}; };

View file

@ -1837,6 +1837,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break; /* Ignore event during drv initialization */ break; /* Ignore event during drv initialization */
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
wpas_p2p_update_channel_list(wpa_s); wpas_p2p_update_channel_list(wpa_s);
#endif /* CONFIG_P2P */
break;
case EVENT_INTERFACE_UNAVAILABLE:
#ifdef CONFIG_P2P
wpas_p2p_interface_unavailable(wpa_s);
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
break; break;
default: default:

View file

@ -220,6 +220,9 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s)
case P2P_GROUP_REMOVAL_IDLE_TIMEOUT: case P2P_GROUP_REMOVAL_IDLE_TIMEOUT:
reason = " reason=IDLE"; reason = " reason=IDLE";
break; break;
case P2P_GROUP_REMOVAL_UNAVAILABLE:
reason = " reason=UNAVAILABLE";
break;
default: default:
reason = ""; reason = "";
break; break;
@ -3742,3 +3745,15 @@ int wpas_p2p_cancel(struct wpa_supplicant *wpa_s)
return 0; return 0;
} }
void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s)
{
if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
return;
wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not "
"being available anymore");
wpa_s->removal_reason = P2P_GROUP_REMOVAL_UNAVAILABLE;
wpas_p2p_group_delete(wpa_s);
}

View file

@ -117,5 +117,6 @@ void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s);
int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s); int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s);
void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s); void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s);
int wpas_p2p_cancel(struct wpa_supplicant *wpa_s); int wpas_p2p_cancel(struct wpa_supplicant *wpa_s);
void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s);
#endif /* P2P_SUPPLICANT_H */ #endif /* P2P_SUPPLICANT_H */

View file

@ -518,7 +518,8 @@ struct wpa_supplicant {
enum { enum {
P2P_GROUP_REMOVAL_UNKNOWN, P2P_GROUP_REMOVAL_UNKNOWN,
P2P_GROUP_REMOVAL_REQUESTED, P2P_GROUP_REMOVAL_REQUESTED,
P2P_GROUP_REMOVAL_IDLE_TIMEOUT P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
P2P_GROUP_REMOVAL_UNAVAILABLE
} removal_reason; } removal_reason;
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */