Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Dec 2012 13:59:45 -0500 (EST)
From:      "J.R. Oldroyd" <fbsd@opal.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/174402: [patch] www/chromium: add Wi-Fi geolocation provider
Message-ID:  <201212121859.qBCIxjYO006407@linwhf.opal.com>
Resent-Message-ID: <201212121910.qBCJA0ph088577@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         174402
>Category:       ports
>Synopsis:       [patch] www/chromium: add Wi-Fi geolocation provider
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Dec 12 19:10:00 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     J.R. Oldroyd
>Release:        FreeBSD 8.2-RELEASE amd64
>Organization:
>Environment:
System: FreeBSD xx.opal.com 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Thu Feb 17 02:41:51 UTC 2011 root@mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64
>Description:
This patch adds a FreeBSD Wi-Fi geolocation provider to enable precise position
look-up using Google Location Services.  The absence of this forces chromium to
do position look-up using IP addresses which is often inaccurate for IPv4 and
extremely inaccurate for IPv6.  The existing chromium code already has Wi-Fi
geolocation providers for Windows, Mac and Linux.

This patch was discused and given a week of CFT time here:

http://lists.freebsd.org/pipermail/freebsd-chromium/2012-December/000599.html
>How-To-Repeat:
n/a
>Fix:
diff -ruN /usr/ports/www/chromium/files/patch-content__browser__geolocation__empty_device_data_provider.cc www/chromium/files/patch-content__browser__geolocation__empty_device_data_provider.cc
--- /usr/ports/www/chromium/files/patch-content__browser__geolocation__empty_device_data_provider.cc	1969-12-31 19:00:00.000000000 -0500
+++ www/chromium/files/patch-content__browser__geolocation__empty_device_data_provider.cc	2012-12-06 15:42:33.765041198 -0500
@@ -0,0 +1,11 @@
+--- content/browser/geolocation/empty_device_data_provider.cc.orig	2012-11-27 21:01:24.000000000 -0500
++++ content/browser/geolocation/empty_device_data_provider.cc	2012-12-06 15:40:02.698863304 -0500
+@@ -5,7 +5,7 @@
+ #include "content/browser/geolocation/empty_device_data_provider.h"
+ 
+ // Only define for platforms that lack a real wifi data provider.
+-#if !defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_LINUX)
++#if !defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_LINUX) && !defined(OS_FREEBSD)
+ // static
+ template<>
+ WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() {
diff -ruN /usr/ports/www/chromium/files/patch-content__browser__geolocation__location_provider.cc www/chromium/files/patch-content__browser__geolocation__location_provider.cc
--- /usr/ports/www/chromium/files/patch-content__browser__geolocation__location_provider.cc	2012-08-28 16:25:56.000000000 -0400
+++ www/chromium/files/patch-content__browser__geolocation__location_provider.cc	2012-12-06 15:44:32.232318789 -0500
@@ -5,7 +5,7 @@
  }
  
 -#if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_WIN) && !defined OS_ANDROID
-+#if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_WIN) && !defined OS_ANDROID && !defined(OS_FREEBSD)
++#if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_ANDROID) && !defined(OS_FREEBSD)
  LocationProviderBase* NewSystemLocationProvider() {
    return NULL;
  }
