Add nl80211 handler message events
This commit is contained in:
parent
938f73cd80
commit
022585f3a1
@ -113,6 +113,46 @@ void wifi_driver_free(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
int wifi_event_getfd(struct pollfd* fds, struct wifi_event* events, int count) {
|
||||
int i, j;
|
||||
int result = 0;
|
||||
|
||||
if ((count > 0) && (!fds || !events)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get from driver */
|
||||
for (i = 0; wifi_driver[i].ops != NULL; i++) {
|
||||
if (wifi_driver[i].ops->global_getfdevent) {
|
||||
result += wifi_driver[i].ops->global_getfdevent(wifi_driver[i].handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL));
|
||||
}
|
||||
}
|
||||
|
||||
/* Get from device */
|
||||
for (i = 0; i < g_wifidevice->count; i++) {
|
||||
struct wifi_device* device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, i);
|
||||
if (device->handle) {
|
||||
if (device->instance->ops->device_getfdevent) {
|
||||
result += device->instance->ops->device_getfdevent(device->handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL));
|
||||
}
|
||||
|
||||
/* Get from wlan */
|
||||
if (device->instance->ops->wlan_getfdevent) {
|
||||
for (j = 0; j < device->wlan->count; j++) {
|
||||
struct wifi_wlan* wlan = (struct wifi_wlan*)capwap_array_get_item_pointer(device->wlan, j);
|
||||
|
||||
if (wlan->handle) {
|
||||
result += device->instance->ops->wlan_getfdevent(wlan->handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
int wifi_device_connect(int radioid, const char* ifname, const char* driver) {
|
||||
int i;
|
||||
|
@ -152,6 +152,13 @@ struct wifi_frequency {
|
||||
uint32_t frequency;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct wifi_event {
|
||||
void (*event_handler)(int fd, void* param1, void* param2);
|
||||
void* param1;
|
||||
void* param2;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct wifi_driver_ops {
|
||||
const char* name; /* Name of wifi driver */
|
||||
@ -159,16 +166,19 @@ 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 */
|
||||
wifi_device_handle (*device_init)(wifi_global_handle handle, struct device_init_params* params);
|
||||
int (*device_getfdevent)(wifi_device_handle handle, struct pollfd* fds, struct wifi_event* events);
|
||||
int (*device_getcapability)(wifi_device_handle handle, struct wifi_capability* capability);
|
||||
int (*device_setfrequency)(wifi_device_handle handle, struct wifi_frequency* freq);
|
||||
void (*device_deinit)(wifi_device_handle handle);
|
||||
|
||||
/* WLAN functions */
|
||||
wifi_wlan_handle (*wlan_create)(wifi_device_handle handle, struct wlan_init_params* params);
|
||||
int (*wlan_getfdevent)(wifi_wlan_handle handle, struct pollfd* fds, struct wifi_event* events);
|
||||
int (*wlan_setupap)(wifi_wlan_handle handle, struct wlan_setupap_params* params);
|
||||
int (*wlan_startap)(wifi_wlan_handle handle);
|
||||
int (*wlan_stopap)(wifi_wlan_handle handle);
|
||||
@ -210,6 +220,9 @@ struct wifi_wlan {
|
||||
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);
|
||||
|
||||
/* */
|
||||
int wifi_device_connect(int radioid, const char* ifname, const char* driver);
|
||||
struct wifi_capability* wifi_device_getcapability(int radioid);
|
||||
|
@ -93,6 +93,19 @@ static int nl80211_process_bss_event(struct nl_msg* msg, void* arg) {
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_event_receive(int fd, void* param1, void* param2) {
|
||||
int res;
|
||||
struct nl_sock* nl = (struct nl_sock*)param1;
|
||||
struct nl_cb* nl_cb = (struct nl_cb*)param2;
|
||||
|
||||
/* */
|
||||
res = nl_recvmsgs(nl, nl_cb);
|
||||
if (res) {
|
||||
capwap_logging_warning("Receive nl80211 message failed: %d", res);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_global_valid_handler(struct nl_msg* msg, void* arg) {
|
||||
/* TODO */
|
||||
@ -622,6 +635,11 @@ static wifi_device_handle nl80211_device_init(wifi_global_handle handle, struct
|
||||
return devicehandle;
|
||||
}
|
||||
|
||||
/* */
|
||||
int nl80211_device_getfdevent(wifi_device_handle handle, struct pollfd* fds, struct wifi_event* events) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
int nl80211_device_getcapability(wifi_device_handle handle, struct wifi_capability* capability) {
|
||||
int result;
|
||||
@ -805,7 +823,9 @@ static wifi_wlan_handle nl80211_wlan_create(wifi_device_handle handle, struct wl
|
||||
nl_cb_set(wlanhandle->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_process_bss_event, NULL);
|
||||
|
||||
wlanhandle->nl = nl_create_handle(wlanhandle->nl_cb);
|
||||
if (!wlanhandle->nl) {
|
||||
if (wlanhandle->nl) {
|
||||
wlanhandle->nl_fd = nl_socket_get_fd(wlanhandle->nl);
|
||||
} else {
|
||||
nl80211_wlan_delete((wifi_wlan_handle)wlanhandle);
|
||||
return NULL;
|
||||
}
|
||||
@ -813,6 +833,26 @@ static wifi_wlan_handle nl80211_wlan_create(wifi_device_handle handle, struct wl
|
||||
return wlanhandle;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_wlan_getfdevent(wifi_wlan_handle handle, struct pollfd* fds, struct wifi_event* events) {
|
||||
struct nl80211_wlan_handle* wlanhandle = (struct nl80211_wlan_handle*)handle;
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
|
||||
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].param1 = (void*)wlanhandle->nl;
|
||||
events[0].param2 = (void*)wlanhandle->nl_cb;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_wlan_setupap(wifi_wlan_handle handle, struct wlan_setupap_params* params) {
|
||||
int i;
|
||||
@ -1005,17 +1045,25 @@ 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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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_setfrequency = nl80211_device_setfrequency,
|
||||
.device_deinit = nl80211_device_deinit,
|
||||
.wlan_create = nl80211_wlan_create,
|
||||
.wlan_getfdevent = nl80211_wlan_getfdevent,
|
||||
.wlan_setupap = nl80211_wlan_setupap,
|
||||
.wlan_startap = nl80211_wlan_startap,
|
||||
.wlan_stopap = nl80211_wlan_stopap,
|
||||
|
@ -33,6 +33,7 @@ struct nl80211_wlan_handle {
|
||||
struct nl80211_device_handle* devicehandle;
|
||||
|
||||
struct nl_sock* nl;
|
||||
int nl_fd;
|
||||
struct nl_cb* nl_cb;
|
||||
|
||||
uint32_t virtindex;
|
||||
|
@ -81,8 +81,14 @@ struct wtp_t {
|
||||
|
||||
char wlanprefix[IFNAMSIZ];
|
||||
|
||||
struct wtp_state dfa;
|
||||
/* */
|
||||
struct capwap_network net;
|
||||
struct pollfd* fds;
|
||||
int fdstotalcount;
|
||||
int fdsnetworkcount;
|
||||
|
||||
/* */
|
||||
struct wtp_state dfa;
|
||||
|
||||
struct capwap_wtpname_element name;
|
||||
struct capwap_acname_element acname;
|
||||
@ -106,6 +112,7 @@ struct wtp_t {
|
||||
struct capwap_packet_rxmng* rxmngctrlpacket;
|
||||
struct capwap_packet_rxmng* rxmngdatapacket;
|
||||
|
||||
/* */
|
||||
unsigned char localseqnumber;
|
||||
unsigned char remoteseqnumber;
|
||||
unsigned short mtu;
|
||||
@ -128,7 +135,10 @@ struct wtp_t {
|
||||
struct capwap_socket acctrlsock;
|
||||
struct capwap_socket acdatasock;
|
||||
|
||||
/* */
|
||||
struct capwap_array* radios;
|
||||
struct wifi_event* events;
|
||||
int eventscount;
|
||||
|
||||
/* Dtls */
|
||||
int enabledtls;
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#define WTP_RECV_NOERROR_RADIO -1001
|
||||
|
||||
/* Handler signal */
|
||||
static void wtp_signal_handler(int signum) {
|
||||
if ((signum == SIGINT) || (signum == SIGTERM)) {
|
||||
@ -146,6 +148,44 @@ static void wtp_dfa_execute(struct capwap_parsed_packet* packet, struct timeout_
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static int wtp_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr, struct timeout_control* timeout) {
|
||||
int index;
|
||||
|
||||
ASSERT(fds);
|
||||
ASSERT(fdscount > 0);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(size != NULL);
|
||||
ASSERT(*size > 0);
|
||||
ASSERT(recvfromaddr != NULL);
|
||||
ASSERT(recvtoaddr != NULL);
|
||||
|
||||
/* Wait packet */
|
||||
index = capwap_wait_recvready(fds, fdscount, timeout);
|
||||
if (index < 0) {
|
||||
return index;
|
||||
} else if (index >= g_wtp.fdsnetworkcount) {
|
||||
int pos = index - g_wtp.fdsnetworkcount;
|
||||
|
||||
if (pos < g_wtp.eventscount) {
|
||||
if (!g_wtp.events[pos].event_handler) {
|
||||
return CAPWAP_RECV_ERROR_SOCKET;
|
||||
}
|
||||
|
||||
g_wtp.events[pos].event_handler(fds[index].fd, g_wtp.events[pos].param1, g_wtp.events[pos].param2);
|
||||
}
|
||||
|
||||
return WTP_RECV_NOERROR_RADIO;
|
||||
}
|
||||
|
||||
/* Receive packet */
|
||||
if (!capwap_recvfrom_fd(fds[index].fd, buffer, size, recvfromaddr, recvtoaddr)) {
|
||||
return CAPWAP_RECV_ERROR_SOCKET;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/* WTP state machine */
|
||||
int wtp_dfa_running(void) {
|
||||
int res;
|
||||
@ -165,23 +205,21 @@ int wtp_dfa_running(void) {
|
||||
struct sockaddr_storage recvfromaddr;
|
||||
struct sockaddr_storage recvtoaddr;
|
||||
int isrecvpacket = 0;
|
||||
|
||||
struct pollfd* fds;
|
||||
int fdscount;
|
||||
|
||||
|
||||
/* Init */
|
||||
capwap_init_timeout(&timeout);
|
||||
capwap_set_timeout(0, &timeout, CAPWAP_TIMER_CONTROL_CONNECTION); /* Start DFA with timeout */
|
||||
|
||||
|
||||
memset(&packet, 0, sizeof(struct capwap_parsed_packet));
|
||||
|
||||
|
||||
/* Configure poll struct */
|
||||
fdscount = CAPWAP_MAX_SOCKETS * 2;
|
||||
fds = (struct pollfd*)capwap_alloc(sizeof(struct pollfd) * fdscount);
|
||||
|
||||
g_wtp.fdstotalcount = CAPWAP_MAX_SOCKETS * 2;
|
||||
g_wtp.fds = (struct pollfd*)capwap_alloc(sizeof(struct pollfd) * g_wtp.fdstotalcount);
|
||||
|
||||
/* Retrive all socket for polling */
|
||||
fdscount = capwap_network_set_pollfd(&g_wtp.net, fds, fdscount);
|
||||
ASSERT(fdscount > 0);
|
||||
g_wtp.fdsnetworkcount = capwap_network_set_pollfd(&g_wtp.net, g_wtp.fds, g_wtp.fdstotalcount);
|
||||
g_wtp.fdstotalcount = g_wtp.fdsnetworkcount;
|
||||
ASSERT(g_wtp.fdstotalcount > 0);
|
||||
|
||||
/* Handler signal */
|
||||
g_wtp.running = 1;
|
||||
@ -199,7 +237,7 @@ int wtp_dfa_running(void) {
|
||||
isrecvpacket = 0;
|
||||
buffer = bufferencrypt;
|
||||
buffersize = CAPWAP_MAX_PACKET_SIZE;
|
||||
index = capwap_recvfrom(fds, fdscount, buffer, &buffersize, &recvfromaddr, &recvtoaddr, &timeout);
|
||||
index = wtp_recvfrom(g_wtp.fds, g_wtp.fdstotalcount, buffer, &buffersize, &recvfromaddr, &recvtoaddr, &timeout);
|
||||
if (!g_wtp.running) {
|
||||
capwap_logging_debug("Closing WTP, Teardown connection");
|
||||
|
||||
@ -219,7 +257,7 @@ int wtp_dfa_running(void) {
|
||||
int check;
|
||||
|
||||
/* Retrieve network information */
|
||||
capwap_get_network_socket(&g_wtp.net, &socket, fds[index].fd);
|
||||
capwap_get_network_socket(&g_wtp.net, &socket, g_wtp.fds[index].fd);
|
||||
|
||||
/* Check source */
|
||||
if (socket.isctrlsocket && (g_wtp.acctrladdress.ss_family != AF_UNSPEC)) {
|
||||
@ -297,7 +335,7 @@ int wtp_dfa_running(void) {
|
||||
socklen_t sockinfolen = sizeof(struct sockaddr_storage);
|
||||
|
||||
memset(&sockinfo, 0, sizeof(struct sockaddr_storage));
|
||||
if (getsockname(fds[index].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) {
|
||||
if (getsockname(g_wtp.fds[index].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -386,7 +424,7 @@ int wtp_dfa_running(void) {
|
||||
isrecvpacket = 1;
|
||||
}
|
||||
}
|
||||
} else if (index == CAPWAP_RECV_ERROR_INTR) {
|
||||
} else if ((index == CAPWAP_RECV_ERROR_INTR) || (index == WTP_RECV_NOERROR_RADIO)) {
|
||||
/* Ignore recv */
|
||||
continue;
|
||||
} else if (index == CAPWAP_RECV_ERROR_SOCKET) {
|
||||
@ -405,7 +443,7 @@ int wtp_dfa_running(void) {
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
capwap_free(fds);
|
||||
capwap_free(g_wtp.fds);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -83,6 +83,10 @@ void wtp_radio_free(void) {
|
||||
ASSERT(g_wtp.radios != NULL);
|
||||
ASSERT(g_wtp.radios->count == 0);
|
||||
|
||||
if (g_wtp.events) {
|
||||
capwap_free(g_wtp.events);
|
||||
}
|
||||
|
||||
capwap_array_free(g_wtp.radios);
|
||||
}
|
||||
|
||||
@ -350,6 +354,45 @@ struct wtp_radio_wlan* wtp_radio_get_wlan(struct wtp_radio* radio, uint8_t wlani
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void wtp_radio_update_fdevent(void) {
|
||||
int count;
|
||||
|
||||
/* Retrieve number of File Descriptor Event */
|
||||
count = wifi_event_getfd(NULL, NULL, 0);
|
||||
if (count < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
if (g_wtp.eventscount != count) {
|
||||
struct pollfd* fds;
|
||||
|
||||
/* Resize poll */
|
||||
fds = (struct pollfd*)capwap_alloc(sizeof(struct pollfd) * (g_wtp.fdsnetworkcount + count));
|
||||
memcpy(fds, g_wtp.fds, sizeof(struct pollfd) * g_wtp.fdsnetworkcount);
|
||||
capwap_free(g_wtp.fds);
|
||||
g_wtp.fds = fds;
|
||||
|
||||
/* Events Callback */
|
||||
if (g_wtp.events) {
|
||||
capwap_free(g_wtp.events);
|
||||
}
|
||||
|
||||
g_wtp.events = (struct wifi_event*)((count > 0) ? capwap_alloc(sizeof(struct wifi_event) * count) : NULL);
|
||||
|
||||
/* */
|
||||
g_wtp.eventscount = count;
|
||||
g_wtp.fdstotalcount = g_wtp.fdsnetworkcount + g_wtp.eventscount;
|
||||
}
|
||||
|
||||
/* Retrieve File Descriptor Event */
|
||||
if (count > 0) {
|
||||
count = wifi_event_getfd(&g_wtp.fds[g_wtp.fdsnetworkcount], g_wtp.events, g_wtp.eventscount);
|
||||
ASSERT(g_wtp.eventscount == count);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwap_80211_assignbssid_element* bssid) {
|
||||
uint32_t band;
|
||||
@ -426,7 +469,10 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwa
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* */
|
||||
/* Update Event File Descriptor */
|
||||
wtp_radio_update_fdevent();
|
||||
|
||||
/* Retrieve macaddress of new device */
|
||||
bssid->radioid = addwlan->radioid;
|
||||
bssid->wlanid = addwlan->wlanid;
|
||||
wifi_wlan_getbssid(addwlan->radioid, addwlan->wlanid, bssid->bssid);
|
||||
|
Loading…
Reference in New Issue
Block a user