diff --git a/src/device.c b/src/device.c index 38f77e66..dca2858f 100644 --- a/src/device.c +++ b/src/device.c @@ -1024,17 +1024,21 @@ static bool device_remove_network(const void *key, void *data, void *user_data) return true; } -static void device_netdev_notify(struct netdev *netdev, bool up, +static void device_netdev_notify(struct netdev *netdev, + enum netdev_watch_event event, void *user_data) { struct device *device = user_data; struct l_dbus *dbus = dbus_get_bus(); - if (up) { + if (event == NETDEV_EVENT_UP) { device_enter_state(device, DEVICE_STATE_AUTOCONNECT); __device_watch_call_added(device); - } else { + + l_dbus_property_changed(dbus, device_get_path(device), + IWD_DEVICE_INTERFACE, "Powered"); + } else if (event == NETDEV_EVENT_DOWN) { device_enter_state(device, DEVICE_STATE_OFF); if (device->scan_pending) @@ -1072,10 +1076,10 @@ static void device_netdev_notify(struct netdev *netdev, bool up, device->networks_sorted = l_queue_new(); __device_watch_call_removed(device); - } - l_dbus_property_changed(dbus, device_get_path(device), - IWD_DEVICE_INTERFACE, "Powered"); + l_dbus_property_changed(dbus, device_get_path(device), + IWD_DEVICE_INTERFACE, "Powered"); + } } struct device *device_create(struct wiphy *wiphy, struct netdev *netdev) @@ -1103,7 +1107,8 @@ struct device *device_create(struct wiphy *wiphy, struct netdev *netdev) scan_ifindex_add(device->index); - device_netdev_notify(netdev, netdev_get_is_up(netdev), device); + device_netdev_notify(netdev, netdev_get_is_up(netdev) ? + NETDEV_EVENT_UP : NETDEV_EVENT_DOWN, device); device->netdev_watch_id = netdev_watch_add(netdev, device_netdev_notify, device); diff --git a/src/netdev.c b/src/netdev.c index 601953c9..98867801 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -1166,33 +1166,61 @@ static void netdev_mlme_notify(struct l_genl_msg *msg, void *user_data) } } +struct netdev_watch_event_data { + struct netdev *netdev; + enum netdev_watch_event type; +}; + static void netdev_watch_notify(void *data, void *user_data) { struct netdev_watch *watch = data; - struct netdev *netdev = user_data; + struct netdev_watch_event_data *event = user_data; - watch->callback(netdev, netdev_get_is_up(netdev), watch->user_data); + watch->callback(event->netdev, event->type, watch->user_data); } static void netdev_newlink_notify(const struct ifinfomsg *ifi, int bytes) { struct netdev *netdev; bool old_up, new_up; + char old_name[IFNAMSIZ]; + struct rtattr *attr; + struct netdev_watch_event_data event; netdev = netdev_find(ifi->ifi_index); if (!netdev) return; old_up = netdev_get_is_up(netdev); + strcpy(old_name, netdev->name); netdev->ifi_flags = ifi->ifi_flags; + for (attr = IFLA_RTA(ifi); RTA_OK(attr, bytes); + attr = RTA_NEXT(attr, bytes)) { + if (attr->rta_type != IFLA_IFNAME) + continue; + + strcpy(netdev->name, RTA_DATA(attr)); + + break; + } + new_up = netdev_get_is_up(netdev); - if (old_up == new_up) - return; + if (old_up != new_up) { + event.netdev = netdev; + event.type = new_up ? NETDEV_EVENT_UP : NETDEV_EVENT_DOWN; - l_queue_foreach(netdev->watches, netdev_watch_notify, netdev); + l_queue_foreach(netdev->watches, netdev_watch_notify, &event); + } + + if (strcmp(old_name, netdev->name)) { + event.netdev = netdev; + event.type = NETDEV_EVENT_NAME_CHANGE; + + l_queue_foreach(netdev->watches, netdev_watch_notify, &event); + } } static void netdev_dellink_notify(const struct ifinfomsg *ifi, int bytes) diff --git a/src/netdev.h b/src/netdev.h index 431b3307..6f446513 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -43,6 +43,12 @@ enum netdev_event { NETDEV_EVENT_DISCONNECT_BY_AP, }; +enum netdev_watch_event { + NETDEV_EVENT_UP, + NETDEV_EVENT_DOWN, + NETDEV_EVENT_NAME_CHANGE, +}; + typedef void (*netdev_command_func_t) (bool result, void *user_data); typedef void (*netdev_connect_cb_t)(struct netdev *netdev, enum netdev_result result, @@ -52,7 +58,8 @@ typedef void (*netdev_event_func_t)(struct netdev *netdev, void *user_data); typedef void (*netdev_disconnect_cb_t)(struct netdev *netdev, bool result, void *user_data); -typedef void (*netdev_watch_func_t)(struct netdev *netdev, bool up, +typedef void (*netdev_watch_func_t)(struct netdev *netdev, + enum netdev_watch_event event, void *user_data); typedef void (*netdev_set_powered_cb_t)(struct netdev *netdev, int result, void *user_data);