first features of mac80211 driver
This commit is contained in:
parent
bb449e7ec6
commit
0a2ae76acc
@ -43,6 +43,7 @@ include $(top_srcdir)/build/Makefile_common.am
|
||||
wtp_SOURCES = \
|
||||
$(capwap_SOURCES) \
|
||||
$(top_srcdir)/src/wtp/wtp.c \
|
||||
$(top_srcdir)/src/wtp/wtp_element_helper.c \
|
||||
$(top_srcdir)/src/wtp/wtp_dfa.c \
|
||||
$(top_srcdir)/src/wtp/wtp_dfa_idle.c \
|
||||
$(top_srcdir)/src/wtp/wtp_dfa_discovery.c \
|
||||
|
@ -1,4 +1,7 @@
|
||||
#include "wifi_drivers.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "capwap_array.h"
|
||||
|
||||
/* Declare enable wifi driver */
|
||||
@ -41,7 +44,7 @@ void wifi_free_driver(void) {
|
||||
if (wifi_device) {
|
||||
for (i = 0; i < wifi_device->count; i++) {
|
||||
struct wifi_device* device = (struct wifi_device*)capwap_array_get_item_pointer(wifi_device, i);
|
||||
if (device->instance->ops->device_deinit) {
|
||||
if (device->handle && device->instance->ops->device_deinit) {
|
||||
device->instance->ops->device_deinit(device->handle);
|
||||
}
|
||||
}
|
||||
@ -103,3 +106,40 @@ int wifi_create_device(int radioid, char* ifname, char* driver) {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
void wifi_iface_updown(int sock, const char* ifname, int up) {
|
||||
int localsock = -1;
|
||||
struct ifreq ifreq;
|
||||
|
||||
ASSERT(ifname != NULL);
|
||||
ASSERT(*ifname != 0);
|
||||
|
||||
/* Check if build local socket */
|
||||
if (sock < 0) {
|
||||
localsock = socket(AF_PACKET, SOCK_RAW, 0);
|
||||
if (localsock < 0) {
|
||||
return;
|
||||
} else {
|
||||
sock = localsock;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change link state of interface */
|
||||
memset(&ifreq, 0, sizeof(ifreq));
|
||||
strcpy(ifreq.ifr_name, ifname);
|
||||
if (!ioctl(sock, SIOCGIFFLAGS, &ifreq)) {
|
||||
if (up) {
|
||||
ifreq.ifr_flags |= IFF_UP;
|
||||
} else {
|
||||
ifreq.ifr_flags &= ~IFF_UP;
|
||||
}
|
||||
|
||||
ioctl(sock, SIOCSIFFLAGS, &ifreq);
|
||||
}
|
||||
|
||||
/* Free local socket */
|
||||
if (localsock >= 0) {
|
||||
close(localsock);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,13 @@
|
||||
/* */
|
||||
#define WIFI_DRIVER_NAME_SIZE 16
|
||||
|
||||
/* */
|
||||
#define WIFI_CAPABILITY_AP_SUPPORTED 0x00000001
|
||||
#define WIFI_CAPABILITY_AP_VLAN_SUPPORTED 0x00000002
|
||||
#define WIFI_CAPABILITY_ADHOC_SUPPORTED 0x00000004
|
||||
#define WIFI_CAPABILITY_MONITOR_SUPPORTED 0x00000008
|
||||
#define WIFI_CAPABILITY_WDS_SUPPORTED 0x00000010
|
||||
|
||||
/* */
|
||||
typedef void* wifi_global_handle;
|
||||
typedef void* wifi_device_handle;
|
||||
@ -58,4 +65,7 @@ void wifi_free_driver(void);
|
||||
/* */
|
||||
int wifi_create_device(int radioid, char* ifname, char* driver);
|
||||
|
||||
/* Util functions */
|
||||
void wifi_iface_updown(int sock, const char* ifname, int up);
|
||||
|
||||
#endif /* __WIFI_DRIVERS_HEADER__ */
|
||||
|
@ -125,6 +125,52 @@ static int nl80211_send_and_recv_msg(struct nl80211_global_handle* globalhandle,
|
||||
return nl80211_send_and_recv(globalhandle->nl, globalhandle->nl_cb, msg, valid_cb, data);
|
||||
}
|
||||
|
||||
/* */
|
||||
static int cb_get_virtdevice_list(struct nl_msg* msg, void* data) {
|
||||
struct nlattr* tb_msg[NL80211_ATTR_MAX + 1];
|
||||
struct genlmsghdr* gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
struct capwap_list* list = (struct capwap_list*)data;
|
||||
|
||||
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
|
||||
|
||||
if (tb_msg[NL80211_ATTR_WIPHY] && tb_msg[NL80211_ATTR_IFNAME] && tb_msg[NL80211_ATTR_IFINDEX]) {
|
||||
struct capwap_list_item* item = capwap_itemlist_create(sizeof(struct nl80211_virtdevice_item));
|
||||
struct nl80211_virtdevice_item* virtitem = (struct nl80211_virtdevice_item*)item->item;
|
||||
|
||||
/* Add virtual device info */
|
||||
virtitem->phyindex = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]);
|
||||
virtitem->virtindex = nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX]);
|
||||
strcpy(virtitem->virtname, nla_get_string(tb_msg[NL80211_ATTR_IFNAME]));
|
||||
capwap_itemlist_insert_after(list, NULL, item);
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_get_virtdevice_list(struct nl80211_global_handle* globalhandle, struct capwap_list* list) {
|
||||
int result;
|
||||
struct nl_msg* msg;
|
||||
|
||||
ASSERT(globalhandle != NULL);
|
||||
ASSERT(list != NULL);
|
||||
|
||||
/* */
|
||||
msg = nlmsg_alloc();
|
||||
if (!msg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
genlmsg_put(msg, 0, 0, globalhandle->nl80211_id, 0, NLM_F_DUMP, NL80211_CMD_GET_INTERFACE, 0);
|
||||
|
||||
/* Retrieve all virtual interface */
|
||||
result = nl80211_send_and_recv_msg(globalhandle, msg, cb_get_virtdevice_list, list);
|
||||
|
||||
/* */
|
||||
nlmsg_free(msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int cb_get_phydevice_list(struct nl_msg* msg, void* data) {
|
||||
struct nlattr* tb_msg[NL80211_ATTR_MAX + 1];
|
||||
@ -160,7 +206,6 @@ static int nl80211_get_phydevice_list(struct nl80211_global_handle* globalhandle
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Retrieve list of physical device */
|
||||
genlmsg_put(msg, 0, 0, globalhandle->nl80211_id, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
|
||||
|
||||
/* Retrieve all physical interface */
|
||||
@ -171,6 +216,139 @@ static int nl80211_get_phydevice_list(struct nl80211_global_handle* globalhandle
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int cb_get_phydevice_capability(struct nl_msg* msg, void* data) {
|
||||
struct nlattr* tb_msg[NL80211_ATTR_MAX + 1];
|
||||
struct genlmsghdr* gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
struct nl80211_device_handle* devicehandle = (struct nl80211_device_handle*)data;
|
||||
|
||||
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
|
||||
|
||||
if (tb_msg[NL80211_ATTR_WIPHY] && (nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]) == devicehandle->phyindex)) {
|
||||
/* Interface supported */
|
||||
if (tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES]) {
|
||||
int i;
|
||||
struct nlattr* nl_mode;
|
||||
|
||||
devicehandle->physupported = 0;
|
||||
nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
|
||||
switch (nla_type(nl_mode)) {
|
||||
case NL80211_IFTYPE_AP: {
|
||||
devicehandle->physupported |= WIFI_CAPABILITY_AP_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
case NL80211_IFTYPE_AP_VLAN: {
|
||||
devicehandle->physupported |= WIFI_CAPABILITY_AP_VLAN_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
case NL80211_IFTYPE_ADHOC: {
|
||||
devicehandle->physupported |= WIFI_CAPABILITY_ADHOC_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
case NL80211_IFTYPE_WDS: {
|
||||
devicehandle->physupported |= WIFI_CAPABILITY_WDS_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
case NL80211_IFTYPE_MONITOR: {
|
||||
devicehandle->physupported |= WIFI_CAPABILITY_MONITOR_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_get_phydevice_capability(struct nl80211_device_handle* devicehandle) {
|
||||
int result;
|
||||
struct nl_msg* msg;
|
||||
|
||||
ASSERT(devicehandle != NULL);
|
||||
|
||||
/* */
|
||||
msg = nlmsg_alloc();
|
||||
if (!msg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
genlmsg_put(msg, 0, 0, devicehandle->globalhandle->nl80211_id, 0, 0, NL80211_CMD_GET_WIPHY, 0);
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY, devicehandle->phyindex);
|
||||
|
||||
/* Retrieve physical device capability */
|
||||
result = nl80211_send_and_recv_msg(devicehandle->globalhandle, msg, cb_get_phydevice_capability, devicehandle);
|
||||
|
||||
/* */
|
||||
nlmsg_free(msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int nl80211_destroy_virtdevice(struct nl80211_global_handle* globalhandle, uint32_t virtindex) {
|
||||
int result;
|
||||
struct nl_msg* msg;
|
||||
|
||||
ASSERT(globalhandle != NULL);
|
||||
|
||||
/* */
|
||||
msg = nlmsg_alloc();
|
||||
if (!msg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
genlmsg_put(msg, 0, 0, globalhandle->nl80211_id, 0, 0, NL80211_CMD_DEL_INTERFACE, 0);
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, virtindex);
|
||||
|
||||
/* Destroy virtual device */
|
||||
result = nl80211_send_and_recv_msg(globalhandle, msg, NULL, NULL);
|
||||
|
||||
/* */
|
||||
nlmsg_free(msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_destroy_all_virtdevice(struct nl80211_global_handle* globalhandle, uint32_t phyindex) {
|
||||
int result;
|
||||
struct capwap_list* list;
|
||||
|
||||
/* Retrieve all virtual device */
|
||||
list = capwap_list_create();
|
||||
result = nl80211_get_virtdevice_list(globalhandle, list);
|
||||
if (!result) {
|
||||
struct capwap_list_item* item = list->first;
|
||||
|
||||
/* Search virtual device by physical device */
|
||||
while (item) {
|
||||
struct nl80211_virtdevice_item* virtitem = (struct nl80211_virtdevice_item*)item->item;
|
||||
|
||||
/* Destroy virtual device */
|
||||
if (virtitem->phyindex == phyindex) {
|
||||
wifi_iface_updown(globalhandle->sock_util, virtitem->virtname, 0);
|
||||
result = nl80211_destroy_virtdevice(globalhandle, virtitem->virtindex);
|
||||
if (result) {
|
||||
capwap_logging_error("Unable to destroy virtual device, error code: %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
/* Next */
|
||||
item = item->next;
|
||||
}
|
||||
} else {
|
||||
/* Error get virtual devices */
|
||||
capwap_logging_error("Unable retrieve virtual device info, error code: %d", result);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_list_free(list);
|
||||
}
|
||||
|
||||
/* */
|
||||
static wifi_device_handle nl80211_device_init(wifi_global_handle handle, struct device_init_params* params) {
|
||||
int result;
|
||||
@ -222,8 +400,18 @@ static wifi_device_handle nl80211_device_init(wifi_global_handle handle, struct
|
||||
/* */
|
||||
devicehandle->globalhandle = globalhandle;
|
||||
|
||||
/* Remove all virtual adapter from wifi device */
|
||||
nl80211_destroy_all_virtdevice(globalhandle, devicehandle->phyindex);
|
||||
|
||||
/* Retrieve wifi device capability */
|
||||
result = nl80211_get_phydevice_capability(devicehandle);
|
||||
if (result) {
|
||||
capwap_logging_error("Unable retrieve physical device capability, error code: %d", result);
|
||||
}
|
||||
|
||||
/* Save device handle into global handle */
|
||||
item = capwap_itemlist_create_with_item(devicehandle, sizeof(struct nl80211_device_handle));
|
||||
item->autodelete = 0;
|
||||
capwap_itemlist_insert_after(globalhandle->devicelist, NULL, item);
|
||||
|
||||
return devicehandle;
|
||||
@ -239,9 +427,12 @@ static void nl80211_device_deinit(wifi_device_handle handle) {
|
||||
/* Remove device handle from global handle*/
|
||||
search = devicehandle->globalhandle->devicelist->first;
|
||||
while (search) {
|
||||
/* Remove item from list without destroy */
|
||||
if ((struct nl80211_device_handle*)search->item == devicehandle) {
|
||||
capwap_itemlist_remove(devicehandle->globalhandle->devicelist, search);
|
||||
/* Remove all virtual adapter from wifi device */
|
||||
nl80211_destroy_all_virtdevice(devicehandle->globalhandle, devicehandle->phyindex);
|
||||
|
||||
/* Remove item from list */
|
||||
capwap_itemlist_free(capwap_itemlist_remove(devicehandle->globalhandle->devicelist, search));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -253,6 +444,32 @@ static void nl80211_device_deinit(wifi_device_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->nl) {
|
||||
nl_socket_free(globalhandle->nl);
|
||||
}
|
||||
|
||||
if (globalhandle->nl_cb) {
|
||||
nl_cb_put(globalhandle->nl_cb);
|
||||
}
|
||||
|
||||
if (globalhandle->devicelist) {
|
||||
ASSERT(globalhandle->devicelist->count == 0);
|
||||
capwap_list_free(globalhandle->devicelist);
|
||||
}
|
||||
|
||||
if (globalhandle->sock_util >= 0) {
|
||||
close(globalhandle->sock_util);
|
||||
}
|
||||
|
||||
capwap_free(globalhandle);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static wifi_global_handle nl80211_global_init(void) {
|
||||
struct nl80211_global_handle* globalhandle;
|
||||
@ -260,19 +477,19 @@ static wifi_global_handle nl80211_global_init(void) {
|
||||
/* */
|
||||
globalhandle = (struct nl80211_global_handle*)capwap_alloc(sizeof(struct nl80211_global_handle));
|
||||
memset(globalhandle, 0, sizeof(struct nl80211_global_handle));
|
||||
globalhandle->sock_util = -1;
|
||||
|
||||
/* Configure global netlink callback */
|
||||
globalhandle->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
|
||||
if (!globalhandle->nl_cb) {
|
||||
capwap_free(globalhandle);
|
||||
nl80211_global_deinit((wifi_global_handle)globalhandle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create netlink socket */
|
||||
globalhandle->nl = nl_create_handle(globalhandle->nl_cb);
|
||||
if (!globalhandle->nl) {
|
||||
nl_cb_put(globalhandle->nl_cb);
|
||||
capwap_free(globalhandle);
|
||||
nl80211_global_deinit((wifi_global_handle)globalhandle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -280,9 +497,7 @@ static wifi_global_handle nl80211_global_init(void) {
|
||||
globalhandle->nl80211_id = genl_ctrl_resolve(globalhandle->nl, "nl80211");
|
||||
if (globalhandle->nl80211_id < 0) {
|
||||
capwap_logging_warning("Unable to found mac80211 kernel module");
|
||||
nl_socket_free(globalhandle->nl);
|
||||
nl_cb_put(globalhandle->nl_cb);
|
||||
capwap_free(globalhandle);
|
||||
nl80211_global_deinit((wifi_global_handle)globalhandle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -293,29 +508,16 @@ static wifi_global_handle nl80211_global_init(void) {
|
||||
/* Device list */
|
||||
globalhandle->devicelist = capwap_list_create();
|
||||
|
||||
/* Socket utils */
|
||||
globalhandle->sock_util = socket(AF_PACKET, SOCK_RAW, 0);
|
||||
if (globalhandle->sock_util < 0) {
|
||||
nl80211_global_deinit((wifi_global_handle)globalhandle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (wifi_global_handle)globalhandle;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_global_deinit(wifi_global_handle handle) {
|
||||
struct nl80211_global_handle* globalhandle = (struct nl80211_global_handle*)handle;
|
||||
|
||||
if (globalhandle) {
|
||||
ASSERT(globalhandle->devicelist->count == 0);
|
||||
|
||||
if (globalhandle->nl) {
|
||||
nl_socket_free(globalhandle->nl);
|
||||
}
|
||||
|
||||
if (globalhandle->nl_cb) {
|
||||
nl_cb_put(globalhandle->nl_cb);
|
||||
}
|
||||
|
||||
capwap_list_free(globalhandle->devicelist);
|
||||
capwap_free(globalhandle);
|
||||
}
|
||||
}
|
||||
|
||||
/* Driver function */
|
||||
const struct wifi_driver_ops wifi_driver_nl80211_ops = {
|
||||
.name = "nl80211",
|
||||
|
@ -15,6 +15,8 @@ struct nl80211_global_handle {
|
||||
struct nl_cb* nl_cb;
|
||||
int nl80211_id;
|
||||
|
||||
int sock_util;
|
||||
|
||||
struct capwap_list* devicelist;
|
||||
};
|
||||
|
||||
@ -24,6 +26,9 @@ struct nl80211_device_handle {
|
||||
|
||||
uint32_t phyindex;
|
||||
char phyname[IFNAMSIZ];
|
||||
|
||||
/* Capability */
|
||||
unsigned long physupported;
|
||||
};
|
||||
|
||||
/* Physical device info */
|
||||
@ -32,4 +37,11 @@ struct nl80211_phydevice_item {
|
||||
char name[IFNAMSIZ];
|
||||
};
|
||||
|
||||
/* Virtual device info */
|
||||
struct nl80211_virtdevice_item {
|
||||
uint32_t phyindex;
|
||||
uint32_t virtindex;
|
||||
char virtname[IFNAMSIZ];
|
||||
};
|
||||
|
||||
#endif /* __WIFI_NL80211_HEADER__ */
|
||||
|
@ -155,7 +155,6 @@ int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control
|
||||
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
} else {
|
||||
int i;
|
||||
int result;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
@ -182,10 +181,7 @@ int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPMACTYPE_ELEMENT(&g_wtp.mactype));
|
||||
|
||||
if (g_wtp.binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
for (i = 0; i < g_wtp.radios->count; i++) {
|
||||
struct wtp_radio* radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_80211_WTPRADIOINFORMATION_ELEMENT(&radio->radioinformation));
|
||||
}
|
||||
wtp_create_80211_wtpradioinformation_element(buildpacket);
|
||||
} else {
|
||||
capwap_logging_debug("Unknown capwap binding");
|
||||
}
|
||||
|
@ -68,10 +68,7 @@ int wtp_dfa_state_dtlsconnect_to_join(struct capwap_packet* packet, struct timeo
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPMACTYPE_ELEMENT(&g_wtp.mactype));
|
||||
|
||||
if (g_wtp.binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
for (i = 0; i < g_wtp.radios->count; i++) {
|
||||
struct wtp_radio* radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_80211_WTPRADIOINFORMATION_ELEMENT(&radio->radioinformation));
|
||||
}
|
||||
wtp_create_80211_wtpradioinformation_element(buildpacket);
|
||||
} else {
|
||||
capwap_logging_debug("Unknown capwap binding");
|
||||
}
|
||||
@ -245,6 +242,12 @@ int wtp_dfa_state_join_to_configure(struct capwap_packet* packet, struct timeout
|
||||
/* CAPWAP_CREATE_WTPSTATICIPADDRESS_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
if (g_wtp.binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
wtp_create_80211_wtpradioinformation_element(buildpacket);
|
||||
} else {
|
||||
capwap_logging_debug("Unknown capwap binding");
|
||||
}
|
||||
|
||||
/* Create Configuration Status request packet */
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
wtp_free_reference_last_request();
|
||||
|
10
src/wtp/wtp_element_helper.c
Normal file
10
src/wtp/wtp_element_helper.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include "wtp.h"
|
||||
|
||||
void wtp_create_80211_wtpradioinformation_element(struct capwap_build_packet* buildpacket) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g_wtp.radios->count; i++) {
|
||||
struct wtp_radio* radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_80211_WTPRADIOINFORMATION_ELEMENT(&radio->radioinformation));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user