switch timeout processing to libev
Rework the timeout and network code to use libev.
This commit is contained in:
@ -4,6 +4,8 @@
|
||||
#include "wifi_drivers.h"
|
||||
#include "netlink_link.h"
|
||||
|
||||
static void netlink_event_receive_cb(EV_P_ ev_io *w, int revents);
|
||||
|
||||
/* */
|
||||
struct netlink_request {
|
||||
struct nlmsghdr hdr;
|
||||
@ -12,7 +14,8 @@ struct netlink_request {
|
||||
};
|
||||
|
||||
/* */
|
||||
struct netlink* netlink_init(void) {
|
||||
struct netlink *netlink_init(wifi_global_handle handle)
|
||||
{
|
||||
int sock;
|
||||
struct sockaddr_nl local;
|
||||
struct netlink* netlinkhandle;
|
||||
@ -34,43 +37,61 @@ struct netlink* netlink_init(void) {
|
||||
|
||||
/* Netlink reference */
|
||||
netlinkhandle = (struct netlink*)capwap_alloc(sizeof(struct netlink));
|
||||
netlinkhandle->handle = handle;
|
||||
netlinkhandle->sock = sock;
|
||||
netlinkhandle->nl_sequence = 1;
|
||||
|
||||
ev_io_init(&netlinkhandle->io_ev, netlink_event_receive_cb, sock, EV_READ);
|
||||
ev_io_start(EV_DEFAULT_UC_ &netlinkhandle->io_ev);
|
||||
|
||||
return netlinkhandle;
|
||||
}
|
||||
|
||||
/* */
|
||||
void netlink_free(struct netlink* netlinkhandle) {
|
||||
void netlink_free(struct netlink* netlinkhandle)
|
||||
{
|
||||
ASSERT(netlinkhandle != NULL);
|
||||
ASSERT(netlinkhandle->sock >= 0);
|
||||
|
||||
if (ev_is_active(&netlinkhandle->io_ev))
|
||||
ev_io_stop(EV_DEFAULT_UC_ &netlinkhandle->io_ev);
|
||||
|
||||
/* */
|
||||
close(netlinkhandle->sock);
|
||||
capwap_free(netlinkhandle);
|
||||
}
|
||||
|
||||
static void invoke_event_fn(netlink_event_fn event_fn, struct netlink *netlinkhandle, struct nlmsghdr* message)
|
||||
{
|
||||
if (!event_fn)
|
||||
return;
|
||||
|
||||
if (NLMSG_PAYLOAD(message, 0) < sizeof(struct ifinfomsg))
|
||||
return;
|
||||
|
||||
event_fn(netlinkhandle->handle,
|
||||
NLMSG_DATA(message),
|
||||
(uint8_t*)(NLMSG_DATA(message) + NLMSG_ALIGN(sizeof(struct ifinfomsg))),
|
||||
NLMSG_PAYLOAD(message, sizeof(struct ifinfomsg)));
|
||||
}
|
||||
|
||||
/* */
|
||||
void netlink_event_receive(int fd, void** params, int paramscount) {
|
||||
static void netlink_event_receive_cb(EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
struct netlink *netlinkhandle = (struct netlink *)
|
||||
(((char *)w) - offsetof(struct netlink, io_ev));
|
||||
int result;
|
||||
struct netlink* netlinkhandle;
|
||||
struct sockaddr_nl from;
|
||||
socklen_t fromlen;
|
||||
char buffer[8192];
|
||||
struct nlmsghdr* message;
|
||||
|
||||
ASSERT(fd >= 0);
|
||||
ASSERT(params != NULL);
|
||||
ASSERT(paramscount == 2);
|
||||
|
||||
/* */
|
||||
netlinkhandle = (struct netlink*)params[0];
|
||||
|
||||
/* Retrieve all netlink message */
|
||||
for (;;) {
|
||||
/* Get message */
|
||||
fromlen = sizeof(struct sockaddr_nl);
|
||||
result = recvfrom(netlinkhandle->sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&from, &fromlen);
|
||||
result = recvfrom(w->fd, buffer, sizeof(buffer), MSG_DONTWAIT,
|
||||
(struct sockaddr *)&from, &fromlen);
|
||||
if (result <= 0) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
@ -84,21 +105,18 @@ void netlink_event_receive(int fd, void** params, int paramscount) {
|
||||
message = (struct nlmsghdr*)buffer;
|
||||
while (NLMSG_OK(message, result)) {
|
||||
switch (message->nlmsg_type) {
|
||||
case RTM_NEWLINK: {
|
||||
if (netlinkhandle->newlink_event && NLMSG_PAYLOAD(message, 0) >= sizeof(struct ifinfomsg)) {
|
||||
netlinkhandle->newlink_event((wifi_global_handle)params[1], NLMSG_DATA(message), (uint8_t*)(NLMSG_DATA(message) + NLMSG_ALIGN(sizeof(struct ifinfomsg))), NLMSG_PAYLOAD(message, sizeof(struct ifinfomsg)));
|
||||
}
|
||||
case RTM_NEWLINK:
|
||||
invoke_event_fn(netlinkhandle->newlink_event,
|
||||
netlinkhandle, message);
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
case RTM_DELLINK:
|
||||
invoke_event_fn(netlinkhandle->dellink_event,
|
||||
netlinkhandle, message);
|
||||
break;
|
||||
|
||||
case RTM_DELLINK: {
|
||||
if (netlinkhandle->dellink_event && NLMSG_PAYLOAD(message, 0) >= sizeof(struct ifinfomsg)) {
|
||||
netlinkhandle->dellink_event((wifi_global_handle)params[1], NLMSG_DATA(message), (uint8_t*)(NLMSG_DATA(message) + NLMSG_ALIGN(sizeof(struct ifinfomsg))), NLMSG_PAYLOAD(message, sizeof(struct ifinfomsg)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/netlink.h>
|
||||
|
||||
#include <ev.h>
|
||||
|
||||
/* */
|
||||
#ifndef IFLA_IFNAME
|
||||
#define IFLA_IFNAME 3
|
||||
@ -37,17 +39,23 @@
|
||||
#define IFF_DORMANT 0x20000
|
||||
#endif
|
||||
|
||||
typedef void (*netlink_event_fn)(wifi_global_handle handle, struct ifinfomsg* infomsg,
|
||||
uint8_t* data, int length);
|
||||
|
||||
/* */
|
||||
struct netlink {
|
||||
wifi_global_handle handle;
|
||||
int sock;
|
||||
void (*newlink_event)(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length);
|
||||
void (*dellink_event)(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length);
|
||||
ev_io io_ev;
|
||||
|
||||
netlink_event_fn newlink_event;
|
||||
netlink_event_fn dellink_event;
|
||||
|
||||
int nl_sequence;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct netlink* netlink_init(void);
|
||||
struct netlink* netlink_init(wifi_global_handle handle);
|
||||
void netlink_free(struct netlink* netlinkhandle);
|
||||
|
||||
/* */
|
||||
|
@ -25,15 +25,22 @@ static struct wifi_global g_wifiglobal;
|
||||
static uint8_t g_bufferIEEE80211[IEEE80211_MTU];
|
||||
|
||||
/* */
|
||||
static void wifi_station_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
|
||||
static void wifi_wlan_deauthentication_station(struct wifi_wlan* wlan, struct wifi_station* station, uint16_t reasoncode, int reusestation);
|
||||
static void wifi_station_timeout_delete(EV_P_ ev_timer *w, int revents);
|
||||
static void wifi_station_timeout_deauth(EV_P_ ev_timer *w, int revents);
|
||||
static void wifi_wlan_deauthentication_station(struct wifi_wlan* wlan,
|
||||
struct wifi_station* station,
|
||||
uint16_t reasoncode,
|
||||
int reusestation);
|
||||
|
||||
/* */
|
||||
static void wifi_wlan_getrates(struct wifi_device* device, uint8_t* rates, int ratescount, struct device_setrates_params* device_params) {
|
||||
static void wifi_wlan_getrates(struct wifi_device* device,
|
||||
uint8_t* rates, int ratescount,
|
||||
struct device_setrates_params* device_params)
|
||||
{
|
||||
int i, j, w;
|
||||
int radiotype;
|
||||
uint32_t mode = 0;
|
||||
const struct wifi_capability* capability;
|
||||
const struct wifi_capability* capability;
|
||||
|
||||
ASSERT(device != NULL);
|
||||
ASSERT(rates != NULL);
|
||||
@ -262,10 +269,7 @@ static void wifi_station_clean(struct wifi_station* station) {
|
||||
}
|
||||
|
||||
/* Remove timers */
|
||||
if (station->idtimeout != CAPWAP_TIMEOUT_INDEX_NO_SET) {
|
||||
capwap_timeout_deletetimer(g_wifiglobal.timeout, station->idtimeout);
|
||||
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
|
||||
}
|
||||
ev_timer_stop(EV_DEFAULT_UC_ &station->timeout);
|
||||
|
||||
/* */
|
||||
station->flags = 0;
|
||||
@ -273,7 +277,8 @@ static void wifi_station_clean(struct wifi_station* station) {
|
||||
}
|
||||
|
||||
/* */
|
||||
static void wifi_station_delete(struct wifi_station* station) {
|
||||
static void wifi_station_delete(struct wifi_station* station)
|
||||
{
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* */
|
||||
@ -283,8 +288,10 @@ static void wifi_station_delete(struct wifi_station* station) {
|
||||
wifi_station_clean(station);
|
||||
|
||||
/* Delay delete station */
|
||||
station->timeoutaction = WIFI_STATION_TIMEOUT_ACTION_DELETE;
|
||||
station->idtimeout = capwap_timeout_set(g_wifiglobal.timeout, station->idtimeout, WIFI_STATION_TIMEOUT_AFTER_DEAUTHENTICATED, wifi_station_timeout, station, NULL);
|
||||
ev_timer_stop(EV_DEFAULT_UC_ &station->timeout);
|
||||
ev_timer_init(&station->timeout, wifi_station_timeout_delete,
|
||||
WIFI_STATION_TIMEOUT_AFTER_DEAUTHENTICATED / 1000.0, 0.);
|
||||
ev_timer_start(EV_DEFAULT_UC_ &station->timeout);
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -327,7 +334,6 @@ static struct wifi_station* wifi_station_create(struct wifi_wlan* wlan, const ui
|
||||
/* Initialize station */
|
||||
memcpy(station->address, address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_printf_macaddress(station->addrtext, address, MACADDRESS_EUI48_LENGTH);
|
||||
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
|
||||
|
||||
/* Add to pool */
|
||||
capwap_hash_add(g_wifiglobal.stations, station);
|
||||
@ -371,7 +377,11 @@ static void wifi_wlan_send_mgmt_deauthentication(struct wifi_wlan* wlan, const u
|
||||
}
|
||||
|
||||
/* */
|
||||
static void wifi_wlan_deauthentication_station(struct wifi_wlan* wlan, struct wifi_station* station, uint16_t reasoncode, int reusestation) {
|
||||
static void wifi_wlan_deauthentication_station(struct wifi_wlan* wlan,
|
||||
struct wifi_station* station,
|
||||
uint16_t reasoncode,
|
||||
int reusestation)
|
||||
{
|
||||
ASSERT(wlan != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
@ -389,31 +399,33 @@ static void wifi_wlan_deauthentication_station(struct wifi_wlan* wlan, struct wi
|
||||
}
|
||||
|
||||
/* */
|
||||
static void wifi_station_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param) {
|
||||
struct wifi_station* station = (struct wifi_station*)context;
|
||||
static void wifi_station_timeout_delete(EV_P_ ev_timer *w, int revents)
|
||||
{
|
||||
struct wifi_station *station = (struct wifi_station *)
|
||||
(((char *)w) - offsetof(struct wifi_station, timeout));
|
||||
|
||||
ASSERT(station != NULL);
|
||||
/* Free station into hash callback function */
|
||||
wifi_station_clean(station);
|
||||
capwap_hash_delete(g_wifiglobal.stations, station->address);
|
||||
}
|
||||
|
||||
if (station->idtimeout == index) {
|
||||
switch (station->timeoutaction) {
|
||||
case WIFI_STATION_TIMEOUT_ACTION_DELETE: {
|
||||
/* Free station into hash callback function */
|
||||
wifi_station_clean(station);
|
||||
capwap_hash_delete(g_wifiglobal.stations, station->address);
|
||||
break;
|
||||
}
|
||||
static void wifi_station_timeout_deauth(EV_P_ ev_timer *w, int revents)
|
||||
{
|
||||
struct wifi_station *station = (struct wifi_station *)
|
||||
(((char *)w) - offsetof(struct wifi_station, timeout));
|
||||
struct wifi_wlan* wlan = (struct wifi_wlan *)w->data;
|
||||
|
||||
case WIFI_STATION_TIMEOUT_ACTION_DEAUTHENTICATE: {
|
||||
capwap_logging_warning("The %s station has not completed the association in time", station->addrtext);
|
||||
wifi_wlan_deauthentication_station((struct wifi_wlan*)param, station, IEEE80211_REASON_PREV_AUTH_NOT_VALID, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
capwap_logging_warning("The %s station has not completed the association in time",
|
||||
station->addrtext);
|
||||
wifi_wlan_deauthentication_station(wlan, station, IEEE80211_REASON_PREV_AUTH_NOT_VALID, 0);
|
||||
}
|
||||
|
||||
/* */
|
||||
static void wifi_wlan_receive_station_mgmt_probe_request(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, int length, uint8_t rssi, uint8_t snr, uint16_t rate) {
|
||||
static void wifi_wlan_receive_station_mgmt_probe_request(struct wifi_wlan* wlan,
|
||||
const struct ieee80211_header_mgmt* frame,
|
||||
int length, uint8_t rssi,
|
||||
uint8_t snr, uint16_t rate)
|
||||
{
|
||||
int ielength;
|
||||
int ssidcheck;
|
||||
int nowaitack;
|
||||
@ -590,8 +602,11 @@ static void wifi_wlan_receive_station_mgmt_authentication(struct wifi_wlan* wlan
|
||||
station = wifi_station_create(wlan, frame->sa);
|
||||
if (station) {
|
||||
/* A station is removed if the association does not complete within a given period of time */
|
||||
station->timeoutaction = WIFI_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
|
||||
station->idtimeout = capwap_timeout_set(g_wifiglobal.timeout, station->idtimeout, WIFI_STATION_TIMEOUT_ASSOCIATION_COMPLETE, wifi_station_timeout, station, wlan);
|
||||
ev_timer_stop(EV_DEFAULT_UC_ &station->timeout);
|
||||
ev_timer_init(&station->timeout, wifi_station_timeout_deauth,
|
||||
WIFI_STATION_TIMEOUT_ASSOCIATION_COMPLETE / 1000.0, 0.);
|
||||
station->timeout.data = wlan;
|
||||
ev_timer_start(EV_DEFAULT_UC_ &station->timeout);
|
||||
responsestatuscode = IEEE80211_STATUS_SUCCESS;
|
||||
} else {
|
||||
responsestatuscode = IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
|
||||
@ -1134,11 +1149,10 @@ static int wifi_wlan_receive_ac_mgmt_frame(struct wifi_wlan* wlan, struct ieee80
|
||||
}
|
||||
|
||||
/* */
|
||||
int wifi_driver_init(struct capwap_timeout* timeout) {
|
||||
int wifi_driver_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
/* Socket utils */
|
||||
memset(&g_wifiglobal, 0, sizeof(struct wifi_global));
|
||||
g_wifiglobal.sock_util = socket(AF_PACKET, SOCK_RAW, 0);
|
||||
@ -1156,7 +1170,6 @@ int wifi_driver_init(struct capwap_timeout* timeout) {
|
||||
}
|
||||
|
||||
/* */
|
||||
g_wifiglobal.timeout = timeout;
|
||||
g_wifiglobal.devices = capwap_list_create();
|
||||
g_wifiglobal.stations = capwap_hash_create(WIFI_STATIONS_HASH_SIZE);
|
||||
g_wifiglobal.stations->item_gethash = wifi_hash_station_gethash;
|
||||
@ -1234,44 +1247,6 @@ void wifi_driver_free(void) {
|
||||
close(g_wifiglobal.sock_util);
|
||||
}
|
||||
|
||||
/* */
|
||||
int wifi_event_getfd(struct pollfd* fds, struct wifi_event* events, int count) {
|
||||
int i;
|
||||
int result = 0;
|
||||
struct capwap_list_item* itemdevice;
|
||||
struct capwap_list_item* itemwlan;
|
||||
|
||||
if ((count > 0) && (!fds || !events)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get from driver */
|
||||
for (i = 0; wifi_driver[i].ops != NULL; i++) {
|
||||
result += wifi_driver[i].ops->global_getfdevent(wifi_driver[i].handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL));
|
||||
}
|
||||
|
||||
/* Get from device */
|
||||
for (itemdevice = g_wifiglobal.devices->first; itemdevice != NULL; itemdevice = itemdevice->next) {
|
||||
struct wifi_device* device = (struct wifi_device*)itemdevice->item;
|
||||
if (device->handle) {
|
||||
result += device->instance->ops->device_getfdevent(device, (count ? &fds[result] : NULL), (count ? &events[result] : NULL));
|
||||
|
||||
/* Get from wlan */
|
||||
if (device->wlans) {
|
||||
for (itemwlan = device->wlans->first; itemwlan != NULL; itemwlan = itemwlan->next) {
|
||||
struct wifi_wlan* wlan = (struct wifi_wlan*)itemwlan->item;
|
||||
|
||||
if (wlan->handle) {
|
||||
result += device->instance->ops->wlan_getfdevent(wlan, (count ? &fds[result] : NULL), (count ? &events[result] : NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct wifi_wlan* wifi_get_wlan(uint32_t ifindex) {
|
||||
struct capwap_list_item* itemdevice;
|
||||
@ -1318,39 +1293,40 @@ struct wifi_device* wifi_device_connect(const char* ifname, const char* driver)
|
||||
|
||||
/* Search driver */
|
||||
for (i = 0; wifi_driver[i].ops != NULL; i++) {
|
||||
if (!strcmp(driver, wifi_driver[i].ops->name)) {
|
||||
itemdevice = capwap_itemlist_create(sizeof(struct wifi_device));
|
||||
device = (struct wifi_device*)itemdevice->item;
|
||||
memset(device, 0, sizeof(struct wifi_device));
|
||||
if (strcmp(driver, wifi_driver[i].ops->name) != 0)
|
||||
continue;
|
||||
|
||||
/* */
|
||||
device->global = &g_wifiglobal;
|
||||
device->instance = &wifi_driver[i];
|
||||
strcpy(device->phyname, ifname);
|
||||
itemdevice = capwap_itemlist_create(sizeof(struct wifi_device));
|
||||
device = (struct wifi_device*)itemdevice->item;
|
||||
memset(device, 0, sizeof(struct wifi_device));
|
||||
|
||||
/* Device init */
|
||||
if (!wifi_driver[i].ops->device_init(wifi_driver[i].handle, device)) {
|
||||
/* Registered new device */
|
||||
device->wlans = capwap_list_create();
|
||||
/* */
|
||||
device->global = &g_wifiglobal;
|
||||
device->instance = &wifi_driver[i];
|
||||
strcpy(device->phyname, ifname);
|
||||
|
||||
/* Device capability */
|
||||
device->capability = (struct wifi_capability*)capwap_alloc(sizeof(struct wifi_capability));
|
||||
memset(device->capability, 0, sizeof(struct wifi_capability));
|
||||
device->capability->bands = capwap_array_create(sizeof(struct wifi_band_capability), 0, 1);
|
||||
device->capability->ciphers = capwap_array_create(sizeof(struct wifi_cipher_capability), 0, 1);
|
||||
|
||||
/* Retrieve device capability */
|
||||
device->instance->ops->device_getcapability(device, device->capability);
|
||||
|
||||
/* Appent to device list */
|
||||
capwap_itemlist_insert_after(g_wifiglobal.devices, NULL, itemdevice);
|
||||
} else {
|
||||
capwap_itemlist_free(itemdevice);
|
||||
device = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
/* Device init */
|
||||
if (wifi_driver[i].ops->device_init(wifi_driver[i].handle, device)) {
|
||||
capwap_itemlist_free(itemdevice);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Registered new device */
|
||||
device->wlans = capwap_list_create();
|
||||
|
||||
/* Device capability */
|
||||
device->capability = (struct wifi_capability*)capwap_alloc(sizeof(struct wifi_capability));
|
||||
memset(device->capability, 0, sizeof(struct wifi_capability));
|
||||
device->capability->bands = capwap_array_create(sizeof(struct wifi_band_capability), 0, 1);
|
||||
device->capability->ciphers = capwap_array_create(sizeof(struct wifi_cipher_capability), 0, 1);
|
||||
|
||||
/* Retrieve device capability */
|
||||
device->instance->ops->device_getcapability(device, device->capability);
|
||||
|
||||
/* Appent to device list */
|
||||
capwap_itemlist_insert_after(g_wifiglobal.devices, NULL, itemdevice);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return device;
|
||||
@ -1886,10 +1862,6 @@ int wifi_station_authorize(struct wifi_wlan* wlan, struct station_add_params* pa
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_timeout_deletetimer(g_wifiglobal.timeout, station->idtimeout);
|
||||
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
|
||||
|
||||
/* Station is authorized only after Authentication and Association */
|
||||
station->flags |= WIFI_STATION_FLAGS_AUTHORIZED;
|
||||
if (!(station->flags & WIFI_STATION_FLAGS_AUTHENTICATED) ||
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <linux/if_ether.h>
|
||||
#include "ieee80211.h"
|
||||
|
||||
#include <ev.h>
|
||||
|
||||
/* */
|
||||
#define WIFI_DRIVER_NAME_SIZE 16
|
||||
|
||||
@ -227,9 +229,6 @@ struct wifi_global {
|
||||
int sock_util;
|
||||
struct capwap_list* devices;
|
||||
|
||||
/* Timeout */
|
||||
struct capwap_timeout* timeout;
|
||||
|
||||
/* Stations */
|
||||
struct capwap_hash* stations;
|
||||
};
|
||||
@ -353,8 +352,7 @@ struct wifi_station {
|
||||
unsigned long flags;
|
||||
|
||||
/* Timers */
|
||||
int timeoutaction;
|
||||
unsigned long idtimeout;
|
||||
struct ev_timer timeout;
|
||||
|
||||
/* */
|
||||
uint16_t capability;
|
||||
@ -380,12 +378,10 @@ struct wifi_driver_ops {
|
||||
|
||||
/* Global initialize driver */
|
||||
wifi_global_handle (*global_init)(void);
|
||||
int (*global_getfdevent)(wifi_global_handle handle, struct pollfd* fds, struct wifi_event* events);
|
||||
void (*global_deinit)(wifi_global_handle handle);
|
||||
|
||||
/* Device functions */
|
||||
int (*device_init)(wifi_global_handle handle, struct wifi_device* device);
|
||||
int (*device_getfdevent)(struct wifi_device* device, struct pollfd* fds, struct wifi_event* events);
|
||||
int (*device_getcapability)(struct wifi_device* device, struct wifi_capability* capability);
|
||||
void (*device_updatebeacons)(struct wifi_device* device);
|
||||
int (*device_setfrequency)(struct wifi_device* device);
|
||||
@ -395,7 +391,6 @@ struct wifi_driver_ops {
|
||||
|
||||
/* WLAN functions */
|
||||
wifi_wlan_handle (*wlan_create)(struct wifi_device* device, struct wifi_wlan* wlan);
|
||||
int (*wlan_getfdevent)(struct wifi_wlan* wlan, struct pollfd* fds, struct wifi_event* events);
|
||||
int (*wlan_startap)(struct wifi_wlan* wlan);
|
||||
void (*wlan_stopap)(struct wifi_wlan* wlan);
|
||||
int (*wlan_sendframe)(struct wifi_wlan* wlan, uint8_t* frame, int length, uint32_t frequency, uint32_t duration, int offchannel_tx_ok, int no_cck_rate, int no_wait_ack);
|
||||
@ -407,12 +402,9 @@ struct wifi_driver_ops {
|
||||
};
|
||||
|
||||
/* Initialize wifi driver engine */
|
||||
int wifi_driver_init(struct capwap_timeout* timeout);
|
||||
int wifi_driver_init(void);
|
||||
void wifi_driver_free(void);
|
||||
|
||||
/* Get File Descriptor Event */
|
||||
int wifi_event_getfd(struct pollfd* fds, struct wifi_event* events, int count);
|
||||
|
||||
/* */
|
||||
struct wifi_wlan* wifi_get_wlan(uint32_t ifindex);
|
||||
|
||||
|
@ -120,7 +120,12 @@ static int nl80211_ack_handler(struct nl_msg* msg, void* arg) {
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_send_and_recv(struct nl_sock* nl, struct nl_cb* nl_cb, struct nl_msg* msg, nl_valid_cb valid_cb, void* data) {
|
||||
static int nl80211_send_and_recv(struct nl_sock *nl,
|
||||
struct nl_cb *nl_cb,
|
||||
struct nl_msg *msg,
|
||||
nl_valid_cb valid_cb,
|
||||
void *data)
|
||||
{
|
||||
int result;
|
||||
struct nl_cb* cb;
|
||||
|
||||
@ -156,12 +161,17 @@ static int nl80211_send_and_recv(struct nl_sock* nl, struct nl_cb* nl_cb, struct
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_send_and_recv_msg(struct nl80211_global_handle* globalhandle, struct nl_msg* msg, nl_valid_cb valid_cb, void* data) {
|
||||
static int nl80211_send_and_recv_msg(struct nl80211_global_handle* globalhandle,
|
||||
struct nl_msg* msg,
|
||||
nl_valid_cb valid_cb,
|
||||
void* data)
|
||||
{
|
||||
return nl80211_send_and_recv(globalhandle->nl, globalhandle->nl_cb, msg, valid_cb, data);
|
||||
}
|
||||
|
||||
/* */
|
||||
static int cb_family_handler(struct nl_msg* msg, void* data) {
|
||||
static int cb_family_handler(struct nl_msg* msg, void* data)
|
||||
{
|
||||
int i;
|
||||
struct nlattr* mcast_group;
|
||||
struct nlattr* tb_msg[CTRL_ATTR_MAX + 1];
|
||||
@ -591,52 +601,37 @@ static wifi_wlan_handle nl80211_wlan_create(struct wifi_device* device, struct w
|
||||
memset(wlanhandle, 0, sizeof(struct nl80211_wlan_handle));
|
||||
|
||||
wlanhandle->devicehandle = devicehandle;
|
||||
wlanhandle->nl_fd = -1;
|
||||
|
||||
return (wifi_wlan_handle)wlanhandle;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_event_receive(int fd, void** params, int paramscount) {
|
||||
static void nl80211_global_event_receive_cb(EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
struct nl80211_global_handle *globalhandle = (struct nl80211_global_handle *)
|
||||
(((char *)w) - offsetof(struct nl80211_global_handle, nl_event_ev));
|
||||
int res;
|
||||
|
||||
ASSERT(fd >= 0);
|
||||
ASSERT(params != NULL);
|
||||
ASSERT(paramscount == 2);
|
||||
|
||||
capwap_logging_warning("nl80211_global_event_receive_cb on fd %d", w->fd);
|
||||
/* */
|
||||
res = nl_recvmsgs((struct nl_sock*)params[0], (struct nl_cb*)params[1]);
|
||||
res = nl_recvmsgs(globalhandle->nl_event, globalhandle->nl_cb);
|
||||
if (res) {
|
||||
capwap_logging_warning("Receive nl80211 message failed: %d", res);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_wlan_getfdevent(struct wifi_wlan* wlan, struct pollfd* fds, struct wifi_event* events) {
|
||||
struct nl80211_wlan_handle* wlanhandle;
|
||||
|
||||
ASSERT(wlan != NULL);
|
||||
ASSERT(wlan->handle != NULL);
|
||||
static void nl80211_wlan_event_receive_cb(EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
struct nl80211_wlan_handle *wlanhandle = (struct nl80211_wlan_handle *)
|
||||
(((char *)w) - offsetof(struct nl80211_wlan_handle, nl_ev));
|
||||
int res;
|
||||
|
||||
capwap_logging_warning("nl80211_wlan_event_receive_cb on fd %d", w->fd);
|
||||
/* */
|
||||
wlanhandle = (struct nl80211_wlan_handle*)wlan->handle;
|
||||
if (!(wlan->flags & WIFI_WLAN_RUNNING) || (wlanhandle->nl_fd < 0)) {
|
||||
return 0;
|
||||
res = nl_recvmsgs(wlanhandle->nl, wlanhandle->nl_cb);
|
||||
if (res) {
|
||||
capwap_logging_warning("Receive nl80211 message failed: %d", res);
|
||||
}
|
||||
|
||||
if (fds) {
|
||||
fds[0].fd = wlanhandle->nl_fd;
|
||||
fds[0].events = POLLIN | POLLERR | POLLHUP;
|
||||
}
|
||||
|
||||
if (events) {
|
||||
events[0].event_handler = nl80211_event_receive;
|
||||
events[0].params[0] = (void*)wlanhandle->nl;
|
||||
events[0].params[1] = (void*)wlanhandle->nl_cb;
|
||||
events[0].paramscount = 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -807,11 +802,8 @@ static int nl80211_wlan_startap(struct wifi_wlan* wlan) {
|
||||
nl_cb_set(wlanhandle->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_wlan_valid_handler, (void*)wlan);
|
||||
|
||||
wlanhandle->nl = nl_create_handle(wlanhandle->nl_cb);
|
||||
if (wlanhandle->nl) {
|
||||
wlanhandle->nl_fd = nl_socket_get_fd(wlanhandle->nl);
|
||||
} else {
|
||||
if (!wlanhandle->nl)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Register frames */
|
||||
for (i = 0; i < sizeof(g_stypes) / sizeof(g_stypes[0]); i++) {
|
||||
@ -837,6 +829,12 @@ static int nl80211_wlan_startap(struct wifi_wlan* wlan) {
|
||||
|
||||
/* Enable interface */
|
||||
wlan->flags |= WIFI_WLAN_RUNNING;
|
||||
|
||||
/* hook into I/O loop */
|
||||
ev_io_init(&wlanhandle->nl_ev, nl80211_wlan_event_receive_cb,
|
||||
nl_socket_get_fd(wlanhandle->nl), EV_READ);
|
||||
ev_io_start(EV_DEFAULT_UC_ &wlanhandle->nl_ev);
|
||||
|
||||
if (wifi_iface_up(wlanhandle->devicehandle->globalhandle->sock_util, wlan->virtname)) {
|
||||
return -1;
|
||||
}
|
||||
@ -897,10 +895,12 @@ static void nl80211_wlan_stopap(struct wifi_wlan* wlan) {
|
||||
nl80211_wlan_set_profile(wlan, NL80211_IFTYPE_STATION);
|
||||
|
||||
/* */
|
||||
if (ev_is_active(&wlanhandle->nl_ev))
|
||||
ev_io_stop(EV_DEFAULT_UC_ &wlanhandle->nl_ev);
|
||||
|
||||
if (wlanhandle->nl) {
|
||||
nl_socket_free(wlanhandle->nl);
|
||||
wlanhandle->nl = NULL;
|
||||
wlanhandle->nl_fd = -1;
|
||||
}
|
||||
|
||||
if (wlanhandle->nl_cb) {
|
||||
@ -1229,14 +1229,6 @@ int nl80211_device_init(wifi_global_handle handle, struct wifi_device* device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_device_getfdevent(struct wifi_device* device, struct pollfd* fds, struct wifi_event* events) {
|
||||
ASSERT(device != NULL);
|
||||
ASSERT(device->handle != NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static unsigned long nl80211_get_cipher(uint32_t chiper) {
|
||||
switch (chiper) {
|
||||
@ -1676,7 +1668,8 @@ static int nl80211_device_setfrequency(struct wifi_device* device) {
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_device_deinit(struct wifi_device* device) {
|
||||
static void nl80211_device_deinit(struct wifi_device* device)
|
||||
{
|
||||
struct nl80211_device_handle* devicehandle;
|
||||
|
||||
ASSERT(device != NULL);
|
||||
@ -1689,36 +1682,38 @@ static void nl80211_device_deinit(struct wifi_device* device) {
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_global_deinit(wifi_global_handle handle) {
|
||||
static void nl80211_global_deinit(wifi_global_handle handle)
|
||||
{
|
||||
struct nl80211_global_handle* globalhandle = (struct nl80211_global_handle*)handle;
|
||||
|
||||
if (globalhandle) {
|
||||
if (globalhandle->netlinkhandle) {
|
||||
netlink_free(globalhandle->netlinkhandle);
|
||||
}
|
||||
if (!globalhandle)
|
||||
return;
|
||||
|
||||
if (globalhandle->nl) {
|
||||
nl_socket_free(globalhandle->nl);
|
||||
}
|
||||
if (globalhandle->netlinkhandle)
|
||||
netlink_free(globalhandle->netlinkhandle);
|
||||
|
||||
if (globalhandle->nl_event) {
|
||||
nl_socket_free(globalhandle->nl_event);
|
||||
}
|
||||
if (globalhandle->nl)
|
||||
nl_socket_free(globalhandle->nl);
|
||||
|
||||
if (globalhandle->nl_cb) {
|
||||
nl_cb_put(globalhandle->nl_cb);
|
||||
}
|
||||
if (globalhandle->nl_event)
|
||||
nl_socket_free(globalhandle->nl_event);
|
||||
|
||||
if (globalhandle->sock_util >= 0) {
|
||||
close(globalhandle->sock_util);
|
||||
}
|
||||
if (ev_is_active(&globalhandle->nl_event_ev))
|
||||
ev_io_stop(EV_DEFAULT_UC_ &globalhandle->nl_event_ev);
|
||||
|
||||
capwap_free(globalhandle);
|
||||
}
|
||||
if (globalhandle->nl_cb)
|
||||
nl_cb_put(globalhandle->nl_cb);
|
||||
|
||||
if (globalhandle->sock_util >= 0)
|
||||
close(globalhandle->sock_util);
|
||||
|
||||
capwap_free(globalhandle);
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_global_newlink_event(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length) {
|
||||
static void nl80211_global_newlink_event(wifi_global_handle handle, struct ifinfomsg* infomsg,
|
||||
uint8_t* data, int length)
|
||||
{
|
||||
struct wifi_wlan* wlan;
|
||||
struct nl80211_global_handle* globalhandle = (struct nl80211_global_handle*)handle;
|
||||
|
||||
@ -1727,22 +1722,29 @@ static void nl80211_global_newlink_event(wifi_global_handle handle, struct ifinf
|
||||
|
||||
/* Search device */
|
||||
wlan = wifi_get_wlan(infomsg->ifi_index);
|
||||
if (wlan) {
|
||||
if (!(wlan->flags & WIFI_WLAN_RUNNING)) {
|
||||
if ((infomsg->ifi_flags & IFF_UP) && (wifi_iface_getstatus(globalhandle->sock_util, wlan->virtname) > 0)) {
|
||||
wifi_iface_down(globalhandle->sock_util, wlan->virtname);
|
||||
}
|
||||
} else if (wlan->flags & WIFI_WLAN_SET_BEACON) {
|
||||
if ((wlan->flags & WIFI_WLAN_OPERSTATE_RUNNING) && (infomsg->ifi_flags & IFF_LOWER_UP) && !(infomsg->ifi_flags & (IFF_RUNNING | IFF_DORMANT))) {
|
||||
struct nl80211_wlan_handle* wlanhandle = (struct nl80211_wlan_handle*)wlan->handle;
|
||||
netlink_set_link_status(wlanhandle->devicehandle->globalhandle->netlinkhandle, wlan->virtindex, -1, IF_OPER_UP);
|
||||
}
|
||||
if (!wlan)
|
||||
return;
|
||||
|
||||
if (!(wlan->flags & WIFI_WLAN_RUNNING)) {
|
||||
if ((infomsg->ifi_flags & IFF_UP) &&
|
||||
(wifi_iface_getstatus(globalhandle->sock_util, wlan->virtname) > 0)) {
|
||||
wifi_iface_down(globalhandle->sock_util, wlan->virtname);
|
||||
}
|
||||
} else if (wlan->flags & WIFI_WLAN_SET_BEACON) {
|
||||
if ((wlan->flags & WIFI_WLAN_OPERSTATE_RUNNING) &&
|
||||
(infomsg->ifi_flags & IFF_LOWER_UP) &&
|
||||
!(infomsg->ifi_flags & (IFF_RUNNING | IFF_DORMANT))) {
|
||||
struct nl80211_wlan_handle* wlanhandle = (struct nl80211_wlan_handle*)wlan->handle;
|
||||
netlink_set_link_status(wlanhandle->devicehandle->globalhandle->netlinkhandle,
|
||||
wlan->virtindex, -1, IF_OPER_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_global_dellink_event(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length) {
|
||||
static void nl80211_global_dellink_event(wifi_global_handle handle, struct ifinfomsg* infomsg,
|
||||
uint8_t* data, int length)
|
||||
{
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -1768,7 +1770,8 @@ static int nl80211_global_valid_handler(struct nl_msg* msg, void* data) {
|
||||
}
|
||||
|
||||
/* */
|
||||
static wifi_global_handle nl80211_global_init(void) {
|
||||
static wifi_global_handle nl80211_global_init()
|
||||
{
|
||||
int result;
|
||||
struct nl80211_global_handle* globalhandle;
|
||||
|
||||
@ -1793,19 +1796,22 @@ static wifi_global_handle nl80211_global_init(void) {
|
||||
|
||||
/* Create netlink socket for event */
|
||||
globalhandle->nl_event = nl_create_handle(globalhandle->nl_cb);
|
||||
if (globalhandle->nl_event) {
|
||||
globalhandle->nl_event_fd = nl_socket_get_fd(globalhandle->nl_event);
|
||||
} else {
|
||||
if (!globalhandle->nl_event) {
|
||||
nl80211_global_deinit((wifi_global_handle)globalhandle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* hook into I/O loop */
|
||||
ev_io_init(&globalhandle->nl_event_ev, nl80211_global_event_receive_cb,
|
||||
nl_socket_get_fd(globalhandle->nl_event), EV_READ);
|
||||
ev_io_start(EV_DEFAULT_UC_ &globalhandle->nl_event_ev);
|
||||
|
||||
/* Add membership scan events */
|
||||
result = nl80211_get_multicast_id(globalhandle, "nl80211", "scan");
|
||||
if (result >= 0) {
|
||||
result = nl_socket_add_membership(globalhandle->nl_event, result);
|
||||
}
|
||||
|
||||
|
||||
if (result < 0) {
|
||||
nl80211_global_deinit((wifi_global_handle)globalhandle);
|
||||
return NULL;
|
||||
@ -1841,7 +1847,7 @@ static wifi_global_handle nl80211_global_init(void) {
|
||||
nl_cb_set(globalhandle->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_global_valid_handler, NULL);
|
||||
|
||||
/* Netlink lisk status */
|
||||
globalhandle->netlinkhandle = netlink_init();
|
||||
globalhandle->netlinkhandle = netlink_init((wifi_global_handle)globalhandle);
|
||||
if (!globalhandle->netlinkhandle) {
|
||||
nl80211_global_deinit((wifi_global_handle)globalhandle);
|
||||
return NULL;
|
||||
@ -1860,46 +1866,14 @@ static wifi_global_handle nl80211_global_init(void) {
|
||||
return (wifi_global_handle)globalhandle;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_global_getfdevent(wifi_global_handle handle, struct pollfd* fds, struct wifi_event* events) {
|
||||
struct nl80211_global_handle* globalhandle = (struct nl80211_global_handle*)handle;
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT(globalhandle->nl_event_fd >= 0);
|
||||
ASSERT(globalhandle->netlinkhandle != NULL);
|
||||
ASSERT(globalhandle->netlinkhandle->sock >= 0);
|
||||
|
||||
if (fds) {
|
||||
fds[0].fd = globalhandle->nl_event_fd;
|
||||
fds[0].events = POLLIN | POLLERR | POLLHUP;
|
||||
fds[1].fd = globalhandle->netlinkhandle->sock;
|
||||
fds[1].events = POLLIN | POLLERR | POLLHUP;
|
||||
}
|
||||
|
||||
if (events) {
|
||||
events[0].event_handler = nl80211_event_receive;
|
||||
events[0].params[0] = (void*)globalhandle->nl_event;
|
||||
events[0].params[1] = (void*)globalhandle->nl_cb;
|
||||
events[0].paramscount = 2;
|
||||
events[1].event_handler = netlink_event_receive;
|
||||
events[1].params[0] = (void*)globalhandle->netlinkhandle;
|
||||
events[1].params[1] = (void*)globalhandle;
|
||||
events[1].paramscount = 2;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Driver function */
|
||||
const struct wifi_driver_ops wifi_driver_nl80211_ops = {
|
||||
.name = "nl80211",
|
||||
.description = "Linux nl80211/cfg80211",
|
||||
.global_init = nl80211_global_init,
|
||||
.global_getfdevent = nl80211_global_getfdevent,
|
||||
.global_deinit = nl80211_global_deinit,
|
||||
|
||||
.device_init = nl80211_device_init,
|
||||
.device_getfdevent = nl80211_device_getfdevent,
|
||||
.device_getcapability = nl80211_device_getcapability,
|
||||
.device_updatebeacons = nl80211_device_updatebeacons,
|
||||
.device_settxqueue = nl80211_device_settxqueue,
|
||||
@ -1907,7 +1881,6 @@ const struct wifi_driver_ops wifi_driver_nl80211_ops = {
|
||||
.device_deinit = nl80211_device_deinit,
|
||||
|
||||
.wlan_create = nl80211_wlan_create,
|
||||
.wlan_getfdevent = nl80211_wlan_getfdevent,
|
||||
.wlan_startap = nl80211_wlan_startap,
|
||||
.wlan_stopap = nl80211_wlan_stopap,
|
||||
.wlan_sendframe = nl80211_wlan_sendframe,
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef __WIFI_NL80211_HEADER__
|
||||
#define __WIFI_NL80211_HEADER__
|
||||
|
||||
#include <ev.h>
|
||||
|
||||
#include "capwap_hash.h"
|
||||
#include "netlink_link.h"
|
||||
|
||||
@ -18,12 +20,13 @@ typedef int (*nl_valid_cb)(struct nl_msg* msg, void* data);
|
||||
|
||||
/* Global handle */
|
||||
struct nl80211_global_handle {
|
||||
struct nl_sock* nl;
|
||||
struct nl_cb* nl_cb;
|
||||
int nl80211_id;
|
||||
|
||||
struct nl_sock* nl_event;
|
||||
int nl_event_fd;
|
||||
struct nl_sock* nl;
|
||||
struct nl_cb* nl_cb;
|
||||
|
||||
struct nl_sock *nl_event;
|
||||
ev_io nl_event_ev;
|
||||
|
||||
struct netlink* netlinkhandle;
|
||||
|
||||
@ -39,9 +42,9 @@ struct nl80211_device_handle {
|
||||
struct nl80211_wlan_handle {
|
||||
struct nl80211_device_handle* devicehandle;
|
||||
|
||||
struct nl_sock* nl;
|
||||
int nl_fd;
|
||||
struct nl_cb* nl_cb;
|
||||
struct nl_sock *nl;
|
||||
ev_io nl_ev;
|
||||
struct nl_cb *nl_cb;
|
||||
|
||||
uint64_t last_cookie;
|
||||
};
|
||||
|
Reference in New Issue
Block a user