Skip site navigation (1)Skip section navigation (2)
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>