* Untested work-in-progress. Actually cannot work because of missing
functionality in BNetworkAddress. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39687 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -53,6 +53,8 @@ public:
|
||||
status_t GetScanResultAt(int32 index,
|
||||
wireless_network& network);
|
||||
|
||||
status_t JoinNetwork(wireless_network& network,
|
||||
const char* password = NULL);
|
||||
status_t JoinNetwork(const BNetworkAddress& address,
|
||||
const char* password = NULL);
|
||||
status_t LeaveNetwork();
|
||||
|
||||
@@ -10,14 +10,20 @@
|
||||
#include <net/if.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <Messenger.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <NetServer.h>
|
||||
|
||||
extern "C" {
|
||||
# include <net80211/ieee80211_ioctl.h>
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
namespace {
|
||||
|
||||
|
||||
static status_t
|
||||
get_80211(const char* name, int32 type, void* data, int32& length)
|
||||
{
|
||||
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||
@@ -96,6 +102,40 @@ do_request(T& request, const char* name, int option)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fill_wireless_network(wireless_network& network,
|
||||
struct ieee80211req_sta_req& request)
|
||||
{
|
||||
// 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);
|
||||
|
||||
while (ieLength > 1) {
|
||||
switch (ie->type) {
|
||||
case IEEE80211_ELEMID_SSID:
|
||||
strlcpy(network.name, (char*)ie->data,
|
||||
min_c(ie->length + 1, (int)sizeof(network.name)));
|
||||
break;
|
||||
}
|
||||
|
||||
ieLength -= 2 + ie->length;
|
||||
ie = (ie_data*)((uint8*)ie + 2 + ie->length);
|
||||
}
|
||||
|
||||
network.address.SetToLinkLevel(request.info[0].isi_macaddr,
|
||||
IEEE80211_ADDR_LEN);
|
||||
network.signal_strength = request.info[0].isi_rssi;
|
||||
network.noise_level = request.info[0].isi_noise;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@@ -328,3 +368,97 @@ BNetworkDevice::GetScanResultAt(int32 index, wireless_network& network)
|
||||
|
||||
return B_BAD_INDEX;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::JoinNetwork(wireless_network& network, const char* password)
|
||||
{
|
||||
return JoinNetwork(network.address, password);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::JoinNetwork(const BNetworkAddress& address,
|
||||
const char* password)
|
||||
{
|
||||
if (address.InitCheck() != B_OK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BMessage message(kMsgJoinNetwork);
|
||||
status_t status = message.AddString("device", Name());
|
||||
|
||||
if (status == B_OK) {
|
||||
status = message.AddFlat("address",
|
||||
const_cast<BNetworkAddress*>(&address));
|
||||
}
|
||||
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::LeaveNetwork()
|
||||
{
|
||||
BMessage message(kMsgLeaveNetwork);
|
||||
status_t status = message.AddString("device", Name());
|
||||
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::GetCurrentNetwork(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;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkDevice::GetCurrentNetwork(BNetworkAddress& address)
|
||||
{
|
||||
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;
|
||||
|
||||
address.SetToLinkLevel(mac, IEEE80211_ADDR_LEN);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user