]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS ER: Delay wpa_supplicant termination to allow unsubscription
authorJouni Malinen <j@w1.fi>
Sat, 19 Dec 2009 21:47:54 +0000 (23:47 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 19 Dec 2009 21:47:54 +0000 (23:47 +0200)
Instead of forcefully deinitializing ER immediately, give it some
time to complete unsubscription and call eloop_terminate() only once
ER code has completed its work.

src/wps/wps.h
src/wps/wps_er.c
src/wps/wps_er.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h
wpa_supplicant/wps_supplicant.c
wpa_supplicant/wps_supplicant.h

index 8d6c1a615e81ba995eab7e8897841e5de99dfed2..7fc16d95ecc020208a849378254a39a84fc3394e 100644 (file)
@@ -674,7 +674,7 @@ int wps_attr_text(struct wpabuf *data, char *buf, char *end);
 
 struct wps_er * wps_er_init(struct wps_context *wps, const char *ifname);
 void wps_er_refresh(struct wps_er *er);
-void wps_er_deinit(struct wps_er *er);
+void wps_er_deinit(struct wps_er *er, void (*cb)(void *ctx), void *ctx);
 void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
                        u16 sel_reg_config_methods);
 int wps_er_pbc(struct wps_er *er, const u8 *uuid);
index 780fddd32699c2354cef26a31dead61a75b89cfb..3eed6e9f4ec30b767c5875f1ae97cf3b8071ffea 100644 (file)
@@ -1161,19 +1161,19 @@ wps_er_init(struct wps_context *wps, const char *ifname)
                           er->mac_addr, &er->mac_addr_text)) {
                wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "
                           "for %s. Does it have IP address?", ifname);
-               wps_er_deinit(er);
+               wps_er_deinit(er, NULL, NULL);
                return NULL;
        }
 
        if (wps_er_ssdp_init(er) < 0) {
-               wps_er_deinit(er);
+               wps_er_deinit(er, NULL, NULL);
                return NULL;
        }
 
        addr.s_addr = er->ip_addr;
        er->http_srv = http_server_init(&addr, -1, wps_er_http_req, er);
        if (er->http_srv == NULL) {
-               wps_er_deinit(er);
+               wps_er_deinit(er, NULL, NULL);
                return NULL;
        }
        er->http_port = http_server_get_port(er->http_srv);
@@ -1204,23 +1204,35 @@ void wps_er_refresh(struct wps_er *er)
 static void wps_er_deinit_finish(void *eloop_data, void *user_ctx)
 {
        struct wps_er *er = eloop_data;
+       void (*deinit_done_cb)(void *ctx);
+       void *deinit_done_ctx;
+
        wpa_printf(MSG_DEBUG, "WPS ER: Finishing deinit");
+
+       deinit_done_cb = er->deinit_done_cb;
+       deinit_done_ctx = er->deinit_done_ctx;
        os_free(er->ip_addr_text);
        os_free(er->mac_addr_text);
        os_free(er);
+
+       if (deinit_done_cb)
+               deinit_done_cb(deinit_done_ctx);
 }
 
 
-void wps_er_deinit(struct wps_er *er)
+void wps_er_deinit(struct wps_er *er, void (*cb)(void *ctx), void *ctx)
 {
        if (er == NULL)
                return;
        http_server_deinit(er->http_srv);
        wps_er_ap_remove_all(er);
        wps_er_ssdp_deinit(er);
-       eloop_register_timeout(5, 0, wps_er_deinit_finish, er, NULL);
+       eloop_register_timeout(dl_list_empty(&er->ap_unsubscribing) ? 0 : 5, 0,
+                              wps_er_deinit_finish, er, NULL);
        wpa_printf(MSG_DEBUG, "WPS ER: Finish deinit from timeout");
        er->deinitializing = 1;
+       er->deinit_done_cb = cb;
+       er->deinit_done_ctx = ctx;
 }
 
 
index 4bf6b3ade68b6e3a588c745fa767f3fb1c1c7d66..7719b7dadae6fc666d2a80df31d15fc80f69b081 100644 (file)
@@ -88,6 +88,8 @@ struct wps_er {
        unsigned int next_ap_id;
        unsigned int event_id;
        int deinitializing;
+       void (*deinit_done_cb)(void *ctx);
+       void *deinit_done_ctx;
 };
 
 
index d19500d6bb814d7ec1097ad0f52852a37f6dc70c..559cbe5aeb981ed0c7e3114ae98468aeb94cfcb4 100644 (file)
@@ -1714,7 +1714,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                if (wpa_supplicant_reload_configuration(wpa_s))
                        reply_len = -1;
        } else if (os_strcmp(buf, "TERMINATE") == 0) {
-               eloop_terminate();
+               wpa_supplicant_terminate_proc(wpa_s->global);
        } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
                if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
                        reply_len = -1;
