From f3fc0ea1f95f22f28e79d8540af082ec725d146c Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Thu, 5 May 2016 12:13:45 -0500 Subject: [PATCH] device: Refactor netdev watches Turn netdev watches into device watches. The intent is to refactor out netdev specific details into its own class and move device specific logic into device.c away from wiphy.c --- Makefile.am | 1 + src/device.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/device.h | 39 ++++++++++++++++ src/main.c | 9 ++++ src/netdev.c | 88 ----------------------------------- src/netdev.h | 8 ---- src/wiphy.c | 5 +- src/wsc.c | 17 +++---- 8 files changed, 188 insertions(+), 106 deletions(-) create mode 100644 src/device.c create mode 100644 src/device.h diff --git a/Makefile.am b/Makefile.am index c576975b..fd819bbd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,6 +59,7 @@ bin_PROGRAMS = src/iwd client/iwctl monitor/iwmon src_iwd_SOURCES = src/main.c linux/nl80211.h \ src/netdev.h src/netdev.c \ src/wiphy.h src/wiphy.c \ + src/device.h src/device.c \ src/ie.h src/ie.c \ src/dbus.h src/dbus.c \ src/manager.h src/manager.c \ diff --git a/src/device.c b/src/device.c new file mode 100644 index 00000000..19e13aae --- /dev/null +++ b/src/device.c @@ -0,0 +1,127 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2013-2016 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "src/device.h" + +struct device_watchlist_item { + uint32_t id; + device_watch_func_t added; + device_watch_func_t removed; + void *userdata; + device_destroy_func_t destroy; +}; + +static struct l_queue *device_watches = NULL; +static uint32_t device_next_watch_id = 0; + +static void device_watchlist_item_free(void *userdata) +{ + struct device_watchlist_item *item = userdata; + + if (item->destroy) + item->destroy(item->userdata); + + l_free(item); +} + +static bool device_watchlist_item_match(const void *a, const void *b) +{ + const struct device_watchlist_item *item = a; + uint32_t id = L_PTR_TO_UINT(b); + + return item->id == id; +} + +uint32_t device_watch_add(device_watch_func_t added, + device_watch_func_t removed, + void *userdata, device_destroy_func_t destroy) +{ + struct device_watchlist_item *item; + + item = l_new(struct device_watchlist_item, 1); + item->id = ++device_next_watch_id; + item->added = added; + item->removed = removed; + item->userdata = userdata; + item->destroy = destroy; + + l_queue_push_tail(device_watches, item); + + return item->id; +} + +bool device_watch_remove(uint32_t id) +{ + struct device_watchlist_item *item; + + item = l_queue_remove_if(device_watches, device_watchlist_item_match, + L_UINT_TO_PTR(id)); + if (!item) + return false; + + device_watchlist_item_free(item); + return true; +} + +void __device_watch_call_added(struct netdev *device) +{ + const struct l_queue_entry *e; + + for (e = l_queue_get_entries(device_watches); e; e = e->next) { + struct device_watchlist_item *item = e->data; + + if (item->added) + item->added(device, item->userdata); + } +} + +void __device_watch_call_removed(struct netdev *device) +{ + const struct l_queue_entry *e; + + for (e = l_queue_get_entries(device_watches); e; e = e->next) { + struct device_watchlist_item *item = e->data; + + if (item->removed) + item->removed(device, item->userdata); + } +} + +bool device_init(void) +{ + device_watches = l_queue_new(); + + return true; +} + +bool device_exit(void) +{ + l_queue_destroy(device_watches, device_watchlist_item_free); + + return true; +} diff --git a/src/device.h b/src/device.h new file mode 100644 index 00000000..2e8e9a8f --- /dev/null +++ b/src/device.h @@ -0,0 +1,39 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2013-2016 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +struct netdev; + +typedef void (*device_watch_func_t)(struct netdev *device, void *userdata); +typedef void (*device_destroy_func_t)(void *userdata); + +uint32_t device_watch_add(device_watch_func_t added, + device_watch_func_t removed, + void *userdata, device_destroy_func_t destroy); +bool device_watch_remove(uint32_t id); + +void __device_watch_call_added(struct netdev *device); +void __device_watch_call_removed(struct netdev *device); + +bool device_init(void); +bool device_exit(void); diff --git a/src/main.c b/src/main.c index 84c7bce2..eb614e0a 100644 --- a/src/main.c +++ b/src/main.c @@ -32,6 +32,7 @@ #include "linux/nl80211.h" #include "src/netdev.h" +#include "src/device.h" #include "src/wiphy.h" #include "src/dbus.h" #include "src/agent.h" @@ -185,6 +186,11 @@ int main(int argc, char *argv[]) if (getenv("IWD_GENL_DEBUG")) l_genl_set_debug(genl, do_debug, "[GENL] ", NULL); + if (!device_init()) { + exit_status = EXIT_FAILURE; + goto fail_device; + } + if (!netdev_init()) { exit_status = EXIT_FAILURE; goto fail_netdev; @@ -217,6 +223,9 @@ fail_nl80211: netdev_exit(); fail_netdev: + device_exit(); + +fail_device: l_genl_unref(genl); fail_genl: diff --git a/src/netdev.c b/src/netdev.c index 202d2d9e..e35b9b3e 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -39,20 +39,9 @@ struct netdev_data { char ifname[IF_NAMESIZE]; }; -struct netdev_watchlist_item { - uint32_t id; - netdev_watch_func_t added; - netdev_watch_func_t removed; - void *userdata; - netdev_destroy_func_t destroy; -}; - static struct l_netlink *rtnl = NULL; static struct l_hashmap *netdev_list = NULL; -static struct l_queue *netdev_watches = NULL; -static uint32_t netdev_next_watch_id = 0; - static void do_debug(const char *str, void *user_data) { const char *prefix = user_data; @@ -199,79 +188,6 @@ static void link_notify(uint16_t type, const void *data, uint32_t len, } } -static void netdev_watchlist_item_free(void *userdata) -{ - struct netdev_watchlist_item *item = userdata; - - if (item->destroy) - item->destroy(item->userdata); - - l_free(item); -} - -static bool netdev_watchlist_item_match(const void *a, const void *b) -{ - const struct netdev_watchlist_item *item = a; - uint32_t id = L_PTR_TO_UINT(b); - - return item->id == id; -} - -uint32_t netdev_watch_add(netdev_watch_func_t added, - netdev_watch_func_t removed, - void *userdata, netdev_destroy_func_t destroy) -{ - struct netdev_watchlist_item *item; - - item = l_new(struct netdev_watchlist_item, 1); - item->id = ++netdev_next_watch_id; - item->added = added; - item->removed = removed; - item->userdata = userdata; - item->destroy = destroy; - - l_queue_push_tail(netdev_watches, item); - - return item->id; -} - -bool netdev_watch_remove(uint32_t id) -{ - struct netdev_watchlist_item *item; - - item = l_queue_remove_if(netdev_watches, netdev_watchlist_item_match, - L_UINT_TO_PTR(id)); - if (!item) - return false; - - netdev_watchlist_item_free(item); - return true; -} - -void __netdev_watch_call_added(struct netdev *netdev) -{ - const struct l_queue_entry *e; - - for (e = l_queue_get_entries(netdev_watches); e; e = e->next) { - struct netdev_watchlist_item *item = e->data; - - if (item->added) - item->added(netdev, item->userdata); - } -} - -void __netdev_watch_call_removed(struct netdev *netdev) -{ - const struct l_queue_entry *e; - - for (e = l_queue_get_entries(netdev_watches); e; e = e->next) { - struct netdev_watchlist_item *item = e->data; - - if (item->removed) - item->removed(netdev, item->userdata); - } -} - static void netdev_destroy(void) { /* @@ -309,8 +225,6 @@ bool netdev_init(void) goto destroy; } - netdev_watches = l_queue_new(); - return true; destroy: @@ -328,7 +242,5 @@ bool netdev_exit(void) netdev_destroy(); - l_queue_destroy(netdev_watches, netdev_watchlist_item_free); - return true; } diff --git a/src/netdev.h b/src/netdev.h index 107f2451..9130896a 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -33,14 +33,6 @@ void netdev_set_linkmode_and_operstate(uint32_t ifindex, uint8_t linkmode, uint8_t operstate, netdev_command_func_t cb, void *user_data); -uint32_t netdev_watch_add(netdev_watch_func_t added, - netdev_watch_func_t removed, - void *userdata, netdev_destroy_func_t destroy); -bool netdev_watch_remove(uint32_t id); - -void __netdev_watch_call_added(struct netdev *netdev); -void __netdev_watch_call_removed(struct netdev *netdev); - uint32_t netdev_get_ifindex(struct netdev *netdev); const uint8_t *netdev_get_address(struct netdev *netdev); diff --git a/src/wiphy.c b/src/wiphy.c index 491a79ff..68daa98a 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -48,6 +48,7 @@ #include "src/mpdu.h" #include "src/storage.h" #include "src/network.h" +#include "src/device.h" static struct l_genl_family *nl80211 = NULL; @@ -893,7 +894,7 @@ static void netdev_free(void *data) dbus_pending_reply(&netdev->connect_pending, dbus_error_aborted(netdev->connect_pending)); - __netdev_watch_call_removed(netdev); + __device_watch_call_removed(netdev); dbus = dbus_get_bus(); l_dbus_unregister_object(dbus, iwd_device_get_path(netdev)); @@ -1923,7 +1924,7 @@ static void interface_dump_callback(struct l_genl_msg *msg, void *user_data) l_info("Unable to register %s interface", IWD_DEVICE_INTERFACE); else { - __netdev_watch_call_added(netdev); + __device_watch_call_added(netdev); device_emit_added(netdev); } diff --git a/src/wsc.c b/src/wsc.c index f04cbe9a..5767d995 100644 --- a/src/wsc.c +++ b/src/wsc.c @@ -29,6 +29,7 @@ #include "src/dbus.h" #include "src/netdev.h" +#include "src/device.h" #include "src/wiphy.h" #include "src/scan.h" #include "src/mpdu.h" @@ -40,7 +41,7 @@ #define WALK_TIME 120 static struct l_genl_family *nl80211 = NULL; -static uint32_t netdev_watch = 0; +static uint32_t device_watch = 0; struct wsc_sm { uint32_t ifindex; @@ -294,15 +295,15 @@ static void wsc_free(void *userdata) l_free(wsc); } -static void netdev_appeared(struct netdev *netdev, void *userdata) +static void device_appeared(struct netdev *device, void *userdata) { struct l_dbus *dbus = dbus_get_bus(); struct wsc *wsc; wsc = l_new(struct wsc, 1); - wsc->netdev = netdev; + wsc->netdev = device; - if (!l_dbus_object_add_interface(dbus, iwd_device_get_path(netdev), + if (!l_dbus_object_add_interface(dbus, iwd_device_get_path(device), IWD_WSC_INTERFACE, wsc)) { wsc_free(wsc); @@ -310,7 +311,7 @@ static void netdev_appeared(struct netdev *netdev, void *userdata) } } -static void netdev_disappeared(struct netdev *netdev, void *userdata) +static void device_disappeared(struct netdev *device, void *userdata) { } @@ -321,9 +322,9 @@ bool wsc_init(struct l_genl_family *in) wsc_free, false)) return false; - netdev_watch = netdev_watch_add(netdev_appeared, netdev_disappeared, + device_watch = device_watch_add(device_appeared, device_disappeared, NULL, NULL); - if (!netdev_watch) + if (!device_watch) return false; nl80211 = in; @@ -339,7 +340,7 @@ bool wsc_exit() l_dbus_unregister_interface(dbus_get_bus(), IWD_WSC_INTERFACE); - netdev_watch_remove(netdev_watch); + device_watch_remove(device_watch); nl80211 = 0; return true;