diff -ruN /usr/ports/www/chromium/files/patch-content__browser__geolocation__wifi_data_provider_freebsd.cc www/chromium/files/patch-content__browser__geolocation__wifi_data_provider_freebsd.cc
--- /usr/ports/www/chromium/files/patch-content__browser__geolocation__wifi_data_provider_freebsd.cc	1969-12-31 19:00:00.000000000 -0500
+++ www/chromium/files/patch-content__browser__geolocation__wifi_data_provider_freebsd.cc	2012-12-06 16:45:44.295961550 -0500
@@ -0,0 +1,201 @@
+--- content/browser/geolocation/wifi_data_provider_freebsd.cc.orig	2012-12-06 11:09:56.159107947 -0500
++++ content/browser/geolocation/wifi_data_provider_freebsd.cc	2012-12-06 16:43:53.540918568 -0500
+@@ -0,0 +1,198 @@
++// Copyright (c) 2010 The Chromium Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++// 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 "content/browser/geolocation/wifi_data_provider_freebsd.h"
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.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>
++
++#include "base/utf_string_conversions.h"
++#include "content/browser/geolocation/wifi_data_provider_common.h"
++
++namespace {
++// The time periods, in milliseconds, between successive polls of the wifi data.
++const int kDefaultPollingInterval = 120000;  // 2 mins
++const int kNoChangePollingInterval = 300000;  // 5 mins
++const int kTwoNoChangePollingInterval = 600000;  // 10 mins
++const int kNoWifiPollingIntervalMilliseconds = 20 * 1000; // 20s
++
++// 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 frquency_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 AccessPointData().channel;  // invalid channel
++}
++
++// Provides the wifi API binding for FreeBSD.
++class FreeBSDAccessPointData : public WifiDataProviderCommon::WlanApiInterface {
++public:
++	FreeBSDAccessPointData();
++	~FreeBSDAccessPointData();
++
++	// this does nothing
++	bool Init();
++
++	// get the AP data
++	virtual bool GetAccessPointData(WifiData::AccessPointDataSet* data);
++
++private:
++	DISALLOW_COPY_AND_ASSIGN(FreeBSDAccessPointData);
++};
++
++FreeBSDAccessPointData::FreeBSDAccessPointData() {
++}
++
++FreeBSDAccessPointData::~FreeBSDAccessPointData() {
++}
++
++bool FreeBSDAccessPointData::Init() {
++	return true;
++}
++
++bool FreeBSDAccessPointData::GetAccessPointData(WifiData::AccessPointDataSet* data) {
++	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;
++	AccessPointData		apd;
++
++	if (getifaddrs(&ifal) < 0)
++		return NULL;
++
++	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';
++			apd.ssid = UTF8ToUTF16(ssid);
++			apd.mac_address = MacAddressAsString16(isr->isr_bssid);
++			apd.radio_signal_strength = (isr->isr_rssi/2) + isr->isr_noise;
++			apd.signal_to_noise = apd.radio_signal_strength - isr->isr_noise;
++			apd.channel = frquency_to_channel(isr->isr_freq);
++			VLOG(1) << "FreeBSD access point: "
++				<< "SSID: " << apd.ssid << ", "
++				<< "MAC: " << apd.mac_address << ", "
++				<< "Strength: " << apd.radio_signal_strength << ":"
++					        << apd.signal_to_noise << ", "
++				<< "Channel: " << apd.channel;
++			data->insert(apd);
++			res = true;
++			len -= isr->isr_len;
++			vsr += isr->isr_len;
++		}
++        }
++
++	freeifaddrs(ifal);
++
++	return res;
++}
++
++}  // namespace
++
++// static
++template<>
++WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() {
++	return new FreeBSDWifiDataProvider();
++}
++
++FreeBSDWifiDataProvider::FreeBSDWifiDataProvider() {
++}
++
++FreeBSDWifiDataProvider::~FreeBSDWifiDataProvider() {
++}
++
++WifiDataProviderCommon::WlanApiInterface* FreeBSDWifiDataProvider::NewWlanApi() {
++
++	scoped_ptr<FreeBSDAccessPointData> wlan_api(new FreeBSDAccessPointData);
++	if (wlan_api->Init())
++		return wlan_api.release();
++
++	return NULL;
++}
++
++PollingPolicyInterface* FreeBSDWifiDataProvider::NewPollingPolicy() {
++	return new GenericPollingPolicy<kDefaultPollingInterval,
++	    kNoChangePollingInterval,
++	    kTwoNoChangePollingInterval,
++	    kNoWifiPollingIntervalMilliseconds>;
++}
diff -ruN /usr/ports/www/chromium/files/patch-content__browser__geolocation__wifi_data_provider_freebsd.h www/chromium/files/patch-content__browser__geolocation__wifi_data_provider_freebsd.h
--- /usr/ports/www/chromium/files/patch-content__browser__geolocation__wifi_data_provider_freebsd.h	1969-12-31 19:00:00.000000000 -0500
+++ www/chromium/files/patch-content__browser__geolocation__wifi_data_provider_freebsd.h	2012-12-06 11:46:33.544131323 -0500
@@ -0,0 +1,28 @@
+--- content/browser/geolocation/wifi_data_provider_freebsd.h.orig	2012-12-06 11:09:56.178148204 -0500
++++ content/browser/geolocation/wifi_data_provider_freebsd.h	2012-12-06 11:09:56.178148204 -0500
+@@ -0,0 +1,25 @@
++// Copyright (c) 2012 The Chromium Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_FREEBSD_H_
++#define CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_FREEBSD_H_
++
++#include "content/browser/geolocation/wifi_data_provider_common.h"
++
++// Implementation of the wifi data provider for FreeBSD.
++class FreeBSDWifiDataProvider : public WifiDataProviderCommon {
++public:
++	FreeBSDWifiDataProvider();
++
++private:
++	virtual ~FreeBSDWifiDataProvider();
++
++	// WifiDataProviderCommon
++	virtual WlanApiInterface* NewWlanApi() OVERRIDE;
++	virtual PollingPolicyInterface* NewPollingPolicy() OVERRIDE;
++
++	DISALLOW_COPY_AND_ASSIGN(FreeBSDWifiDataProvider);
++};
++
++#endif  // CONTENT_BROWSER_GEOLOCATION_WIFI_DATA_PROVIDER_FREEBSD_H_
diff -ruN /usr/ports/www/chromium/files/patch-content__content_browser.gypi www/chromium/files/patch-content__content_browser.gypi
--- /usr/ports/www/chromium/files/patch-content__content_browser.gypi	2012-11-07 19:10:16.000000000 -0500
+++ www/chromium/files/patch-content__content_browser.gypi	2012-12-05 16:42:29.000000000 -0500
@@ -1,6 +1,15 @@
---- content/content_browser.gypi.orig	2012-10-31 21:01:37.000000000 +0200
-+++ content/content_browser.gypi	2012-11-07 13:18:40.000000000 +0200
-@@ -995,8 +995,17 @@
+--- content/content_browser.gypi.orig	2012-11-27 21:01:27.000000000 -0500
++++ content/content_browser.gypi	2012-12-05 16:15:35.000000000 -0500
+@@ -409,6 +409,8 @@
+     'browser/geolocation/wifi_data_provider_common_win.cc',
+     'browser/geolocation/wifi_data_provider_common_win.h',
+     'browser/geolocation/wifi_data_provider_corewlan_mac.mm',
++    'browser/geolocation/wifi_data_provider_freebsd.cc',
++    'browser/geolocation/wifi_data_provider_freebsd.h',
+     'browser/geolocation/wifi_data_provider_linux.cc',
+     'browser/geolocation/wifi_data_provider_linux.h',
+     'browser/geolocation/wifi_data_provider_mac.cc',
+@@ -995,8 +997,17 @@
      }],
      ['os_bsd==1', {
        'sources/': [
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212121859.qBCIxjYO006407>