@@ -2007,7 +2007,7 @@ char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
                reply_len = wpa_supplicant_global_iface_interfaces(
                        global, reply, reply_size);
        } else if (os_strcmp(buf, "TERMINATE") == 0) {
-               eloop_terminate();
+               wpa_supplicant_terminate_proc(global);
        } else {
                os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
                reply_len = 16;
index df7d1d557084611e7db038cff156903ff18b4c31..cfe99e86859a15ff705c853c1c1859b3a2345a4a 100644 (file)
@@ -546,6 +546,23 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state)
 }
 
 
+void wpa_supplicant_terminate_proc(struct wpa_global *global)
+{
+       int pending = 0;
+#ifdef CONFIG_WPS
+       struct wpa_supplicant *wpa_s = global->ifaces;
+       while (wpa_s) {
+               if (wpas_wps_terminate_pending(wpa_s) == 1)
+                       pending = 1;
+               wpa_s = wpa_s->next;
+       }
+#endif /* CONFIG_WPS */
+       if (pending)
+               return;
+       eloop_terminate();
+}
+
+
 static void wpa_supplicant_terminate(int sig, void *signal_ctx)
 {
        struct wpa_global *global = signal_ctx;
@@ -554,7 +571,7 @@ static void wpa_supplicant_terminate(int sig, void *signal_ctx)
                wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING "- signal %d "
                        "received", sig);
        }
-       eloop_terminate();
+       wpa_supplicant_terminate_proc(global);
 }
 
 
@@ -653,7 +670,7 @@ static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
        wpa_printf(MSG_DEBUG, "Signal %d received - reconfiguring", sig);
        for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
                if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
-                       eloop_terminate();
+                       wpa_supplicant_terminate_proc(global);
                }
        }
 }
index 377f4c82baca437fa84aab475811744f0d528b0a..77142b29efa26e11423c38f39e25fd2206976a1c 100644 (file)
@@ -478,6 +478,7 @@ void wpa_supplicant_deinit(struct wpa_global *global);
 
 int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
                              struct wpa_ssid *ssid);
+void wpa_supplicant_terminate_proc(struct wpa_global *global);
 
 /* scan.c */
 int wpa_supplicant_enabled_networks(struct wpa_config *conf);
index 69df72d0b036d2c0ca4860635f8c8b89d4494815..1231d44dbf96410b35ff1f2eb694f672f0c6e77c 100644 (file)
@@ -888,7 +888,7 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
                return;
 
 #ifdef CONFIG_WPS_ER
-       wps_er_deinit(wpa_s->wps_er);
+       wps_er_deinit(wpa_s->wps_er, NULL, NULL);
        wpa_s->wps_er = NULL;
 #endif /* CONFIG_WPS_ER */
 
@@ -1131,7 +1131,7 @@ int wpas_wps_er_start(struct wpa_supplicant *wpa_s)
 int wpas_wps_er_stop(struct wpa_supplicant *wpa_s)
 {
 #ifdef CONFIG_WPS_ER
-       wps_er_deinit(wpa_s->wps_er);
+       wps_er_deinit(wpa_s->wps_er, NULL, NULL);
        wpa_s->wps_er = NULL;
 #endif /* CONFIG_WPS_ER */
        return 0;
@@ -1174,4 +1174,24 @@ int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
        return wps_er_learn(wpa_s->wps_er, u, (const u8 *) pin,
                            os_strlen(pin));
 }
+
+
+static void wpas_wps_terminate_cb(void *ctx)
+{
+       wpa_printf(MSG_DEBUG, "WPS ER: Terminated");
+       eloop_terminate();
+}
+#endif /* CONFIG_WPS_ER */
+
+
+int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_WPS_ER
+       if (wpa_s->wps_er) {
+               wps_er_deinit(wpa_s->wps_er, wpas_wps_terminate_cb, wpa_s);
+               wpa_s->wps_er = NULL;
+               return 1;
+       }
 #endif /* CONFIG_WPS_ER */
+       return 0;
+}
index d51ff61c6adb3cd3370909c8181ce426c0fbe54f..e94b8ee9e5d1ba60f2d311cebd3c4dedf35e4296 100644 (file)
@@ -56,6 +56,7 @@ int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const char *uuid,
 int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid);
 int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
                      const char *pin);
+int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s);
 
 #else /* CONFIG_WPS */