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>