ports/180530: [patch] www/firefox adds WiFi geolocation support

J.R. Oldroyd fbsd at opal.com
Sat Jul 13 13:40:01 UTC 2013


>Number:         180530
>Category:       ports
>Synopsis:       [patch] www/firefox adds WiFi geolocation support
>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:   Sat Jul 13 13:40:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     J.R. Oldroyd
>Release:        FreeBSD 9.1-RELEASE amd64
>Organization:
>Environment:
System: FreeBSD xx.opal.com 9.1-RELEASE FreeBSD 9.1-RELEASE #0 r244985: Tue Jan 8 10:51:13 EST 2013 xx at xx.opal.com:/usr/src/sys/amd64/compile/GENERIC amd64
>Description:
The attached patch adds a WiFi geolocation provider to firefox.
>How-To-Repeat:
n/a
>Fix:
1. Remove the patch files/patch-bug803480.
2. Add the three new files/patch-* attached here.
3. Apply the patch patch-bsd.gecko.mk to Mk/bsd.gecko.mk.

files/patch-configure-necko_wifi

diff --git configure.in configure.in
index fa283d0..936b6e0 100644
--- configure.in
+++ configure.in
@@ -8229,16 +8229,28 @@ MOZ_ARG_DISABLE_BOOL(necko-wifi,
     NECKO_WIFI=,
     NECKO_WIFI=1)
 
-if test "$OS_ARCH" = "OS2"; then
-  dnl OS/2 implementation of Necko-WiFi support will be added in bug 506566
-  NECKO_WIFI=
-fi
-if test "$NECKO_WIFI" -a \
-        "$OS_ARCH" != "Linux" -a \
-        "$OS_ARCH" != "Darwin" -a \
-        "$OS_ARCH" != "SunOS" -a \
-        "$OS_ARCH" != "WINNT"; then
-  AC_MSG_ERROR([Necko WiFi scanning not supported on your platform, use --disable-necko-wifi])
+if test "$NECKO_WIFI"; then
+  case "$OS_TARGET" in
+    Android)
+      ;;
+    Darwin)
+      ;;
+    FreeBSD)
+      ;;
+    SunOS)
+      ;;
+    WINNT)
+      ;;
+    OS2)
+      dnl OS/2 implementation of Necko-WiFi support will be added in bug 506566
+      NECKO_WIFI=
+      ;;
+    *)
+      if test -z "$MOZ_ENABLE_DBUS"; then
+        AC_MSG_ERROR([Necko WiFi scanning needs DBus on your platform, remove --disable-dbus or use --disable-necko-wifi])
+      fi
+      ;;
+  esac
 fi
 
 if test "$NECKO_WIFI"; then

files/patch-netwerk-wifi-Makefile.in

--- netwerk/wifi/Makefile.in.orig	2013-06-18 07:01:38.000000000 -0400
+++ netwerk/wifi/Makefile.in	2013-07-12 20:06:03.000000000 -0400
@@ -32,6 +32,10 @@
 CMMSRCS = osx_corewlan.mm
 endif
 
+ifeq ($(OS_ARCH),FreeBSD)
+CPPSRCS += nsWifiScannerFreeBSD.cpp
+endif
+
 ifneq (,$(filter WINNT,$(OS_ARCH)))
 CPPSRCS += nsWifiScannerWin.cpp
 endif
@@ -41,10 +45,12 @@
 OS_INCLUDES += $(GLIB_CFLAGS)
 endif
 
+ifneq ($(OS_ARCH),FreeBSD)
 ifdef MOZ_ENABLE_DBUS
 CPPSRCS += nsWifiScannerDBus.cpp
 OS_INCLUDES += $(MOZ_DBUS_GLIB_CFLAGS)
 endif
+endif
 
 include $(topsrcdir)/config/rules.mk
 
files/patch-netwerk-wifi-nsWifiScannerFreeBSD.cpp

