From 1d8e6ee862d36468a620df521b8b0ea37f9e32c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 30 Nov 2010 21:22:25 +0000 Subject: [PATCH] * 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 --- headers/os/net/NetworkDevice.h | 2 + src/kits/network/libnetapi/NetworkDevice.cpp | 136 ++++++++++++++++++- 2 files changed, 137 insertions(+), 1 deletion(-) diff --git a/headers/os/net/NetworkDevice.h b/headers/os/net/NetworkDevice.h index 5b46a07f01..5218a54802 100644 --- a/headers/os/net/NetworkDevice.h +++ b/headers/os/net/NetworkDevice.h @@ -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(); diff --git a/src/kits/network/libnetapi/NetworkDevice.cpp b/src/kits/network/libnetapi/NetworkDevice.cpp index a500861743..00e0a9cdad 100644 --- a/src/kits/network/libnetapi/NetworkDevice.cpp +++ b/src/kits/network/libnetapi/NetworkDevice.cpp @@ -10,14 +10,20 @@ #include #include +#include + #include +#include extern "C" { # include } -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(&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; +}