Date: Wed, 11 Nov 2009 11:14:27 -0500 (EST) From: "J.R. Oldroyd" <fbsd@opal.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: ports/140475: [patch] sysutils/xfce4-wavelan-plugin fix for wlan0 interface and signal bars Message-ID: <200911111614.nABGERJh022264@shibato.opal.com> Resent-Message-ID: <200911111620.nABGK1vE007204@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 140475 >Category: ports >Synopsis: [patch] sysutils/xfce4-wavelan-plugin fix for wlan0 interface and signal bars >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Nov 11 16:20:01 UTC 2009 >Closed-Date: >Last-Modified: >Originator: J.R. Oldroyd >Release: FreeBSD 8.0-RC2 amd64 >Organization: >Environment: System: FreeBSD xx.opal.com 8.0-RC2 FreeBSD 8.0-RC2 #1 r198553: Wed Oct 28 16:43:17 EDT 2009 xx@xx.opal.com:/usr/src/sys/amd64/compile/XX amd64 >Description: On systems using wlan0 as WiFi interface, wavelan-plugin does not detect interface. This patch fixes this. In addition, the scaling of the rssi value means that wavelan-plugin only shows "3 bars" even for strong signals. This patch adjusts the scaling. >How-To-Repeat: Configure a wlan0 WiFi interface and run this plugin. Observe that the interface is not detected. >Fix: --- panel-plugin/wi_bsd.c.orig 2006-12-21 16:33:39.000000000 -0500 +++ panel-plugin/wi_bsd.c 2009-10-29 09:51:21.000000000 -0400 @@ -1,6 +1,8 @@ /* $Id: wi_bsd.c 562 2004-12-03 18:29:41Z benny $ */ /*- * Copyright (c) 2003 Benedikt Meurer <benny@xfce.org> + * 2008 Pietro Cerutti <gahr@gahr.ch> + * (FreeBSD > 700000 adaptation) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,16 +38,19 @@ #include <net/if.h> #include <net/if_media.h> #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include <netinet/in.h> +#include <netinet/if_ether.h> +#include <sys/endian.h> +#if __FreeBSD_version >= 700000 +#include <sys/types.h> +#include <sys/sysctl.h> +#include <net80211/ieee80211_ioctl.h> +#else #include <net/if_var.h> #include <net/ethernet.h> - #include <dev/wi/if_wavelan_ieee.h> -#if __FreeBSD_version >= 500033 -#include <sys/endian.h> #endif #else -#include <netinet/in.h> -#include <netinet/if_ether.h> #ifdef __NetBSD__ #include <net80211/ieee80211.h> #include <net80211/ieee80211_ioctl.h> @@ -95,7 +100,11 @@ }; static int _wi_carrier(const struct wi_device *); +#if defined(__FreeBSD__) && __FreeBSD_version > 700000 +static int _wi_getval(const struct wi_device *, struct ieee80211req_scan_result *); +#else static int _wi_getval(const struct wi_device *, struct wi_req *); +#endif static int _wi_vendor(const struct wi_device *, char *, size_t); static int _wi_netname(const struct wi_device *, char *, size_t); static int _wi_quality(const struct wi_device *, int *); @@ -193,24 +202,76 @@ return((ifmr.ifm_status & IFM_ACTIVE) != 0 ? WI_OK : WI_NOCARRIER); } +#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 static int -_wi_getval(const struct wi_device *device, struct wi_req *wr) +_wi_getval(const struct wi_device *device, struct ieee80211req_scan_result *scan) { - struct ifreq ifr; + char buffer[24 * 1024]; + const uint8_t *bp; + struct ieee80211req ireq; + size_t len; + bzero(&ireq, sizeof(ireq)); + strlcpy(ireq.i_name, device->interface, sizeof(ireq.i_name)); + + ireq.i_type = IEEE80211_IOC_SCAN_RESULTS; + ireq.i_data = buffer; + ireq.i_len = sizeof(buffer); + + if(ioctl(device->socket, SIOCG80211, &ireq) < 0) + return(WI_NOSUCHDEV); - bzero((void*)&ifr, sizeof(ifr)); - strlcpy(ifr.ifr_name, device->interface, sizeof(ifr.ifr_name)); - ifr.ifr_data = (void*)wr; + if(ireq.i_len < sizeof(struct ieee80211req_scan_result)) + return(WI_NOSUCHDEV); - if (ioctl(device->socket, SIOCGWAVELAN, &ifr) < 0) - return(WI_NOSUCHDEV); + memcpy(scan, buffer, sizeof(struct ieee80211req_scan_result)); - return(WI_OK); + return(WI_OK); } +#else +static int +_wi_getval(const struct wi_device *device, struct wi_req *wr) +{ + struct ifreq ifr; + + bzero((void*)&ifr, sizeof(ifr)); + strlcpy(ifr.ifr_name, device->interface, sizeof(ifr.ifr_name)); + ifr.ifr_data = (void*)wr; + + if (ioctl(device->socket, SIOCGWAVELAN, &ifr) < 0) + return(WI_NOSUCHDEV); + + return (WI_OK); +} +#endif static int _wi_vendor(const struct wi_device *device, char *buffer, size_t len) { +#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 + /* + * We use sysctl to get a device description + */ + char mib[WI_MAXSTRLEN]; + char dev_name[WI_MAXSTRLEN]; + char *c = dev_name; + int dev_number; + + /* + * Dirty hack to split the device name into name and number + */ + strncpy(dev_name, device->interface, WI_MAXSTRLEN); + while(!isdigit(*c)) c++; + dev_number = (int)strtol(c, NULL, 10); + *c = '\0'; + + snprintf(mib, sizeof(mib), "dev.%s.%d.%%desc", dev_name, dev_number); + if(sysctlbyname(mib, buffer, &len, NULL, 0) == -1) { + /* check for wlan device instead */ + snprintf(mib, sizeof(mib), "net.%s.%d.%%parent", dev_name, dev_number); + if(sysctlbyname(mib, buffer, &len, NULL, 0) == -1) + return (WI_NOSUCHDEV); + } +#else #define WI_RID_STA_IDENTITY_LUCENT 0x1 #define WI_RID_STA_IDENTITY_PRISMII 0x2 #define WI_RID_STA_IDENTITY_SAMSUNG 0x3 @@ -250,6 +311,7 @@ snprintf(buffer, len, "%s (ID %d, version %d.%d)", vendor, wr.wi_val[0], wr.wi_val[2], wr.wi_val[3]); +#endif return(WI_OK); } @@ -257,6 +319,18 @@ static int _wi_netname(const struct wi_device *device, char *buffer, size_t len) { +#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 + struct ieee80211req ireq; + + memset(&ireq, 0, sizeof(ireq)); + strncpy(ireq.i_name, device->interface, sizeof(ireq.i_name)); + ireq.i_type = IEEE80211_IOC_SSID; + ireq.i_val = -1; + ireq.i_data = buffer; + ireq.i_len = len; + if (ioctl(device->socket, SIOCG80211, &ireq) < 0) + return WI_NOSUCHDEV; +#else struct wi_req wr; int result; @@ -268,6 +342,7 @@ return(result); strlcpy(buffer, (char *)&wr.wi_val[1], MIN(len, le16toh(wr.wi_val[0]) + 1)); +#endif return(WI_OK); } @@ -275,6 +350,16 @@ static int _wi_quality(const struct wi_device *device, int *quality) { +#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 + struct ieee80211req_scan_result req; + int result; + bzero(&req, sizeof(req)); + + if((result = _wi_getval(device, &req)) != WI_OK) + return (result); + + *quality = req.isr_rssi * 2; +#else struct wi_req wr; int result; @@ -289,6 +374,7 @@ *quality = le16toh(wr.wi_val[1]); else *quality = le16toh(wr.wi_val[0]); +#endif return(WI_OK); } @@ -296,6 +382,20 @@ static int _wi_rate(const struct wi_device *device, int *rate) { +#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 + struct ieee80211req_scan_result req; + int result, i, high; + bzero(&req, sizeof(req)); + + if((result = _wi_getval(device, &req)) != WI_OK) + return (result); + + for(i=0, high=-1; i<req.isr_nrates; i++) + if((req.isr_rates[i] & IEEE80211_RATE_VAL) > high) + high = req.isr_rates[i] & IEEE80211_RATE_VAL; + + *rate = high / 2; +#else struct wi_req wr; int result; @@ -307,6 +407,7 @@ return(result); *rate = le16toh(wr.wi_val[0]); +#endif return(WI_OK); } >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911111614.nABGERJh022264>