* Work in progress network API changes.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39147 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _NETWORK_DEVICE_H
|
||||||
|
#define _NETWORK_DEVICE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include <NetworkAddress.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BNetworkAddress;
|
||||||
|
|
||||||
|
|
||||||
|
struct wireless_network {
|
||||||
|
char name[32];
|
||||||
|
BNetworkAddress address;
|
||||||
|
uint8 noise_level;
|
||||||
|
uint8 signal_strength;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BNetworkDevice {
|
||||||
|
public:
|
||||||
|
BNetworkDevice();
|
||||||
|
BNetworkDevice(const char* name);
|
||||||
|
~BNetworkDevice();
|
||||||
|
|
||||||
|
void Unset();
|
||||||
|
void SetTo(const char* name);
|
||||||
|
|
||||||
|
const char* Name() const;
|
||||||
|
|
||||||
|
uint32 Flags() const;
|
||||||
|
bool HasLink() const;
|
||||||
|
|
||||||
|
int32 CountMedia() const;
|
||||||
|
int32 GetMediaAt(int32 index) const;
|
||||||
|
|
||||||
|
int32 Media() const;
|
||||||
|
status_t SetMedia(int32 media);
|
||||||
|
|
||||||
|
status_t GetHardwareAddress(BNetworkAddress& address);
|
||||||
|
|
||||||
|
bool IsEthernet();
|
||||||
|
bool IsWireless();
|
||||||
|
|
||||||
|
status_t Scan(bool wait = true,
|
||||||
|
bool forceRescan = true);
|
||||||
|
ssize_t CountScanResults();
|
||||||
|
status_t GetScanResultAt(int32 index,
|
||||||
|
wireless_network& network);
|
||||||
|
|
||||||
|
status_t JoinNetwork(const BNetworkAddress& address,
|
||||||
|
const char* password = NULL);
|
||||||
|
status_t LeaveNetwork();
|
||||||
|
status_t GetCurrentNetwork(wireless_network& network);
|
||||||
|
status_t GetCurrentNetwork(BNetworkAddress& address);
|
||||||
|
|
||||||
|
private:
|
||||||
|
char fName[IF_NAMESIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _NETWORK_DEVICE_H
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _NETWORK_NOTIFICATIONS_H
|
||||||
|
#define _NETWORK_NOTIFICATIONS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BHandler;
|
||||||
|
class BLooper;
|
||||||
|
class BMessenger;
|
||||||
|
|
||||||
|
|
||||||
|
#define B_NETWORK_INTERFACE_ADDED 0x0001
|
||||||
|
#define B_NETWORK_INTERFACE_REMOVED 0x0002
|
||||||
|
#define B_NETWORK_INTERFACE_CHANGED 0x0003
|
||||||
|
#define B_NETWORK_DEVICE_LINK_CHANGED 0x0010
|
||||||
|
#define B_NETWORK_WLAN_JOINED 0x0100
|
||||||
|
#define B_NETWORK_WLAN_LEFT 0x0200
|
||||||
|
#define B_NETWORK_WLAN_SCANNED 0x0300
|
||||||
|
#define B_NETWORK_WLAN_MESSAGE_INTEGRITY_FAILED 0x0400
|
||||||
|
|
||||||
|
// TODO: add routes, stack unloaded/loaded, ... events
|
||||||
|
|
||||||
|
enum {
|
||||||
|
B_WATCH_NETWORK_INTERFACE_CHANGES = 0x000f,
|
||||||
|
B_WATCH_NETWORK_LINK_CHANGES = 0x00f0,
|
||||||
|
B_WATCH_NETWORK_WLAN_CHANGES = 0x0f00
|
||||||
|
};
|
||||||
|
|
||||||
|
#define B_NETWORK_MONITOR '_NTN'
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
status_t start_watching_network(uint32 flags, const BMessenger& target);
|
||||||
|
status_t start_watching_network(uint32 flags, const BHandler* handler,
|
||||||
|
const BLooper* looper = NULL);
|
||||||
|
|
||||||
|
status_t stop_watching_network(const BMessenger& target);
|
||||||
|
status_t stop_watching_network(const BHandler* handler,
|
||||||
|
const BLooper* looper = NULL);
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _NETWORK_NOTIFICATIONS_H
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <Locker.h>
|
#include <Locker.h>
|
||||||
|
#include <NetworkNotifications.h>
|
||||||
|
|
||||||
|
|
||||||
class BMessenger;
|
class BMessenger;
|
||||||
|
|||||||
@@ -0,0 +1,302 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, Axel Dörfler, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <NetworkDevice.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <net80211/ieee80211_ioctl.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
get_80211(const char* name, int32 type, void* data, int32& length)
|
||||||
|
{
|
||||||
|
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (socket < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
FileDescriptorCloser closer(socket);
|
||||||
|
|
||||||
|
struct ieee80211req ireq;
|
||||||
|
strlcpy(ireq.i_name, name, IF_NAMESIZE);
|
||||||
|
ireq.i_type = type;
|
||||||
|
ireq.i_val = 0;
|
||||||
|
ireq.i_len = length;
|
||||||
|
ireq.i_data = data;
|
||||||
|
|
||||||
|
if (ioctl(socket, SIOCG80211, &ireq, sizeof(struct ieee80211req)) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
length = ireq.i_len;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static status_t
|
||||||
|
set_80211(const char* name, int32 type, void* data,
|
||||||
|
int32 length = 0, int32 value = 0)
|
||||||
|
{
|
||||||
|
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (socket < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
FileDescriptorCloser closer(socket);
|
||||||
|
|
||||||
|
struct ieee80211req ireq;
|
||||||
|
strlcpy(ireq.i_name, name, IF_NAMESIZE);
|
||||||
|
ireq.i_type = type;
|
||||||
|
ireq.i_val = value;
|
||||||
|
ireq.i_len = length;
|
||||||
|
ireq.i_data = data;
|
||||||
|
|
||||||
|
if (ioctl(socket, SIOCS80211, &ireq, sizeof(struct ieee80211req)) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T> status_t
|
||||||
|
set_80211(const char* name, int32 type, T& data, int32 length = 0,
|
||||||
|
int32 value = 0)
|
||||||
|
{
|
||||||
|
if (length == 0)
|
||||||
|
length = sizeof(T);
|
||||||
|
|
||||||
|
return set_80211(name, &data, length, value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T> status_t
|
||||||
|
do_request(T& request, const char* name, int option)
|
||||||
|
{
|
||||||
|
int socket = ::socket(AF_LINK, SOCK_DGRAM, 0);
|
||||||
|
if (socket < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
FileDescriptorCloser closer(socket);
|
||||||
|
|
||||||
|
strlcpy(((struct ifreq&)request).ifr_name, name, IF_NAMESIZE);
|
||||||
|
|
||||||
|
if (ioctl(socket, option, &request, sizeof(T)) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
BNetworkDevice::BNetworkDevice()
|
||||||
|
{
|
||||||
|
Unset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BNetworkDevice::BNetworkDevice(const char* name)
|
||||||
|
{
|
||||||
|
SetTo(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BNetworkDevice::~BNetworkDevice()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNetworkDevice::Unset()
|
||||||
|
{
|
||||||
|
fName[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNetworkDevice::SetTo(const char* name)
|
||||||
|
{
|
||||||
|
strlcpy(fName, name, IF_NAMESIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
BNetworkDevice::Name() const
|
||||||
|
{
|
||||||
|
return fName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
BNetworkDevice::Flags() const
|
||||||
|
{
|
||||||
|
ifreq request;
|
||||||
|
if (do_request(request, Name(), SIOCGIFFLAGS) != B_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return request.ifr_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BNetworkDevice::HasLink() const
|
||||||
|
{
|
||||||
|
return (Flags() & IFF_LINK) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BNetworkDevice::CountMedia() const
|
||||||
|
{
|
||||||
|
ifmediareq request;
|
||||||
|
request.ifm_count = 0;
|
||||||
|
request.ifm_ulist = NULL;
|
||||||
|
|
||||||
|
if (do_request(request, Name(), SIOCGIFMEDIA) != B_OK)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return request.ifm_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BNetworkDevice::Media() const
|
||||||
|
{
|
||||||
|
ifmediareq request;
|
||||||
|
request.ifm_count = 0;
|
||||||
|
request.ifm_ulist = NULL;
|
||||||
|
|
||||||
|
if (do_request(request, Name(), SIOCGIFMEDIA) != B_OK)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return request.ifm_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BNetworkDevice::GetMediaAt(int32 index) const
|
||||||
|
{
|
||||||
|
// TODO: this could do some caching
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BNetworkDevice::SetMedia(int32 media)
|
||||||
|
{
|
||||||
|
ifreq request;
|
||||||
|
request.ifr_media = media;
|
||||||
|
return do_request(request, Name(), SIOCSIFMEDIA);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BNetworkDevice::GetHardwareAddress(BNetworkAddress& address)
|
||||||
|
{
|
||||||
|
ifreq request;
|
||||||
|
status_t status = do_request(request, Name(), SIOCSIFMEDIA);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
address.SetTo(request.ifr_addr);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
BNetworkDevice::CountScanResults()
|
||||||
|
{
|
||||||
|
// TODO: this needs some caching!
|
||||||
|
const size_t kBufferSize = 32768;
|
||||||
|
uint8* buffer = (uint8*)malloc(kBufferSize);
|
||||||
|
if (buffer == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
MemoryDeleter deleter(buffer);
|
||||||
|
|
||||||
|
int32 length = kBufferSize;
|
||||||
|
status_t status = get_80211(Name(), IEEE80211_IOC_SCAN_RESULTS,
|
||||||
|
buffer, length);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
int32 bytesLeft = length;
|
||||||
|
uint8* entry = buffer;
|
||||||
|
int32 count = 0;
|
||||||
|
|
||||||
|
while (bytesLeft > (int32)sizeof(struct ieee80211req_scan_result)) {
|
||||||
|
ieee80211req_scan_result* result
|
||||||
|
= (ieee80211req_scan_result*)entry;
|
||||||
|
|
||||||
|
entry += result->isr_len;
|
||||||
|
bytesLeft -= result->isr_len;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BNetworkDevice::GetScanResultAt(int32 index, wireless_network& network)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (index == 0) {
|
||||||
|
struct ieee80211_scan_req request;
|
||||||
|
memset(&request, 0, sizeof(request));
|
||||||
|
request.sr_flags = IEEE80211_IOC_SCAN_ACTIVE | IEEE80211_IOC_SCAN_ONCE
|
||||||
|
| IEEE80211_IOC_SCAN_NOJOIN;
|
||||||
|
request.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
|
||||||
|
set_80211(Name(), IEEE80211_IOC_SCAN_REQ, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const size_t kBufferSize = 32768;
|
||||||
|
uint8* buffer = (uint8*)malloc(kBufferSize);
|
||||||
|
if (buffer == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
MemoryDeleter deleter(buffer);
|
||||||
|
|
||||||
|
int32 length = kBufferSize;
|
||||||
|
status_t status = get_80211(Name(), IEEE80211_IOC_SCAN_RESULTS,
|
||||||
|
buffer, length);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
int32 bytesLeft = length;
|
||||||
|
uint8* entry = buffer;
|
||||||
|
int32 count = 0;
|
||||||
|
|
||||||
|
while (bytesLeft > (int32)sizeof(struct ieee80211req_scan_result)) {
|
||||||
|
ieee80211req_scan_result* result
|
||||||
|
= (ieee80211req_scan_result*)entry;
|
||||||
|
|
||||||
|
if (count == index) {
|
||||||
|
// Fill wireless_network with scan result data
|
||||||
|
// TODO: add more fields
|
||||||
|
strlcpy(network.name, (char*)(result + 1),
|
||||||
|
min_c((int)sizeof(network.name), result->isr_ssid_len + 1));
|
||||||
|
network.address.SetToLinkLevel(result->isr_bssid,
|
||||||
|
IEEE80211_ADDR_LEN);
|
||||||
|
network.signal_strength = result->isr_rssi;
|
||||||
|
network.noise_level = result->isr_noise;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry += result->isr_len;
|
||||||
|
bytesLeft -= result->isr_len;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_BAD_INDEX;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user