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;