--- netwerk/wifi/nsWifiScannerFreeBSD.cpp.orig	2013-07-12 12:45:13.000000000 -0400
+++ netwerk/wifi/nsWifiScannerFreeBSD.cpp	2013-07-12 12:45:13.000000000 -0400
@@ -0,0 +1,187 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Developed by J.R. Oldroyd <fbsd at opal.com> and offered to the FreeBSD
+// www/chromium and www/firefox ports under the terms of each browser's
+// license.
+
+// For FreeBSD we use the getifaddrs(3) to obtain the list of interfaces
+// and then check for those with an 802.11 media type and able to return
+// a list of stations.  This is similar to ifconfig(8).
+
+#include "nsCOMPtr.h"
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "nsThreadUtils.h"
+#include "nsXPCOM.h"
+#include "nsXPCOMCID.h"
+#include "nsIObserver.h"
+#include "nsIObserverService.h"
+#include "nsWifiMonitor.h"
+#include "nsWifiAccessPoint.h"
+
+#include "nsServiceManagerUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "mozilla/Services.h"
+
+using namespace mozilla;
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <net/if_media.h>
+#include <ifaddrs.h>
+#include <net80211/ieee80211_ioctl.h>
+#include <net/ethernet.h>
+
+// Convert a wifi frequency to the corresponding channel.
+// Taken from wifi_data_provider_linux.cc where it says this was
+// adapted from geolocaiton/wifilib.cc in googleclient (internal to google).
+int frequency_to_channel(int frequency_Mhz) {
+	if (frequency_Mhz >= 2412 && frequency_Mhz <= 2472)  // Channels 1-13.
+		return (frequency_Mhz - 2407) / 5;
+	if (frequency_Mhz == 2484)
+		return 14;
+	if (frequency_Mhz > 5000 && frequency_Mhz < 6000)  // .11a bands.
+		return (frequency_Mhz - 5000) / 5;
+	// Ignore everything else.
+	return -1;  // invalid channel
+}
+
+nsresult
+FreeBSDGetAccessPointData(nsCOMArray<nsWifiAccessPoint> &accessPoints) {
+	bool			res;
+	char			*dupn;
+	struct ifaddrs		*ifal, *ifa;
+	struct ifreq		ifr;
+	struct ifmediareq	ifmr;
+	struct ieee80211req 	i802r;
+	int			s;
+	char			iscanbuf[32*1024], *vsr;
+	unsigned		len;
+	nsWifiAccessPoint	*ap;
+
+	if (getifaddrs(&ifal) < 0)
+		return NS_ERROR_FAILURE;
+
+	accessPoints.Clear();
+
+	res = false;
+	dupn = NULL;
+	for (ifa = ifal; ifa; ifa = ifa->ifa_next) {
+		memset(&ifr, 0, sizeof(ifr));
+
+		if (dupn != NULL && strcmp(dupn, ifa->ifa_name) == 0)
+			continue;
+		dupn = ifa->ifa_name;
+
+		strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name));
+		ifr.ifr_addr.sa_family = AF_LOCAL;
+                 
+		if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
+			continue;
+
+		(void) memset(&ifmr, 0, sizeof(ifmr));
+		(void) strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name));
+
+		if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
+			close(s);
+			continue;
+		}
+		if (IFM_TYPE(ifmr.ifm_active) != IFM_IEEE80211) {
+			close(s);
+			continue;
+		}
+
+		(void) memset(&i802r, 0, sizeof(i802r));
+		(void) strncpy(i802r.i_name, ifa->ifa_name, sizeof(i802r.i_name));
+		i802r.i_type = IEEE80211_IOC_SCAN_RESULTS;
+		i802r.i_data = iscanbuf;
+		i802r.i_len = sizeof(iscanbuf);
+		if (ioctl(s, SIOCG80211, &i802r) < 0) {
+			close(s);
+			continue;
+		}
+
+		close(s);
+
+		vsr = (char *) i802r.i_data;
+		len = i802r.i_len;
+		while (len >= sizeof(struct ieee80211req_scan_result)) {
+			struct ieee80211req_scan_result *isr;
+			char		*id;
+			int		idlen;
+			char		ssid[IEEE80211_NWID_LEN+1];
+
+			isr = (struct ieee80211req_scan_result *) vsr;
+
+			if (isr->isr_meshid_len) {
+				id = vsr + isr->isr_ie_off + isr->isr_ssid_len;
+				idlen = isr->isr_meshid_len;
+			}
+			else {
+				id = vsr + isr->isr_ie_off;
+				idlen = isr->isr_ssid_len;
+			}
+			strncpy(ssid, id, idlen);
+			ssid[idlen] = '\0';
+			ap = new nsWifiAccessPoint();
+			ap->setSSID(ssid, strlen(ssid));
+			ap->setMac(isr->isr_bssid);
+			ap->setSignal(isr->isr_rssi);
+			// apd.radio_signal_strength = (isr->isr_rssi/2) + isr->isr_noise;
+			// apd.signal_to_noise = apd.radio_signal_strength - isr->isr_noise;
+			// apd.channel = frequency_to_channel(isr->isr_freq);
+			LOG((	   "FreeBSD access point: "
+				<< "SSID: " << apd.ssid << ", "
+				<< "MAC: " << apd.mac_address << ", "
+				<< "Strength: " << apd.radio_signal_strength << ":"
+					        << apd.signal_to_noise << ", "
+				<< "Channel: " << apd.channel ));
+			accessPoints.AppendObject(ap);
+			res = true;
+			len -= isr->isr_len;
+			vsr += isr->isr_len;
+		}
+        }
+
+	freeifaddrs(ifal);
+
+	return res ? NS_OK : NS_ERROR_FAILURE;
+}
+
+nsresult
+nsWifiMonitor::DoScan()
+{
+	// Regularly get the access point data.
+
+	nsCOMArray<nsWifiAccessPoint> lastAccessPoints;
+	nsCOMArray<nsWifiAccessPoint> accessPoints;
+
+	do {
+		nsresult rv = FreeBSDGetAccessPointData(accessPoints);
+		if (NS_FAILED(rv))
+			return rv;
+
+		bool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
+		ReplaceArray(lastAccessPoints, accessPoints);
+
+		rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+		NS_ENSURE_SUCCESS(rv, rv);
+
+		// wait for some reasonable amount of time.  pref?
+		LOG(("waiting on monitor\n"));
+
+		ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+		mon.Wait(PR_SecondsToInterval(60));
+	}
+	while (mKeepGoing);
+
+	return NS_OK;
+}

./patch-bsd.gecko.mk

--- Mk/bsd.gecko.mk.orig	2013-06-26 07:01:34.000000000 -0400
+++ Mk/bsd.gecko.mk	2013-07-13 09:05:24.000000000 -0400
@@ -672,9 +672,13 @@
 LIBS+=		-Wl,--as-needed,-lcxxrt,--no-as-needed
 .endif
 
+.if exists(${FILESDIR}/patch-netwerk-wifi-nsWifiScannerFreeBSD.cpp)
+MOZ_OPTIONS+=	--enable-necko-wifi
+.else
 .if !exists(${FILESDIR}/patch-bug803480) || ! ${PORT_OPTIONS:MDBUS}
 MOZ_OPTIONS+=	--disable-necko-wifi
 .endif
+.endif
 
 .if ${MOZ_TOOLKIT:Mcairo-qt}
 # don't use - transparent backgrounds (bug 521582),
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-ports-bugs mailing list