* Work in progress of reworking the net80211 stack a bit, implementing some of
the missing notifications. * Renamed ieee80211_haiku.c to .cpp, and made it compile (this part requires the updated GCC2, as it uses the ISO-C varargs macros). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38378 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -35,15 +35,21 @@ struct net_notifications_control {
|
||||
// TODO: the following part of this header should end up in a public header
|
||||
// some day!
|
||||
|
||||
#define B_NETWORK_INTERFACE_ADDED 0x01
|
||||
#define B_NETWORK_INTERFACE_REMOVED 0x02
|
||||
#define B_NETWORK_INTERFACE_CHANGED 0x03
|
||||
#define B_NETWORK_DEVICE_LINK_CHANGED 0x10
|
||||
#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_LINK_CHANGES = 0x00f0,
|
||||
B_WATCH_NETWORK_WLAN_CHANGES = 0x0f00
|
||||
};
|
||||
|
||||
#define B_NETWORK_MONITOR '_NTN'
|
||||
|
||||
@@ -11,10 +11,10 @@ UsePrivateKernelHeaders ;
|
||||
Includes [ FGristFiles kernel_c++_structs.h ]
|
||||
: <src!system!kernel>kernel_c++_struct_sizes.h ;
|
||||
|
||||
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ]
|
||||
-Wno-format
|
||||
-Wno-unused
|
||||
-Wno-uninitialized ;
|
||||
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ]
|
||||
-Wno-format -Wno-unused -Wno-uninitialized ;
|
||||
SubDirC++Flags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ]
|
||||
-Wno-format -Wno-unused -Wno-uninitialized ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) .. crypto rijndael ] ;
|
||||
|
||||
@@ -30,7 +30,7 @@ KernelStaticLibrary libfreebsd_wlan.a :
|
||||
ieee80211_crypto_tkip.c
|
||||
ieee80211_crypto_wep.c
|
||||
ieee80211_dfs.c
|
||||
ieee80211_haiku.c
|
||||
ieee80211_haiku.cpp
|
||||
ieee80211_ht.c
|
||||
ieee80211_input.c
|
||||
ieee80211_ioctl.c
|
||||
@@ -60,5 +60,4 @@ KernelStaticLibrary libfreebsd_wlan.a :
|
||||
# NOT SUPPORTED YET ieee80211_superg.c
|
||||
# NOT SUPPORTED YET ieee80211_tdma.c
|
||||
# NOT SUPPORTED YET ieee80211_xauth.c
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
+112
-59
@@ -35,12 +35,12 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include "ieee80211_haiku.h"
|
||||
|
||||
extern "C" {
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/haiku-module.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <net/if.h>
|
||||
@@ -48,10 +48,16 @@
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_var.h>
|
||||
|
||||
#include <ieee80211_var.h>
|
||||
#include "ieee80211_var.h"
|
||||
};
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <util/KMessage.h>
|
||||
|
||||
#include <ether_driver.h>
|
||||
#include <bosii_driver.h>
|
||||
#include <net_notifications.h>
|
||||
|
||||
#include <shared.h>
|
||||
|
||||
@@ -62,21 +68,42 @@ do { \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
|
||||
static net_notifications_module_info* sNotificationModule;
|
||||
|
||||
|
||||
static struct ifnet*
|
||||
get_ifnet(device_t device, int& i)
|
||||
{
|
||||
int unit = device_get_unit(device);
|
||||
|
||||
for (i = 0; i < MAX_DEVICES; i++) {
|
||||
if (gDevices[i] != NULL && gDevices[i]->if_dunit == unit)
|
||||
return gDevices[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
init_wlan_stack()
|
||||
init_wlan_stack(void)
|
||||
{
|
||||
ieee80211_phy_init();
|
||||
ieee80211_auth_setup();
|
||||
ieee80211_ht_init();
|
||||
|
||||
get_module(NET_NOTIFICATIONS_MODULE_NAME,
|
||||
(module_info**)&sNotificationModule);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uninit_wlan_stack()
|
||||
uninit_wlan_stack(void)
|
||||
{
|
||||
|
||||
if (sNotificationModule != NULL)
|
||||
put_module(NET_NOTIFICATIONS_MODULE_NAME);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,21 +111,11 @@ status_t
|
||||
start_wlan(device_t device)
|
||||
{
|
||||
int i;
|
||||
int unit = device_get_unit(device);
|
||||
struct ifnet* ifp;
|
||||
struct ieee80211com* ic;
|
||||
struct ieee80211vap* vap;
|
||||
|
||||
for (i = 0; i < MAX_DEVICES; i++) {
|
||||
if (gDevices[i] != NULL && gDevices[i]->if_dunit == unit)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAX_DEVICES)
|
||||
return B_ERROR;
|
||||
|
||||
ifp = gDevices[i];
|
||||
struct ifnet* ifp = get_ifnet(device, i);
|
||||
if (ifp == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// TODO: review this and find a cleaner solution!
|
||||
// This ensures that the cloned device gets
|
||||
// the same index assigned as the base device
|
||||
// Resulting in the same device name
|
||||
@@ -106,11 +123,10 @@ start_wlan(device_t device)
|
||||
// /dev/net/atheros/1
|
||||
gDevices[i] = NULL;
|
||||
|
||||
ic = ifp->if_l2com;
|
||||
struct ieee80211com* ic = (ieee80211com*)ifp->if_l2com;
|
||||
|
||||
vap = ic->ic_vap_create(ic,
|
||||
"wlan",
|
||||
unit,
|
||||
struct ieee80211vap* vap = ic->ic_vap_create(ic, "wlan",
|
||||
device_get_unit(device),
|
||||
IEEE80211_M_STA, // mode
|
||||
0, // flags
|
||||
NULL, // BSSID
|
||||
@@ -140,30 +156,21 @@ status_t
|
||||
stop_wlan(device_t device)
|
||||
{
|
||||
int i;
|
||||
int unit = device_get_unit(device);
|
||||
struct ifnet* ifp;
|
||||
struct ieee80211com* ic;
|
||||
struct ieee80211vap* vap;
|
||||
struct ifnet* ifp = get_ifnet(device, i);
|
||||
if (ifp == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
for (i = 0; i < MAX_DEVICES; i++) {
|
||||
if (gDevices[i] != NULL && gDevices[i]->if_dunit == unit)
|
||||
break;
|
||||
if (ifp->if_type == IFT_IEEE80211) {
|
||||
// This happens when there was an error in starting the wlan before,
|
||||
// resulting in never creating a clone device
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
if (i == MAX_DEVICES)
|
||||
return B_ERROR;
|
||||
|
||||
ifp = gDevices[i];
|
||||
if (ifp->if_type == IFT_IEEE80211)
|
||||
// This happens when there was an error
|
||||
// in starting the wlan before, resulting
|
||||
// in never creating a clone device
|
||||
return B_OK;
|
||||
|
||||
delete_sem(ifp->scan_done_sem);
|
||||
|
||||
vap = ifp->if_softc;
|
||||
ic = vap->iv_ic;
|
||||
struct ieee80211vap* vap = (ieee80211vap*)ifp->if_softc;
|
||||
struct ieee80211com* ic = vap->iv_ic;
|
||||
|
||||
ic->ic_vap_delete(vap);
|
||||
|
||||
// ic_vap_delete freed gDevices[i]
|
||||
@@ -179,7 +186,7 @@ stop_wlan(device_t device)
|
||||
status_t
|
||||
wlan_control(void* cookie, uint32 op, void* arg, size_t length)
|
||||
{
|
||||
struct ifnet* ifp = cookie;
|
||||
struct ifnet* ifp = (struct ifnet*)cookie;
|
||||
|
||||
switch (op) {
|
||||
case BOSII_DEVICE:
|
||||
@@ -237,7 +244,7 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t length)
|
||||
|
||||
// Tell the user space how much data was copied
|
||||
networkRequest->mtu = request.i_len;
|
||||
if (user_memcpy(arg + offsetof(struct ifreq, ifr_route.mtu),
|
||||
if (user_memcpy(&((struct ifreq*)arg)->ifr_route.mtu,
|
||||
&networkRequest->mtu, sizeof(networkRequest->mtu)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
@@ -256,19 +263,17 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t length)
|
||||
if (length < sizeof(struct ifreq))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) < B_OK)
|
||||
if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) != B_OK
|
||||
|| user_memcpy(&network, networkRequest->source,
|
||||
sizeof(ieee80211req_scan_result)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
if (user_memcpy(&network, networkRequest->source,
|
||||
sizeof(network)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
memset(&request, 0, sizeof(ieee80211req));
|
||||
|
||||
request.i_type = IEEE80211_IOC_SSID;
|
||||
request.i_val = 0;
|
||||
request.i_len = network.isr_ssid_len;
|
||||
request.i_data = ((void*) networkRequest->source)
|
||||
request.i_data = (uint8*)networkRequest->source
|
||||
+ network.isr_ie_off;
|
||||
if (ifp->if_ioctl(ifp, SIOCS80211, (caddr_t)&request) < B_OK)
|
||||
return B_ERROR;
|
||||
@@ -312,8 +317,8 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t length)
|
||||
|
||||
// Tell the user space how much data was copied
|
||||
networkRequest->mtu = request.i_len;
|
||||
if (user_memcpy(arg + offsetof(struct ifreq, ifr_route.mtu),
|
||||
&networkRequest->mtu, sizeof(networkRequest->mtu)) < B_OK)
|
||||
if (user_memcpy(&((struct ifreq*)arg)->ifr_route.mtu,
|
||||
&networkRequest->mtu, sizeof(networkRequest->mtu)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return B_OK;
|
||||
@@ -321,9 +326,25 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t length)
|
||||
|
||||
case SIOCG80211:
|
||||
case SIOCS80211:
|
||||
{
|
||||
// Allowing FreeBSD based WLAN ioctls to pass, as those will become
|
||||
// the future Haiku WLAN ioctls anyway.
|
||||
return ifp->if_ioctl(ifp, op, (caddr_t)arg);
|
||||
|
||||
// FreeBSD drivers assume that the request structure has already
|
||||
// been copied into kernel space
|
||||
struct ieee80211req request;
|
||||
if (user_memcpy(&request, arg, sizeof(struct ieee80211req)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status_t status = ifp->if_ioctl(ifp, op, (caddr_t)&request);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (op == SIOCG80211 && user_memcpy(arg, &request,
|
||||
sizeof(struct ieee80211req)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return B_BAD_VALUE;
|
||||
@@ -333,7 +354,7 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t length)
|
||||
status_t
|
||||
wlan_close(void* cookie)
|
||||
{
|
||||
struct ifnet* ifp = cookie;
|
||||
struct ifnet* ifp = (struct ifnet*)cookie;
|
||||
|
||||
ifp->if_flags &= ~IFF_UP;
|
||||
ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
|
||||
@@ -345,7 +366,7 @@ wlan_close(void* cookie)
|
||||
status_t
|
||||
wlan_if_l2com_alloc(void* data)
|
||||
{
|
||||
struct ifnet* ifp = data;
|
||||
struct ifnet* ifp = (struct ifnet*)data;
|
||||
|
||||
ifp->if_l2com = _kernel_malloc(sizeof(struct ieee80211com), M_ZERO);
|
||||
((struct ieee80211com*)(ifp->if_l2com))->ic_ifp = ifp;
|
||||
@@ -358,7 +379,7 @@ wlan_if_l2com_alloc(void* data)
|
||||
void
|
||||
get_random_bytes(void* p, size_t n)
|
||||
{
|
||||
uint8_t* dp = p;
|
||||
uint8_t* dp = (uint8_t*)p;
|
||||
|
||||
while (n > 0) {
|
||||
uint32_t v = arc4random();
|
||||
@@ -388,7 +409,7 @@ ieee80211_getmgtframe(uint8_t** frm, int headroom, int pktlen)
|
||||
}
|
||||
if (m != NULL) {
|
||||
m->m_data += headroom;
|
||||
*frm = m->m_data;
|
||||
*frm = (uint8_t*)m->m_data;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
@@ -546,6 +567,17 @@ ieee80211_notify_node_join(struct ieee80211_node* ni, int newassoc)
|
||||
|
||||
if (ni == vap->iv_bss)
|
||||
if_link_state_change(ifp, LINK_STATE_UP);
|
||||
|
||||
if (sNotificationModule != NULL) {
|
||||
char messageBuffer[512];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR);
|
||||
message.AddInt32("opcode", B_NETWORK_WLAN_JOINED);
|
||||
message.AddString("interface", ifp->if_xname);
|
||||
// TODO: add data about the node
|
||||
|
||||
sNotificationModule->send_notification(&message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -557,6 +589,17 @@ ieee80211_notify_node_leave(struct ieee80211_node* ni)
|
||||
|
||||
if (ni == vap->iv_bss)
|
||||
if_link_state_change(ifp, LINK_STATE_DOWN);
|
||||
|
||||
if (sNotificationModule != NULL) {
|
||||
char messageBuffer[512];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR);
|
||||
message.AddInt32("opcode", B_NETWORK_WLAN_LEFT);
|
||||
message.AddString("interface", ifp->if_xname);
|
||||
// TODO: add data about the node
|
||||
|
||||
sNotificationModule->send_notification(&message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -565,6 +608,16 @@ ieee80211_notify_scan_done(struct ieee80211vap* vap)
|
||||
{
|
||||
release_sem_etc(vap->iv_ifp->scan_done_sem, 1,
|
||||
B_DO_NOT_RESCHEDULE | B_RELEASE_ALL);
|
||||
|
||||
if (sNotificationModule != NULL) {
|
||||
char messageBuffer[512];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR);
|
||||
message.AddInt32("opcode", B_NETWORK_WLAN_SCANNED);
|
||||
message.AddString("interface", vap->iv_ifp->if_xname);
|
||||
|
||||
sNotificationModule->send_notification(&message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,21 @@
|
||||
#ifndef _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_
|
||||
#define _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
# ifdef __cplusplus
|
||||
// Those includes are needed to avoid C/C++ function export clashes
|
||||
# include <new>
|
||||
# include <thread.h>
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/taskqueue.h>
|
||||
@@ -291,6 +304,10 @@ typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *,
|
||||
struct ieee80211req *);
|
||||
SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc);
|
||||
#define IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/*
|
||||
|
||||
@@ -103,7 +103,7 @@ ieee80211_rate2phytype(const struct ieee80211_rate_table *rt, uint8_t rate)
|
||||
{
|
||||
uint8_t rix = rt->rateCodeToIndex[rate];
|
||||
KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate));
|
||||
return rt->info[rix].phy;
|
||||
return (enum ieee80211_phytype)rt->info[rix].phy;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
|
||||
@@ -126,7 +126,7 @@ void ieee80211_addbasicrates(struct ieee80211_rateset *,
|
||||
static __inline int
|
||||
ieee80211_hdrsize(const void *data)
|
||||
{
|
||||
const struct ieee80211_frame *wh = data;
|
||||
const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data;
|
||||
int size = sizeof(struct ieee80211_frame);
|
||||
|
||||
/* NB: we don't handle control frames */
|
||||
@@ -145,7 +145,7 @@ ieee80211_hdrsize(const void *data)
|
||||
static __inline int
|
||||
ieee80211_anyhdrsize(const void *data)
|
||||
{
|
||||
const struct ieee80211_frame *wh = data;
|
||||
const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data;
|
||||
|
||||
if ((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
|
||||
switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
|
||||
|
||||
Reference in New Issue
Block a user