|
@@ -1510,15 +1510,8 @@ void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd,
|
|
|
#endif /* CONFIG_FST */
|
|
|
|
|
|
|
|
|
-/**
|
|
|
- * hostapd_setup_interface_complete - Complete interface setup
|
|
|
- *
|
|
|
- * This function is called when previous steps in the interface setup has been
|
|
|
- * completed. This can also start operations, e.g., DFS, that will require
|
|
|
- * additional processing before interface is ready to be enabled. Such
|
|
|
- * operations will call this function from eloop callbacks when finished.
|
|
|
- */
|
|
|
-int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
|
|
|
+static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
|
|
|
+ int err)
|
|
|
{
|
|
|
struct hostapd_data *hapd = iface->bss[0];
|
|
|
size_t j;
|
|
@@ -1720,6 +1713,89 @@ fail:
|
|
|
}
|
|
|
|
|
|
|
|
|
+/**
|
|
|
+ * hostapd_setup_interface_complete - Complete interface setup
|
|
|
+ *
|
|
|
+ * This function is called when previous steps in the interface setup has been
|
|
|
+ * completed. This can also start operations, e.g., DFS, that will require
|
|
|
+ * additional processing before interface is ready to be enabled. Such
|
|
|
+ * operations will call this function from eloop callbacks when finished.
|
|
|
+ */
|
|
|
+int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
|
|
|
+{
|
|
|
+ struct hapd_interfaces *interfaces = iface->interfaces;
|
|
|
+ struct hostapd_data *hapd = iface->bss[0];
|
|
|
+ unsigned int i;
|
|
|
+ int not_ready_in_sync_ifaces = 0;
|
|
|
+
|
|
|
+ if (!iface->need_to_start_in_sync)
|
|
|
+ return hostapd_setup_interface_complete_sync(iface, err);
|
|
|
+
|
|
|
+ if (err) {
|
|
|
+ wpa_printf(MSG_ERROR, "Interface initialization failed");
|
|
|
+ hostapd_set_state(iface, HAPD_IFACE_DISABLED);
|
|
|
+ iface->need_to_start_in_sync = 0;
|
|
|
+ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
|
|
|
+ if (interfaces && interfaces->terminate_on_error)
|
|
|
+ eloop_terminate();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (iface->ready_to_start_in_sync) {
|
|
|
+ /* Already in ready and waiting. should never happpen */
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < interfaces->count; i++) {
|
|
|
+ if (interfaces->iface[i]->need_to_start_in_sync &&
|
|
|
+ !interfaces->iface[i]->ready_to_start_in_sync)
|
|
|
+ not_ready_in_sync_ifaces++;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if this is the last interface, if yes then start all the other
|
|
|
+ * waiting interfaces. If not, add this interface to the waiting list.
|
|
|
+ */
|
|
|
+ if (not_ready_in_sync_ifaces > 1 && iface->state == HAPD_IFACE_DFS) {
|
|
|
+ /*
|
|
|
+ * If this interface went through CAC, do not synchronize, just
|
|
|
+ * start immediately.
|
|
|
+ */
|
|
|
+ iface->need_to_start_in_sync = 0;
|
|
|
+ wpa_printf(MSG_INFO,
|
|
|
+ "%s: Finished CAC - bypass sync and start interface",
|
|
|
+ iface->bss[0]->conf->iface);
|
|
|
+ return hostapd_setup_interface_complete_sync(iface, err);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (not_ready_in_sync_ifaces > 1) {
|
|
|
+ /* need to wait as there are other interfaces still coming up */
|
|
|
+ iface->ready_to_start_in_sync = 1;
|
|
|
+ wpa_printf(MSG_INFO,
|
|
|
+ "%s: Interface waiting to sync with other interfaces",
|
|
|
+ iface->bss[0]->conf->iface);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ wpa_printf(MSG_INFO,
|
|
|
+ "%s: Last interface to sync - starting all interfaces",
|
|
|
+ iface->bss[0]->conf->iface);
|
|
|
+ iface->need_to_start_in_sync = 0;
|
|
|
+ hostapd_setup_interface_complete_sync(iface, err);
|
|
|
+ for (i = 0; i < interfaces->count; i++) {
|
|
|
+ if (interfaces->iface[i]->need_to_start_in_sync &&
|
|
|
+ interfaces->iface[i]->ready_to_start_in_sync) {
|
|
|
+ hostapd_setup_interface_complete_sync(
|
|
|
+ interfaces->iface[i], 0);
|
|
|
+ /* Only once the interfaces are sync started */
|
|
|
+ interfaces->iface[i]->need_to_start_in_sync = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* hostapd_setup_interface - Setup of an interface
|
|
|
* @iface: Pointer to interface data.
|