WPS ER: Delay wpa_supplicant termination to allow unsubscription

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.
This commit is contained in:
Jouni Malinen 2009-12-19 23:47:54 +02:00
parent e46338fc76
commit 1a1bf008cb
8 changed files with 65 additions and 12 deletions

View 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); struct wps_er * wps_er_init(struct wps_context *wps, const char *ifname);
void wps_er_refresh(struct wps_er *er); 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, void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
u16 sel_reg_config_methods); u16 sel_reg_config_methods);
int wps_er_pbc(struct wps_er *er, const u8 *uuid); int wps_er_pbc(struct wps_er *er, const u8 *uuid);

View file

@ -1161,19 +1161,19 @@ wps_er_init(struct wps_context *wps, const char *ifname)
er->mac_addr, &er->mac_addr_text)) { er->mac_addr, &er->mac_addr_text)) {
wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address " wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "
"for %s. Does it have IP address?", ifname); "for %s. Does it have IP address?", ifname);
wps_er_deinit(er); wps_er_deinit(er, NULL, NULL);
return NULL; return NULL;
} }
if (wps_er_ssdp_init(er) < 0) { if (wps_er_ssdp_init(er) < 0) {
wps_er_deinit(er); wps_er_deinit(er, NULL, NULL);
return NULL; return NULL;
} }
addr.s_addr = er->ip_addr; addr.s_addr = er->ip_addr;
er->http_srv = http_server_init(&addr, -1, wps_er_http_req, er); er->http_srv = http_server_init(&addr, -1, wps_er_http_req, er);
if (er->http_srv == NULL) { if (er->http_srv == NULL) {
wps_er_deinit(er); wps_er_deinit(er, NULL, NULL);
return NULL; return NULL;
} }
er->http_port = http_server_get_port(er->http_srv); 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) static void wps_er_deinit_finish(void *eloop_data, void *user_ctx)
{ {
struct wps_er *er = eloop_data; struct wps_er *er = eloop_data;
void (*deinit_done_cb)(void *ctx);
void *deinit_done_ctx;
wpa_printf(MSG_DEBUG, "WPS ER: Finishing deinit"); 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->ip_addr_text);
os_free(er->mac_addr_text); os_free(er->mac_addr_text);
os_free(er); 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) if (er == NULL)
return; return;
http_server_deinit(er->http_srv); http_server_deinit(er->http_srv);
wps_er_ap_remove_all(er); wps_er_ap_remove_all(er);
wps_er_ssdp_deinit(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"); wpa_printf(MSG_DEBUG, "WPS ER: Finish deinit from timeout");
er->deinitializing = 1; er->deinitializing = 1;
er->deinit_done_cb = cb;
er->deinit_done_ctx = ctx;
} }

View file

@ -88,6 +88,8 @@ struct wps_er {
unsigned int next_ap_id; unsigned int next_ap_id;
unsigned int event_id; unsigned int event_id;
int deinitializing; int deinitializing;
void (*deinit_done_cb)(void *ctx);
void *deinit_done_ctx;
}; };

View file

@ -1714,7 +1714,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
if (wpa_supplicant_reload_configuration(wpa_s)) if (wpa_supplicant_reload_configuration(wpa_s))
reply_len = -1; reply_len = -1;
} else if (os_strcmp(buf, "TERMINATE") == 0) { } else if (os_strcmp(buf, "TERMINATE") == 0) {
eloop_terminate(); wpa_supplicant_terminate_proc(wpa_s->global);
} else if (os_strncmp(buf, "BSSID ", 6) == 0) { } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
reply_len = -1; 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( reply_len = wpa_supplicant_global_iface_interfaces(
global, reply, reply_size); global, reply, reply_size);
} else if (os_strcmp(buf, "TERMINATE") == 0) { } else if (os_strcmp(buf, "TERMINATE") == 0) {
eloop_terminate(); wpa_supplicant_terminate_proc(global);
} else { } else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16); os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16; reply_len = 16;

View 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) static void wpa_supplicant_terminate(int sig, void *signal_ctx)
{ {
struct wpa_global *global = 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 " wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING "- signal %d "
"received", sig); "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); wpa_printf(MSG_DEBUG, "Signal %d received - reconfiguring", sig);
for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
if (wpa_supplicant_reload_configuration(wpa_s) < 0) { if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
eloop_terminate(); wpa_supplicant_terminate_proc(global);
} }
} }
} }

View file

@ -478,6 +478,7 @@ void wpa_supplicant_deinit(struct wpa_global *global);
int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s, int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid); struct wpa_ssid *ssid);
void wpa_supplicant_terminate_proc(struct wpa_global *global);
/* scan.c */ /* scan.c */
int wpa_supplicant_enabled_networks(struct wpa_config *conf); int wpa_supplicant_enabled_networks(struct wpa_config *conf);

View file

@ -888,7 +888,7 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
return; return;
#ifdef CONFIG_WPS_ER #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; wpa_s->wps_er = NULL;
#endif /* CONFIG_WPS_ER */ #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) int wpas_wps_er_stop(struct wpa_supplicant *wpa_s)
{ {
#ifdef CONFIG_WPS_ER #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; wpa_s->wps_er = NULL;
#endif /* CONFIG_WPS_ER */ #endif /* CONFIG_WPS_ER */
return 0; 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, return wps_er_learn(wpa_s->wps_er, u, (const u8 *) pin,
os_strlen(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 */ #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;
}

View 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_pbc(struct wpa_supplicant *wpa_s, const char *uuid);
int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid, int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
const char *pin); const char *pin);
int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s);
#else /* CONFIG_WPS */ #else /* CONFIG_WPS */