P2P: Remove P2P group on driver resource becoming unavailable
authorJouni Malinen <jouni.malinen@atheros.com>
Mon, 25 Oct 2010 16:16:11 +0000 (19:16 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 25 Oct 2010 16:16:11 +0000 (19:16 +0300)
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

src/drivers/driver.h
wpa_supplicant/events.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/wpa_supplicant_i.h

index 9a0b7be..4bdc13d 100644 (file)
@@ -2212,7 +2212,21 @@ enum wpa_event_type {
         * e.g., because of a regulatory domain change triggered by scan
         * 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
 };
 
 
index de030d2..c0d9935 100644 (file)
@@ -1839,6 +1839,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                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 */
+               break;
        default:
                wpa_printf(MSG_INFO, "Unknown event %d", event);
                break;
index 7a7524e..194a430 100644 (file)
@@ -220,6 +220,9 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s)
        case P2P_GROUP_REMOVAL_IDLE_TIMEOUT:
                reason = " reason=IDLE";
                break;
+       case P2P_GROUP_REMOVAL_UNAVAILABLE:
+               reason = " reason=UNAVAILABLE";
+               break;
        default:
                reason = "";
                break;
@@ -3742,3 +3745,15 @@ int wpas_p2p_cancel(struct wpa_supplicant *wpa_s)
 
        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);
+}
index 9b76b4a..a411c9a 100644 (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);
 void wpas_p2p_update_channel_list(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 */
index f5e80ba..a4d7511 100644 (file)
@@ -518,7 +518,8 @@ struct wpa_supplicant {
        enum {
                P2P_GROUP_REMOVAL_UNKNOWN,
                P2P_GROUP_REMOVAL_REQUESTED,
-               P2P_GROUP_REMOVAL_IDLE_TIMEOUT
+               P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
+               P2P_GROUP_REMOVAL_UNAVAILABLE
        } removal_reason;
 #endif /* CONFIG_P2P */