Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
25da5ad965 | |||
04b1f205c5 | |||
c2a07804db | |||
a96bb07868 | |||
f9bb716dac | |||
7b9f515bd7 | |||
9ee69a6778 |
@ -56,6 +56,6 @@ WolfSSL:
|
||||
SmartCAPWAP:
|
||||
|
||||
autoreconf -f -i
|
||||
./configure --without-ac
|
||||
./configure --disable-ac
|
||||
make
|
||||
make install
|
||||
|
@ -208,7 +208,7 @@ fi
|
||||
# Check Netlink library
|
||||
PKG_CHECK_MODULES(
|
||||
[LIBNL3],
|
||||
[libnl-3.0 >= 3.1],
|
||||
[libnl-3.0 >= 3.1 libnl-genl-3.0 >= 3.1],
|
||||
[have_libnl3=yes],
|
||||
[PKG_CHECK_MODULES(
|
||||
[LIBNL],
|
||||
|
@ -11,6 +11,7 @@
|
||||
/* */
|
||||
#define CAPWAP_MACADDRESS_EUI48_BUFFER 18
|
||||
#define CAPWAP_MACADDRESS_EUI64_BUFFER 24
|
||||
#define CAPWAP_MAX_FQDN_SIZE 256
|
||||
|
||||
/* */
|
||||
union sockaddr_capwap {
|
||||
@ -20,6 +21,12 @@ union sockaddr_capwap {
|
||||
struct sockaddr_storage ss;
|
||||
};
|
||||
|
||||
struct addr_capwap {
|
||||
char fqdn[CAPWAP_MAX_FQDN_SIZE];
|
||||
union sockaddr_capwap sockaddr;
|
||||
char resolved;
|
||||
};
|
||||
|
||||
/* Helper */
|
||||
#define CAPWAP_GET_NETWORK_PORT(addr) ntohs((((addr)->ss.ss_family == AF_INET) ? (addr)->sin.sin_port : (((addr)->ss.ss_family == AF_INET6) ? (addr)->sin6.sin6_port : 0)))
|
||||
#define CAPWAP_SET_NETWORK_PORT(addr, port) if ((addr)->ss.ss_family == AF_INET) { \
|
||||
|
@ -67,16 +67,16 @@ static int wtp_init(void) {
|
||||
g_wtp.validdtlsdatapolicy = CAPWAP_ACDESC_CLEAR_DATA_CHANNEL_ENABLED;
|
||||
|
||||
/* Tx fragment packets */
|
||||
g_wtp.mtu = CAPWAP_MTU_DEFAULT;
|
||||
g_wtp.requestfragmentpacket = capwap_list_create();
|
||||
g_wtp.responsefragmentpacket = capwap_list_create();
|
||||
g_wtp.remoteseqnumber = WTP_INIT_REMOTE_SEQUENCE;
|
||||
|
||||
wtp_reset_state();
|
||||
|
||||
/* AC information */
|
||||
g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_UNKNOWN;
|
||||
g_wtp.acdiscoveryrequest = 1;
|
||||
g_wtp.acdiscoveryarray = capwap_array_create(sizeof(union sockaddr_capwap), 0, 0);
|
||||
g_wtp.acpreferedarray = capwap_array_create(sizeof(union sockaddr_capwap), 0, 0);
|
||||
g_wtp.acdiscoveryarray = capwap_array_create(sizeof(struct addr_capwap), 0, 0);
|
||||
g_wtp.acpreferedarray = capwap_array_create(sizeof(struct addr_capwap), 0, 0);
|
||||
g_wtp.acdiscoveryresponse = capwap_array_create(sizeof(struct wtp_discovery_response), 0, 1);
|
||||
|
||||
/* Radios */
|
||||
@ -136,14 +136,15 @@ static void wtp_destroy(void) {
|
||||
|
||||
/* */
|
||||
static void wtp_add_default_acaddress() {
|
||||
union sockaddr_capwap address;
|
||||
struct addr_capwap address;
|
||||
|
||||
/* Broadcast IPv4 */
|
||||
memset(&address, 0, sizeof(union sockaddr_capwap));
|
||||
address.sin.sin_family = AF_INET;
|
||||
address.sin.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
address.sin.sin_port = htons(CAPWAP_CONTROL_PORT);
|
||||
memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &address, sizeof(union sockaddr_capwap));
|
||||
memset(&address, 0, sizeof(struct addr_capwap));
|
||||
address.resolved = 1;
|
||||
address.sockaddr.sin.sin_family = AF_INET;
|
||||
address.sockaddr.sin.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
address.sockaddr.sin.sin_port = htons(CAPWAP_CONTROL_PORT);
|
||||
memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &address, sizeof(struct addr_capwap));
|
||||
|
||||
/* Multicast IPv4 */
|
||||
/* TODO */
|
||||
@ -745,12 +746,12 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
|
||||
capability = wifi_device_getcapability(radio->devicehandle);
|
||||
if (capability) {
|
||||
uint8_t bssid;
|
||||
char wlanname[IFNAMSIZ];
|
||||
struct capwap_list_item* itemwlan;
|
||||
struct wtp_radio_wlanpool* wlanpool;
|
||||
|
||||
/* Create interface */
|
||||
for (bssid = 0; bssid < radio->radioconfig.maxbssid; bssid++) {
|
||||
char wlanname[IFNAMSIZ];
|
||||
struct wtp_radio_wlan *wlan;
|
||||
|
||||
sprintf(wlanname, "%s%02d.%02d", radio->wlanprefix, (int)radio->radioid, (int)bssid + 1);
|
||||
if (wifi_iface_index(wlanname)) {
|
||||
capwap_logging_error("interface %s already exists", wlanname);
|
||||
@ -758,18 +759,16 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
|
||||
}
|
||||
|
||||
/* */
|
||||
itemwlan = capwap_itemlist_create(sizeof(struct wtp_radio_wlanpool));
|
||||
wlanpool = (struct wtp_radio_wlanpool*)itemwlan->item;
|
||||
wlanpool->radio = radio;
|
||||
wlanpool->wlanhandle = wifi_wlan_create(radio->devicehandle, wlanname);
|
||||
if (!wlanpool->wlanhandle) {
|
||||
wlan = (struct wtp_radio_wlan *)capwap_array_get_item_pointer(radio->wlan, bssid + 1);
|
||||
wlan->in_use = 0;
|
||||
wlan->radio = radio;
|
||||
wlan->wlanhandle = wifi_wlan_create(radio->devicehandle, wlanname);
|
||||
if (!wlan->wlanhandle) {
|
||||
capwap_logging_error("Unable to create interface: %s", wlanname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Appent to wlan pool */
|
||||
capwap_logging_debug("Created wlan interface: %s", wlanname);
|
||||
capwap_itemlist_insert_after(radio->wlanpool, NULL, itemwlan);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1068,20 +1067,22 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
|
||||
for (i = 0; i < count; i++) {
|
||||
const char* address = config_setting_get_string_elem(configSetting, i);
|
||||
if (address != NULL) {
|
||||
union sockaddr_capwap acaddr;
|
||||
struct addr_capwap acaddr;
|
||||
memset(&acaddr, 0, sizeof(struct addr_capwap));
|
||||
strncpy(acaddr.fqdn, address, CAPWAP_MAX_FQDN_SIZE-1);
|
||||
acaddr.resolved = 0;
|
||||
|
||||
/* Parsing address */
|
||||
if (capwap_address_from_string(address, &acaddr)) {
|
||||
if (!CAPWAP_GET_NETWORK_PORT(&acaddr)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&acaddr, CAPWAP_CONTROL_PORT);
|
||||
if (capwap_address_from_string(address, &acaddr.sockaddr)) {
|
||||
if (!CAPWAP_GET_NETWORK_PORT(&acaddr.sockaddr)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&acaddr.sockaddr, CAPWAP_CONTROL_PORT);
|
||||
}
|
||||
|
||||
memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &acaddr, sizeof(union sockaddr_capwap));
|
||||
acaddr.resolved = 1;
|
||||
g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_STATIC;
|
||||
} else {
|
||||
capwap_logging_error("Invalid configuration file, invalid application.acdiscovery.host value");
|
||||
return 0;
|
||||
capwap_logging_info("%s:%d Could not resolve application.acdiscovery.host %s", __FILE__, __LINE__, address);
|
||||
}
|
||||
memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &acaddr, sizeof(struct addr_capwap));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1094,19 +1095,21 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
|
||||
for (i = 0; i < count; i++) {
|
||||
const char* address = config_setting_get_string_elem(configSetting, i);
|
||||
if (address != NULL) {
|
||||
union sockaddr_capwap acaddr;
|
||||
struct addr_capwap acaddr;
|
||||
memset(&acaddr, 0, sizeof(struct addr_capwap));
|
||||
strncpy(acaddr.fqdn, address, CAPWAP_MAX_FQDN_SIZE-1);
|
||||
acaddr.resolved = 0;
|
||||
|
||||
/* Parsing address */
|
||||
if (capwap_address_from_string(address, &acaddr)) {
|
||||
if (!CAPWAP_GET_NETWORK_PORT(&acaddr)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&acaddr, CAPWAP_CONTROL_PORT);
|
||||
if (capwap_address_from_string(address, &acaddr.sockaddr)) {
|
||||
if (!CAPWAP_GET_NETWORK_PORT(&acaddr.sockaddr)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&acaddr.sockaddr, CAPWAP_CONTROL_PORT);
|
||||
}
|
||||
|
||||
memcpy(capwap_array_get_item_pointer(g_wtp.acpreferedarray, g_wtp.acpreferedarray->count), &acaddr, sizeof(union sockaddr_capwap));
|
||||
acaddr.resolved = 1;
|
||||
} else {
|
||||
capwap_logging_error("Invalid configuration file, invalid application.acprefered.host value");
|
||||
return 0;
|
||||
capwap_logging_info("%s:%d Could not resolve application.acprefered.host %s", __FILE__, __LINE__, acaddr.fqdn);
|
||||
}
|
||||
memcpy(capwap_array_get_item_pointer(g_wtp.acpreferedarray, g_wtp.acpreferedarray->count), &acaddr, sizeof(struct addr_capwap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -544,3 +544,20 @@ void wtp_dfa_retransmition_timeout(struct capwap_timeout* timeout, unsigned long
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wtp_reset_state(void)
|
||||
{
|
||||
/* reset WTP state */
|
||||
wtp_radio_reset();
|
||||
|
||||
wtp_free_reference_last_request();
|
||||
wtp_free_reference_last_response();
|
||||
wtp_free_packet_rxmng();
|
||||
|
||||
g_wtp.mtu = CAPWAP_MTU_DEFAULT;
|
||||
g_wtp.remotetype = 0;
|
||||
g_wtp.remoteseqnumber = WTP_INIT_REMOTE_SEQUENCE;
|
||||
|
||||
memset(&g_wtp.dtls.localaddr, 0, sizeof(g_wtp.dtls.localaddr));
|
||||
memset(&g_wtp.dtls.peeraddr, 0, sizeof(g_wtp.dtls.peeraddr));
|
||||
}
|
||||
|
@ -70,4 +70,6 @@ void wtp_ieee80211_packet(uint8_t radioid, const struct ieee80211_header* header
|
||||
void wtp_recv_data_keepalive(void);
|
||||
void wtp_recv_data(uint8_t* buffer, int length);
|
||||
|
||||
void wtp_reset_state(void);
|
||||
|
||||
#endif /* __WTP_DFA_HEADER__ */
|
||||
|
@ -49,9 +49,18 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo
|
||||
|
||||
/* Check for preferred AC */
|
||||
for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) {
|
||||
union sockaddr_capwap* acpreferredaddr = (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
|
||||
|
||||
if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) {
|
||||
struct addr_capwap* acpreferredaddr = (struct addr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
|
||||
if (!acpreferredaddr->resolved) {
|
||||
if (capwap_address_from_string(acpreferredaddr->fqdn, &acpreferredaddr->sockaddr)) {
|
||||
if (!CAPWAP_GET_NETWORK_PORT(&acpreferredaddr->sockaddr)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&acpreferredaddr->sockaddr, CAPWAP_CONTROL_PORT);
|
||||
}
|
||||
acpreferredaddr->resolved = 1;
|
||||
} else {
|
||||
capwap_logging_info("%s:%d Could not resolve application.acprefered.host %s", __FILE__, __LINE__, acpreferredaddr->fqdn);
|
||||
}
|
||||
}
|
||||
if (!capwap_compare_ip(&acpreferredaddr->sockaddr, &checkaddr)) {
|
||||
indexpreferred = j;
|
||||
memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap));
|
||||
break;
|
||||
@ -79,9 +88,18 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo
|
||||
|
||||
/* Check for preferred AC */
|
||||
for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) {
|
||||
union sockaddr_capwap* acpreferredaddr = (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
|
||||
|
||||
if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) {
|
||||
struct addr_capwap* acpreferredaddr = (struct addr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
|
||||
if (!acpreferredaddr->resolved) {
|
||||
if (capwap_address_from_string(acpreferredaddr->fqdn, &acpreferredaddr->sockaddr)) {
|
||||
if (!CAPWAP_GET_NETWORK_PORT(&acpreferredaddr->sockaddr)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&acpreferredaddr->sockaddr, CAPWAP_CONTROL_PORT);
|
||||
}
|
||||
acpreferredaddr->resolved = 1;
|
||||
} else {
|
||||
capwap_logging_info("Could not resolve application.acprefered.host %s", acpreferredaddr->fqdn);
|
||||
}
|
||||
}
|
||||
if (!capwap_compare_ip(&acpreferredaddr->sockaddr, &checkaddr)) {
|
||||
indexpreferred = j;
|
||||
memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap));
|
||||
break;
|
||||
@ -183,8 +201,20 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo
|
||||
|
||||
/* Send discovery request to AC */
|
||||
for (i = 0; i < g_wtp.acdiscoveryarray->count; i++) {
|
||||
if (!capwap_sendto_fragmentpacket(g_wtp.net.socket, g_wtp.requestfragmentpacket, (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, i))) {
|
||||
capwap_logging_debug("Warning: error to send discovery request packet");
|
||||
struct addr_capwap* addr = capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, i);
|
||||
if (!addr->resolved) {
|
||||
if (capwap_address_from_string(addr->fqdn, &addr->sockaddr)) {
|
||||
if (!CAPWAP_GET_NETWORK_PORT(&addr->sockaddr)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&addr->sockaddr, CAPWAP_CONTROL_PORT);
|
||||
}
|
||||
addr->resolved = 1;
|
||||
g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_STATIC;
|
||||
} else {
|
||||
capwap_logging_info("%s:%d Could not resolve application.acdiscovery.host %s", __FILE__, __LINE__, addr->fqdn);
|
||||
}
|
||||
}
|
||||
if (!capwap_sendto_fragmentpacket(g_wtp.net.socket, g_wtp.requestfragmentpacket, &addr->sockaddr)) {
|
||||
capwap_logging_info("Error to send discovery request packet");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,9 +71,7 @@ static void wtp_dfa_state_dtlsteardown_timeout(struct capwap_timeout* timeout, u
|
||||
}
|
||||
|
||||
/* */
|
||||
wtp_free_reference_last_request();
|
||||
wtp_free_reference_last_response();
|
||||
wtp_free_packet_rxmng();
|
||||
wtp_reset_state();
|
||||
|
||||
/* */
|
||||
if (!g_wtp.running) {
|
||||
|
@ -12,12 +12,13 @@ static int wtp_join_prefered_ac()
|
||||
while (g_wtp.acpreferedselected < g_wtp.acpreferedarray->count)
|
||||
{
|
||||
union sockaddr_capwap localaddr;
|
||||
union sockaddr_capwap *peeraddr;
|
||||
struct addr_capwap *peeraddr;
|
||||
|
||||
/* Found in configuration file the AC address */
|
||||
peeraddr = capwap_array_get_item_pointer(g_wtp.acpreferedarray,
|
||||
g_wtp.acpreferedselected);
|
||||
|
||||
|
||||
/* Next AC */
|
||||
g_wtp.acpreferedselected++;
|
||||
|
||||
@ -28,7 +29,18 @@ static int wtp_join_prefered_ac()
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (capwap_connect_socket(&g_wtp.net, peeraddr) < 0) {
|
||||
if(!peeraddr->resolved) {
|
||||
if (capwap_address_from_string(peeraddr->fqdn, &peeraddr->sockaddr)) {
|
||||
if (!CAPWAP_GET_NETWORK_PORT(&peeraddr->sockaddr)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&peeraddr->sockaddr, CAPWAP_CONTROL_PORT);
|
||||
}
|
||||
peeraddr->resolved = 1;
|
||||
} else {
|
||||
capwap_logging_info("%s:%d Could not resolve application.acprefered.host %s", __FILE__, __LINE__, peeraddr->fqdn);
|
||||
}
|
||||
}
|
||||
|
||||
if (capwap_connect_socket(&g_wtp.net, &peeraddr->sockaddr) < 0) {
|
||||
capwap_logging_fatal("Cannot bind control address");
|
||||
capwap_close_sockets(&g_wtp.net);
|
||||
return -1;
|
||||
@ -42,7 +54,7 @@ static int wtp_join_prefered_ac()
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_crypt_setconnection(&g_wtp.dtls, g_wtp.net.socket, &localaddr, peeraddr);
|
||||
capwap_crypt_setconnection(&g_wtp.dtls, g_wtp.net.socket, &localaddr, &peeraddr->sockaddr);
|
||||
|
||||
/* */
|
||||
if (!g_wtp.enabledtls) {
|
||||
|
@ -18,7 +18,11 @@ struct wtp_update_configuration_item {
|
||||
};
|
||||
|
||||
/* */
|
||||
static int wtp_radio_configure_phy(struct wtp_radio* radio) {
|
||||
static int wtp_radio_configure_phy(struct wtp_radio* radio)
|
||||
{
|
||||
if (radio->initialized)
|
||||
return 0;
|
||||
|
||||
/* Default rate set is all supported rate */
|
||||
if (radio->radioid != radio->rateset.radioid) {
|
||||
if (radio->radioid != radio->supportedrates.radioid) {
|
||||
@ -32,7 +36,8 @@ static int wtp_radio_configure_phy(struct wtp_radio* radio) {
|
||||
memcpy(radio->rateset.rateset, radio->supportedrates.supportedrates, CAPWAP_RATESET_MAXLENGTH);
|
||||
|
||||
/* Update rates */
|
||||
if (wifi_device_updaterates(radio->devicehandle, radio->rateset.rateset, radio->rateset.ratesetcount)) {
|
||||
if (wifi_device_updaterates(radio->devicehandle, radio->rateset.rateset,
|
||||
radio->rateset.ratesetcount)) {
|
||||
capwap_logging_debug("Config Phy: update rates failed");
|
||||
return -1;
|
||||
}
|
||||
@ -45,17 +50,22 @@ static int wtp_radio_configure_phy(struct wtp_radio* radio) {
|
||||
} else if (radio->radioid != radio->radioconfig.radioid) {
|
||||
capwap_logging_debug("Config Phy: RC id mismatch");
|
||||
return -1;
|
||||
} else if ((!radio->directsequencecontrol.radioid && !radio->ofdmcontrol.radioid) || ((radio->directsequencecontrol.radioid == radio->radioid) && (radio->ofdmcontrol.radioid == radio->radioid))) {
|
||||
} else if ((!radio->directsequencecontrol.radioid && !radio->ofdmcontrol.radioid) ||
|
||||
((radio->directsequencecontrol.radioid == radio->radioid) &&
|
||||
(radio->ofdmcontrol.radioid == radio->radioid))) {
|
||||
capwap_logging_debug("Config Phy: DSSS / OFDM mismatch");
|
||||
return -1; /* Only one from DSSS and OFDM can select */
|
||||
} else if ((radio->radioid == radio->directsequencecontrol.radioid) && !(radio->radioinformation.radiotype & (CAPWAP_RADIO_TYPE_80211B | CAPWAP_RADIO_TYPE_80211G))) {
|
||||
} else if ((radio->radioid == radio->directsequencecontrol.radioid) &&
|
||||
!(radio->radioinformation.radiotype & (CAPWAP_RADIO_TYPE_80211B | CAPWAP_RADIO_TYPE_80211G))) {
|
||||
capwap_logging_debug("Config Phy: DSSS B/G mismatch");
|
||||
return -1;
|
||||
} else if ((radio->radioid == radio->ofdmcontrol.radioid) && !(radio->radioinformation.radiotype & CAPWAP_RADIO_TYPE_80211A)) {
|
||||
} else if ((radio->radioid == radio->ofdmcontrol.radioid) &&
|
||||
!(radio->radioinformation.radiotype & CAPWAP_RADIO_TYPE_80211A)) {
|
||||
capwap_logging_debug("Config Phy: OFDM A mismatch");
|
||||
return -1;
|
||||
}
|
||||
|
||||
radio->initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -89,43 +99,28 @@ void wtp_radio_init(void) {
|
||||
}
|
||||
|
||||
/* */
|
||||
void wtp_radio_close(void) {
|
||||
void wtp_radio_close(void)
|
||||
{
|
||||
int i;
|
||||
struct capwap_list_item* itemwlan;
|
||||
|
||||
ASSERT(g_wtp.radios != NULL);
|
||||
|
||||
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);
|
||||
struct wtp_radio* radio =
|
||||
(struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i);
|
||||
|
||||
if (radio->antenna.selections) {
|
||||
capwap_array_free(radio->antenna.selections);
|
||||
}
|
||||
|
||||
if (radio->wlan) {
|
||||
for (itemwlan = radio->wlan->first; itemwlan != NULL; itemwlan = itemwlan->next) {
|
||||
struct wtp_radio_wlan* wlan = (struct wtp_radio_wlan*)itemwlan->item;
|
||||
|
||||
for (i = 0; i < radio->wlan->count; i++) {
|
||||
struct wtp_radio_wlan *wlan =
|
||||
(struct wtp_radio_wlan *)capwap_array_get_item_pointer(radio->wlan, i);
|
||||
/* Destroy BSS interface */
|
||||
if (wlan->wlanhandle) {
|
||||
if (wlan->wlanhandle)
|
||||
wifi_wlan_destroy(wlan->wlanhandle);
|
||||
}
|
||||
}
|
||||
|
||||
capwap_list_free(radio->wlan);
|
||||
}
|
||||
|
||||
if (radio->wlanpool) {
|
||||
for (itemwlan = radio->wlanpool->first; itemwlan != NULL; itemwlan = itemwlan->next) {
|
||||
struct wtp_radio_wlanpool* wlanpool = (struct wtp_radio_wlanpool*)itemwlan->item;
|
||||
|
||||
/* Destroy BSS interface */
|
||||
if (wlanpool->wlanhandle) {
|
||||
wifi_wlan_destroy(wlanpool->wlanhandle);
|
||||
}
|
||||
}
|
||||
|
||||
capwap_list_free(radio->wlanpool);
|
||||
capwap_array_free(radio->wlan);
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,6 +139,36 @@ void wtp_radio_free(void) {
|
||||
capwap_hash_free(g_wtp.aclstations);
|
||||
}
|
||||
|
||||
/* */
|
||||
void wtp_radio_reset()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!g_wtp.radios)
|
||||
return;
|
||||
|
||||
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);
|
||||
|
||||
for (j = 0; j < radio->wlan->count; j++) {
|
||||
struct wtp_radio_wlan *wlan =
|
||||
(struct wtp_radio_wlan *)capwap_array_get_item_pointer(radio->wlan, j);
|
||||
|
||||
/* Destroy WLAN interface */
|
||||
if (wlan->wlanhandle)
|
||||
wifi_wlan_stopap(wlan->wlanhandle);
|
||||
|
||||
wlan->in_use = 0;
|
||||
}
|
||||
|
||||
radio->initialized = 0;
|
||||
}
|
||||
|
||||
/* Update Event File Descriptor */
|
||||
wtp_dfa_update_fdspool(&g_wtp.fds);
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet) {
|
||||
int i;
|
||||
@ -512,8 +537,7 @@ struct wtp_radio* wtp_radio_create_phy(void) {
|
||||
radio->status = WTP_RADIO_DISABLED;
|
||||
|
||||
/* Init configuration radio */
|
||||
radio->wlan = capwap_list_create();
|
||||
radio->wlanpool = capwap_list_create();
|
||||
radio->wlan = capwap_array_create(sizeof(struct wtp_radio_wlan), 0, 1);
|
||||
radio->antenna.selections = capwap_array_create(sizeof(uint8_t), 0, 1);
|
||||
return radio;
|
||||
}
|
||||
@ -539,10 +563,10 @@ struct wtp_radio* wtp_radio_get_phy(uint8_t radioid) {
|
||||
}
|
||||
|
||||
/* */
|
||||
struct wtp_radio_wlan* wtp_radio_get_wlan(struct wtp_radio* radio, uint8_t wlanid) {
|
||||
struct capwap_list_item* itemwlan;
|
||||
|
||||
struct wtp_radio_wlan *wtp_radio_get_wlan(struct wtp_radio *radio, uint8_t wlanid)
|
||||
{
|
||||
ASSERT(radio != NULL);
|
||||
ASSERT(radio->wlan != NULL);
|
||||
|
||||
/* Check */
|
||||
if (!IS_VALID_WLANID(wlanid)) {
|
||||
@ -550,37 +574,42 @@ struct wtp_radio_wlan* wtp_radio_get_wlan(struct wtp_radio* radio, uint8_t wlani
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Retrieve BSS */
|
||||
for (itemwlan = radio->wlan->first; itemwlan != NULL; itemwlan = itemwlan->next) {
|
||||
struct wtp_radio_wlan* wlan = (struct wtp_radio_wlan*)itemwlan->item;
|
||||
capwap_logging_debug("wtp_radio_get_wlan: checking (%d .. %d)", wlanid, wlan->wlanid);
|
||||
if (wlanid == wlan->wlanid) {
|
||||
return wlan;
|
||||
}
|
||||
}
|
||||
|
||||
if (wlanid > radio->wlan->count) {
|
||||
capwap_logging_warning("wtp_radio_get_wlan: invalid wlanid (%d > %d)",
|
||||
wlanid, radio->wlan->count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Retrieve BSS */
|
||||
return (struct wtp_radio_wlan *)capwap_array_get_item_pointer(radio->wlan, wlanid);
|
||||
}
|
||||
|
||||
/* */
|
||||
static struct wtp_radio_wlan* __wtp_radio_search_wlan(struct wtp_radio* radio, const uint8_t* bssid) {
|
||||
struct capwap_list_item* itemwlan;
|
||||
static struct wtp_radio_wlan *__wtp_radio_search_wlan(struct wtp_radio *radio, const uint8_t *bssid)
|
||||
{
|
||||
int i;
|
||||
|
||||
ASSERT(radio != NULL);
|
||||
ASSERT(radio->wlan != NULL);
|
||||
|
||||
/* Retrieve BSS */
|
||||
for (itemwlan = radio->wlan->first; itemwlan != NULL; itemwlan = itemwlan->next) {
|
||||
struct wtp_radio_wlan* wlan = (struct wtp_radio_wlan*)itemwlan->item;
|
||||
if (!memcmp(bssid, wlan->wlanhandle->address, MACADDRESS_EUI48_LENGTH)) {
|
||||
for (i = 0; i < radio->wlan->count; i++) {
|
||||
struct wtp_radio_wlan *wlan =
|
||||
(struct wtp_radio_wlan *)capwap_array_get_item_pointer(radio->wlan, i);
|
||||
|
||||
if (!wlan->wlanhandle)
|
||||
continue;
|
||||
|
||||
if (!memcmp(bssid, wlan->wlanhandle->address, MACADDRESS_EUI48_LENGTH))
|
||||
return wlan;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct wtp_radio_wlan* wtp_radio_search_wlan(struct wtp_radio* radio, const uint8_t* bssid) {
|
||||
struct wtp_radio_wlan *wtp_radio_search_wlan(struct wtp_radio *radio, const uint8_t *bssid)
|
||||
{
|
||||
int i;
|
||||
|
||||
ASSERT(bssid != NULL);
|
||||
@ -628,12 +657,11 @@ void wtp_radio_receive_data_packet(uint8_t radioid, unsigned short binding, cons
|
||||
}
|
||||
|
||||
/* */
|
||||
uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwap_80211_assignbssid_element* bssid) {
|
||||
uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet,
|
||||
struct capwap_80211_assignbssid_element* bssid)
|
||||
{
|
||||
struct wtp_radio* radio;
|
||||
struct wtp_radio_wlan* wlan;
|
||||
struct wtp_radio_wlanpool* wlanpool;
|
||||
struct capwap_list_item* itemwlan;
|
||||
struct capwap_list_item* itemwlanpool;
|
||||
struct wlan_startap_params params;
|
||||
struct capwap_80211_addwlan_element* addwlan;
|
||||
|
||||
@ -655,35 +683,21 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwa
|
||||
|
||||
/* Check if virtual interface is already exist */
|
||||
wlan = wtp_radio_get_wlan(radio, addwlan->wlanid);
|
||||
if (wlan) {
|
||||
if (!wlan && !wlan->wlanhandle) {
|
||||
capwap_logging_debug("Create WLAN: invalid WLAN ID");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
if (wlan->in_use) {
|
||||
capwap_logging_debug("Create WLAN: vif already exists");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* Verify exist interface into pool */
|
||||
if (!radio->wlanpool->first) {
|
||||
capwap_logging_debug("Create WLAN: not first if in pool");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* Prepare physical interface for create wlan */
|
||||
if (!radio->wlan->count) {
|
||||
if (wtp_radio_configure_phy(radio)) {
|
||||
capwap_logging_debug("Create WLAN: config phy failed");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get interface from pool */
|
||||
itemwlanpool = capwap_itemlist_remove_head(radio->wlanpool);
|
||||
wlanpool = (struct wtp_radio_wlanpool*)itemwlanpool->item;
|
||||
|
||||
/* Create interface used */
|
||||
itemwlan = capwap_itemlist_create(sizeof(struct wtp_radio_wlan));
|
||||
wlan = (struct wtp_radio_wlan*)itemwlan->item;
|
||||
wlan->wlanid = addwlan->wlanid;
|
||||
wlan->wlanhandle = wlanpool->wlanhandle;
|
||||
wlan->radio = wlanpool->radio;
|
||||
|
||||
/* Wlan configuration */
|
||||
memset(¶ms, 0, sizeof(struct wlan_startap_params));
|
||||
@ -699,17 +713,13 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwa
|
||||
params.ie = (struct capwap_array *)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE);
|
||||
|
||||
/* Start AP */
|
||||
if (wifi_wlan_startap(wlanpool->wlanhandle, ¶ms)) {
|
||||
if (wifi_wlan_startap(wlan->wlanhandle, ¶ms)) {
|
||||
capwap_logging_debug("Create WLAN: start AP failes");
|
||||
/* Set interface to pool */
|
||||
capwap_itemlist_free(itemwlan);
|
||||
capwap_itemlist_insert_before(radio->wlanpool, NULL, itemwlanpool);
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* Move interface from pool to used */
|
||||
capwap_itemlist_free(itemwlanpool);
|
||||
capwap_itemlist_insert_after(radio->wlan, NULL, itemwlan);
|
||||
/* Mark interface as used */
|
||||
wlan->in_use = 1;
|
||||
|
||||
/* Update Event File Descriptor */
|
||||
wtp_dfa_update_fdspool(&g_wtp.fds);
|
||||
|
@ -20,13 +20,7 @@
|
||||
#define WTP_PREFIX_DEFAULT_NAME "ap"
|
||||
|
||||
struct wtp_radio_wlan {
|
||||
uint8_t wlanid;
|
||||
struct wifi_wlan* wlanhandle;
|
||||
struct wtp_radio* radio;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct wtp_radio_wlanpool {
|
||||
uint8_t in_use;
|
||||
struct wifi_wlan* wlanhandle;
|
||||
struct wtp_radio* radio;
|
||||
};
|
||||
@ -38,8 +32,9 @@ struct wtp_radio {
|
||||
struct wifi_device* devicehandle;
|
||||
|
||||
char wlanprefix[IFNAMSIZ];
|
||||
struct capwap_list* wlan;
|
||||
struct capwap_list* wlanpool;
|
||||
struct capwap_array* wlan;
|
||||
|
||||
int initialized;
|
||||
|
||||
int status;
|
||||
struct capwap_80211_antenna_element antenna;
|
||||
@ -60,6 +55,7 @@ struct wtp_radio {
|
||||
void wtp_radio_init(void);
|
||||
void wtp_radio_close(void);
|
||||
void wtp_radio_free(void);
|
||||
void wtp_radio_reset(void);
|
||||
|
||||
/* */
|
||||
struct wtp_radio* wtp_radio_create_phy(void);
|
||||
|
Reference in New Issue
Block a user