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");
__wireless_device_set_down(wdev);
}
+static void
+wdev_prepare_prev_config(struct wireless_device *wdev)
+{
+ prepare_config(wdev, &b, false);
+ free(wdev->prev_config);
+ wdev->prev_config = blob_memdup(b.head);
+}
+
static void
wdev_change_config(struct wireless_device *wdev, struct wireless_device *wd_new)
{
wireless_vlan_set_data(vlan);
else if (vif)
wireless_interface_set_data(vif);
+ wdev_prepare_prev_config(wdev);
break;
case NOTIFY_CMD_PROCESS_ADD:
return wireless_device_add_process(wdev, cur);
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;
+ size_t 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;