netdev/device: Combine watches
There was somewhat overlapping functionality in the device_watch infrastructure as well as the netdev_event_watch. This commit combines the two into a single watch based on the netdev object and cleans up the various interface additions / removals. With this commit the interfaces are created when the netdev/device is switched to Powered=True state AND when the netdev iftype is also in the correct state for that interface. If the device is brought down, then all interfaces except the .Device interface are removed. This will make it easy to implement Device.Mode property properly since most nl80211 devices need to be brought into Powered=False state prior to switching the iftype.
This commit is contained in:
parent
da52bcd109
commit
996a6d2546
54
src/adhoc.c
54
src/adhoc.c
|
@ -62,7 +62,7 @@ struct sta_state {
|
||||||
bool authenticated : 1;
|
bool authenticated : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t device_watch;
|
static uint32_t netdev_watch;
|
||||||
|
|
||||||
static void adhoc_sta_free(void *data)
|
static void adhoc_sta_free(void *data)
|
||||||
{
|
{
|
||||||
|
@ -180,20 +180,6 @@ static void adhoc_handshake_event(struct handshake_state *hs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adhoc_netdev_notify(struct netdev *netdev,
|
|
||||||
enum netdev_watch_event event, void *user_data)
|
|
||||||
{
|
|
||||||
struct adhoc_state *ap = user_data;
|
|
||||||
|
|
||||||
switch (event) {
|
|
||||||
case NETDEV_WATCH_EVENT_DOWN:
|
|
||||||
adhoc_reset(ap);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct eapol_sm *adhoc_new_sm(struct sta_state *sta, bool authenticator)
|
static struct eapol_sm *adhoc_new_sm(struct sta_state *sta, bool authenticator)
|
||||||
{
|
{
|
||||||
struct netdev *netdev = device_get_netdev(sta->adhoc->device);
|
struct netdev *netdev = device_get_netdev(sta->adhoc->device);
|
||||||
|
@ -250,10 +236,6 @@ static struct eapol_sm *adhoc_new_sm(struct sta_state *sta, bool authenticator)
|
||||||
static void adhoc_free(struct adhoc_state *adhoc)
|
static void adhoc_free(struct adhoc_state *adhoc)
|
||||||
{
|
{
|
||||||
adhoc_reset(adhoc);
|
adhoc_reset(adhoc);
|
||||||
|
|
||||||
netdev_watch_remove(device_get_netdev(adhoc->device),
|
|
||||||
adhoc->netdev_watch_id);
|
|
||||||
|
|
||||||
l_free(adhoc);
|
l_free(adhoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,7 +524,6 @@ static void adhoc_destroy_interface(void *user_data)
|
||||||
adhoc_free(adhoc);
|
adhoc_free(adhoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void adhoc_add_interface(struct device *device)
|
static void adhoc_add_interface(struct device *device)
|
||||||
{
|
{
|
||||||
struct adhoc_state *adhoc;
|
struct adhoc_state *adhoc;
|
||||||
|
@ -551,9 +532,6 @@ static void adhoc_add_interface(struct device *device)
|
||||||
adhoc = l_new(struct adhoc_state, 1);
|
adhoc = l_new(struct adhoc_state, 1);
|
||||||
adhoc->device = device;
|
adhoc->device = device;
|
||||||
|
|
||||||
adhoc->netdev_watch_id = netdev_watch_add(device_get_netdev(device),
|
|
||||||
adhoc_netdev_notify, adhoc);
|
|
||||||
|
|
||||||
/* setup ap dbus interface */
|
/* setup ap dbus interface */
|
||||||
l_dbus_object_add_interface(dbus_get_bus(),
|
l_dbus_object_add_interface(dbus_get_bus(),
|
||||||
device_get_path(device), IWD_ADHOC_INTERFACE, adhoc);
|
device_get_path(device), IWD_ADHOC_INTERFACE, adhoc);
|
||||||
|
@ -565,15 +543,24 @@ static void adhoc_remove_interface(struct device *device)
|
||||||
device_get_path(device), IWD_ADHOC_INTERFACE);
|
device_get_path(device), IWD_ADHOC_INTERFACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ap_device_event(struct device *device, enum device_event event,
|
static void adhoc_netdev_watch(struct netdev *netdev,
|
||||||
void *userdata)
|
enum netdev_watch_event event, void *userdata)
|
||||||
{
|
{
|
||||||
|
struct device *device = netdev_get_device(netdev);
|
||||||
|
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case DEVICE_EVENT_MODE_CHANGED:
|
case NETDEV_WATCH_EVENT_UP:
|
||||||
if (device_get_mode(device) == DEVICE_MODE_ADHOC)
|
case NETDEV_WATCH_EVENT_NEW:
|
||||||
|
if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_ADHOC)
|
||||||
adhoc_add_interface(device);
|
adhoc_add_interface(device);
|
||||||
else
|
break;
|
||||||
|
case NETDEV_WATCH_EVENT_DOWN:
|
||||||
|
case NETDEV_WATCH_EVENT_DEL:
|
||||||
adhoc_remove_interface(device);
|
adhoc_remove_interface(device);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -581,17 +568,14 @@ static void ap_device_event(struct device *device, enum device_event event,
|
||||||
|
|
||||||
bool adhoc_init(void)
|
bool adhoc_init(void)
|
||||||
{
|
{
|
||||||
device_watch = device_watch_add(ap_device_event, NULL, NULL);
|
netdev_watch = netdev_watch_add(adhoc_netdev_watch, NULL, NULL);
|
||||||
if (!device_watch)
|
l_dbus_register_interface(dbus_get_bus(), IWD_ADHOC_INTERFACE,
|
||||||
return false;
|
|
||||||
|
|
||||||
return l_dbus_register_interface(dbus_get_bus(), IWD_ADHOC_INTERFACE,
|
|
||||||
adhoc_setup_interface, adhoc_destroy_interface, false);
|
adhoc_setup_interface, adhoc_destroy_interface, false);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void adhoc_exit(void)
|
void adhoc_exit(void)
|
||||||
{
|
{
|
||||||
device_watch_remove(device_watch);
|
netdev_watch_remove(netdev_watch);
|
||||||
|
|
||||||
l_dbus_unregister_interface(dbus_get_bus(), IWD_ADHOC_INTERFACE);
|
l_dbus_unregister_interface(dbus_get_bus(), IWD_ADHOC_INTERFACE);
|
||||||
}
|
}
|
||||||
|
|
48
src/ap.c
48
src/ap.c
|
@ -55,7 +55,6 @@ struct ap_state {
|
||||||
uint8_t pmk[32];
|
uint8_t pmk[32];
|
||||||
struct l_queue *frame_watch_ids;
|
struct l_queue *frame_watch_ids;
|
||||||
uint32_t start_stop_cmd_id;
|
uint32_t start_stop_cmd_id;
|
||||||
uint32_t netdev_watch_id;
|
|
||||||
|
|
||||||
uint16_t last_aid;
|
uint16_t last_aid;
|
||||||
struct l_queue *sta_states;
|
struct l_queue *sta_states;
|
||||||
|
@ -81,7 +80,7 @@ struct sta_state {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct l_genl_family *nl80211 = NULL;
|
static struct l_genl_family *nl80211 = NULL;
|
||||||
static uint32_t device_watch;
|
static uint32_t netdev_watch;
|
||||||
|
|
||||||
static void ap_sta_free(void *data)
|
static void ap_sta_free(void *data)
|
||||||
{
|
{
|
||||||
|
@ -128,8 +127,6 @@ static void ap_reset(struct ap_state *ap)
|
||||||
if (ap->start_stop_cmd_id)
|
if (ap->start_stop_cmd_id)
|
||||||
l_genl_family_cancel(nl80211, ap->start_stop_cmd_id);
|
l_genl_family_cancel(nl80211, ap->start_stop_cmd_id);
|
||||||
|
|
||||||
netdev_watch_remove(netdev, ap->netdev_watch_id);
|
|
||||||
|
|
||||||
l_queue_destroy(ap->sta_states, ap_sta_free);
|
l_queue_destroy(ap->sta_states, ap_sta_free);
|
||||||
|
|
||||||
if (ap->rates)
|
if (ap->rates)
|
||||||
|
@ -1126,20 +1123,6 @@ static void ap_deauth_cb(struct netdev *netdev, const struct mmpdu_header *hdr,
|
||||||
ap_sta_free(sta);
|
ap_sta_free(sta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ap_netdev_notify(struct netdev *netdev,
|
|
||||||
enum netdev_watch_event event, void *user_data)
|
|
||||||
{
|
|
||||||
struct ap_state *ap = user_data;
|
|
||||||
|
|
||||||
switch (event) {
|
|
||||||
case NETDEV_WATCH_EVENT_DOWN:
|
|
||||||
ap_reset(ap);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ap_start_cb(struct l_genl_msg *msg, void *user_data)
|
static void ap_start_cb(struct l_genl_msg *msg, void *user_data)
|
||||||
{
|
{
|
||||||
struct ap_state *ap = user_data;
|
struct ap_state *ap = user_data;
|
||||||
|
@ -1308,8 +1291,6 @@ static int ap_start(struct ap_state *ap, const char *ssid, const char *psk,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ap->netdev_watch_id = netdev_watch_add(netdev, ap_netdev_notify, ap);
|
|
||||||
|
|
||||||
ap->pending = l_dbus_message_ref(message);
|
ap->pending = l_dbus_message_ref(message);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1465,15 +1446,24 @@ static void ap_remove_interface(struct device *device)
|
||||||
device_get_path(device), IWD_AP_INTERFACE);
|
device_get_path(device), IWD_AP_INTERFACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ap_device_event(struct device *device, enum device_event event,
|
static void ap_netdev_watch(struct netdev *netdev,
|
||||||
void *userdata)
|
enum netdev_watch_event event, void *userdata)
|
||||||
{
|
{
|
||||||
|
struct device *device = netdev_get_device(netdev);
|
||||||
|
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case DEVICE_EVENT_MODE_CHANGED:
|
case NETDEV_WATCH_EVENT_UP:
|
||||||
if (device_get_mode(device) == DEVICE_MODE_AP)
|
case NETDEV_WATCH_EVENT_NEW:
|
||||||
|
if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_AP)
|
||||||
ap_add_interface(device);
|
ap_add_interface(device);
|
||||||
else
|
break;
|
||||||
|
case NETDEV_WATCH_EVENT_DOWN:
|
||||||
|
case NETDEV_WATCH_EVENT_DEL:
|
||||||
ap_remove_interface(device);
|
ap_remove_interface(device);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1481,10 +1471,7 @@ static void ap_device_event(struct device *device, enum device_event event,
|
||||||
|
|
||||||
bool ap_init(struct l_genl_family *in)
|
bool ap_init(struct l_genl_family *in)
|
||||||
{
|
{
|
||||||
device_watch = device_watch_add(ap_device_event, NULL, NULL);
|
netdev_watch = netdev_watch_add(ap_netdev_watch, NULL, NULL);
|
||||||
if (!device_watch)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
nl80211 = in;
|
nl80211 = in;
|
||||||
|
|
||||||
return l_dbus_register_interface(dbus_get_bus(), IWD_AP_INTERFACE,
|
return l_dbus_register_interface(dbus_get_bus(), IWD_AP_INTERFACE,
|
||||||
|
@ -1497,7 +1484,6 @@ bool ap_init(struct l_genl_family *in)
|
||||||
|
|
||||||
void ap_exit(void)
|
void ap_exit(void)
|
||||||
{
|
{
|
||||||
device_watch_remove(device_watch);
|
netdev_watch_remove(netdev_watch);
|
||||||
|
|
||||||
l_dbus_unregister_interface(dbus_get_bus(), IWD_AP_INTERFACE);
|
l_dbus_unregister_interface(dbus_get_bus(), IWD_AP_INTERFACE);
|
||||||
}
|
}
|
||||||
|
|
52
src/device.c
52
src/device.c
|
@ -74,7 +74,6 @@ struct device {
|
||||||
struct l_queue *autoconnect_list;
|
struct l_queue *autoconnect_list;
|
||||||
struct l_dbus_message *connect_pending;
|
struct l_dbus_message *connect_pending;
|
||||||
struct l_dbus_message *disconnect_pending;
|
struct l_dbus_message *disconnect_pending;
|
||||||
uint32_t netdev_watch_id;
|
|
||||||
struct watchlist state_watches;
|
struct watchlist state_watches;
|
||||||
struct timespec roam_min_time;
|
struct timespec roam_min_time;
|
||||||
struct l_timeout *roam_trigger_timeout;
|
struct l_timeout *roam_trigger_timeout;
|
||||||
|
@ -106,25 +105,14 @@ struct signal_agent {
|
||||||
unsigned int disconnect_watch;
|
unsigned int disconnect_watch;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct watchlist device_watches;
|
|
||||||
static struct l_queue *device_list;
|
static struct l_queue *device_list;
|
||||||
|
static uint32_t netdev_watch;
|
||||||
|
|
||||||
static void device_roam_timeout_rearm(struct device *device, int seconds);
|
static void device_roam_timeout_rearm(struct device *device, int seconds);
|
||||||
|
|
||||||
static void device_netdev_event(struct netdev *netdev, enum netdev_event event,
|
static void device_netdev_event(struct netdev *netdev, enum netdev_event event,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
uint32_t device_watch_add(device_watch_func_t func,
|
|
||||||
void *userdata, device_destroy_func_t destroy)
|
|
||||||
{
|
|
||||||
return watchlist_add(&device_watches, func, userdata, destroy);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool device_watch_remove(uint32_t id)
|
|
||||||
{
|
|
||||||
return watchlist_remove(&device_watches, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __iwd_device_foreach(iwd_device_foreach_func func, void *user_data)
|
void __iwd_device_foreach(iwd_device_foreach_func func, void *user_data)
|
||||||
{
|
{
|
||||||
const struct l_queue_entry *device_entry;
|
const struct l_queue_entry *device_entry;
|
||||||
|
@ -2515,9 +2503,6 @@ static struct l_dbus_message *device_change_mode(struct device *device,
|
||||||
|
|
||||||
device->mode = mode;
|
device->mode = mode;
|
||||||
|
|
||||||
WATCHLIST_NOTIFY(&device_watches, device_watch_func_t, device,
|
|
||||||
DEVICE_EVENT_MODE_CHANGED);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2598,17 +2583,17 @@ static void device_netdev_notify(struct netdev *netdev,
|
||||||
enum netdev_watch_event event,
|
enum netdev_watch_event event,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
struct device *device = user_data;
|
struct device *device = netdev_get_device(netdev);
|
||||||
struct l_dbus *dbus = dbus_get_bus();
|
struct l_dbus *dbus = dbus_get_bus();
|
||||||
|
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NETDEV_WATCH_EVENT_UP:
|
case NETDEV_WATCH_EVENT_UP:
|
||||||
device->autoconnect = true;
|
device->autoconnect = true;
|
||||||
device_enter_state(device, DEVICE_STATE_AUTOCONNECT);
|
device_enter_state(device, DEVICE_STATE_AUTOCONNECT);
|
||||||
|
|
||||||
WATCHLIST_NOTIFY(&device_watches, device_watch_func_t,
|
|
||||||
device, DEVICE_EVENT_INSERTED);
|
|
||||||
|
|
||||||
l_dbus_property_changed(dbus, device_get_path(device),
|
l_dbus_property_changed(dbus, device_get_path(device),
|
||||||
IWD_DEVICE_INTERFACE, "Powered");
|
IWD_DEVICE_INTERFACE, "Powered");
|
||||||
break;
|
break;
|
||||||
|
@ -2637,9 +2622,6 @@ static void device_netdev_notify(struct netdev *netdev,
|
||||||
l_queue_destroy(device->networks_sorted, NULL);
|
l_queue_destroy(device->networks_sorted, NULL);
|
||||||
device->networks_sorted = l_queue_new();
|
device->networks_sorted = l_queue_new();
|
||||||
|
|
||||||
WATCHLIST_NOTIFY(&device_watches, device_watch_func_t,
|
|
||||||
device, DEVICE_EVENT_REMOVED);
|
|
||||||
|
|
||||||
l_dbus_property_changed(dbus, device_get_path(device),
|
l_dbus_property_changed(dbus, device_get_path(device),
|
||||||
IWD_DEVICE_INTERFACE, "Powered");
|
IWD_DEVICE_INTERFACE, "Powered");
|
||||||
break;
|
break;
|
||||||
|
@ -2651,6 +2633,8 @@ static void device_netdev_notify(struct netdev *netdev,
|
||||||
l_dbus_property_changed(dbus, device_get_path(device),
|
l_dbus_property_changed(dbus, device_get_path(device),
|
||||||
IWD_DEVICE_INTERFACE, "Address");
|
IWD_DEVICE_INTERFACE, "Address");
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2687,15 +2671,6 @@ struct device *device_create(struct wiphy *wiphy, struct netdev *netdev)
|
||||||
|
|
||||||
scan_ifindex_add(device->index);
|
scan_ifindex_add(device->index);
|
||||||
|
|
||||||
netdev_set_iftype(device->netdev, NETDEV_IFTYPE_STATION);
|
|
||||||
|
|
||||||
device_netdev_notify(netdev, netdev_get_is_up(netdev) ?
|
|
||||||
NETDEV_WATCH_EVENT_UP :
|
|
||||||
NETDEV_WATCH_EVENT_DOWN,
|
|
||||||
device);
|
|
||||||
device->netdev_watch_id =
|
|
||||||
netdev_watch_add(netdev, device_netdev_notify, device);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* register for AP roam transition watch
|
* register for AP roam transition watch
|
||||||
*/
|
*/
|
||||||
|
@ -2703,6 +2678,9 @@ struct device *device_create(struct wiphy *wiphy, struct netdev *netdev)
|
||||||
action_ap_roam_prefix, sizeof(action_ap_roam_prefix),
|
action_ap_roam_prefix, sizeof(action_ap_roam_prefix),
|
||||||
device_ap_roam_frame_event, device);
|
device_ap_roam_frame_event, device);
|
||||||
|
|
||||||
|
if (netdev_get_is_up(netdev))
|
||||||
|
device_enter_state(device, DEVICE_STATE_AUTOCONNECT);
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2727,9 +2705,6 @@ static void device_free(void *user)
|
||||||
signal_agent_free(device->signal_agent);
|
signal_agent_free(device->signal_agent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->state != DEVICE_STATE_OFF)
|
|
||||||
WATCHLIST_NOTIFY(&device_watches, device_watch_func_t,
|
|
||||||
device, DEVICE_EVENT_REMOVED);
|
|
||||||
|
|
||||||
watchlist_destroy(&device->state_watches);
|
watchlist_destroy(&device->state_watches);
|
||||||
|
|
||||||
|
@ -2743,8 +2718,6 @@ static void device_free(void *user)
|
||||||
l_queue_destroy(device->old_bss_list, bss_free);
|
l_queue_destroy(device->old_bss_list, bss_free);
|
||||||
l_queue_destroy(device->autoconnect_list, l_free);
|
l_queue_destroy(device->autoconnect_list, l_free);
|
||||||
|
|
||||||
netdev_watch_remove(device->netdev, device->netdev_watch_id);
|
|
||||||
|
|
||||||
l_timeout_remove(device->roam_trigger_timeout);
|
l_timeout_remove(device->roam_trigger_timeout);
|
||||||
|
|
||||||
scan_ifindex_remove(device->index);
|
scan_ifindex_remove(device->index);
|
||||||
|
@ -2770,7 +2743,7 @@ bool device_init(void)
|
||||||
NULL, false))
|
NULL, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
watchlist_init(&device_watches, NULL);
|
netdev_watch = netdev_watch_add(device_netdev_notify, NULL, NULL);
|
||||||
device_list = l_queue_new();
|
device_list = l_queue_new();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -2783,8 +2756,7 @@ void device_exit(void)
|
||||||
|
|
||||||
l_queue_destroy(device_list, device_free);
|
l_queue_destroy(device_list, device_free);
|
||||||
device_list = NULL;
|
device_list = NULL;
|
||||||
|
netdev_watch_remove(netdev_watch);
|
||||||
watchlist_destroy(&device_watches);
|
|
||||||
|
|
||||||
l_dbus_unregister_interface(dbus_get_bus(), IWD_DEVICE_INTERFACE);
|
l_dbus_unregister_interface(dbus_get_bus(), IWD_DEVICE_INTERFACE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,10 +56,6 @@ typedef void (*device_watch_func_t)(struct device *device,
|
||||||
typedef void (*device_state_watch_func_t)(enum device_state, void *userdata);
|
typedef void (*device_state_watch_func_t)(enum device_state, void *userdata);
|
||||||
typedef void (*device_destroy_func_t)(void *userdata);
|
typedef void (*device_destroy_func_t)(void *userdata);
|
||||||
|
|
||||||
uint32_t device_watch_add(device_watch_func_t func,
|
|
||||||
void *userdata, device_destroy_func_t destroy);
|
|
||||||
bool device_watch_remove(uint32_t id);
|
|
||||||
|
|
||||||
struct network *device_get_connected_network(struct device *device);
|
struct network *device_get_connected_network(struct device *device);
|
||||||
const char *device_get_path(struct device *device);
|
const char *device_get_path(struct device *device);
|
||||||
bool device_is_busy(struct device *device);
|
bool device_is_busy(struct device *device);
|
||||||
|
|
40
src/netdev.c
40
src/netdev.c
|
@ -109,8 +109,6 @@ struct netdev {
|
||||||
void *set_powered_user_data;
|
void *set_powered_user_data;
|
||||||
netdev_destroy_func_t set_powered_destroy;
|
netdev_destroy_func_t set_powered_destroy;
|
||||||
|
|
||||||
struct watchlist event_watches;
|
|
||||||
|
|
||||||
struct watchlist frame_watches;
|
struct watchlist frame_watches;
|
||||||
|
|
||||||
struct watchlist station_watches;
|
struct watchlist station_watches;
|
||||||
|
@ -150,6 +148,7 @@ static struct l_genl_family *nl80211;
|
||||||
static struct l_queue *netdev_list;
|
static struct l_queue *netdev_list;
|
||||||
static char **whitelist_filter;
|
static char **whitelist_filter;
|
||||||
static char **blacklist_filter;
|
static char **blacklist_filter;
|
||||||
|
static struct watchlist netdev_watches;
|
||||||
|
|
||||||
static void do_debug(const char *str, void *user_data)
|
static void do_debug(const char *str, void *user_data)
|
||||||
{
|
{
|
||||||
|
@ -606,8 +605,10 @@ static void netdev_free(void *data)
|
||||||
netdev->set_powered_cmd_id = 0;
|
netdev->set_powered_cmd_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t,
|
||||||
|
netdev, NETDEV_WATCH_EVENT_DEL);
|
||||||
device_remove(netdev->device);
|
device_remove(netdev->device);
|
||||||
watchlist_destroy(&netdev->event_watches);
|
|
||||||
watchlist_destroy(&netdev->frame_watches);
|
watchlist_destroy(&netdev->frame_watches);
|
||||||
watchlist_destroy(&netdev->station_watches);
|
watchlist_destroy(&netdev->station_watches);
|
||||||
|
|
||||||
|
@ -4009,16 +4010,16 @@ static void netdev_newlink_notify(const struct ifinfomsg *ifi, int bytes)
|
||||||
new_up = netdev_get_is_up(netdev);
|
new_up = netdev_get_is_up(netdev);
|
||||||
|
|
||||||
if (old_up != new_up)
|
if (old_up != new_up)
|
||||||
WATCHLIST_NOTIFY(&netdev->event_watches, netdev_watch_func_t,
|
WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t,
|
||||||
netdev, new_up ? NETDEV_WATCH_EVENT_UP :
|
netdev, new_up ? NETDEV_WATCH_EVENT_UP :
|
||||||
NETDEV_WATCH_EVENT_DOWN);
|
NETDEV_WATCH_EVENT_DOWN);
|
||||||
|
|
||||||
if (strcmp(old_name, netdev->name))
|
if (strcmp(old_name, netdev->name))
|
||||||
WATCHLIST_NOTIFY(&netdev->event_watches, netdev_watch_func_t,
|
WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t,
|
||||||
netdev, NETDEV_WATCH_EVENT_NAME_CHANGE);
|
netdev, NETDEV_WATCH_EVENT_NAME_CHANGE);
|
||||||
|
|
||||||
if (memcmp(old_addr, netdev->addr, ETH_ALEN))
|
if (memcmp(old_addr, netdev->addr, ETH_ALEN))
|
||||||
WATCHLIST_NOTIFY(&netdev->event_watches, netdev_watch_func_t,
|
WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t,
|
||||||
netdev, NETDEV_WATCH_EVENT_ADDRESS_CHANGE);
|
netdev, NETDEV_WATCH_EVENT_ADDRESS_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4067,6 +4068,8 @@ static void netdev_initial_up_cb(int error, uint16_t type, const void *data,
|
||||||
l_debug("Interface %i initialized", netdev->index);
|
l_debug("Interface %i initialized", netdev->index);
|
||||||
|
|
||||||
netdev->device = device_create(netdev->wiphy, netdev);
|
netdev->device = device_create(netdev->wiphy, netdev);
|
||||||
|
WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t,
|
||||||
|
netdev, NETDEV_WATCH_EVENT_NEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netdev_initial_down_cb(int error, uint16_t type, const void *data,
|
static void netdev_initial_down_cb(int error, uint16_t type, const void *data,
|
||||||
|
@ -4409,7 +4412,6 @@ static void netdev_create_from_genl(struct l_genl_msg *msg)
|
||||||
netdev_pae_destroy);
|
netdev_pae_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
watchlist_init(&netdev->event_watches, NULL);
|
|
||||||
watchlist_init(&netdev->frame_watches, &netdev_frame_watch_ops);
|
watchlist_init(&netdev->frame_watches, &netdev_frame_watch_ops);
|
||||||
watchlist_init(&netdev->station_watches, NULL);
|
watchlist_init(&netdev->station_watches, NULL);
|
||||||
|
|
||||||
|
@ -4530,17 +4532,6 @@ static void netdev_link_notify(uint16_t type, const void *data, uint32_t len,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t netdev_watch_add(struct netdev *netdev, netdev_watch_func_t func,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
return watchlist_add(&netdev->event_watches, func, user_data, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool netdev_watch_remove(struct netdev *netdev, uint32_t id)
|
|
||||||
{
|
|
||||||
return watchlist_remove(&netdev->event_watches, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t netdev_station_watch_add(struct netdev *netdev,
|
uint32_t netdev_station_watch_add(struct netdev *netdev,
|
||||||
netdev_station_watch_func_t func, void *user_data)
|
netdev_station_watch_func_t func, void *user_data)
|
||||||
{
|
{
|
||||||
|
@ -4552,6 +4543,17 @@ bool netdev_station_watch_remove(struct netdev *netdev, uint32_t id)
|
||||||
return watchlist_remove(&netdev->station_watches, id);
|
return watchlist_remove(&netdev->station_watches, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t netdev_watch_add(netdev_watch_func_t func,
|
||||||
|
void *user_data, netdev_destroy_func_t destroy)
|
||||||
|
{
|
||||||
|
return watchlist_add(&netdev_watches, func, user_data, destroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool netdev_watch_remove(uint32_t id)
|
||||||
|
{
|
||||||
|
return watchlist_remove(&netdev_watches, id);
|
||||||
|
}
|
||||||
|
|
||||||
bool netdev_init(const char *whitelist, const char *blacklist)
|
bool netdev_init(const char *whitelist, const char *blacklist)
|
||||||
{
|
{
|
||||||
if (rtnl)
|
if (rtnl)
|
||||||
|
@ -4575,6 +4577,7 @@ bool netdev_init(const char *whitelist, const char *blacklist)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchlist_init(&netdev_watches, NULL);
|
||||||
netdev_list = l_queue_new();
|
netdev_list = l_queue_new();
|
||||||
|
|
||||||
__handshake_set_install_tk_func(netdev_set_tk);
|
__handshake_set_install_tk_func(netdev_set_tk);
|
||||||
|
@ -4626,6 +4629,7 @@ void netdev_exit(void)
|
||||||
l_strfreev(whitelist_filter);
|
l_strfreev(whitelist_filter);
|
||||||
l_strfreev(blacklist_filter);
|
l_strfreev(blacklist_filter);
|
||||||
|
|
||||||
|
watchlist_destroy(&netdev_watches);
|
||||||
nl80211 = NULL;
|
nl80211 = NULL;
|
||||||
|
|
||||||
l_debug("Closing route netlink socket");
|
l_debug("Closing route netlink socket");
|
||||||
|
|
|
@ -50,6 +50,8 @@ enum netdev_event {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum netdev_watch_event {
|
enum netdev_watch_event {
|
||||||
|
NETDEV_WATCH_EVENT_NEW,
|
||||||
|
NETDEV_WATCH_EVENT_DEL,
|
||||||
NETDEV_WATCH_EVENT_UP,
|
NETDEV_WATCH_EVENT_UP,
|
||||||
NETDEV_WATCH_EVENT_DOWN,
|
NETDEV_WATCH_EVENT_DOWN,
|
||||||
NETDEV_WATCH_EVENT_NAME_CHANGE,
|
NETDEV_WATCH_EVENT_NAME_CHANGE,
|
||||||
|
@ -167,9 +169,9 @@ void netdev_handshake_failed(struct handshake_state *hs, uint16_t reason_code);
|
||||||
|
|
||||||
struct netdev *netdev_find(int ifindex);
|
struct netdev *netdev_find(int ifindex);
|
||||||
|
|
||||||
uint32_t netdev_watch_add(struct netdev *netdev, netdev_watch_func_t func,
|
uint32_t netdev_watch_add(netdev_watch_func_t func,
|
||||||
void *user_data);
|
void *user_data, netdev_destroy_func_t destroy);
|
||||||
bool netdev_watch_remove(struct netdev *netdev, uint32_t id);
|
bool netdev_watch_remove(uint32_t id);
|
||||||
|
|
||||||
uint32_t netdev_station_watch_add(struct netdev *netdev,
|
uint32_t netdev_station_watch_add(struct netdev *netdev,
|
||||||
netdev_station_watch_func_t func, void *user_data);
|
netdev_station_watch_func_t func, void *user_data);
|
||||||
|
|
57
src/wsc.c
57
src/wsc.c
|
@ -46,7 +46,7 @@
|
||||||
|
|
||||||
#define WALK_TIME 120
|
#define WALK_TIME 120
|
||||||
|
|
||||||
static uint32_t device_watch = 0;
|
static uint32_t netdev_watch = 0;
|
||||||
|
|
||||||
struct wsc {
|
struct wsc {
|
||||||
struct device *device;
|
struct device *device;
|
||||||
|
@ -1043,7 +1043,7 @@ static void wsc_free(void *userdata)
|
||||||
l_free(wsc);
|
l_free(wsc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_appeared(struct device *device, void *userdata)
|
static void wsc_add_interface(struct device *device)
|
||||||
{
|
{
|
||||||
struct l_dbus *dbus = dbus_get_bus();
|
struct l_dbus *dbus = dbus_get_bus();
|
||||||
struct wsc *wsc;
|
struct wsc *wsc;
|
||||||
|
@ -1059,7 +1059,7 @@ static void device_appeared(struct device *device, void *userdata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_disappeared(struct device *device, void *userdata)
|
static void wsc_remove_interface(struct device *device)
|
||||||
{
|
{
|
||||||
struct l_dbus *dbus = dbus_get_bus();
|
struct l_dbus *dbus = dbus_get_bus();
|
||||||
|
|
||||||
|
@ -1067,55 +1067,44 @@ static void device_disappeared(struct device *device, void *userdata)
|
||||||
IWD_WSC_INTERFACE);
|
IWD_WSC_INTERFACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_mode_changed(struct device *device, void *userdata)
|
static void wsc_netdev_watch(struct netdev *netdev,
|
||||||
|
enum netdev_watch_event event, void *userdata)
|
||||||
{
|
{
|
||||||
enum device_mode mode = device_get_mode(device);
|
struct device *device = netdev_get_device(netdev);
|
||||||
|
|
||||||
switch (mode) {
|
if (!device)
|
||||||
case DEVICE_MODE_STATION:
|
return;
|
||||||
device_appeared(device, userdata);
|
|
||||||
|
switch (event) {
|
||||||
|
case NETDEV_WATCH_EVENT_UP:
|
||||||
|
case NETDEV_WATCH_EVENT_NEW:
|
||||||
|
if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_STATION)
|
||||||
|
wsc_add_interface(device);
|
||||||
|
break;
|
||||||
|
case NETDEV_WATCH_EVENT_DOWN:
|
||||||
|
case NETDEV_WATCH_EVENT_DEL:
|
||||||
|
wsc_remove_interface(device);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
device_disappeared(device, userdata);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_event(struct device *device, enum device_event event,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
switch (event) {
|
|
||||||
case DEVICE_EVENT_INSERTED:
|
|
||||||
return device_appeared(device, userdata);
|
|
||||||
case DEVICE_EVENT_REMOVED:
|
|
||||||
return device_disappeared(device, userdata);
|
|
||||||
case DEVICE_EVENT_MODE_CHANGED:
|
|
||||||
return device_mode_changed(device, userdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wsc_init(void)
|
bool wsc_init(void)
|
||||||
{
|
{
|
||||||
if (!l_dbus_register_interface(dbus_get_bus(), IWD_WSC_INTERFACE,
|
l_debug("");
|
||||||
|
netdev_watch = netdev_watch_add(wsc_netdev_watch, NULL, NULL);
|
||||||
|
l_dbus_register_interface(dbus_get_bus(), IWD_WSC_INTERFACE,
|
||||||
setup_wsc_interface,
|
setup_wsc_interface,
|
||||||
wsc_free, false))
|
wsc_free, false);
|
||||||
return false;
|
|
||||||
|
|
||||||
device_watch = device_watch_add(device_event, NULL, NULL);
|
|
||||||
if (!device_watch) {
|
|
||||||
l_dbus_unregister_interface(dbus_get_bus(), IWD_WSC_INTERFACE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wsc_exit()
|
bool wsc_exit()
|
||||||
{
|
{
|
||||||
l_debug("");
|
l_debug("");
|
||||||
|
|
||||||
l_dbus_unregister_interface(dbus_get_bus(), IWD_WSC_INTERFACE);
|
l_dbus_unregister_interface(dbus_get_bus(), IWD_WSC_INTERFACE);
|
||||||
device_watch_remove(device_watch);
|
netdev_watch_remove(netdev_watch);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue