* Pretty much completed BNetworkDevice. The only parts missing are GetMediaAt(),
and parsing the extra station data to retrieve the authentication details. Comments welcome. * NetworkStatus should now mark the currently associated network (if any). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39774 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -19,8 +19,43 @@ struct wireless_network {
|
||||
BNetworkAddress address;
|
||||
uint8 noise_level;
|
||||
uint8 signal_strength;
|
||||
uint32 flags;
|
||||
uint32 authentication_mode;
|
||||
uint32 cipher;
|
||||
uint32 key_mode;
|
||||
};
|
||||
|
||||
// flags
|
||||
#define B_NETWORK_IS_ENCRYPTED 0x01
|
||||
|
||||
// authentication modes
|
||||
enum {
|
||||
B_NETWORK_AUTHENTICATION_NONE = 0,
|
||||
B_NETWORK_AUTHENTICATION_WEP = 1,
|
||||
B_NETWORK_AUTHENTICATION_WPA = 2,
|
||||
B_NETWORK_AUTHENTICATION_WPA2 = 3
|
||||
};
|
||||
|
||||
// cipher algorithms
|
||||
enum {
|
||||
B_NETWORK_CIPHER_NONE = 0x01,
|
||||
B_NETWORK_CIPHER_WEP_40 = 0x02,
|
||||
B_NETWORK_CIPHER_WEP_104 = 0x04,
|
||||
B_NETWORK_CIPHER_WEP_TKIP = 0x08,
|
||||
B_NETWORK_CIPHER_WEP_CCMP = 0x10,
|
||||
B_NETWORK_CIPHER_WEP_AES_128_CMAC = 0x20
|
||||
};
|
||||
|
||||
// key modes
|
||||
enum {
|
||||
B_KEY_MODE_IEEE802_1X = 0x0001,
|
||||
B_KEY_MODE_PSK = 0x0002,
|
||||
B_KEY_MODE_IEEE802_1X_SHA256 = 0x0080,
|
||||
B_KEY_MODE_PSK_SHA256 = 0x0100,
|
||||
B_KEY_MODE_WPS = 0x0200
|
||||
};
|
||||
|
||||
|
||||
class BNetworkDevice {
|
||||
public:
|
||||
BNetworkDevice();
|
||||
@@ -31,6 +66,7 @@ public:
|
||||
void SetTo(const char* name);
|
||||
|
||||
const char* Name() const;
|
||||
bool Exists() const;
|
||||
uint32 Index() const;
|
||||
|
||||
uint32 Flags() const;
|
||||
@@ -49,17 +85,29 @@ public:
|
||||
|
||||
status_t Scan(bool wait = true,
|
||||
bool forceRescan = true);
|
||||
ssize_t CountScanResults();
|
||||
status_t GetScanResultAt(int32 index,
|
||||
|
||||
status_t GetNextNetwork(uint32& cookie,
|
||||
wireless_network& network);
|
||||
status_t GetNetwork(const char* name,
|
||||
wireless_network& network);
|
||||
status_t GetNetwork(const BNetworkAddress& address,
|
||||
wireless_network& network);
|
||||
|
||||
status_t JoinNetwork(wireless_network& network,
|
||||
status_t JoinNetwork(const char* name,
|
||||
const char* password = NULL);
|
||||
status_t JoinNetwork(const wireless_network& network,
|
||||
const char* password = NULL);
|
||||
status_t JoinNetwork(const BNetworkAddress& address,
|
||||
const char* password = NULL);
|
||||
status_t LeaveNetwork();
|
||||
status_t GetCurrentNetwork(wireless_network& network);
|
||||
status_t GetCurrentNetwork(BNetworkAddress& address);
|
||||
|
||||
status_t LeaveNetwork(const char* name);
|
||||
status_t LeaveNetwork(const wireless_network& network);
|
||||
status_t LeaveNetwork(const BNetworkAddress& address);
|
||||
|
||||
status_t GetNextAssociatedNetwork(uint32& cookie,
|
||||
wireless_network& network);
|
||||
status_t GetNextAssociatedNetwork(uint32& cookie,
|
||||
BNetworkAddress& address);
|
||||
|
||||
private:
|
||||
char fName[IF_NAMESIZE];
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "NetworkStatusView.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <stdio.h>
|
||||
@@ -503,13 +505,23 @@ NetworkStatusView::MouseDown(BPoint point)
|
||||
if (!device.IsWireless())
|
||||
continue;
|
||||
|
||||
std::set<BNetworkAddress> associated;
|
||||
BNetworkAddress address;
|
||||
uint32 cookie = 0;
|
||||
while (device.GetNextAssociatedNetwork(cookie, address) == B_OK)
|
||||
associated.insert(address);
|
||||
|
||||
wireless_network network;
|
||||
int32 count = 0;
|
||||
for (int32 i = 0; device.GetScanResultAt(i, network) == B_OK; i++) {
|
||||
printf("%s: noise %u : rssi %u\n", network.name,
|
||||
network.noise_level, network.signal_strength);
|
||||
menu->AddItem(new WirelessNetworkMenuItem(network.name,
|
||||
network.signal_strength, false, NULL));
|
||||
cookie = 0;
|
||||
while (device.GetNextNetwork(cookie, network) == B_OK) {
|
||||
BMenuItem* item = new WirelessNetworkMenuItem(network.name,
|
||||
network.signal_strength,
|
||||
(network.flags & B_NETWORK_IS_ENCRYPTED) != 0, NULL);
|
||||
menu->AddItem(item);
|
||||
if (associated.find(network.address) != associated.end())
|
||||
item->SetMarked(true);
|
||||
|
||||
count++;
|
||||
}
|
||||
if (count == 0) {
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <Messenger.h>
|
||||
@@ -23,6 +25,13 @@ extern "C" {
|
||||
namespace {
|
||||
|
||||
|
||||
struct ie_data {
|
||||
uint8 type;
|
||||
uint8 length;
|
||||
uint8 data[1];
|
||||
};
|
||||
|
||||
|
||||
static status_t
|
||||
get_80211(const char* name, int32 type, void* data, int32& length)
|
||||
{
|
||||
@@ -102,17 +111,11 @@ do_request(T& request, const char* name, int option)
|
||||
}
|
||||
|
||||
|
||||
//! Parse information elements.
|
||||
static void
|
||||
fill_wireless_network(wireless_network& network,
|
||||
struct ieee80211req_sta_req& request)
|
||||
parse_ie(wireless_network& network, uint8* _ie, int32 ieLength)
|
||||
{
|
||||
// Parse IE data
|
||||
int32 ieLength = request.info[0].isi_ie_len;
|
||||
struct ie_data {
|
||||
uint8 type;
|
||||
uint8 length;
|
||||
uint8 data[1];
|
||||
} *ie = (ie_data*)((uint8*)&request.info[0] + request.info[0].isi_ie_off);
|
||||
struct ie_data* ie = (ie_data*)_ie;
|
||||
|
||||
while (ieLength > 1) {
|
||||
switch (ie->type) {
|
||||
@@ -120,16 +123,206 @@ fill_wireless_network(wireless_network& network,
|
||||
strlcpy(network.name, (char*)ie->data,
|
||||
min_c(ie->length + 1, (int)sizeof(network.name)));
|
||||
break;
|
||||
case IEEE80211_ELEMID_RSN:
|
||||
// TODO: we might need to parse those in order to find out
|
||||
// the authentication mode (WPA info in vendor?)
|
||||
break;
|
||||
}
|
||||
|
||||
ieLength -= 2 + ie->length;
|
||||
ie = (ie_data*)((uint8*)ie + 2 + ie->length);
|
||||
}
|
||||
}
|
||||
|
||||
network.address.SetToLinkLevel(request.info[0].isi_macaddr,
|
||||
|
||||
static void
|
||||
parse_ie(wireless_network& network, struct ieee80211req_sta_info& info)
|
||||
{
|
||||
parse_ie(network, (uint8*)&info + info.isi_ie_off, info.isi_ie_len);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
parse_ie(wireless_network& network, struct ieee80211req_scan_result& result)
|
||||
{
|
||||
parse_ie(network, (uint8*)&result + result.isr_ie_off + result.isr_ssid_len
|
||||
+ result.isr_meshid_len, result.isr_ie_len);
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
get_ssid_from_ie(char* name, uint8* _ie, int32 ieLength)
|
||||
{
|
||||
struct ie_data* ie = (ie_data*)_ie;
|
||||
|
||||
while (ieLength > 1) {
|
||||
switch (ie->type) {
|
||||
case IEEE80211_ELEMID_SSID:
|
||||
strlcpy(name, (char*)ie->data, min_c(ie->length + 1, 32));
|
||||
return true;
|
||||
}
|
||||
|
||||
ieLength -= 2 + ie->length;
|
||||
ie = (ie_data*)((uint8*)ie + 2 + ie->length);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
get_ssid_from_ie(char* name, struct ieee80211req_sta_info& info)
|
||||
{
|
||||
return get_ssid_from_ie(name, (uint8*)&info + info.isi_ie_off,
|
||||
info.isi_ie_len);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fill_wireless_network(wireless_network& network,
|
||||
struct ieee80211req_sta_info& info)
|
||||
{
|
||||
network.name[0] = '\0';
|
||||
network.address.SetToLinkLevel(info.isi_macaddr,
|
||||
IEEE80211_ADDR_LEN);
|
||||
network.signal_strength = request.info[0].isi_rssi;
|
||||
network.noise_level = request.info[0].isi_noise;
|
||||
network.signal_strength = info.isi_rssi;
|
||||
network.noise_level = info.isi_noise;
|
||||
network.flags |= (info.isi_capinfo & IEEE80211_CAPINFO_PRIVACY) != 0
|
||||
? B_NETWORK_IS_ENCRYPTED : 0;
|
||||
network.authentication_mode = 0;
|
||||
// TODO: build from IE if possible
|
||||
|
||||
parse_ie(network, info);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fill_wireless_network(wireless_network& network, const char* networkName,
|
||||
struct ieee80211req_scan_result& result)
|
||||
{
|
||||
strlcpy(network.name, networkName, sizeof(network.name));
|
||||
network.address.SetToLinkLevel(result.isr_bssid,
|
||||
IEEE80211_ADDR_LEN);
|
||||
network.signal_strength = result.isr_rssi;
|
||||
network.noise_level = result.isr_noise;
|
||||
network.flags = (result.isr_capinfo & IEEE80211_CAPINFO_PRIVACY)
|
||||
!= 0 ? B_NETWORK_IS_ENCRYPTED : 0;
|
||||
network.authentication_mode = 0;
|
||||
// TODO: build from IE if possible
|
||||
|
||||
parse_ie(network, result);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_scan_result(const char* device, wireless_network& network, uint32 index,
|
||||
const BNetworkAddress* address, const char* name)
|
||||
{
|
||||
if (address != NULL && address->Family() != AF_LINK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
const size_t kBufferSize = 65535;
|
||||
uint8* buffer = (uint8*)malloc(kBufferSize);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
MemoryDeleter deleter(buffer);
|
||||
|
||||
int32 length = kBufferSize;
|
||||
status_t status = get_80211(device, IEEE80211_IOC_SCAN_RESULTS, buffer,
|
||||
length);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
int32 bytesLeft = length;
|
||||
uint8* entry = buffer;
|
||||
uint32 count = 0;
|
||||
|
||||
while (bytesLeft > (int32)sizeof(struct ieee80211req_scan_result)) {
|
||||
ieee80211req_scan_result* result
|
||||
= (ieee80211req_scan_result*)entry;
|
||||
|
||||
char networkName[32];
|
||||
strlcpy(networkName, (char*)(result + 1),
|
||||
min_c((int)sizeof(networkName), result->isr_ssid_len + 1));
|
||||
|
||||
if (index == count || (address != NULL && !memcmp(
|
||||
address->LinkLevelAddress(), result->isr_bssid,
|
||||
IEEE80211_ADDR_LEN))
|
||||
|| (name != NULL && !strcmp(networkName, name))) {
|
||||
// Fill wireless_network with scan result data
|
||||
fill_wireless_network(network, networkName, *result);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
entry += result->isr_len;
|
||||
bytesLeft -= result->isr_len;
|
||||
count++;
|
||||
}
|
||||
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_station(const char* device, wireless_network& network, uint32 index,
|
||||
const BNetworkAddress* address, const char* name)
|
||||
{
|
||||
if (address != NULL && address->Family() != AF_LINK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
const size_t kBufferSize = 65535;
|
||||
uint8* buffer = (uint8*)malloc(kBufferSize);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
MemoryDeleter deleter(buffer);
|
||||
|
||||
struct ieee80211req_sta_req& request = *(ieee80211req_sta_req*)buffer;
|
||||
if (address != NULL) {
|
||||
memcpy(request.is_u.macaddr, address->LinkLevelAddress(),
|
||||
IEEE80211_ADDR_LEN);
|
||||
} else
|
||||
memset(request.is_u.macaddr, 0xff, IEEE80211_ADDR_LEN);
|
||||
|
||||
int32 length = kBufferSize;
|
||||
status_t status = get_80211(device, IEEE80211_IOC_STA_INFO, &request,
|
||||
length);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
int32 bytesLeft = length;
|
||||
uint8* entry = (uint8*)&request.info[0];
|
||||
uint32 count = 0;
|
||||
|
||||
while (bytesLeft > (int32)sizeof(struct ieee80211req_sta_info)) {
|
||||
ieee80211req_sta_info* info = (ieee80211req_sta_info*)entry;
|
||||
|
||||
char networkName[32];
|
||||
get_ssid_from_ie(networkName, *info);
|
||||
if (index == count || address != NULL
|
||||
|| (name != NULL && !strcmp(networkName, name))) {
|
||||
fill_wireless_network(network, *info);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
entry += info->isi_len;
|
||||
bytesLeft -= info->isi_len;
|
||||
count++;
|
||||
}
|
||||
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_network(const char* device, wireless_network& network, uint32 index,
|
||||
const BNetworkAddress* address, const char* name)
|
||||
{
|
||||
status_t status = get_station(device, network, index, address, name);
|
||||
if (status != B_OK)
|
||||
return get_scan_result(device, network, index, address, name);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +370,14 @@ BNetworkDevice::Name() const
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BNetworkDevice::Exists() const
|
||||
{
|
||||
ifreq request;
|
||||
return do_request(request, Name(), SIOCGIFINDEX) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
BNetworkDevice::Index() const
|
||||
{
|
||||
@@ -267,54 +468,19 @@ BNetworkDevice::GetHardwareAddress(BNetworkAddress& address)
|
||||
bool
|
||||
BNetworkDevice::IsEthernet()
|
||||
{
|
||||
return !IsWireless();
|
||||
return IFM_TYPE(Media()) == IFM_ETHER;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BNetworkDevice::IsWireless()
|
||||
{
|
||||
// TODO: fix me!
|
||||
return strstr(Name(), "wifi") != NULL;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
return IFM_TYPE(Media()) == IFM_IEEE80211;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::GetScanResultAt(int32 index, wireless_network& network)
|
||||
BNetworkDevice::Scan(bool wait, bool forceRescan)
|
||||
{
|
||||
#if 0
|
||||
if (index == 0) {
|
||||
@@ -326,52 +492,74 @@ BNetworkDevice::GetScanResultAt(int32 index, wireless_network& network)
|
||||
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;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::JoinNetwork(wireless_network& network, const char* password)
|
||||
BNetworkDevice::GetNextNetwork(uint32& cookie, wireless_network& network)
|
||||
{
|
||||
status_t status = get_scan_result(Name(), network, cookie, NULL, NULL);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
cookie++;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::GetNetwork(const char* name, wireless_network& network)
|
||||
{
|
||||
if (name == NULL || name[0] == '\0')
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return get_network(Name(), network, UINT32_MAX, NULL, name);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::GetNetwork(const BNetworkAddress& address,
|
||||
wireless_network& network)
|
||||
{
|
||||
if (address.Family() != AF_LINK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return get_network(Name(), network, UINT32_MAX, &address, NULL);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::JoinNetwork(const char* name, const char* password)
|
||||
{
|
||||
if (name == NULL || name[0] == '\0')
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BMessage message(kMsgJoinNetwork);
|
||||
status_t status = message.AddString("device", Name());
|
||||
|
||||
if (status == B_OK)
|
||||
status = message.AddString("name", name);
|
||||
if (status == B_OK && password != NULL)
|
||||
status = message.AddString("password", password);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
// Send message to the net_server
|
||||
|
||||
BMessenger networkServer(kNetServerSignature);
|
||||
BMessage reply;
|
||||
status = networkServer.SendMessage(&message, &reply);
|
||||
if (status == B_OK)
|
||||
reply.FindInt32("status", &status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::JoinNetwork(const wireless_network& network,
|
||||
const char* password)
|
||||
{
|
||||
return JoinNetwork(network.address, password);
|
||||
}
|
||||
@@ -409,10 +597,14 @@ BNetworkDevice::JoinNetwork(const BNetworkAddress& address,
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::LeaveNetwork()
|
||||
BNetworkDevice::LeaveNetwork(const char* name)
|
||||
{
|
||||
BMessage message(kMsgLeaveNetwork);
|
||||
status_t status = message.AddString("device", Name());
|
||||
if (status == B_OK)
|
||||
status = message.AddString("name", name);
|
||||
if (status == B_OK)
|
||||
status = message.AddInt32("reason", IEEE80211_REASON_UNSPECIFIED);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
@@ -427,38 +619,68 @@ BNetworkDevice::LeaveNetwork()
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::GetCurrentNetwork(wireless_network& network)
|
||||
BNetworkDevice::LeaveNetwork(const wireless_network& network)
|
||||
{
|
||||
BNetworkAddress address;
|
||||
status_t status = GetCurrentNetwork(address);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
uint8 buffer[10240];
|
||||
struct ieee80211req_sta_req& request = *(ieee80211req_sta_req*)buffer;
|
||||
memcpy(request.is_u.macaddr, address.LinkLevelAddress(),
|
||||
IEEE80211_ADDR_LEN);
|
||||
|
||||
int32 length = sizeof(buffer);
|
||||
status = get_80211(Name(), IEEE80211_IOC_STA_INFO, &request, length);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
fill_wireless_network(network, request);
|
||||
return B_OK;
|
||||
return LeaveNetwork(network.address);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::GetCurrentNetwork(BNetworkAddress& address)
|
||||
BNetworkDevice::LeaveNetwork(const BNetworkAddress& address)
|
||||
{
|
||||
uint8 mac[IEEE80211_ADDR_LEN];
|
||||
int32 length = IEEE80211_ADDR_LEN;
|
||||
status_t status = get_80211(Name(), IEEE80211_IOC_BSSID,
|
||||
mac, length);
|
||||
BMessage message(kMsgLeaveNetwork);
|
||||
status_t status = message.AddString("device", Name());
|
||||
if (status == B_OK) {
|
||||
status = message.AddFlat("address",
|
||||
const_cast<BNetworkAddress*>(&address));
|
||||
}
|
||||
if (status == B_OK)
|
||||
status = message.AddInt32("reason", IEEE80211_REASON_UNSPECIFIED);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
BMessenger networkServer(kNetServerSignature);
|
||||
BMessage reply;
|
||||
status = networkServer.SendMessage(&message, &reply);
|
||||
if (status == B_OK)
|
||||
reply.FindInt32("status", &status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::GetNextAssociatedNetwork(uint32& cookie,
|
||||
wireless_network& network)
|
||||
{
|
||||
BNetworkAddress address;
|
||||
status_t status = GetNextAssociatedNetwork(cookie, address);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return GetNetwork(address, network);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::GetNextAssociatedNetwork(uint32& cookie,
|
||||
BNetworkAddress& address)
|
||||
{
|
||||
// We currently support only a single associated network
|
||||
if (cookie != 0)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
uint8 mac[IEEE80211_ADDR_LEN];
|
||||
int32 length = IEEE80211_ADDR_LEN;
|
||||
status_t status = get_80211(Name(), IEEE80211_IOC_BSSID, mac, length);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0
|
||||
&& mac[5] == 0)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
address.SetToLinkLevel(mac, IEEE80211_ADDR_LEN);
|
||||
cookie++;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user