From fe4c8eb02250a6130c47dbd0a23a16ec8af7b7e2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Oct 2011 09:44:11 -0500 Subject: [PATCH] wifi: add some mesh bits to wifi utils --- src/wifi-utils-private.h | 8 +++++ src/wifi-utils-wext.c | 64 ++++++++++++++++++++++++++++++++++++++++ src/wifi-utils.c | 25 ++++++++++++++-- src/wifi-utils.h | 6 ++++ 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/wifi-utils-private.h b/src/wifi-utils-private.h index 7a4c45bada..a29ed27302 100644 --- a/src/wifi-utils-private.h +++ b/src/wifi-utils-private.h @@ -56,6 +56,14 @@ struct WifiData { int (*get_qual) (WifiData *data); void (*deinit) (WifiData *data); + + /* OLPC Mesh-only functions */ + + /* channel == 0 means "auto channel" */ + gboolean (*set_mesh_channel) (WifiData *data, guint32 channel); + + /* ssid == NULL means "auto SSID" */ + gboolean (*set_mesh_ssid) (WifiData *data, const GByteArray *ssid); }; gpointer wifi_data_new (const char *iface, int ifindex, gsize len); diff --git a/src/wifi-utils-wext.c b/src/wifi-utils-wext.c index 2e24d198dd..3c383d4674 100644 --- a/src/wifi-utils-wext.c +++ b/src/wifi-utils-wext.c @@ -364,6 +364,68 @@ wifi_wext_get_qual (WifiData *data) return wext_qual_to_percent (&stats.qual, &wext->max_qual); } +/*********************/ +/* OLPC Mesh-only functions */ + +static gboolean +wifi_wext_set_mesh_channel (WifiData *data, guint32 channel) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + + if (channel > 0) { + wrq.u.freq.flags = IW_FREQ_FIXED; + wrq.u.freq.e = 0; + wrq.u.freq.m = channel; + } + + if (ioctl (wext->fd, SIOCSIWFREQ, &wrq) < 0) { + nm_log_err (LOGD_HW | LOGD_WIFI | LOGD_OLPC_MESH, + "(%s): error setting channel to %d: %s", + wext->parent.iface, channel, strerror (errno)); + return FALSE; + } + + return TRUE; +} + +static gboolean +wifi_wext_set_mesh_ssid (WifiData *data, const GByteArray *ssid) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + guint32 len = 0; + char buf[IW_ESSID_MAX_SIZE + 1]; + + memset (buf, 0, sizeof (buf)); + if (ssid) { + len = ssid->len; + memcpy (buf, ssid->data, MIN (sizeof (buf) - 1, len)); + } + wrq.u.essid.pointer = (caddr_t) buf; + wrq.u.essid.length = len; + wrq.u.essid.flags = (len > 0) ? 1 : 0; /* 1=enable SSID, 0=disable/any */ + + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + if (ioctl (wext->fd, SIOCSIWESSID, &wrq) == 0) + return TRUE; + + if (errno != ENODEV) { + nm_log_err (LOGD_HW | LOGD_WIFI | LOGD_OLPC_MESH, + "(%s): error setting SSID to '%s': %s", + wext->parent.iface, + ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(null)", + strerror (errno)); + } + + return FALSE; +} + +/*********************/ + static gboolean wext_can_scan (WifiDataWext *wext) { @@ -487,6 +549,8 @@ wifi_wext_init (const char *iface, int ifindex) wext->parent.get_rate = wifi_wext_get_rate; wext->parent.get_qual = wifi_wext_get_qual; wext->parent.deinit = wifi_wext_deinit; + 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, 0); if (wext->fd < 0) diff --git a/src/wifi-utils.c b/src/wifi-utils.c index 748a11d112..9794c364be 100644 --- a/src/wifi-utils.c +++ b/src/wifi-utils.c @@ -88,9 +88,7 @@ wifi_utils_set_mode (WifiData *data, const NM80211Mode mode) g_return_val_if_fail ((mode == NM_802_11_MODE_INFRA) || (mode == NM_802_11_MODE_ADHOC), FALSE); /* nl80211 probably doesn't need this */ - if (data->set_mode) - return data->set_mode (data, mode); - return TRUE; + return data->set_mode ? data->set_mode (data, mode) : TRUE; } guint32 @@ -158,3 +156,24 @@ wifi_utils_is_wifi (const char *iface) return FALSE; } + +/* OLPC Mesh-only functions */ + +gboolean +wifi_utils_set_mesh_channel (WifiData *data, guint32 channel) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (channel >= 0, FALSE); + g_return_val_if_fail (channel <= 13, FALSE); + 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 GByteArray *ssid) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->set_mesh_ssid != NULL, FALSE); + return data->set_mesh_ssid (data, ssid); +} + diff --git a/src/wifi-utils.h b/src/wifi-utils.h index e75f563bca..daac5b1a5a 100644 --- a/src/wifi-utils.h +++ b/src/wifi-utils.h @@ -61,4 +61,10 @@ guint32 wifi_utils_get_rate (WifiData *data); /* Returns quality 0 - 100% on succes, or -1 on error */ int wifi_utils_get_qual (WifiData *data); + +/* OLPC Mesh-only functions */ +gboolean wifi_utils_set_mesh_channel (WifiData *data, guint32 channel); + +gboolean wifi_utils_set_mesh_ssid (WifiData *data, const GByteArray *ssid); + #endif /* WIFI_UTILS_H */