#include "ubus.h"
#include "config.h"
#include "system.h"
+#include "wireless.h"
struct vlist_tree interfaces;
static LIST_HEAD(iface_all_users);
const char *error = NULL;
iface->autostart = true;
+ wireless_check_network_enabled();
if (iface->state != IFS_DOWN)
return;
__interface_set_down(iface, false);
} else {
iface->autostart = false;
+ wireless_check_network_enabled();
__interface_set_down(iface, false);
}
}
l = blobmsg_open_table(&b, "interfaces");
vlist_for_each_element(&wdev->interfaces, vif, node) {
+ if (vif->disabled)
+ continue;
+
i = blobmsg_open_table(&b, vif->name);
vif_config_add_bridge(&b, vif->network, up);
put_container(&b, vif->config, "config");
return 0;
}
-/* called on startup and by netifd reload() */
-void
-wireless_start_pending(void)
+static void
+wdev_check_network_enabled(struct wireless_device *wdev)
+{
+ struct wireless_interface *vif;
+ struct interface *iface;
+ struct blob_attr *cur;
+ int rem;
+
+ vlist_for_each_element(&wdev->interfaces, vif, node) {
+ int enabled = -1;
+
+ blobmsg_for_each_attr(cur, vif->network, rem) {
+ iface = vlist_find(&interfaces, blobmsg_get_string(cur), iface, node);
+ if (!iface)
+ continue;
+
+ if (iface->autostart) {
+ enabled = 1;
+ break;
+ }
+ if (enabled != 1)
+ enabled = 0;
+ }
+
+ if (vif->disabled == !enabled)
+ continue;
+
+ vif->disabled = !enabled;
+ wdev->config_update = true;
+ }
+}
+
+static void
+__wireless_start_pending(struct uloop_timeout *t)
{
struct wireless_device *wdev;
vlist_for_each_element(&wireless_devices, wdev, node) {
+ wdev_check_network_enabled(wdev);
if (wdev->config_update)
wdev_set_config_state(wdev, IFC_RELOAD);
__wireless_device_set_up(wdev, 0);
}
}
+void wireless_start_pending(int timeout)
+{
+ static struct uloop_timeout timer = {
+ .cb = __wireless_start_pending
+ };
+
+ if (timeout) {
+ uloop_timeout_set(&timer, timeout);
+ return;
+ }
+
+ uloop_timeout_cancel(&timer);
+ timer.cb(&timer);
+}
+
+void wireless_check_network_enabled(void)
+{
+ struct wireless_device *wdev;
+
+ vlist_for_each_element(&wireless_devices, wdev, node) {
+ wdev_check_network_enabled(wdev);
+
+ if (wdev->config_update)
+ wireless_start_pending(1000);
+ }
+}
+
void wireless_device_hotplug_event(const char *name, bool add)
{
struct wireless_interface *vif;
int multicast_to_unicast;
int vlan_idx;
int sta_idx;
+ bool disabled;
};
struct wireless_vlan {
int wireless_device_notify(struct wireless_device *wdev, struct blob_attr *data,
struct ubus_request_data *req);
-void wireless_start_pending(void);
+void wireless_check_network_enabled(void);
+void wireless_start_pending(int timeout);
void wireless_init(void);
void wireless_device_hotplug_event(const char *name, bool add);