mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 893397 - Add FreeBSD support for NeckoWifi. r=ted, r=jdm
This commit is contained in:
parent
9bd8336634
commit
d9e2f3f810
@ -8281,7 +8281,7 @@ case "$OS_TARGET" in
|
||||
NECKO_WIFI=1
|
||||
fi
|
||||
;;
|
||||
Darwin|SunOS|WINNT)
|
||||
Darwin|FreeBSD|SunOS|WINNT)
|
||||
NECKO_WIFI=1
|
||||
;;
|
||||
Linux)
|
||||
|
@ -35,6 +35,10 @@ if CONFIG['OS_ARCH'] == 'Darwin':
|
||||
UNIFIED_SOURCES += [
|
||||
'osx_corewlan.mm',
|
||||
]
|
||||
elif CONFIG['OS_ARCH'] == 'FreeBSD':
|
||||
UNIFIED_SOURCES += [
|
||||
'nsWifiScannerFreeBSD.cpp',
|
||||
]
|
||||
elif CONFIG['OS_ARCH'] == 'WINNT':
|
||||
UNIFIED_SOURCES += [
|
||||
'nsWifiScannerWin.cpp',
|
||||
|
167
netwerk/wifi/nsWifiScannerFreeBSD.cpp
Normal file
167
netwerk/wifi/nsWifiScannerFreeBSD.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
/* 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@opal.com>, December 2012.
|
||||
|
||||
// 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 <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net80211/ieee80211_ioctl.h>
|
||||
|
||||
#include <ifaddrs.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nsWifiAccessPoint.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
static nsresult
|
||||
FreeBSDGetAccessPointData(nsCOMArray<nsWifiAccessPoint> &accessPoints)
|
||||
{
|
||||
// get list of interfaces
|
||||
struct ifaddrs *ifal;
|
||||
if (getifaddrs(&ifal) < 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
accessPoints.Clear();
|
||||
|
||||
// loop through the interfaces
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
struct ifaddrs *ifa;
|
||||
for (ifa = ifal; ifa; ifa = ifa->ifa_next) {
|
||||
// limit to one interface per address
|
||||
if (ifa->ifa_addr->sa_family != AF_LINK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// store interface name in socket structure
|
||||
struct ifreq ifr;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name));
|
||||
ifr.ifr_addr.sa_family = AF_LOCAL;
|
||||
|
||||
// open socket to interface
|
||||
int s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// clear interface media structure
|
||||
struct ifmediareq ifmr;
|
||||
memset(&ifmr, 0, sizeof(ifmr));
|
||||
strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name));
|
||||
|
||||
// get interface media information
|
||||
if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
// check interface is a WiFi interface
|
||||
if (IFM_TYPE(ifmr.ifm_active) != IFM_IEEE80211) {
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
// perform WiFi scan
|
||||
struct ieee80211req i802r;
|
||||
char iscanbuf[32*1024];
|
||||
memset(&i802r, 0, sizeof(i802r));
|
||||
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 socket
|
||||
close(s);
|
||||
|
||||
// loop through WiFi networks and build geoloc-lookup structure
|
||||
char *vsr = (char *) i802r.i_data;
|
||||
unsigned len = i802r.i_len;
|
||||
while (len >= sizeof(struct ieee80211req_scan_result)) {
|
||||
struct ieee80211req_scan_result *isr =
|
||||
(struct ieee80211req_scan_result *) vsr;
|
||||
|
||||
// determine size of this entry
|
||||
char *id;
|
||||
int idlen;
|
||||
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;
|
||||
}
|
||||
|
||||
// copy network data
|
||||
char ssid[IEEE80211_NWID_LEN+1];
|
||||
strncpy(ssid, id, idlen);
|
||||
ssid[idlen] = '\0';
|
||||
nsWifiAccessPoint *ap = new nsWifiAccessPoint();
|
||||
ap->setSSID(ssid, strlen(ssid));
|
||||
ap->setMac(isr->isr_bssid);
|
||||
ap->setSignal(isr->isr_rssi);
|
||||
accessPoints.AppendObject(ap);
|
||||
rv = NS_OK;
|
||||
|
||||
// log the data
|
||||
LOG(( "FreeBSD access point: "
|
||||
"SSID: %s, MAC: %02x-%02x-%02x-%02x-%02x-%02x, "
|
||||
"Strength: %d, Channel: %dMHz\n",
|
||||
ssid, isr->isr_bssid[0], isr->isr_bssid[1], isr->isr_bssid[2],
|
||||
isr->isr_bssid[3], isr->isr_bssid[4], isr->isr_bssid[5],
|
||||
isr->isr_rssi, isr->isr_freq));
|
||||
|
||||
// increment pointers
|
||||
len -= isr->isr_len;
|
||||
vsr += isr->isr_len;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(ifal);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user