* 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:
Axel Dörfler
2010-11-30 21:22:25 +00:00
parent 6ec25bba48
commit 1d8e6ee862
2 changed files with 137 additions and 1 deletions
+2
View File
@@ -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();
+135 -1
View File
@@ -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;
}