diff options
Diffstat (limited to 'src/platform/wifi')
| -rw-r--r-- | src/platform/wifi/wifi-utils-nl80211.c | 372 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-private.h | 14 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-wext.c | 42 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils.c | 61 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils.h | 2 |
5 files changed, 352 insertions, 139 deletions
diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index db187a1f..a5f25b02 100644 --- a/src/platform/wifi/wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -22,17 +22,17 @@ #include "nm-default.h" -#include "wifi-utils-nl80211.h" - #include <errno.h> #include <string.h> #include <sys/ioctl.h> #include <net/ethernet.h> #include <unistd.h> +#include <netlink/netlink.h> +#include <netlink/msg.h> #include <linux/nl80211.h> -#include "platform/nm-netlink.h" #include "wifi-utils-private.h" +#include "wifi-utils-nl80211.h" #include "platform/nm-platform.h" #include "platform/nm-platform-utils.h" #include "nm-utils.h" @@ -46,14 +46,223 @@ _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ } G_STMT_END +/*****************************************************************************/ + +static int +_nl_nla_parse (struct nlattr *tb[], int maxtype, struct nlattr *head, int len, + const struct nla_policy *policy) +{ + return nla_parse (tb, maxtype, head, len, (struct nla_policy *) policy); +} +#define nla_parse(...) _nl_nla_parse(__VA_ARGS__) + +static int +_nl_nla_parse_nested (struct nlattr *tb[], int maxtype, struct nlattr *nla, + const struct nla_policy *policy) +{ + return nla_parse_nested (tb, maxtype, nla, (struct nla_policy *) policy); +} +#define nla_parse_nested(...) _nl_nla_parse_nested(__VA_ARGS__) + +/***************************************************************************** + * Copied from libnl3/genl: + *****************************************************************************/ + +static void * +genlmsg_put (struct nl_msg *msg, uint32_t port, uint32_t seq, int family, + int hdrlen, int flags, uint8_t cmd, uint8_t version) +{ + struct nlmsghdr *nlh; + struct genlmsghdr hdr = { + .cmd = cmd, + .version = version, + }; + + nlh = nlmsg_put (msg, port, seq, family, GENL_HDRLEN + hdrlen, flags); + if (nlh == NULL) + return NULL; + + memcpy (nlmsg_data (nlh), &hdr, sizeof (hdr)); + + return (char *) nlmsg_data (nlh) + GENL_HDRLEN; +} + +static void * +genlmsg_data (const struct genlmsghdr *gnlh) +{ + return ((unsigned char *) gnlh + GENL_HDRLEN); +} + +static void * +genlmsg_user_hdr (const struct genlmsghdr *gnlh) +{ + return genlmsg_data (gnlh); +} + +static struct genlmsghdr * +genlmsg_hdr (struct nlmsghdr *nlh) +{ + return nlmsg_data (nlh); +} + +static void * +genlmsg_user_data (const struct genlmsghdr *gnlh, const int hdrlen) +{ + return (char *) genlmsg_user_hdr (gnlh) + NLMSG_ALIGN (hdrlen); +} + +static struct nlattr * +genlmsg_attrdata (const struct genlmsghdr *gnlh, int hdrlen) +{ + return genlmsg_user_data (gnlh, hdrlen); +} + +static int +genlmsg_len (const struct genlmsghdr *gnlh) +{ + const struct nlmsghdr *nlh; + + nlh = (const struct nlmsghdr *) ((const unsigned char *) gnlh - NLMSG_HDRLEN); + return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN); +} + +static int +genlmsg_attrlen (const struct genlmsghdr *gnlh, int hdrlen) +{ + return genlmsg_len (gnlh) - NLMSG_ALIGN (hdrlen); +} + +static int +genlmsg_valid_hdr (struct nlmsghdr *nlh, int hdrlen) +{ + struct genlmsghdr *ghdr; + + if (!nlmsg_valid_hdr (nlh, GENL_HDRLEN)) + return 0; + + ghdr = nlmsg_data (nlh); + if (genlmsg_len (ghdr) < NLMSG_ALIGN (hdrlen)) + return 0; + + return 1; +} + +static int +genlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], + int maxtype, const struct nla_policy *policy) +{ + struct genlmsghdr *ghdr; + + if (!genlmsg_valid_hdr (nlh, hdrlen)) + return -NLE_MSG_TOOSHORT; + + ghdr = nlmsg_data (nlh); + return nla_parse (tb, maxtype, genlmsg_attrdata (ghdr, hdrlen), + genlmsg_attrlen (ghdr, hdrlen), policy); +} + +/***************************************************************************** + * Reimplementation of libnl3/genl functions: + *****************************************************************************/ + +static int +probe_response (struct nl_msg *msg, void *arg) +{ + static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = { + [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, + [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING, + .maxlen = GENL_NAMSIZ }, + [CTRL_ATTR_VERSION] = { .type = NLA_U32 }, + [CTRL_ATTR_HDRSIZE] = { .type = NLA_U32 }, + [CTRL_ATTR_MAXATTR] = { .type = NLA_U32 }, + [CTRL_ATTR_OPS] = { .type = NLA_NESTED }, + [CTRL_ATTR_MCAST_GROUPS] = { .type = NLA_NESTED }, + }; + struct nlattr *tb[CTRL_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr (msg); + gint32 *response_data = arg; + + if (genlmsg_parse (nlh, 0, tb, CTRL_ATTR_MAX, ctrl_policy)) + return NL_SKIP; + + if (tb[CTRL_ATTR_FAMILY_ID]) + *response_data = nla_get_u16 (tb[CTRL_ATTR_FAMILY_ID]); + + return NL_STOP; +} + +static int +genl_ctrl_resolve (struct nl_sock *sk, const char *name) +{ + struct nl_msg *msg; + struct nl_cb *cb, *orig; + int rc; + int result = -NLE_OBJ_NOTFOUND; + gint32 response_data = -1; + + if (!(orig = nl_socket_get_cb (sk))) + goto out; + + cb = nl_cb_clone (orig); + nl_cb_put (orig); + if (!cb) + goto out; + + msg = nlmsg_alloc (); + if (!msg) + goto out_cb_free; + + if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL, + 0, 0, CTRL_CMD_GETFAMILY, 1)) + goto out_msg_free; + + if (nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name) < 0) + goto out_msg_free; + + rc = nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, probe_response, &response_data); + if (rc < 0) + goto out_msg_free; + + rc = nl_send_auto_complete (sk, msg); + if (rc < 0) + goto out_msg_free; + + rc = nl_recvmsgs (sk, cb); + if (rc < 0) + goto out_msg_free; + + /* If search was successful, request may be ACKed after data */ + rc = nl_wait_for_ack (sk); + if (rc < 0) + goto out_msg_free; + + if (response_data > 0) + result = response_data; + +out_msg_free: + nlmsg_free (msg); +out_cb_free: + nl_cb_put (cb); +out: + if (result >= 0) + _LOGD (LOGD_WIFI, "genl_ctrl_resolve: resolved \"%s\" as 0x%x", name, result); + else + _LOGE (LOGD_WIFI, "genl_ctrl_resolve: failed resolve \"%s\"", name); + return result; +} + +/***************************************************************************** + * </libn-genl-3> + *****************************************************************************/ + typedef struct { WifiData parent; struct nl_sock *nl_sock; - guint32 *freqs; int id; + struct nl_cb *nl_cb; + guint32 *freqs; int num_freqs; int phy; - bool can_wowlan:1; } WifiDataNl80211; static int @@ -83,16 +292,19 @@ error_handler (struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) static struct nl_msg * _nl80211_alloc_msg (int id, int ifindex, int phy, guint32 cmd, guint32 flags) { - nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl_msg *msg; msg = nlmsg_alloc (); - genlmsg_put (msg, 0, 0, id, 0, flags, cmd, 0); - NLA_PUT_U32 (msg, NL80211_ATTR_IFINDEX, ifindex); - if (phy != -1) - NLA_PUT_U32 (msg, NL80211_ATTR_WIPHY, phy); - return g_steal_pointer (&msg); + if (msg) { + genlmsg_put (msg, 0, 0, id, 0, flags, cmd, 0); + NLA_PUT_U32 (msg, NL80211_ATTR_IFINDEX, ifindex); + if (phy != -1) + NLA_PUT_U32 (msg, NL80211_ATTR_WIPHY, phy); + } + return msg; -nla_put_failure: + nla_put_failure: + nlmsg_free (msg); return NULL; } @@ -102,37 +314,42 @@ nl80211_alloc_msg (WifiDataNl80211 *nl80211, guint32 cmd, guint32 flags) return _nl80211_alloc_msg (nl80211->id, nl80211->parent.ifindex, nl80211->phy, cmd, flags); } +/* NOTE: this function consumes 'msg' */ static int _nl80211_send_and_recv (struct nl_sock *nl_sock, + struct nl_cb *nl_cb, struct nl_msg *msg, int (*valid_handler) (struct nl_msg *, void *), void *valid_data) { - int err; - int done = 0; - const struct nl_cb cb = { - .err_cb = error_handler, - .err_arg = &done, - .finish_cb = finish_handler, - .finish_arg = &done, - .ack_cb = ack_handler, - .ack_arg = &done, - .valid_cb = valid_handler, - .valid_arg = valid_data, - }; + struct nl_cb *cb; + int err, done; g_return_val_if_fail (msg != NULL, -ENOMEM); - err = nl_send_auto (nl_sock, msg); + cb = nl_cb_clone (nl_cb); + if (!cb) { + err = -ENOMEM; + goto out; + } + + err = nl_send_auto_complete (nl_sock, msg); if (err < 0) - return err; + goto out; + + done = 0; + nl_cb_err (cb, NL_CB_CUSTOM, error_handler, &done); + nl_cb_set (cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &done); + nl_cb_set (cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done); + if (valid_handler) + nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data); /* Loop until one of our NL callbacks says we're done; on success * done will be 1, on error it will be < 0. */ while (!done) { - err = nl_recvmsgs (nl_sock, &cb); - if (err < 0 && err != -EAGAIN) { + err = nl_recvmsgs (nl_sock, cb); + if (err && err != -NLE_AGAIN) { /* Kernel scan list can change while we are dumping it, as new scan * results from H/W can arrive. BSS info is assured to be consistent * and we don't need consistent view of whole scan list. Hence do @@ -147,9 +364,12 @@ _nl80211_send_and_recv (struct nl_sock *nl_sock, break; } } - - if (err >= 0 && done < 0) + if (err == 0 && done < 0) err = done; + + out: + nl_cb_put (cb); + nlmsg_free (msg); return err; } @@ -159,7 +379,7 @@ nl80211_send_and_recv (WifiDataNl80211 *nl80211, int (*valid_handler) (struct nl_msg *, void *), void *valid_data) { - return _nl80211_send_and_recv (nl80211->nl_sock, msg, + return _nl80211_send_and_recv (nl80211->nl_sock, nl80211->nl_cb, msg, valid_handler, valid_data); } @@ -170,6 +390,8 @@ wifi_nl80211_deinit (WifiData *parent) if (nl80211->nl_sock) nl_socket_free (nl80211->nl_sock); + if (nl80211->nl_cb) + nl_cb_put (nl80211->nl_cb); g_free (nl80211->freqs); } @@ -213,12 +435,12 @@ wifi_nl80211_get_mode (WifiData *data) struct nl80211_iface_info iface_info = { .mode = NM_802_11_MODE_UNKNOWN, }; - nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl_msg *msg; msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_INTERFACE, 0); if (nl80211_send_and_recv (nl80211, msg, nl80211_iface_info_handler, - &iface_info) < 0) + &iface_info) < 0) return NM_802_11_MODE_UNKNOWN; return iface_info.mode; @@ -228,7 +450,7 @@ static gboolean wifi_nl80211_set_mode (WifiData *data, const NM80211Mode mode) { WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; - nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl_msg *msg; int err; msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_INTERFACE, 0); @@ -248,7 +470,7 @@ wifi_nl80211_set_mode (WifiData *data, const NM80211Mode mode) } err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); - return err >= 0; + return err ? FALSE : TRUE; nla_put_failure: nlmsg_free (msg); @@ -259,14 +481,14 @@ static gboolean wifi_nl80211_set_powersave (WifiData *data, guint32 powersave) { WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; - nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl_msg *msg; int err; msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_POWER_SAVE, 0); NLA_PUT_U32 (msg, NL80211_ATTR_PS_STATE, powersave == 1 ? NL80211_PS_ENABLED : NL80211_PS_DISABLED); err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); - return err >= 0; + return err ? FALSE : TRUE; nla_put_failure: nlmsg_free (msg); @@ -296,7 +518,7 @@ struct nl80211_bss_info { gboolean valid; }; -#define WLAN_EID_SSID 0 +#define WLAN_EID_SSID 0 static void find_ssid (guint8 *ies, guint32 ies_len, @@ -396,7 +618,7 @@ static void nl80211_get_bss_info (WifiDataNl80211 *nl80211, struct nl80211_bss_info *bss_info) { - nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl_msg *msg; memset (bss_info, 0, sizeof (*bss_info)); @@ -520,7 +742,7 @@ static void nl80211_get_ap_info (WifiDataNl80211 *nl80211, struct nl80211_station_info *sta_info) { - nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl_msg *msg; struct nl80211_bss_info bss_info; memset (sta_info, 0, sizeof (*sta_info)); @@ -568,38 +790,35 @@ wifi_nl80211_get_qual (WifiData *data) return sta_info.signal; } +#if HAVE_NL80211_CRITICAL_PROTOCOL_CMDS static gboolean wifi_nl80211_indicate_addressing_running (WifiData *data, gboolean running) { WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; - nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl_msg *msg; int err; msg = nl80211_alloc_msg (nl80211, - running - ? 98 /* NL80211_CMD_CRIT_PROTOCOL_START */ - : 99 /* NL80211_CMD_CRIT_PROTOCOL_STOP */, + running ? NL80211_CMD_CRIT_PROTOCOL_START : + NL80211_CMD_CRIT_PROTOCOL_STOP, 0); /* Despite the DHCP name, we're using this for any type of IP addressing, * DHCPv4, DHCPv6, and IPv6 SLAAC. */ - NLA_PUT_U16 (msg, - 179 /* NL80211_ATTR_CRIT_PROT_ID */, - 1 /* NL80211_CRIT_PROTO_DHCP */); + NLA_PUT_U16 (msg, NL80211_ATTR_CRIT_PROT_ID, NL80211_CRIT_PROTO_DHCP); if (running) { /* Give DHCP 5 seconds to complete */ - NLA_PUT_U16 (msg, - 180 /* NL80211_ATTR_MAX_CRIT_PROT_DURATION */, - 5000); + NLA_PUT_U16 (msg, NL80211_ATTR_MAX_CRIT_PROT_DURATION, 5000); } err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); - return err >= 0; + return err ? FALSE : TRUE; nla_put_failure: nlmsg_free (msg); return FALSE; } +#endif struct nl80211_wowlan_info { gboolean enabled; @@ -628,14 +847,12 @@ static gboolean wifi_nl80211_get_wowlan (WifiData *data) { WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; - nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl_msg *msg; struct nl80211_wowlan_info info; - if (!nl80211->can_wowlan) - return FALSE; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0); nl80211_send_and_recv (nl80211, msg, nl80211_wowlan_handler, &info); + return info.enabled; } @@ -845,22 +1062,8 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) WifiData * wifi_nl80211_init (int ifindex) { - static const WifiDataClass klass = { - .struct_size = sizeof (WifiDataNl80211), - .get_mode = wifi_nl80211_get_mode, - .set_mode = wifi_nl80211_set_mode, - .set_powersave = wifi_nl80211_set_powersave, - .get_freq = wifi_nl80211_get_freq, - .find_freq = wifi_nl80211_find_freq, - .get_bssid = wifi_nl80211_get_bssid, - .get_rate = wifi_nl80211_get_rate, - .get_qual = wifi_nl80211_get_qual, - .get_wowlan = wifi_nl80211_get_wowlan, - .indicate_addressing_running = wifi_nl80211_indicate_addressing_running, - .deinit = wifi_nl80211_deinit, - }; WifiDataNl80211 *nl80211; - nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl_msg *msg; struct nl80211_device_info device_info = {}; char ifname[IFNAMSIZ]; @@ -870,7 +1073,19 @@ wifi_nl80211_init (int ifindex) nm_sprintf_buf (ifname, "if %d", ifindex); } - nl80211 = wifi_data_new (&klass, ifindex); + nl80211 = wifi_data_new (ifindex, sizeof (*nl80211)); + nl80211->parent.get_mode = wifi_nl80211_get_mode; + nl80211->parent.set_mode = wifi_nl80211_set_mode; + nl80211->parent.set_powersave = wifi_nl80211_set_powersave; + nl80211->parent.get_freq = wifi_nl80211_get_freq; + nl80211->parent.find_freq = wifi_nl80211_find_freq; + nl80211->parent.get_bssid = wifi_nl80211_get_bssid; + nl80211->parent.get_rate = wifi_nl80211_get_rate; + nl80211->parent.get_qual = wifi_nl80211_get_qual; +#if HAVE_NL80211_CRITICAL_PROTOCOL_CMDS + nl80211->parent.indicate_addressing_running = wifi_nl80211_indicate_addressing_running; +#endif + nl80211->parent.deinit = wifi_nl80211_deinit; nl80211->nl_sock = nl_socket_alloc (); if (nl80211->nl_sock == NULL) @@ -880,10 +1095,12 @@ wifi_nl80211_init (int ifindex) goto error; nl80211->id = genl_ctrl_resolve (nl80211->nl_sock, "nl80211"); - if (nl80211->id < 0) { - _LOGD (LOGD_WIFI, "genl_ctrl_resolve: failed to resolve \"nl80211\""); + if (nl80211->id < 0) + goto error; + + nl80211->nl_cb = nl_cb_alloc (NL_CB_DEFAULT); + if (nl80211->nl_cb == NULL) goto error; - } nl80211->phy = -1; @@ -936,15 +1153,18 @@ wifi_nl80211_init (int ifindex) nl80211->freqs = device_info.freqs; nl80211->num_freqs = device_info.num_freqs; nl80211->parent.caps = device_info.caps; - nl80211->can_wowlan = device_info.can_wowlan; + + if (device_info.can_wowlan) + nl80211->parent.get_wowlan = wifi_nl80211_get_wowlan; _LOGI (LOGD_PLATFORM | LOGD_WIFI, "(%s): using nl80211 for WiFi device control", ifname); + return (WifiData *) nl80211; error: - wifi_utils_unref ((WifiData *) nl80211); + wifi_utils_deinit ((WifiData *) nl80211); return NULL; } diff --git a/src/platform/wifi/wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h index 59386514..11a0f060 100644 --- a/src/platform/wifi/wifi-utils-private.h +++ b/src/platform/wifi/wifi-utils-private.h @@ -24,8 +24,9 @@ #include "nm-dbus-interface.h" #include "wifi-utils.h" -typedef struct { - gsize struct_size; +struct WifiData { + int ifindex; + NMDeviceWifiCapabilities caps; NM80211Mode (*get_mode) (WifiData *data); @@ -65,14 +66,9 @@ typedef struct { gboolean (*set_mesh_ssid) (WifiData *data, const guint8 *ssid, gsize len); gboolean (*indicate_addressing_running) (WifiData *data, gboolean running); -} WifiDataClass; - -struct WifiData { - const WifiDataClass *klass; - int ifindex; - NMDeviceWifiCapabilities caps; }; -gpointer wifi_data_new (const WifiDataClass *klass, int ifindex); +gpointer wifi_data_new (int ifindex, gsize len); +void wifi_data_free (WifiData *data); #endif /* __WIFI_UTILS_PRIVATE_H__ */ diff --git a/src/platform/wifi/wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c index c8744f79..c4d3c999 100644 --- a/src/platform/wifi/wifi-utils-wext.c +++ b/src/platform/wifi/wifi-utils-wext.c @@ -21,14 +21,17 @@ #include "nm-default.h" -#include "wifi-utils-wext.h" - #include <errno.h> #include <string.h> #include <sys/ioctl.h> #include <net/ethernet.h> #include <unistd.h> +#include "wifi-utils-private.h" +#include "wifi-utils-wext.h" +#include "nm-utils.h" +#include "platform/nm-platform-utils.h" + /* Hacks necessary to #include wireless.h; yay for WEXT */ #ifndef __user #define __user @@ -38,10 +41,6 @@ #include <sys/socket.h> #include <linux/wireless.h> -#include "wifi-utils-private.h" -#include "nm-utils.h" -#include "platform/nm-platform-utils.h" - typedef struct { WifiData parent; int fd; @@ -629,21 +628,6 @@ wext_get_caps (WifiDataWext *wext, const char *ifname, struct iw_range *range) WifiData * wifi_wext_init (int ifindex, gboolean check_scan) { - static const WifiDataClass klass = { - .struct_size = sizeof (WifiDataWext), - .get_mode = wifi_wext_get_mode, - .set_mode = wifi_wext_set_mode, - .set_powersave = wifi_wext_set_powersave, - .get_freq = wifi_wext_get_freq, - .find_freq = wifi_wext_find_freq, - .get_bssid = wifi_wext_get_bssid, - .get_rate = wifi_wext_get_rate, - .get_qual = wifi_wext_get_qual, - .deinit = wifi_wext_deinit, - .get_mesh_channel = wifi_wext_get_mesh_channel, - .set_mesh_channel = wifi_wext_set_mesh_channel, - .set_mesh_ssid = wifi_wext_set_mesh_ssid, - }; WifiDataWext *wext; struct iw_range range; guint32 response_len = 0; @@ -658,7 +642,19 @@ wifi_wext_init (int ifindex, gboolean check_scan) return NULL; } - wext = wifi_data_new (&klass, ifindex); + wext = wifi_data_new (ifindex, sizeof (*wext)); + wext->parent.get_mode = wifi_wext_get_mode; + wext->parent.set_mode = wifi_wext_set_mode; + wext->parent.set_powersave = wifi_wext_set_powersave; + wext->parent.get_freq = wifi_wext_get_freq; + wext->parent.find_freq = wifi_wext_find_freq; + wext->parent.get_bssid = wifi_wext_get_bssid; + wext->parent.get_rate = wifi_wext_get_rate; + wext->parent.get_qual = wifi_wext_get_qual; + wext->parent.deinit = wifi_wext_deinit; + wext->parent.get_mesh_channel = wifi_wext_get_mesh_channel; + wext->parent.set_mesh_channel = wifi_wext_set_mesh_channel; + wext->parent.set_mesh_ssid = wifi_wext_set_mesh_ssid; wext->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (wext->fd < 0) @@ -734,7 +730,7 @@ wifi_wext_init (int ifindex, gboolean check_scan) return (WifiData *) wext; error: - wifi_utils_unref ((WifiData *) wext); + wifi_utils_deinit ((WifiData *) wext); return NULL; } diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c index 8818dc9d..d0052121 100644 --- a/src/platform/wifi/wifi-utils.c +++ b/src/platform/wifi/wifi-utils.c @@ -38,19 +38,22 @@ #include "platform/nm-platform-utils.h" gpointer -wifi_data_new (const WifiDataClass *klass, int ifindex) +wifi_data_new (int ifindex, gsize len) { WifiData *data; - nm_assert (klass); - nm_assert (klass->struct_size > sizeof (WifiData)); - - data = g_malloc0 (klass->struct_size); - data->klass = klass; + data = g_malloc0 (len); data->ifindex = ifindex; return data; } +void +wifi_data_free (WifiData *data) +{ + memset (data, 0, sizeof (*data)); + g_free (data); +} + /*****************************************************************************/ WifiData * @@ -82,14 +85,14 @@ wifi_utils_get_caps (WifiData *data) { g_return_val_if_fail (data != NULL, NM_WIFI_DEVICE_CAP_NONE); - return data->caps; + return data->caps; } NM80211Mode wifi_utils_get_mode (WifiData *data) { g_return_val_if_fail (data != NULL, NM_802_11_MODE_UNKNOWN); - return data->klass->get_mode (data); + return data->get_mode (data); } gboolean @@ -101,7 +104,7 @@ wifi_utils_set_mode (WifiData *data, const NM80211Mode mode) || (mode == NM_802_11_MODE_ADHOC), FALSE); /* nl80211 probably doesn't need this */ - return data->klass->set_mode ? data->klass->set_mode (data, mode) : TRUE; + return data->set_mode ? data->set_mode (data, mode) : TRUE; } gboolean @@ -109,14 +112,14 @@ wifi_utils_set_powersave (WifiData *data, guint32 powersave) { g_return_val_if_fail (data != NULL, FALSE); - return data->klass->set_powersave ? data->klass->set_powersave (data, powersave) : TRUE; + return data->set_powersave ? data->set_powersave (data, powersave) : TRUE; } guint32 wifi_utils_get_freq (WifiData *data) { g_return_val_if_fail (data != NULL, 0); - return data->klass->get_freq (data); + return data->get_freq (data); } guint32 @@ -124,7 +127,7 @@ wifi_utils_find_freq (WifiData *data, const guint32 *freqs) { g_return_val_if_fail (data != NULL, 0); g_return_val_if_fail (freqs != NULL, 0); - return data->klass->find_freq (data, freqs); + return data->find_freq (data, freqs); } gboolean @@ -134,40 +137,38 @@ wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid) g_return_val_if_fail (out_bssid != NULL, FALSE); memset (out_bssid, 0, ETH_ALEN); - return data->klass->get_bssid (data, out_bssid); + return data->get_bssid (data, out_bssid); } guint32 wifi_utils_get_rate (WifiData *data) { g_return_val_if_fail (data != NULL, 0); - return data->klass->get_rate (data); + return data->get_rate (data); } int wifi_utils_get_qual (WifiData *data) { g_return_val_if_fail (data != NULL, 0); - return data->klass->get_qual (data); + return data->get_qual (data); } gboolean wifi_utils_get_wowlan (WifiData *data) { g_return_val_if_fail (data != NULL, 0); - - if (!data->klass->get_wowlan) + if (!data->get_wowlan) return FALSE; - return data->klass->get_wowlan (data); + return data->get_wowlan (data); } void -wifi_utils_unref (WifiData *data) +wifi_utils_deinit (WifiData *data) { g_return_if_fail (data != NULL); - - data->klass->deinit (data); - g_free (data); + data->deinit (data); + wifi_data_free (data); } gboolean @@ -190,8 +191,8 @@ guint32 wifi_utils_get_mesh_channel (WifiData *data) { g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (data->klass->get_mesh_channel != NULL, FALSE); - return data->klass->get_mesh_channel (data); + g_return_val_if_fail (data->get_mesh_channel != NULL, FALSE); + return data->get_mesh_channel (data); } gboolean @@ -199,24 +200,24 @@ wifi_utils_set_mesh_channel (WifiData *data, guint32 channel) { g_return_val_if_fail (data != NULL, FALSE); g_return_val_if_fail (channel <= 13, FALSE); - g_return_val_if_fail (data->klass->set_mesh_channel != NULL, FALSE); - return data->klass->set_mesh_channel (data, channel); + g_return_val_if_fail (data->set_mesh_channel != NULL, FALSE); + return data->set_mesh_channel (data, channel); } gboolean wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) { g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (data->klass->set_mesh_ssid != NULL, FALSE); - return data->klass->set_mesh_ssid (data, ssid, len); + g_return_val_if_fail (data->set_mesh_ssid != NULL, FALSE); + return data->set_mesh_ssid (data, ssid, len); } gboolean wifi_utils_indicate_addressing_running (WifiData *data, gboolean running) { g_return_val_if_fail (data != NULL, FALSE); - if (data->klass->indicate_addressing_running) - return data->klass->indicate_addressing_running (data, running); + if (data->indicate_addressing_running) + return data->indicate_addressing_running (data, running); return FALSE; } diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h index 2633e965..705717b0 100644 --- a/src/platform/wifi/wifi-utils.h +++ b/src/platform/wifi/wifi-utils.h @@ -34,7 +34,7 @@ WifiData *wifi_utils_init (int ifindex, gboolean check_scan); int wifi_utils_get_ifindex (WifiData *data); -void wifi_utils_unref (WifiData *data); +void wifi_utils_deinit (WifiData *data); NMDeviceWifiCapabilities wifi_utils_get_caps (WifiData *data); |