Improve memory administration for tx/rx packet manager
This commit is contained in:
@ -3,6 +3,7 @@
|
||||
#include "capwap_protocol.h"
|
||||
#include "capwap_dfa.h"
|
||||
#include "capwap_array.h"
|
||||
#include "capwap_list.h"
|
||||
#include "capwap_element.h"
|
||||
#include "capwap_dtls.h"
|
||||
#include "wtp_dfa.h"
|
||||
@ -24,8 +25,8 @@ static int wtp_init(void) {
|
||||
memset(&g_wtp, 0, sizeof(struct wtp_t));
|
||||
|
||||
/* Standard name */
|
||||
strcpy(g_wtp.name.name, WTP_STANDARD_NAME);
|
||||
strcpy(g_wtp.location.value, WTP_STANDARD_LOCATION);
|
||||
strcpy((char*)g_wtp.name.name, WTP_STANDARD_NAME);
|
||||
strcpy((char*)g_wtp.location.value, WTP_STANDARD_LOCATION);
|
||||
|
||||
/* State machine */
|
||||
g_wtp.dfa.state = CAPWAP_START_STATE;
|
||||
@ -63,8 +64,8 @@ static int wtp_init(void) {
|
||||
|
||||
/* Tx fragment packets */
|
||||
g_wtp.mtu = CAPWAP_MTU_DEFAULT;
|
||||
g_wtp.requestfragmentpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
|
||||
g_wtp.responsefragmentpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
|
||||
g_wtp.requestfragmentpacket = capwap_list_create();
|
||||
g_wtp.responsefragmentpacket = capwap_list_create();
|
||||
|
||||
/* AC information */
|
||||
g_wtp.discoverytype.type = CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_UNKNOWN;
|
||||
@ -90,10 +91,8 @@ static void wtp_destroy(void) {
|
||||
capwap_array_free(g_wtp.boarddata.boardsubelement);
|
||||
|
||||
/* Free fragments packet */
|
||||
capwap_fragment_free(g_wtp.requestfragmentpacket);
|
||||
capwap_fragment_free(g_wtp.responsefragmentpacket);
|
||||
capwap_array_free(g_wtp.requestfragmentpacket);
|
||||
capwap_array_free(g_wtp.responsefragmentpacket);
|
||||
capwap_list_free(g_wtp.requestfragmentpacket);
|
||||
capwap_list_free(g_wtp.responsefragmentpacket);
|
||||
|
||||
/* Free list AC */
|
||||
capwap_array_free(g_wtp.acdiscoveryarray);
|
||||
@ -222,7 +221,7 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(g_wtp.name.name, configString);
|
||||
strcpy((char*)g_wtp.name.name, configString);
|
||||
}
|
||||
|
||||
/* Set location of WTP */
|
||||
@ -232,7 +231,7 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(g_wtp.location.value, configString);
|
||||
strcpy((char*)g_wtp.location.value, configString);
|
||||
}
|
||||
|
||||
/* Set binding of WTP */
|
||||
@ -328,25 +327,25 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
|
||||
if (!strcmp(configName, "model")) {
|
||||
element->type = CAPWAP_BOARD_SUBELEMENT_MODELNUMBER;
|
||||
element->length = lengthValue;
|
||||
strcpy(element->data, configValue);
|
||||
strcpy((char*)element->data, configValue);
|
||||
} else if (!strcmp(configName, "serial")) {
|
||||
element->type = CAPWAP_BOARD_SUBELEMENT_SERIALNUMBER;
|
||||
element->length = lengthValue;
|
||||
strcpy(element->data, configValue);
|
||||
strcpy((char*)element->data, configValue);
|
||||
} else if (!strcmp(configName, "id")) {
|
||||
element->type = CAPWAP_BOARD_SUBELEMENT_ID;
|
||||
element->length = lengthValue;
|
||||
strcpy(element->data, configValue);
|
||||
strcpy((char*)element->data, configValue);
|
||||
} else if (!strcmp(configName, "revision")) {
|
||||
element->type = CAPWAP_BOARD_SUBELEMENT_REVISION;
|
||||
element->length = lengthValue;
|
||||
strcpy(element->data, configValue);
|
||||
strcpy((char*)element->data, configValue);
|
||||
} else if (!strcmp(configName, "macaddress")) {
|
||||
const char* configType;
|
||||
if (config_setting_lookup_string(configElement, "type", &configType) == CONFIG_TRUE) {
|
||||
if (!strcmp(configType, "interface")) {
|
||||
element->type = CAPWAP_BOARD_SUBELEMENT_MACADDRESS;
|
||||
element->length = capwap_get_macaddress_from_interface(configValue, element->data);
|
||||
element->length = capwap_get_macaddress_from_interface(configValue, (char*)element->data);
|
||||
if (!element->length) {
|
||||
capwap_logging_error("Invalid configuration file, unable found macaddress of interface: '%s'", configValue);
|
||||
return 0;
|
||||
@ -567,7 +566,7 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
|
||||
desc->vendor = (unsigned long)configVendor;
|
||||
desc->type = type;
|
||||
desc->length = lengthValue;
|
||||
strcpy(desc->data, configValue);
|
||||
strcpy((char*)desc->data, configValue);
|
||||
} else {
|
||||
capwap_logging_error("Invalid configuration file, application.descriptor.info.value string length exceeded");
|
||||
return 0;
|
||||
@ -981,7 +980,7 @@ int main(int argc, char** argv) {
|
||||
wtp_dfa_change_state(CAPWAP_IDLE_STATE);
|
||||
|
||||
/* Running WTP */
|
||||
result = wtp_dfa_execute();
|
||||
result = wtp_dfa_running();
|
||||
|
||||
/* Close socket */
|
||||
capwap_close_sockets(&g_wtp.net);
|
||||
|
@ -74,37 +74,40 @@ struct wtp_state {
|
||||
/* WTP */
|
||||
struct wtp_t {
|
||||
int running;
|
||||
|
||||
|
||||
struct wtp_state dfa;
|
||||
struct capwap_network net;
|
||||
|
||||
|
||||
struct capwap_wtpname_element name;
|
||||
struct capwap_acname_element acname;
|
||||
struct capwap_location_element location;
|
||||
|
||||
|
||||
unsigned short binding;
|
||||
|
||||
struct capwap_discoverytype_element discoverytype;
|
||||
struct capwap_discoverytype_element discoverytype;
|
||||
struct capwap_wtpframetunnelmode_element mactunnel;
|
||||
struct capwap_wtpmactype_element mactype;
|
||||
struct capwap_wtpboarddata_element boarddata;
|
||||
struct capwap_wtpdescriptor_element descriptor;
|
||||
|
||||
|
||||
struct capwap_sessionid_element sessionid;
|
||||
|
||||
|
||||
struct capwap_ecnsupport_element ecn;
|
||||
struct capwap_transport_element transport;
|
||||
struct capwap_statisticstimer_element statisticstimer;
|
||||
struct capwap_wtprebootstat_element rebootstat;
|
||||
|
||||
|
||||
struct capwap_packet_rxmng* rxmngctrlpacket;
|
||||
struct capwap_packet_rxmng* rxmngdatapacket;
|
||||
|
||||
unsigned char localseqnumber;
|
||||
unsigned char remoteseqnumber;
|
||||
unsigned short mtu;
|
||||
unsigned short fragmentid;
|
||||
capwap_fragment_packet_array* requestfragmentpacket;
|
||||
capwap_fragment_packet_array* responsefragmentpacket;
|
||||
struct capwap_list* requestfragmentpacket;
|
||||
struct capwap_list* responsefragmentpacket;
|
||||
unsigned char lastrecvpackethash[16];
|
||||
|
||||
|
||||
/* */
|
||||
int acdiscoveryrequest;
|
||||
unsigned long acpreferedselected;
|
||||
@ -118,9 +121,9 @@ struct wtp_t {
|
||||
struct sockaddr_storage acdataaddress;
|
||||
struct capwap_socket acctrlsock;
|
||||
struct capwap_socket acdatasock;
|
||||
|
||||
|
||||
struct capwap_array* radios;
|
||||
|
||||
|
||||
/* Dtls */
|
||||
int enabledtls;
|
||||
unsigned char dtlsdatapolicy;
|
||||
@ -153,7 +156,9 @@ extern struct wtp_t g_wtp;
|
||||
/* */
|
||||
int wtp_update_radio_in_use();
|
||||
|
||||
/* build capwap element helper */
|
||||
void wtp_create_80211_wtpradioinformation_element(struct capwap_build_packet* buildpacket);
|
||||
/* Build capwap element helper */
|
||||
void wtp_create_radioadmstate_element(struct capwap_packet_txmng* txmngpacket);
|
||||
void wtp_create_radioopsstate_element(struct capwap_packet_txmng* txmngpacket);
|
||||
void wtp_create_80211_wtpradioinformation_element(struct capwap_packet_txmng* txmngpacket);
|
||||
|
||||
#endif /* __CAPWAP_WTP_HEADER__ */
|
||||
|
@ -13,17 +13,333 @@ static void wtp_signal_handler(int signum) {
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static struct capwap_packet_rxmng* wtp_get_packet_rxmng(int isctrlmsg) {
|
||||
struct capwap_packet_rxmng* rxmngpacket = NULL;
|
||||
|
||||
if (isctrlmsg) {
|
||||
if (!g_wtp.rxmngctrlpacket) {
|
||||
g_wtp.rxmngctrlpacket = capwap_packet_rxmng_create_message(1);
|
||||
}
|
||||
|
||||
rxmngpacket = g_wtp.rxmngctrlpacket;
|
||||
} else {
|
||||
if (!g_wtp.rxmngdatapacket) {
|
||||
g_wtp.rxmngdatapacket = capwap_packet_rxmng_create_message(0);
|
||||
}
|
||||
|
||||
rxmngpacket = g_wtp.rxmngdatapacket;
|
||||
}
|
||||
|
||||
return rxmngpacket;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void wtp_free_packet_rxmng(int isctrlmsg) {
|
||||
if (isctrlmsg && g_wtp.rxmngctrlpacket) {
|
||||
capwap_packet_rxmng_free(g_wtp.rxmngctrlpacket);
|
||||
g_wtp.rxmngctrlpacket = NULL;
|
||||
} else if (!isctrlmsg && g_wtp.rxmngdatapacket) {
|
||||
capwap_packet_rxmng_free(g_wtp.rxmngdatapacket);
|
||||
g_wtp.rxmngdatapacket = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void wtp_send_invalid_request(struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection) {
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
struct capwap_list* responsefragmentpacket;
|
||||
struct capwap_fragment_packet_item* packet;
|
||||
struct capwap_header* header;
|
||||
struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_MSG_UNEXPECTED_UNRECOGNIZED_REQUEST };
|
||||
|
||||
ASSERT(rxmngpacket != NULL);
|
||||
ASSERT(rxmngpacket->fragmentlist->first != NULL);
|
||||
ASSERT(connection != NULL);
|
||||
|
||||
/* */
|
||||
packet = (struct capwap_fragment_packet_item*)rxmngpacket->fragmentlist->first->item;
|
||||
header = (struct capwap_header*)packet->buffer;
|
||||
|
||||
/* Odd message type, response with "Unrecognized Request" */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, GET_WBID_HEADER(header));
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, rxmngpacket->ctrlmsg.type + 1, rxmngpacket->ctrlmsg.seq, g_wtp.mtu);
|
||||
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RESULTCODE, &resultcode);
|
||||
|
||||
/* Unknown response complete, get fragment packets */
|
||||
responsefragmentpacket = capwap_list_create();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, responsefragmentpacket, g_wtp.fragmentid);
|
||||
if (responsefragmentpacket->count > 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send unknown response */
|
||||
capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, connection->socket.socket[connection->socket.type], responsefragmentpacket, &connection->localaddr, &connection->remoteaddr);
|
||||
|
||||
/* Don't buffering a packets sent */
|
||||
capwap_list_free(responsefragmentpacket);
|
||||
}
|
||||
|
||||
/* WTP Execute state */
|
||||
static int wtp_dfa_execute(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
int action = WTP_DFA_NO_PACKET;
|
||||
|
||||
switch (g_wtp.dfa.state) {
|
||||
case CAPWAP_IDLE_STATE: {
|
||||
action = wtp_dfa_state_idle(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IDLE_TO_DISCOVERY_STATE: {
|
||||
action = wtp_dfa_state_idle_to_discovery(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IDLE_TO_DTLS_SETUP_STATE: {
|
||||
action = wtp_dfa_state_idle_to_dtlssetup(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DISCOVERY_STATE: {
|
||||
action = wtp_dfa_state_discovery(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DISCOVERY_TO_SULKING_STATE: {
|
||||
action = wtp_dfa_state_discovery_to_sulking(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DISCOVERY_TO_DTLS_SETUP_STATE: {
|
||||
action = wtp_dfa_state_discovery_to_dtlssetup(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_SULKING_STATE: {
|
||||
action = wtp_dfa_state_sulking(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_SULKING_TO_IDLE_STATE: {
|
||||
action = wtp_dfa_state_sulking_to_idle(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_SETUP_STATE: {
|
||||
action = wtp_dfa_state_dtlssetup(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_SETUP_TO_IDLE_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_SETUP_TO_SULKING_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_SETUP_TO_AUTHORIZE_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_AUTHORIZE_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_AUTHORIZE_TO_DTLS_SETUP_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_AUTHORIZE_TO_DTLS_CONNECT_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_AUTHORIZE_TO_DTLS_TEARDOWN_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_CONNECT_STATE: {
|
||||
action = wtp_dfa_state_dtlsconnect(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_CONNECT_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_dtlsconnect_to_dtlsteardown(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_CONNECT_TO_JOIN_STATE: {
|
||||
action = wtp_dfa_state_dtlsconnect_to_join(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_dtlsteardown(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_TEARDOWN_TO_IDLE_STATE: {
|
||||
action = wtp_dfa_state_dtlsteardown_to_idle(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_TEARDOWN_TO_SULKING_STATE: {
|
||||
action = wtp_dfa_state_dtlsteardown_to_sulking(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_STATE: {
|
||||
action = wtp_dfa_state_join(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_join_to_dtlsteardown(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_TO_IMAGE_DATA_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_TO_CONFIGURE_STATE: {
|
||||
action = wtp_dfa_state_join_to_configure(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_TO_RESET_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_imagedata_to_dtlsteardown(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURE_STATE: {
|
||||
action = wtp_dfa_state_configure(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURE_TO_RESET_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURE_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_configure_to_dtlsteardown(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURE_TO_DATA_CHECK_STATE: {
|
||||
action = wtp_dfa_state_configure_to_datacheck(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_STATE: {
|
||||
action = wtp_dfa_state_reset(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_CHECK_STATE: {
|
||||
action = wtp_dfa_state_datacheck(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_datacheck_to_dtlsteardown(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_CHECK_TO_RUN_STATE: {
|
||||
action = wtp_dfa_state_datacheck_to_run(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RUN_STATE: {
|
||||
action = wtp_dfa_state_run(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_run_to_dtlsteardown(packet, timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RUN_TO_RESET_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DEAD_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
capwap_logging_debug("Unknown action event: %lu", g_wtp.dfa.state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
/* WTP state machine */
|
||||
int wtp_dfa_execute(void) {
|
||||
int wtp_dfa_running(void) {
|
||||
int res;
|
||||
int result = CAPWAP_SUCCESSFUL;
|
||||
int action = WTP_DFA_NO_PACKET;
|
||||
struct timeout_control timeout;
|
||||
|
||||
struct capwap_packet packet;
|
||||
capwap_fragment_list* defraglist;
|
||||
char buffer[CAPWAP_MAX_PACKET_SIZE];
|
||||
char bufferencrypt[CAPWAP_MAX_PACKET_SIZE];
|
||||
char bufferplain[CAPWAP_MAX_PACKET_SIZE];
|
||||
char* buffer;
|
||||
int buffersize;
|
||||
|
||||
struct capwap_socket socket;
|
||||
struct capwap_connection connection;
|
||||
struct capwap_parsed_packet packet;
|
||||
|
||||
int index;
|
||||
struct sockaddr_storage recvfromaddr;
|
||||
struct sockaddr_storage recvtoaddr;
|
||||
@ -36,8 +352,7 @@ int wtp_dfa_execute(void) {
|
||||
capwap_init_timeout(&timeout);
|
||||
capwap_set_timeout(0, &timeout, CAPWAP_TIMER_CONTROL_CONNECTION); /* Start DFA with timeout */
|
||||
|
||||
memset(&packet, 0, sizeof(struct capwap_packet));
|
||||
defraglist = capwap_defragment_init_list();
|
||||
memset(&packet, 0, sizeof(struct capwap_parsed_packet));
|
||||
|
||||
/* Configure poll struct */
|
||||
fdscount = CAPWAP_MAX_SOCKETS * 2;
|
||||
@ -59,6 +374,7 @@ int wtp_dfa_execute(void) {
|
||||
/* If request wait packet from AC */
|
||||
isrecvpacket = 0;
|
||||
if ((action == WTP_DFA_ACCEPT_PACKET) || (action == WTP_DFA_DROP_PACKET)) {
|
||||
buffer = bufferencrypt;
|
||||
buffersize = CAPWAP_MAX_PACKET_SIZE;
|
||||
index = capwap_recvfrom(fds, fdscount, buffer, &buffersize, &recvfromaddr, &recvtoaddr, &timeout);
|
||||
if (!g_wtp.running) {
|
||||
@ -71,24 +387,25 @@ int wtp_dfa_execute(void) {
|
||||
continue;
|
||||
} else {
|
||||
int check;
|
||||
|
||||
|
||||
/* Check of packet */
|
||||
capwap_get_network_socket(&g_wtp.net, &packet.socket, fds[index].fd);
|
||||
check = capwap_sanity_check(packet.socket.isctrlsocket, g_wtp.dfa.state, buffer, buffersize, g_wtp.ctrldtls.enable, g_wtp.datadtls.enable);
|
||||
capwap_get_network_socket(&g_wtp.net, &socket, fds[index].fd);
|
||||
check = capwap_sanity_check(socket.isctrlsocket, g_wtp.dfa.state, buffer, buffersize, g_wtp.ctrldtls.enable, g_wtp.datadtls.enable);
|
||||
if (check == CAPWAP_DTLS_PACKET) {
|
||||
struct capwap_dtls* dtls = (packet.socket.isctrlsocket ? &g_wtp.ctrldtls : &g_wtp.datadtls);
|
||||
|
||||
struct capwap_dtls* dtls = (socket.isctrlsocket ? &g_wtp.ctrldtls : &g_wtp.datadtls);
|
||||
|
||||
if (dtls->enable) {
|
||||
int oldaction = dtls->action;
|
||||
|
||||
|
||||
/* Decrypt packet */
|
||||
buffersize = capwap_decrypt_packet(dtls, buffer, buffersize, NULL, CAPWAP_MAX_PACKET_SIZE);
|
||||
buffersize = capwap_decrypt_packet(dtls, buffer, buffersize, bufferplain, CAPWAP_MAX_PACKET_SIZE);
|
||||
if (buffersize > 0) {
|
||||
buffer = bufferplain;
|
||||
check = CAPWAP_PLAIN_PACKET;
|
||||
} else if (buffersize == CAPWAP_ERROR_AGAIN) {
|
||||
/* Check is handshake complete */
|
||||
if ((oldaction == CAPWAP_DTLS_ACTION_HANDSHAKE) && (dtls->action == CAPWAP_DTLS_ACTION_DATA)) {
|
||||
if (packet.socket.isctrlsocket) {
|
||||
if (socket.isctrlsocket) {
|
||||
if (g_wtp.dfa.state == CAPWAP_DTLS_CONNECT_STATE) {
|
||||
check = CAPWAP_NONE_PACKET;
|
||||
wtp_dfa_change_state(CAPWAP_DTLS_CONNECT_TO_JOIN_STATE);
|
||||
@ -127,49 +444,88 @@ int wtp_dfa_execute(void) {
|
||||
|
||||
/* */
|
||||
if (check == CAPWAP_PLAIN_PACKET) {
|
||||
/* If request, defragmentation packet */
|
||||
check = capwap_defragment_packets(&recvfromaddr, buffer, buffersize, defraglist, &packet);
|
||||
if (check == CAPWAP_REQUEST_MORE_FRAGMENT) {
|
||||
continue;
|
||||
} else if (check != CAPWAP_RECEIVE_COMPLETE_PACKET) {
|
||||
/* Discard fragments */
|
||||
capwap_defragment_remove_sender(defraglist, &recvfromaddr);
|
||||
continue;
|
||||
}
|
||||
|
||||
struct capwap_packet_rxmng* rxmngpacket;
|
||||
|
||||
/* Detect local address */
|
||||
if (recvtoaddr.ss_family == AF_UNSPEC) {
|
||||
if (capwap_get_localaddress_by_remoteaddress(&recvtoaddr, &recvfromaddr, g_wtp.net.bind_interface, (!(g_wtp.net.bind_ctrl_flags & CAPWAP_IPV6ONLY_FLAG) ? 1 : 0))) {
|
||||
struct sockaddr_storage sockinfo;
|
||||
socklen_t sockinfolen = sizeof(struct sockaddr_storage);
|
||||
|
||||
|
||||
memset(&sockinfo, 0, sizeof(struct sockaddr_storage));
|
||||
if (getsockname(fds[index].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
CAPWAP_SET_NETWORK_PORT(&recvtoaddr, CAPWAP_GET_NETWORK_PORT(&sockinfo));
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive a complete packet */
|
||||
isrecvpacket = 1;
|
||||
memcpy(&packet.localaddr, &recvtoaddr, sizeof(struct sockaddr_storage));
|
||||
memcpy(&packet.remoteaddr, &recvfromaddr, sizeof(struct sockaddr_storage));
|
||||
|
||||
/* */
|
||||
if (socket.isctrlsocket) {
|
||||
capwap_logging_debug("Receive control packet");
|
||||
} else {
|
||||
capwap_logging_debug("Receive data packet");
|
||||
}
|
||||
|
||||
/* Defragment management */
|
||||
rxmngpacket = wtp_get_packet_rxmng(socket.isctrlsocket);
|
||||
|
||||
/* If request, defragmentation packet */
|
||||
check = capwap_packet_rxmng_add_recv_packet(rxmngpacket, buffer, buffersize);
|
||||
if (check == CAPWAP_REQUEST_MORE_FRAGMENT) {
|
||||
continue;
|
||||
} else if (check != CAPWAP_RECEIVE_COMPLETE_PACKET) {
|
||||
/* Discard fragments */
|
||||
wtp_free_packet_rxmng(socket.isctrlsocket);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Receive all fragment */
|
||||
memcpy(&connection.socket, &socket, sizeof(struct capwap_socket));
|
||||
memcpy(&connection.localaddr, &recvtoaddr, sizeof(struct sockaddr_storage));
|
||||
memcpy(&connection.remoteaddr, &recvfromaddr, sizeof(struct sockaddr_storage));
|
||||
|
||||
/* Check for already response to packet */
|
||||
if (packet.socket.isctrlsocket) {
|
||||
if (capwap_recv_retrasmitted_request(&g_wtp.ctrldtls, &packet, g_wtp.remoteseqnumber, g_wtp.lastrecvpackethash, &g_wtp.acctrlsock, g_wtp.responsefragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_free_packet(&packet);
|
||||
if (socket.isctrlsocket) {
|
||||
if (capwap_recv_retrasmitted_request(&g_wtp.ctrldtls, rxmngpacket, &connection, g_wtp.lastrecvpackethash, g_wtp.responsefragmentpacket)) {
|
||||
wtp_free_packet_rxmng(socket.isctrlsocket);
|
||||
capwap_logging_debug("Retrasmitted packet");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check message type */
|
||||
if (!capwap_check_message_type(&g_wtp.ctrldtls, &packet, g_wtp.mtu)) {
|
||||
capwap_free_packet(&packet);
|
||||
res = capwap_check_message_type(rxmngpacket);
|
||||
if (res != VALID_MESSAGE_TYPE) {
|
||||
if (res == INVALID_REQUEST_MESSAGE_TYPE) {
|
||||
wtp_send_invalid_request(rxmngpacket, &connection);
|
||||
}
|
||||
|
||||
capwap_logging_debug("Invalid message type");
|
||||
wtp_free_packet_rxmng(socket.isctrlsocket);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parsing packet */
|
||||
if (capwap_parsing_packet(rxmngpacket, &connection, &packet)) {
|
||||
capwap_free_parsed_packet(&packet);
|
||||
wtp_free_packet_rxmng(socket.isctrlsocket);
|
||||
capwap_logging_debug("Failed parsing packet");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Validate packet */
|
||||
if (capwap_validate_parsed_packet(&packet, NULL)) {
|
||||
/* TODO gestione errore risposta */
|
||||
capwap_free_parsed_packet(&packet);
|
||||
wtp_free_packet_rxmng(socket.isctrlsocket);
|
||||
capwap_logging_debug("Failed validation parsed packet");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Receive a complete packet */
|
||||
isrecvpacket = 1;
|
||||
}
|
||||
}
|
||||
} else if (index == CAPWAP_RECV_ERROR_INTR) {
|
||||
@ -182,242 +538,12 @@ int wtp_dfa_execute(void) {
|
||||
}
|
||||
|
||||
/* Execute state */
|
||||
switch (g_wtp.dfa.state) {
|
||||
case CAPWAP_IDLE_STATE: {
|
||||
action = wtp_dfa_state_idle((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IDLE_TO_DISCOVERY_STATE: {
|
||||
action = wtp_dfa_state_idle_to_discovery((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IDLE_TO_DTLS_SETUP_STATE: {
|
||||
action = wtp_dfa_state_idle_to_dtlssetup((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DISCOVERY_STATE: {
|
||||
action = wtp_dfa_state_discovery((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DISCOVERY_TO_SULKING_STATE: {
|
||||
action = wtp_dfa_state_discovery_to_sulking((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DISCOVERY_TO_DTLS_SETUP_STATE: {
|
||||
action = wtp_dfa_state_discovery_to_dtlssetup((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_SULKING_STATE: {
|
||||
action = wtp_dfa_state_sulking((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_SULKING_TO_IDLE_STATE: {
|
||||
action = wtp_dfa_state_sulking_to_idle((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_SETUP_STATE: {
|
||||
action = wtp_dfa_state_dtlssetup((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_SETUP_TO_IDLE_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_SETUP_TO_SULKING_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_SETUP_TO_AUTHORIZE_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_AUTHORIZE_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_AUTHORIZE_TO_DTLS_SETUP_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_AUTHORIZE_TO_DTLS_CONNECT_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_AUTHORIZE_TO_DTLS_TEARDOWN_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_CONNECT_STATE: {
|
||||
action = wtp_dfa_state_dtlsconnect((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_CONNECT_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_dtlsconnect_to_dtlsteardown((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_CONNECT_TO_JOIN_STATE: {
|
||||
action = wtp_dfa_state_dtlsconnect_to_join((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_dtlsteardown((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_TEARDOWN_TO_IDLE_STATE: {
|
||||
action = wtp_dfa_state_dtlsteardown_to_idle((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DTLS_TEARDOWN_TO_SULKING_STATE: {
|
||||
action = wtp_dfa_state_dtlsteardown_to_sulking((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_STATE: {
|
||||
action = wtp_dfa_state_join((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_join_to_dtlsteardown((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_TO_IMAGE_DATA_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_TO_CONFIGURE_STATE: {
|
||||
action = wtp_dfa_state_join_to_configure((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_TO_RESET_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_imagedata_to_dtlsteardown((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURE_STATE: {
|
||||
action = wtp_dfa_state_configure((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURE_TO_RESET_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURE_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_configure_to_dtlsteardown((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURE_TO_DATA_CHECK_STATE: {
|
||||
action = wtp_dfa_state_configure_to_datacheck((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_STATE: {
|
||||
action = wtp_dfa_state_reset((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_CHECK_STATE: {
|
||||
action = wtp_dfa_state_datacheck((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_datacheck_to_dtlsteardown((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_CHECK_TO_RUN_STATE: {
|
||||
action = wtp_dfa_state_datacheck_to_run((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RUN_STATE: {
|
||||
action = wtp_dfa_state_run((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE: {
|
||||
action = wtp_dfa_state_run_to_dtlsteardown((isrecvpacket ? &packet : NULL), &timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RUN_TO_RESET_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
action = wtp_dfa_execute((isrecvpacket ? &packet : NULL), &timeout);
|
||||
|
||||
case CAPWAP_DEAD_STATE: {
|
||||
/* Never called with this state */
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
capwap_logging_debug("Unknown action event: %lu", g_wtp.dfa.state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
capwap_free_parsed_packet(&packet);
|
||||
if (isrecvpacket) {
|
||||
capwap_free_packet(&packet);
|
||||
} else {
|
||||
capwap_defragment_flush_list(defraglist);
|
||||
wtp_free_packet_rxmng(socket.isctrlsocket);
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,8 +560,10 @@ int wtp_dfa_execute(void) {
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
capwap_defragment_free_list(defraglist);
|
||||
wtp_free_packet_rxmng(0);
|
||||
wtp_free_packet_rxmng(1);
|
||||
capwap_free(fds);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -449,11 +577,11 @@ void wtp_dfa_change_state(int state) {
|
||||
|
||||
/* */
|
||||
void wtp_free_reference_last_request(void) {
|
||||
capwap_fragment_free(g_wtp.requestfragmentpacket);
|
||||
capwap_list_flush(g_wtp.requestfragmentpacket);
|
||||
}
|
||||
|
||||
/* */
|
||||
void wtp_free_reference_last_response(void) {
|
||||
capwap_fragment_free(g_wtp.responsefragmentpacket);
|
||||
capwap_list_flush(g_wtp.responsefragmentpacket);
|
||||
memset(&g_wtp.lastrecvpackethash[0], 0, sizeof(g_wtp.lastrecvpackethash));
|
||||
}
|
||||
|
@ -11,11 +11,10 @@
|
||||
#define WTP_DFA_ACCEPT_PACKET 2
|
||||
#define WTP_DFA_DROP_PACKET 3
|
||||
|
||||
/* */
|
||||
/* */ /* TODO da rifare */
|
||||
struct wtp_discovery_response {
|
||||
struct sockaddr_storage acaddr;
|
||||
struct capwap_build_packet* packet;
|
||||
struct capwap_element_discovery_response discoveryresponse;
|
||||
struct capwap_array* controlipv4;
|
||||
struct capwap_array* controlipv6;
|
||||
};
|
||||
|
||||
void wtp_free_discovery_response_array(void);
|
||||
@ -31,46 +30,46 @@ void wtp_free_reference_last_request(void);
|
||||
void wtp_free_reference_last_response(void);
|
||||
|
||||
/* State machine */
|
||||
int wtp_dfa_execute(void);
|
||||
int wtp_dfa_running(void);
|
||||
void wtp_dfa_change_state(int state);
|
||||
|
||||
int wtp_dfa_state_idle(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_idle_to_discovery(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_idle_to_dtlssetup(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_idle(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_idle_to_discovery(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_idle_to_dtlssetup(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_discovery_to_sulking(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_discovery_to_dtlssetup(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_discovery(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_discovery_to_sulking(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_discovery_to_dtlssetup(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_sulking(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_sulking_to_idle(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_sulking(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_sulking_to_idle(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_dtlssetup(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsconnect(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsconnect_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlssetup(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsconnect(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsconnect_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsteardown_to_sulking(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsteardown_to_idle(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsteardown_to_sulking(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsteardown_to_idle(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_dtlsconnect_to_join(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_join(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_join_to_configure(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_join_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_dtlsconnect_to_join(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_join(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_join_to_configure(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_join_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_imagedata_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_imagedata_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_configure(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_configure_to_datacheck(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_configure_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_configure(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_configure_to_datacheck(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_configure_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_datacheck(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_datacheck_to_run(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_datacheck_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_datacheck(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_datacheck_to_run(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_datacheck_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_run(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_run_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_run(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_run_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
int wtp_dfa_state_reset(struct capwap_packet* packet, struct timeout_control* timeout);
|
||||
int wtp_dfa_state_reset(struct capwap_parsed_packet* packet, struct timeout_control* timeout);
|
||||
|
||||
#endif /* __WTP_DFA_HEADER__ */
|
||||
|
@ -6,61 +6,38 @@
|
||||
#include "wtp_dfa.h"
|
||||
|
||||
/* */
|
||||
static unsigned long wtp_configure_ac(struct capwap_element_configurationstatus_response* configureresponse) {
|
||||
static unsigned long wtp_configure_ac(struct capwap_parsed_packet* packet) {
|
||||
/* TODO: gestione richiesta */
|
||||
|
||||
/* */
|
||||
g_wtp.dfa.rfcMaxDiscoveryInterval = configureresponse->timers->discovery;
|
||||
g_wtp.dfa.rfcEchoInterval = configureresponse->timers->echorequest;
|
||||
g_wtp.dfa.rfcMaxDiscoveryInterval = packet->messageelements.timers->discovery;
|
||||
g_wtp.dfa.rfcEchoInterval = packet->messageelements.timers->echorequest;
|
||||
|
||||
return CAPWAP_CONFIGURE_TO_DATA_CHECK_STATE;
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_configure(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_configure(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
int status = WTP_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
if (packet) {
|
||||
if (!capwap_compare_ip(&g_wtp.acctrladdress, &packet->remoteaddr)) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
if (!capwap_compare_ip(&g_wtp.acctrladdress, &packet->connection->remoteaddr)) {
|
||||
unsigned short binding;
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
if (packet->rxmngpacket->isctrlpacket && (binding == g_wtp.binding) && (packet->rxmngpacket->ctrlmsg.type == CAPWAP_CONFIGURATION_STATUS_RESPONSE) && ((g_wtp.localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
/* Valid packet, free request packet */
|
||||
wtp_free_reference_last_request();
|
||||
|
||||
/* Parsing packet */
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
unsigned short binding;
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
if ((binding == g_wtp.binding) && (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_CONFIGURATION_STATUS_RESPONSE) && ((g_wtp.localseqnumber - 1) == buildpacket->ctrlmsg.seq)) {
|
||||
struct capwap_element_configurationstatus_response configureresponse;
|
||||
|
||||
/* Valid packet, free request packet */
|
||||
wtp_free_reference_last_request();
|
||||
|
||||
/* Configuration status response info */
|
||||
capwap_init_element_configurationstatus_response(&configureresponse, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_configurationstatus_response(&configureresponse, buildpacket->elementslist->first)) {
|
||||
wtp_dfa_change_state(wtp_configure_ac(&configureresponse));
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
|
||||
/* Free join response */
|
||||
capwap_free_element_configurationstatus_response(&configureresponse, binding);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
/* Parsing response values */
|
||||
wtp_dfa_change_state(wtp_configure_ac(packet));
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int i;
|
||||
|
||||
/* No Configuration status response received */
|
||||
g_wtp.dfa.rfcRetransmitCount++;
|
||||
if (g_wtp.dfa.rfcRetransmitCount >= g_wtp.dfa.rfcMaxRetransmit) {
|
||||
@ -69,17 +46,11 @@ int wtp_dfa_state_configure(struct capwap_packet* packet, struct timeout_control
|
||||
wtp_dfa_change_state(CAPWAP_CONFIGURE_TO_DTLS_TEARDOWN_STATE);
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
} else {
|
||||
/* Retransmit configuration request */
|
||||
for (i = 0; i < g_wtp.requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send configuration status request packet");
|
||||
break;
|
||||
}
|
||||
/* Retransmit configuration status request */
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.requestfragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send configuration status request packet");
|
||||
}
|
||||
|
||||
|
||||
/* Update timeout */
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
}
|
||||
@ -88,84 +59,44 @@ int wtp_dfa_state_configure(struct capwap_packet* packet, struct timeout_control
|
||||
return status;
|
||||
}
|
||||
|
||||
int wtp_dfa_state_configure_to_datacheck(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
unsigned long i;
|
||||
int result = -1;
|
||||
int wtp_dfa_state_configure_to_datacheck(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
int status = WTP_DFA_NO_PACKET;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
struct capwap_resultcode_element resultcode;
|
||||
|
||||
struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_SUCCESS };
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
/* Build packet */
|
||||
buildpacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
buildpacket->isctrlmsg = 1;
|
||||
|
||||
/* Prepare change state event request */
|
||||
capwap_build_packet_set_control_message_type(buildpacket, CAPWAP_CHANGE_STATE_EVENT_REQUEST, g_wtp.localseqnumber++);
|
||||
|
||||
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 capwap_radiooprstate_element radiooprstate;
|
||||
|
||||
radiooprstate.radioid = (unsigned char)(i + 1);
|
||||
radiooprstate.state = ((radio->status == WTP_RADIO_ENABLED) ? CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED : CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED);
|
||||
|
||||
if (radiooprstate.state == WTP_RADIO_ENABLED) {
|
||||
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_NORMAL;
|
||||
} else if (radiooprstate.state == WTP_RADIO_DISABLED) {
|
||||
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET;
|
||||
} else if (radiooprstate.state == WTP_RADIO_HWFAILURE) {
|
||||
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_RADIOFAILURE;
|
||||
} else if (radiooprstate.state == WTP_RADIO_SWFAILURE) {
|
||||
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE;
|
||||
}
|
||||
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_RADIOOPRSTATE_ELEMENT(&radiooprstate));
|
||||
}
|
||||
|
||||
resultcode.code = CAPWAP_RESULTCODE_SUCCESS;
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_RESULTCODE_ELEMENT(&resultcode));
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_CHANGE_STATE_EVENT_REQUEST, g_wtp.localseqnumber++, g_wtp.mtu);
|
||||
|
||||
/* Add message element */
|
||||
wtp_create_radioopsstate_element(txmngpacket);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RESULTCODE, &resultcode);
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
/* Create change state event request packet */
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
wtp_free_reference_last_request();
|
||||
result = capwap_fragment_build_packet(buildpacket, g_wtp.requestfragmentpacket, g_wtp.mtu, g_wtp.fragmentid);
|
||||
if (result == 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: build invalid change state event request packet");
|
||||
/* Change State Event request complete, get fragment packets */
|
||||
wtp_free_reference_last_request();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, g_wtp.requestfragmentpacket, g_wtp.fragmentid);
|
||||
if (g_wtp.requestfragmentpacket->count > 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
|
||||
capwap_build_packet_free(buildpacket);
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send change state event request to AC */
|
||||
if (result >= 0) {
|
||||
for (i = 0; i < g_wtp.requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send change state event request packet");
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == -1) {
|
||||
/* Error to send packets */
|
||||
wtp_free_reference_last_request();
|
||||
wtp_dfa_change_state(CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
|
||||
} else {
|
||||
g_wtp.dfa.rfcRetransmitCount = 0;
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
wtp_dfa_change_state(CAPWAP_DATA_CHECK_STATE);
|
||||
status = WTP_DFA_ACCEPT_PACKET;
|
||||
}
|
||||
/* Send Change State Event request to AC */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.requestfragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
g_wtp.dfa.rfcRetransmitCount = 0;
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
wtp_dfa_change_state(CAPWAP_DATA_CHECK_STATE);
|
||||
status = WTP_DFA_ACCEPT_PACKET;
|
||||
} else {
|
||||
/* Error to send packets */
|
||||
capwap_logging_debug("Warning: error to send change state event request packet");
|
||||
wtp_free_reference_last_request();
|
||||
wtp_dfa_change_state(CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
|
||||
}
|
||||
|
||||
@ -173,7 +104,7 @@ int wtp_dfa_state_configure_to_datacheck(struct capwap_packet* packet, struct ti
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_configure_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_configure_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(packet == NULL);
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
|
@ -4,57 +4,48 @@
|
||||
#include "wtp_dfa.h"
|
||||
|
||||
/* */
|
||||
static unsigned long wtp_datacheck_ac(struct capwap_element_changestateevent_response* changestateresponse) {
|
||||
static unsigned long wtp_datacheck_ac(struct capwap_parsed_packet* packet) {
|
||||
/* TODO: gestione richiesta */
|
||||
|
||||
return CAPWAP_DATA_CHECK_TO_RUN_STATE;
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_datacheck(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_datacheck(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
int status = WTP_DFA_ACCEPT_PACKET;
|
||||
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
if (packet) {
|
||||
if (!capwap_compare_ip(&g_wtp.acctrladdress, &packet->remoteaddr)) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
if (!capwap_compare_ip(&g_wtp.acctrladdress, &packet->connection->remoteaddr)) {
|
||||
unsigned short binding;
|
||||
|
||||
/* Parsing packet */
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
unsigned short binding;
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
if ((binding == g_wtp.binding) && (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_CHANGE_STATE_EVENT_RESPONSE) && ((g_wtp.localseqnumber - 1) == buildpacket->ctrlmsg.seq)) {
|
||||
struct capwap_element_changestateevent_response changestateresponse;
|
||||
|
||||
/* Valid packet, free request packet */
|
||||
wtp_free_reference_last_request();
|
||||
|
||||
/* Configuration status response info */
|
||||
capwap_init_element_changestateevent_response(&changestateresponse, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_changestateevent_response(&changestateresponse, buildpacket->elementslist->first)) {
|
||||
wtp_dfa_change_state(wtp_datacheck_ac(&changestateresponse));
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
|
||||
if (packet->rxmngpacket->isctrlpacket) {
|
||||
if (binding == g_wtp.binding) {
|
||||
if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_CHANGE_STATE_EVENT_RESPONSE) {
|
||||
if ((g_wtp.localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq) {
|
||||
if (packet->rxmngpacket->packetlength > 0) {
|
||||
int a = packet->rxmngpacket->packetlength;
|
||||
a++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free join response */
|
||||
capwap_free_element_changestateevent_response(&changestateresponse, binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
if (packet->rxmngpacket->isctrlpacket && (binding == g_wtp.binding) && (packet->rxmngpacket->ctrlmsg.type == CAPWAP_CHANGE_STATE_EVENT_RESPONSE) && ((g_wtp.localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
/* Valid packet, free request packet */
|
||||
wtp_free_reference_last_request();
|
||||
|
||||
/* Parsing response values */
|
||||
wtp_dfa_change_state(wtp_datacheck_ac(packet));
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int i;
|
||||
|
||||
/* No change state response received */
|
||||
g_wtp.dfa.rfcRetransmitCount++;
|
||||
if (g_wtp.dfa.rfcRetransmitCount >= g_wtp.dfa.rfcMaxRetransmit) {
|
||||
@ -64,16 +55,10 @@ int wtp_dfa_state_datacheck(struct capwap_packet* packet, struct timeout_control
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
} else {
|
||||
/* Retransmit change state request */
|
||||
for (i = 0; i < g_wtp.requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send change state request packet");
|
||||
break;
|
||||
}
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.requestfragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send change state request packet");
|
||||
}
|
||||
|
||||
|
||||
/* Update timeout */
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
}
|
||||
@ -83,12 +68,12 @@ int wtp_dfa_state_datacheck(struct capwap_packet* packet, struct timeout_control
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_datacheck_to_run(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int result;
|
||||
int wtp_dfa_state_datacheck_to_run(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
struct capwap_list* txfragpacket;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
int status = WTP_DFA_ACCEPT_PACKET;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
capwap_fragment_packet_array* txfragpacket;
|
||||
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -112,52 +97,47 @@ int wtp_dfa_state_datacheck_to_run(struct capwap_packet* packet, struct timeout_
|
||||
return WTP_DFA_NO_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Build packet */
|
||||
buildpacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, CAPWAP_WIRELESS_BINDING_NONE);
|
||||
buildpacket->isctrlmsg = 0;
|
||||
|
||||
/* */
|
||||
SET_FLAG_K_HEADER(&buildpacket->header, 1);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_SESSIONID_ELEMENT(&g_wtp.sessionid));
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
capwap_header_set_keepalive_flag(&capwapheader, 1);
|
||||
txmngpacket = capwap_packet_txmng_create_data_message(&capwapheader, g_wtp.mtu); /* CAPWAP_DONT_FRAGMENT */
|
||||
|
||||
txfragpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
|
||||
result = capwap_fragment_build_packet(buildpacket, txfragpacket, CAPWAP_DONT_FRAGMENT, 0);
|
||||
if (!result) {
|
||||
struct capwap_packet* txpacket;
|
||||
|
||||
ASSERT(txfragpacket->count == 1);
|
||||
|
||||
txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(txfragpacket, 0);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.datadtls, g_wtp.acdatasock.socket[g_wtp.acdatasock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpdataaddress, &g_wtp.acdataaddress)) {
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_SESSIONID, &g_wtp.sessionid);
|
||||
|
||||
/* Data keepalive complete, get fragment packets into local list */
|
||||
txfragpacket = capwap_list_create();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, 0);
|
||||
if (txfragpacket->count == 1) {
|
||||
/* Send Data keepalive to AC */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&g_wtp.datadtls, g_wtp.acdatasock.socket[g_wtp.acdatasock.type], txfragpacket, &g_wtp.wtpdataaddress, &g_wtp.acdataaddress)) {
|
||||
capwap_kill_timeout(timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcEchoInterval, timeout, CAPWAP_TIMER_CONTROL_ECHO);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcDataChannelDeadInterval, timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD);
|
||||
wtp_dfa_change_state(CAPWAP_RUN_STATE);
|
||||
} else {
|
||||
/* Error to send packets */
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet");
|
||||
result = -1;
|
||||
wtp_dfa_change_state(CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
capwap_fragment_free(txfragpacket);
|
||||
capwap_array_free(txfragpacket);
|
||||
capwap_build_packet_free(buildpacket);
|
||||
|
||||
/* Send Configuration Status request to AC */
|
||||
if (!result) {
|
||||
capwap_kill_timeout(timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcEchoInterval, timeout, CAPWAP_TIMER_CONTROL_ECHO);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcDataChannelDeadInterval, timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD);
|
||||
wtp_dfa_change_state(CAPWAP_RUN_STATE);
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet, fragment packet");
|
||||
wtp_dfa_change_state(CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_list_free(txfragpacket);
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* */
|
||||
return status;
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_datacheck_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_datacheck_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(packet == NULL);
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
|
@ -8,50 +8,49 @@
|
||||
/* */
|
||||
void wtp_free_discovery_response_array(void) {
|
||||
int i;
|
||||
|
||||
|
||||
/* Free items */
|
||||
for (i = 0; i < g_wtp.acdiscoveryresponse->count; i++) {
|
||||
struct wtp_discovery_response* response = (struct wtp_discovery_response*)capwap_array_get_item_pointer(g_wtp.acdiscoveryresponse, i);
|
||||
|
||||
capwap_free_element_discovery_response(&response->discoveryresponse, GET_WBID_HEADER(&response->packet->header));
|
||||
capwap_build_packet_free(response->packet);
|
||||
capwap_array_free(response->controlipv4);
|
||||
capwap_array_free(response->controlipv6);
|
||||
}
|
||||
|
||||
|
||||
/* Remove all items */
|
||||
capwap_array_resize(g_wtp.acdiscoveryresponse, 0);
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_discovery(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
int status = WTP_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
if (packet) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
if (capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
capwap_build_packet_free(buildpacket); /* Invalid packet */
|
||||
} else {
|
||||
unsigned short binding;
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
if ((binding != g_wtp.binding) || (ntohl(buildpacket->ctrlmsg.type) != CAPWAP_DISCOVERY_RESPONSE) || ((g_wtp.localseqnumber - 1) != buildpacket->ctrlmsg.seq)) {
|
||||
capwap_build_packet_free(buildpacket); /* Invalid packet */
|
||||
} else {
|
||||
struct wtp_discovery_response* response = (struct wtp_discovery_response*)capwap_array_get_item_pointer(g_wtp.acdiscoveryresponse, g_wtp.acdiscoveryresponse->count);
|
||||
unsigned short binding;
|
||||
|
||||
/* Discovery response info */
|
||||
memcpy(&response->acaddr, &packet->remoteaddr, sizeof(struct sockaddr_storage));
|
||||
response->packet = buildpacket;
|
||||
capwap_init_element_discovery_response(&response->discoveryresponse, binding);
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
if (packet->rxmngpacket->isctrlpacket && (binding == g_wtp.binding) && (packet->rxmngpacket->ctrlmsg.type == CAPWAP_DISCOVERY_RESPONSE) && ((g_wtp.localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
int i;
|
||||
struct wtp_discovery_response* response = (struct wtp_discovery_response*)capwap_array_get_item_pointer(g_wtp.acdiscoveryresponse, g_wtp.acdiscoveryresponse->count);
|
||||
|
||||
/* Parsing elements list */
|
||||
capwap_parsing_element_discovery_response(&response->discoveryresponse, buildpacket->elementslist->first);
|
||||
}
|
||||
/* Create controlipv4 */
|
||||
response->controlipv4 = capwap_array_create(sizeof(struct capwap_controlipv4_element), 0);
|
||||
for (i = 0; i < packet->messageelements.controlipv4->count; i++) {
|
||||
struct capwap_controlipv4_element* src = *(struct capwap_controlipv4_element**)capwap_array_get_item_pointer(packet->messageelements.controlipv4, i);
|
||||
struct capwap_controlipv4_element* dst = (struct capwap_controlipv4_element*)capwap_array_get_item_pointer(response->controlipv4, i);
|
||||
|
||||
memcpy(dst, src, sizeof(struct capwap_controlipv4_element));
|
||||
}
|
||||
|
||||
/* Create controlipv4 */
|
||||
response->controlipv6 = capwap_array_create(sizeof(struct capwap_controlipv6_element), 0);
|
||||
for (i = 0; i < packet->messageelements.controlipv6->count; i++) {
|
||||
struct capwap_controlipv6_element* src = *(struct capwap_controlipv6_element**)capwap_array_get_item_pointer(packet->messageelements.controlipv6, i);
|
||||
struct capwap_controlipv6_element* dst = (struct capwap_controlipv6_element*)capwap_array_get_item_pointer(response->controlipv6, i);
|
||||
|
||||
memcpy(dst, src, sizeof(struct capwap_controlipv6_element));
|
||||
}
|
||||
}
|
||||
} else if (g_wtp.acdiscoveryresponse->count > 0) {
|
||||
@ -72,19 +71,19 @@ int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control
|
||||
|
||||
/* AC with IPv4 */
|
||||
if ((g_wtp.net.sock_family == AF_UNSPEC) || (g_wtp.net.sock_family == AF_INET)) {
|
||||
for (w = 0; w < response->discoveryresponse.controlipv4->count; w++) {
|
||||
struct capwap_controlipv4_element* controlipv4 = *(struct capwap_controlipv4_element**)capwap_array_get_item_pointer(response->discoveryresponse.controlipv4, w);
|
||||
|
||||
for (w = 0; w < response->controlipv4->count; w++) {
|
||||
struct capwap_controlipv4_element* controlipv4 = (struct capwap_controlipv4_element*)capwap_array_get_item_pointer(response->controlipv4, w);
|
||||
|
||||
/* Create IPv4 address */
|
||||
checkaddripv4 = (struct sockaddr_in*)&checkaddr;
|
||||
checkaddripv4->sin_family = AF_INET;
|
||||
checkaddripv4->sin_port = htons(CAPWAP_CONTROL_PORT);
|
||||
memcpy(&checkaddripv4->sin_addr, &controlipv4->address, sizeof(struct in_addr));
|
||||
|
||||
|
||||
/* Check for preferred AC */
|
||||
for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) {
|
||||
struct sockaddr_storage* acpreferredaddr = (struct sockaddr_storage*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
|
||||
|
||||
|
||||
if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) {
|
||||
indexpreferred = j;
|
||||
memcpy(&g_wtp.acctrladdress, &checkaddr, sizeof(struct sockaddr_storage));
|
||||
@ -93,7 +92,7 @@ int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check by number of WTP */
|
||||
if (indexpreferred == -1) {
|
||||
if ((countwtp == -1) || (countwtp > controlipv4->wtpcount)) {
|
||||
@ -108,19 +107,19 @@ int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control
|
||||
|
||||
/* AC with IPv6 */
|
||||
if ((g_wtp.net.sock_family == AF_UNSPEC) || (g_wtp.net.sock_family == AF_INET6)) {
|
||||
for (w = 0; w < response->discoveryresponse.controlipv6->count; w++) {
|
||||
struct capwap_controlipv6_element* controlipv6 = *(struct capwap_controlipv6_element**)capwap_array_get_item_pointer(response->discoveryresponse.controlipv6, w);
|
||||
|
||||
for (w = 0; w < response->controlipv6->count; w++) {
|
||||
struct capwap_controlipv6_element* controlipv6 = (struct capwap_controlipv6_element*)capwap_array_get_item_pointer(response->controlipv6, w);
|
||||
|
||||
/* Create IPv6 address */
|
||||
checkaddripv6 = (struct sockaddr_in6*)&checkaddr;
|
||||
checkaddripv6->sin6_family = AF_INET6;
|
||||
checkaddripv6->sin6_port = htons(CAPWAP_CONTROL_PORT);
|
||||
memcpy(&checkaddripv6->sin6_addr, &controlipv6->address, sizeof(struct in6_addr));
|
||||
|
||||
|
||||
/* Check for preferred AC */
|
||||
for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) {
|
||||
struct sockaddr_storage* acpreferredaddr = (struct sockaddr_storage*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
|
||||
|
||||
|
||||
if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) {
|
||||
indexpreferred = j;
|
||||
memcpy(&g_wtp.acctrladdress, &checkaddr, sizeof(struct sockaddr_storage));
|
||||
@ -129,7 +128,7 @@ int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check by number of WTP */
|
||||
if (indexpreferred == -1) {
|
||||
if ((countwtp == -1) || (countwtp > controlipv6->wtpcount)) {
|
||||
@ -145,19 +144,16 @@ int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control
|
||||
|
||||
/* Free memory */
|
||||
wtp_free_discovery_response_array();
|
||||
|
||||
|
||||
/* Change state if found AC */
|
||||
if (g_wtp.acctrladdress.ss_family != AF_UNSPEC) {
|
||||
memcpy(&g_wtp.acdataaddress, &g_wtp.acctrladdress, sizeof(struct sockaddr_storage));
|
||||
CAPWAP_SET_NETWORK_PORT(&g_wtp.acdataaddress, CAPWAP_GET_NETWORK_PORT(&g_wtp.acdataaddress) + 1);
|
||||
wtp_dfa_change_state(CAPWAP_DISCOVERY_TO_DTLS_SETUP_STATE);
|
||||
}
|
||||
|
||||
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
} else {
|
||||
int result;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
/* No Discovery response received */
|
||||
g_wtp.dfa.rfcDiscoveryCount++;
|
||||
if (g_wtp.dfa.rfcDiscoveryCount >= g_wtp.dfa.rfcMaxDiscoveries) {
|
||||
@ -165,73 +161,58 @@ int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control
|
||||
wtp_dfa_change_state(CAPWAP_DISCOVERY_TO_SULKING_STATE);
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
} else {
|
||||
int i;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
|
||||
/* Update status radio */
|
||||
g_wtp.descriptor.radiosinuse = wtp_update_radio_in_use();
|
||||
|
||||
/* Build packet */
|
||||
buildpacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
buildpacket->isctrlmsg = 1;
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_DISCOVERY_REQUEST, g_wtp.localseqnumber++, g_wtp.mtu);
|
||||
|
||||
/* Prepare discovery request */
|
||||
capwap_build_packet_set_control_message_type(buildpacket, CAPWAP_DISCOVERY_REQUEST, g_wtp.localseqnumber++);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_DISCOVERYTYPE_ELEMENT(&g_wtp.discoverytype));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPBOARDDATA_ELEMENT(&g_wtp.boarddata));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPDESCRIPTOR_ELEMENT(&g_wtp.descriptor));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPFRAMETUNNELMODE_ELEMENT(&g_wtp.mactunnel));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPMACTYPE_ELEMENT(&g_wtp.mactype));
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_DISCOVERYTYPE, &g_wtp.discoverytype);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPBOARDDATA, &g_wtp.boarddata);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPDESCRIPTOR, &g_wtp.descriptor);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE, &g_wtp.mactunnel);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPMACTYPE, &g_wtp.mactype);
|
||||
|
||||
if (g_wtp.binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
wtp_create_80211_wtpradioinformation_element(buildpacket);
|
||||
} else {
|
||||
capwap_logging_debug("Unknown capwap binding");
|
||||
wtp_create_80211_wtpradioinformation_element(txmngpacket);
|
||||
}
|
||||
|
||||
/* CAPWAP_CREATE_MTUDISCOVERYPADDING_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
/* Create discovery request packet */
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
wtp_free_reference_last_request();
|
||||
result = capwap_fragment_build_packet(buildpacket, g_wtp.requestfragmentpacket, g_wtp.mtu, g_wtp.fragmentid);
|
||||
if (result == 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
} else {
|
||||
result = -1;
|
||||
capwap_logging_debug("Warning: build invalid discovery request packet");
|
||||
/* Discovery request complete, get fragment packets */
|
||||
wtp_free_reference_last_request();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, g_wtp.requestfragmentpacket, g_wtp.fragmentid);
|
||||
if (g_wtp.requestfragmentpacket->count > 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
|
||||
capwap_build_packet_free(buildpacket);
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send discovery request to AC */
|
||||
if (result >= 0) {
|
||||
int i;
|
||||
|
||||
/* Send broadcast packet to all socket */
|
||||
for (i = 0; i < g_wtp.requestfragmentpacket->count; i++) {
|
||||
int j;
|
||||
struct capwap_packet* packet = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.requestfragmentpacket, i);
|
||||
|
||||
ASSERT(packet != NULL);
|
||||
|
||||
for (j = 0; j < g_wtp.acdiscoveryarray->count; j++) {
|
||||
int sock;
|
||||
struct sockaddr_storage* sendtoaddr = (struct sockaddr_storage*)capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, j);
|
||||
|
||||
sock = capwap_get_socket(&g_wtp.net, sendtoaddr->ss_family, IPPROTO_UDP, 1);
|
||||
if (sock >= 0) {
|
||||
if (!capwap_sendto(sock, packet->header, packet->packetsize, NULL, sendtoaddr)) {
|
||||
capwap_logging_debug("Warning: error to send discovery request packet");
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < g_wtp.acdiscoveryarray->count; i++) {
|
||||
int sock;
|
||||
struct sockaddr_storage* sendtoaddr = (struct sockaddr_storage*)capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, i);
|
||||
|
||||
sock = capwap_get_socket(&g_wtp.net, sendtoaddr->ss_family, IPPROTO_UDP, 1);
|
||||
if (sock >= 0) {
|
||||
if (!capwap_sendto_fragmentpacket(sock, g_wtp.requestfragmentpacket, NULL, sendtoaddr)) {
|
||||
capwap_logging_debug("Warning: error to send discovery request packet");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't buffering a packets sent */
|
||||
wtp_free_reference_last_request();
|
||||
}
|
||||
|
||||
|
||||
/* Don't buffering a packets sent */
|
||||
wtp_free_reference_last_request();
|
||||
|
||||
/* Wait before send another Discovery Request */
|
||||
capwap_set_timeout(g_wtp.dfa.rfcDiscoveryInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
}
|
||||
@ -241,7 +222,7 @@ int wtp_dfa_state_discovery(struct capwap_packet* packet, struct timeout_control
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_discovery_to_sulking(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_discovery_to_sulking(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -252,7 +233,7 @@ int wtp_dfa_state_discovery_to_sulking(struct capwap_packet* packet, struct time
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_discovery_to_dtlssetup(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_discovery_to_dtlssetup(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
int status = WTP_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
|
@ -12,7 +12,7 @@ int wtp_bio_send(struct capwap_dtls* dtls, char* buffer, int length, void* param
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_dtlssetup(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_dtlssetup(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
int status = WTP_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
@ -36,7 +36,7 @@ int wtp_dfa_state_dtlssetup(struct capwap_packet* packet, struct timeout_control
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_dtlsconnect(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_dtlsconnect(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -45,7 +45,7 @@ int wtp_dfa_state_dtlsconnect(struct capwap_packet* packet, struct timeout_contr
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_dtlsconnect_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_dtlsconnect_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(packet == NULL);
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
@ -74,7 +74,7 @@ int wtp_teardown_connection(struct timeout_control* timeout) {
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -103,7 +103,7 @@ int wtp_dfa_state_dtlsteardown(struct capwap_packet* packet, struct timeout_cont
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_dtlsteardown_to_sulking(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_dtlsteardown_to_sulking(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -114,7 +114,7 @@ int wtp_dfa_state_dtlsteardown_to_sulking(struct capwap_packet* packet, struct t
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_dtlsteardown_to_idle(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_dtlsteardown_to_idle(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "wtp_dfa.h"
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_idle(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_idle(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -32,7 +32,7 @@ int wtp_dfa_state_idle(struct capwap_packet* packet, struct timeout_control* tim
|
||||
}
|
||||
|
||||
/* Prepare to discovery AC */
|
||||
int wtp_dfa_state_idle_to_discovery(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_idle_to_discovery(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -50,7 +50,7 @@ int wtp_dfa_state_idle_to_discovery(struct capwap_packet* packet, struct timeout
|
||||
}
|
||||
|
||||
/* Prepare to connect with AC */
|
||||
int wtp_dfa_state_idle_to_dtlssetup(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_idle_to_dtlssetup(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
int status = WTP_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "wtp_dfa.h"
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_imagedata_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_imagedata_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(packet == NULL);
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
|
@ -6,31 +6,30 @@
|
||||
#include "wtp_dfa.h"
|
||||
|
||||
/* */
|
||||
static unsigned long wtp_join_ac(struct capwap_element_join_response* joinresponse) {
|
||||
static unsigned long wtp_join_ac(struct capwap_parsed_packet* packet) {
|
||||
/* TODO: gestione richiesta
|
||||
CAPWAP_JOIN_TO_IMAGE_DATA_STATE <-> CAPWAP_JOIN_TO_CONFIGURE_STATE
|
||||
*/
|
||||
|
||||
/* Check DTLS data policy */
|
||||
if (!(g_wtp.validdtlsdatapolicy & joinresponse->acdescriptor->dtlspolicy)) {
|
||||
if (!(g_wtp.validdtlsdatapolicy & packet->messageelements.acdescriptor->dtlspolicy)) {
|
||||
return CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE;
|
||||
}
|
||||
|
||||
/* AC name associated */
|
||||
strcpy(g_wtp.acname.name, joinresponse->acname->name);
|
||||
strcpy((char*)g_wtp.acname.name, (char*)packet->messageelements.acname->name);
|
||||
|
||||
/* DTLS data policy */
|
||||
g_wtp.dtlsdatapolicy = joinresponse->acdescriptor->dtlspolicy & g_wtp.validdtlsdatapolicy;
|
||||
g_wtp.dtlsdatapolicy = packet->messageelements.acdescriptor->dtlspolicy & g_wtp.validdtlsdatapolicy;
|
||||
|
||||
return CAPWAP_JOIN_TO_CONFIGURE_STATE;
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_dtlsconnect_to_join(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int i;
|
||||
int result = -1;
|
||||
int wtp_dfa_state_dtlsconnect_to_join(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
int status = WTP_DFA_NO_PACKET;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
#ifdef DEBUG
|
||||
char sessionname[33];
|
||||
@ -54,81 +53,61 @@ int wtp_dfa_state_dtlsconnect_to_join(struct capwap_packet* packet, struct timeo
|
||||
#endif
|
||||
|
||||
/* Build packet */
|
||||
buildpacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
buildpacket->isctrlmsg = 1;
|
||||
|
||||
/* Prepare join request */
|
||||
capwap_build_packet_set_control_message_type(buildpacket, CAPWAP_JOIN_REQUEST, g_wtp.localseqnumber++);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_LOCATION_ELEMENT(&g_wtp.location));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPBOARDDATA_ELEMENT(&g_wtp.boarddata));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPDESCRIPTOR_ELEMENT(&g_wtp.descriptor));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPNAME_ELEMENT(&g_wtp.name));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_SESSIONID_ELEMENT(&g_wtp.sessionid));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPFRAMETUNNELMODE_ELEMENT(&g_wtp.mactunnel));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPMACTYPE_ELEMENT(&g_wtp.mactype));
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_JOIN_REQUEST, g_wtp.localseqnumber++, g_wtp.mtu);
|
||||
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCATION, &g_wtp.location);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPBOARDDATA, &g_wtp.boarddata);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPDESCRIPTOR, &g_wtp.descriptor);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPNAME, &g_wtp.name);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_SESSIONID, &g_wtp.sessionid);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE, &g_wtp.mactunnel);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPMACTYPE, &g_wtp.mactype);
|
||||
|
||||
if (g_wtp.binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
wtp_create_80211_wtpradioinformation_element(buildpacket);
|
||||
} else {
|
||||
capwap_logging_debug("Unknown capwap binding");
|
||||
wtp_create_80211_wtpradioinformation_element(txmngpacket);
|
||||
}
|
||||
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_ECNSUPPORT_ELEMENT(&g_wtp.ecn));
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ECNSUPPORT, &g_wtp.ecn);
|
||||
|
||||
if (g_wtp.wtpctrladdress.ss_family == AF_INET) {
|
||||
struct capwap_localipv4_element addr;
|
||||
|
||||
|
||||
memcpy(&addr.address, &((struct sockaddr_in*)&g_wtp.wtpctrladdress)->sin_addr, sizeof(struct in_addr));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_LOCALIPV4_ELEMENT(&addr));
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV4, &addr);
|
||||
} else if (g_wtp.wtpctrladdress.ss_family == AF_INET6) {
|
||||
struct capwap_localipv6_element addr;
|
||||
|
||||
|
||||
memcpy(&addr.address, &((struct sockaddr_in6*)&g_wtp.wtpctrladdress)->sin6_addr, sizeof(struct in6_addr));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_LOCALIPV6_ELEMENT(&addr));
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV6, &addr);
|
||||
}
|
||||
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_TRANSPORT_ELEMENT(&g_wtp.transport));
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TRANSPORT, &g_wtp.transport);
|
||||
/* CAPWAP_CREATE_MAXIMUMMESSAGELENGTH_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_WTPREBOOTSTATISTICS_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
/* Create join request packet */
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
wtp_free_reference_last_request();
|
||||
result = capwap_fragment_build_packet(buildpacket, g_wtp.requestfragmentpacket, g_wtp.mtu, g_wtp.fragmentid);
|
||||
if (result == 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: build invalid join request packet");
|
||||
/* Join request complete, get fragment packets */
|
||||
wtp_free_reference_last_request();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, g_wtp.requestfragmentpacket, g_wtp.fragmentid);
|
||||
if (g_wtp.requestfragmentpacket->count > 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
|
||||
capwap_build_packet_free(buildpacket);
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send join request to AC */
|
||||
if (result >= 0) {
|
||||
for (i = 0; i < g_wtp.requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send join request packet");
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == -1) {
|
||||
/* Error to send packets */
|
||||
wtp_free_reference_last_request();
|
||||
wtp_dfa_change_state(CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE);
|
||||
} else {
|
||||
g_wtp.dfa.rfcRetransmitCount = 0;
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
wtp_dfa_change_state(CAPWAP_JOIN_STATE);
|
||||
status = WTP_DFA_ACCEPT_PACKET;
|
||||
}
|
||||
if (capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.requestfragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
g_wtp.dfa.rfcRetransmitCount = 0;
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
wtp_dfa_change_state(CAPWAP_JOIN_STATE);
|
||||
status = WTP_DFA_ACCEPT_PACKET;
|
||||
} else {
|
||||
/* Error to send packets */
|
||||
capwap_logging_debug("Warning: error to send join request packet");
|
||||
wtp_free_reference_last_request();
|
||||
wtp_dfa_change_state(CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE);
|
||||
}
|
||||
|
||||
@ -136,50 +115,27 @@ int wtp_dfa_state_dtlsconnect_to_join(struct capwap_packet* packet, struct timeo
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_join(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_join(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
int status = WTP_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
if (packet) {
|
||||
if (!capwap_compare_ip(&g_wtp.acctrladdress, &packet->remoteaddr)) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
if (!capwap_compare_ip(&g_wtp.acctrladdress, &packet->connection->remoteaddr)) {
|
||||
unsigned short binding;
|
||||
|
||||
/* Parsing packet */
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
unsigned short binding;
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
if ((binding == g_wtp.binding) && (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_JOIN_RESPONSE) && ((g_wtp.localseqnumber - 1) == buildpacket->ctrlmsg.seq)) {
|
||||
struct capwap_element_join_response joinresponse;
|
||||
|
||||
/* Valid packet, free request packet */
|
||||
wtp_free_reference_last_request();
|
||||
|
||||
/* Join response info */
|
||||
capwap_init_element_join_response(&joinresponse, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_join_response(&joinresponse, buildpacket->elementslist->first)) {
|
||||
wtp_dfa_change_state(wtp_join_ac(&joinresponse));
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
|
||||
/* Free join response */
|
||||
capwap_free_element_join_response(&joinresponse, binding);
|
||||
}
|
||||
}
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
if (packet->rxmngpacket->isctrlpacket && (binding == g_wtp.binding) && (packet->rxmngpacket->ctrlmsg.type == CAPWAP_JOIN_RESPONSE) && ((g_wtp.localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
/* Valid packet, free request packet */
|
||||
wtp_free_reference_last_request();
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
/* Parsing response values */
|
||||
wtp_dfa_change_state(wtp_join_ac(packet));
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int i;
|
||||
|
||||
/* No Join response received */
|
||||
g_wtp.dfa.rfcRetransmitCount++;
|
||||
if (g_wtp.dfa.rfcRetransmitCount >= g_wtp.dfa.rfcMaxRetransmit) {
|
||||
@ -188,17 +144,11 @@ int wtp_dfa_state_join(struct capwap_packet* packet, struct timeout_control* tim
|
||||
wtp_dfa_change_state(CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
} else {
|
||||
/* Retransmit join request */
|
||||
for (i = 0; i < g_wtp.requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send join request packet");
|
||||
break;
|
||||
}
|
||||
/* Retransmit join request */
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.requestfragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send join request packet");
|
||||
}
|
||||
|
||||
|
||||
/* Update timeout */
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
}
|
||||
@ -208,83 +158,53 @@ int wtp_dfa_state_join(struct capwap_packet* packet, struct timeout_control* tim
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_join_to_configure(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
unsigned long i;
|
||||
int result = -1;
|
||||
int wtp_dfa_state_join_to_configure(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
int status = WTP_DFA_NO_PACKET;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
|
||||
/* Build packet */
|
||||
buildpacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
buildpacket->isctrlmsg = 1;
|
||||
|
||||
/* Prepare Configuration Status request */
|
||||
capwap_build_packet_set_control_message_type(buildpacket, CAPWAP_CONFIGURATION_STATUS_REQUEST, g_wtp.localseqnumber++);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_ACNAME_ELEMENT(&g_wtp.acname));
|
||||
|
||||
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 capwap_radioadmstate_element radioadmstate;
|
||||
|
||||
radioadmstate.radioid = (unsigned char)(i + 1);
|
||||
radioadmstate.state = ((radio->status == WTP_RADIO_DISABLED) ? CAPWAP_RADIO_ADMIN_STATE_DISABLED : CAPWAP_RADIO_ADMIN_STATE_ENABLED);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_RADIOADMSTATE_ELEMENT(&radioadmstate));
|
||||
}
|
||||
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_STATISTICSTIMER_ELEMENT(&g_wtp.statisticstimer));
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_WTPREBOOTSTAT_ELEMENT(&g_wtp.rebootstat));
|
||||
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_CONFIGURATION_STATUS_REQUEST, g_wtp.localseqnumber++, g_wtp.mtu);
|
||||
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACNAME, &g_wtp.acname);
|
||||
wtp_create_radioadmstate_element(txmngpacket);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_STATISTICSTIMER, &g_wtp.statisticstimer);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPREBOOTSTAT, &g_wtp.rebootstat);
|
||||
/* CAPWAP_CREATE_ACNAMEPRIORITY_ELEMENT */ /* TODO */
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_TRANSPORT_ELEMENT(&g_wtp.transport));
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TRANSPORT, &g_wtp.transport);
|
||||
/* 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");
|
||||
wtp_create_80211_wtpradioinformation_element(txmngpacket);
|
||||
}
|
||||
|
||||
/* Create Configuration Status request packet */
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
wtp_free_reference_last_request();
|
||||
result = capwap_fragment_build_packet(buildpacket, g_wtp.requestfragmentpacket, g_wtp.mtu, g_wtp.fragmentid);
|
||||
if (result == 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: build invalid configuretion status request packet");
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
/* Configuration Status request complete, get fragment packets */
|
||||
wtp_free_reference_last_request();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, g_wtp.requestfragmentpacket, g_wtp.fragmentid);
|
||||
if (g_wtp.requestfragmentpacket->count > 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
|
||||
capwap_build_packet_free(buildpacket);
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send Configuration Status request to AC */
|
||||
if (result >= 0) {
|
||||
for (i = 0; i < g_wtp.requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send configuration status request packet");
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == -1) {
|
||||
/* Error to send packets */
|
||||
wtp_free_reference_last_request();
|
||||
wtp_dfa_change_state(CAPWAP_CONFIGURE_TO_DTLS_TEARDOWN_STATE);
|
||||
} else {
|
||||
g_wtp.dfa.rfcRetransmitCount = 0;
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
wtp_dfa_change_state(CAPWAP_CONFIGURE_STATE);
|
||||
status = WTP_DFA_ACCEPT_PACKET;
|
||||
}
|
||||
if (capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.requestfragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
g_wtp.dfa.rfcRetransmitCount = 0;
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
wtp_dfa_change_state(CAPWAP_CONFIGURE_STATE);
|
||||
status = WTP_DFA_ACCEPT_PACKET;
|
||||
} else {
|
||||
/* Error to send packets */
|
||||
capwap_logging_debug("Warning: error to send configuration status request packet");
|
||||
wtp_free_reference_last_request();
|
||||
wtp_dfa_change_state(CAPWAP_CONFIGURE_TO_DTLS_TEARDOWN_STATE);
|
||||
}
|
||||
|
||||
@ -292,7 +212,7 @@ int wtp_dfa_state_join_to_configure(struct capwap_packet* packet, struct timeout
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_join_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_join_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(packet == NULL);
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "wtp_dfa.h"
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_reset(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_reset(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(packet == NULL);
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
|
@ -5,237 +5,165 @@
|
||||
|
||||
/* */
|
||||
static int send_echo_request() {
|
||||
int i;
|
||||
int result = -1;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
|
||||
/* Build packet */
|
||||
buildpacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
buildpacket->isctrlmsg = 1;
|
||||
|
||||
/* Prepare echo request */
|
||||
capwap_build_packet_set_control_message_type(buildpacket, CAPWAP_ECHO_REQUEST, g_wtp.localseqnumber++);
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_ECHO_REQUEST, g_wtp.localseqnumber++, g_wtp.mtu);
|
||||
|
||||
/* Add message element */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
/* Create echo request packet */
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
wtp_free_reference_last_request();
|
||||
result = capwap_fragment_build_packet(buildpacket, g_wtp.requestfragmentpacket, g_wtp.mtu, g_wtp.fragmentid);
|
||||
if (result == 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: build invalid echo request packet");
|
||||
/* Echo request complete, get fragment packets */
|
||||
wtp_free_reference_last_request();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, g_wtp.requestfragmentpacket, g_wtp.fragmentid);
|
||||
if (g_wtp.requestfragmentpacket->count > 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
|
||||
capwap_build_packet_free(buildpacket);
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send echo request to AC */
|
||||
if (result >= 0) {
|
||||
for (i = 0; i < g_wtp.requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send echo request packet");
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == -1) {
|
||||
wtp_free_reference_last_request(); /* Error to send packets */
|
||||
}
|
||||
if (capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.requestfragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
result = 0;
|
||||
} else {
|
||||
/* Error to send packets */
|
||||
capwap_logging_debug("Warning: error to send echo request packet");
|
||||
wtp_free_reference_last_request();
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int receive_echo_response(struct capwap_build_packet* buildpacket) {
|
||||
unsigned short binding;
|
||||
struct capwap_element_echo_response echoresponse;
|
||||
|
||||
ASSERT(buildpacket != NULL);
|
||||
static int receive_echo_response(struct capwap_parsed_packet* packet) {
|
||||
ASSERT(packet != NULL);
|
||||
|
||||
/* Valid packet, free request packet */
|
||||
wtp_free_reference_last_request();
|
||||
|
||||
/* Echo response info */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
capwap_init_element_echo_response(&echoresponse, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_echo_response(&echoresponse, buildpacket->elementslist->first)) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* Free join response */
|
||||
capwap_free_element_echo_response(&echoresponse, binding);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void receive_reset_request(struct capwap_build_packet* buildpacket, struct capwap_packet* packet) {
|
||||
unsigned long i;
|
||||
static void receive_reset_request(struct capwap_parsed_packet* packet) {
|
||||
unsigned short binding;
|
||||
|
||||
ASSERT(buildpacket != NULL);
|
||||
ASSERT(packet != NULL);
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
if ((binding == g_wtp.binding) && IS_SEQUENCE_SMALLER(g_wtp.remoteseqnumber, buildpacket->ctrlmsg.seq)) {
|
||||
struct capwap_element_reset_request resetrequest;
|
||||
|
||||
/* Reset request info*/
|
||||
capwap_init_element_reset_request(&resetrequest, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_reset_request(&resetrequest, buildpacket->elementslist->first)) {
|
||||
struct capwap_build_packet* responsepacket;
|
||||
struct capwap_resultcode_element resultcode = { CAPWAP_RESULTCODE_SUCCESS };
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
if ((binding == g_wtp.binding) && IS_SEQUENCE_SMALLER(g_wtp.remoteseqnumber, packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_SUCCESS };
|
||||
|
||||
/* Create response */
|
||||
responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
|
||||
responsepacket->isctrlmsg = 1;
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_RESET_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, g_wtp.mtu);
|
||||
|
||||
/* Prepare echo response */
|
||||
capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_RESET_RESPONSE, buildpacket->ctrlmsg.seq);
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_RESULTCODE_ELEMENT(&resultcode));
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RESULTCODE, &resultcode);
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
if (!capwap_build_packet_validate(responsepacket, NULL)) {
|
||||
int result;
|
||||
/* Reset response complete, get fragment packets */
|
||||
wtp_free_reference_last_response();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, g_wtp.responsefragmentpacket, g_wtp.fragmentid);
|
||||
if (g_wtp.responsefragmentpacket->count > 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
|
||||
wtp_free_reference_last_response();
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send reset response to AC */
|
||||
result = capwap_fragment_build_packet(responsepacket, g_wtp.responsefragmentpacket, g_wtp.mtu, g_wtp.fragmentid);
|
||||
if (result >= 0) {
|
||||
if (result == 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
/* Save remote sequence number */
|
||||
g_wtp.remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest(packet->rxmngpacket, packet->connection, g_wtp.lastrecvpackethash);
|
||||
|
||||
/* Save remote sequence number */
|
||||
g_wtp.remoteseqnumber = buildpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest((void*)packet->header, packet->packetsize, g_wtp.lastrecvpackethash);
|
||||
|
||||
/* Send */
|
||||
for (i = 0; i < g_wtp.responsefragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.responsefragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
/* Response is already created and saved. When receive a re-request, DFA autoresponse */
|
||||
capwap_logging_debug("Warning: error to send reset response packet");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
capwap_build_packet_free(responsepacket);
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_free_element_reset_request(&resetrequest, binding);
|
||||
/* Send Reset response to AC */
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.responsefragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send reset response packet");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_run(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_run(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
int status = WTP_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
if (packet) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
if (packet->socket.isctrlsocket) {
|
||||
unsigned long typemsg = ntohl(buildpacket->ctrlmsg.type);
|
||||
|
||||
if (capwap_is_request_type(typemsg) || ((g_wtp.localseqnumber - 1) == buildpacket->ctrlmsg.seq)) {
|
||||
switch (typemsg) {
|
||||
case CAPWAP_CONFIGURATION_UPDATE_RESPONSE: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CHANGE_STATE_EVENT_REQUEST: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_ECHO_RESPONSE: {
|
||||
if (!receive_echo_response(buildpacket)) {
|
||||
capwap_kill_timeout(timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcEchoInterval, timeout, CAPWAP_TIMER_CONTROL_ECHO);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CLEAR_CONFIGURATION_RESPONSE: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_WTP_EVENT_REQUEST: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_REQUEST: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_RESPONSE: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_REQUEST: {
|
||||
receive_reset_request(buildpacket, packet);
|
||||
wtp_dfa_change_state(CAPWAP_RESET_STATE);
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IS_FLAG_K_HEADER(&buildpacket->header) && capwap_is_enable_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD)) {
|
||||
struct capwap_sessionid_element sessionid;
|
||||
|
||||
if (capwap_get_sessionid_from_keepalive(buildpacket, &sessionid)) {
|
||||
if (!memcmp(&sessionid, &g_wtp.sessionid, sizeof(struct capwap_sessionid_element))) {
|
||||
/* Receive Data Keep-Alive, wait for next packet */
|
||||
capwap_kill_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcDataChannelKeepAlive, timeout, CAPWAP_TIMER_DATA_KEEPALIVE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (packet->rxmngpacket->isctrlpacket) {
|
||||
if (capwap_is_request_type(packet->rxmngpacket->ctrlmsg.type) || ((g_wtp.localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
switch (packet->rxmngpacket->ctrlmsg.type) {
|
||||
case CAPWAP_CONFIGURATION_UPDATE_RESPONSE: {
|
||||
/* TODO */
|
||||
|
||||
/* Update data keep-alive timeout */
|
||||
if (!capwap_is_enable_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD)) {
|
||||
capwap_set_timeout(g_wtp.dfa.rfcDataChannelKeepAlive, timeout, CAPWAP_TIMER_DATA_KEEPALIVE);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CHANGE_STATE_EVENT_REQUEST: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_ECHO_RESPONSE: {
|
||||
if (!receive_echo_response(packet)) {
|
||||
capwap_kill_timeout(timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcEchoInterval, timeout, CAPWAP_TIMER_CONTROL_ECHO);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CLEAR_CONFIGURATION_RESPONSE: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_WTP_EVENT_REQUEST: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_REQUEST: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_RESPONSE: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_REQUEST: {
|
||||
receive_reset_request(packet);
|
||||
wtp_dfa_change_state(CAPWAP_RESET_STATE);
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
} else {
|
||||
if (IS_FLAG_K_HEADER(packet->rxmngpacket->header) && capwap_is_enable_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD)) {
|
||||
if (!memcmp(packet->messageelements.sessionid, &g_wtp.sessionid, sizeof(struct capwap_sessionid_element))) {
|
||||
/* Receive Data Keep-Alive, wait for next packet */
|
||||
capwap_kill_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcDataChannelKeepAlive, timeout, CAPWAP_TIMER_DATA_KEEPALIVE);
|
||||
}
|
||||
} else {
|
||||
/* TODO */
|
||||
|
||||
/* Update data keep-alive timeout */
|
||||
if (!capwap_is_enable_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD)) {
|
||||
capwap_set_timeout(g_wtp.dfa.rfcDataChannelKeepAlive, timeout, CAPWAP_TIMER_DATA_KEEPALIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (capwap_is_timeout(timeout, CAPWAP_TIMER_CONTROL_CONNECTION)) {
|
||||
int i;
|
||||
|
||||
/* No response received */
|
||||
g_wtp.dfa.rfcRetransmitCount++;
|
||||
if (g_wtp.dfa.rfcRetransmitCount >= g_wtp.dfa.rfcMaxRetransmit) {
|
||||
@ -245,16 +173,10 @@ int wtp_dfa_state_run(struct capwap_packet* packet, struct timeout_control* time
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
} else {
|
||||
/* Retransmit request */
|
||||
for (i = 0; i < g_wtp.requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(g_wtp.requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send request packet");
|
||||
break;
|
||||
}
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.requestfragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send request packet");
|
||||
}
|
||||
|
||||
|
||||
/* Update timeout */
|
||||
capwap_set_timeout(g_wtp.dfa.rfcRetransmitInterval, timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
}
|
||||
@ -270,46 +192,41 @@ int wtp_dfa_state_run(struct capwap_packet* packet, struct timeout_control* time
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
} else if (capwap_is_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVE)) {
|
||||
int result;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
capwap_fragment_packet_array* txfragpacket;
|
||||
struct capwap_list* txfragpacket;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
|
||||
/* Build packet Data Keep-Alive*/
|
||||
buildpacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, CAPWAP_WIRELESS_BINDING_NONE);
|
||||
buildpacket->isctrlmsg = 0;
|
||||
|
||||
/* */
|
||||
SET_FLAG_K_HEADER(&buildpacket->header, 1);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_SESSIONID_ELEMENT(&g_wtp.sessionid));
|
||||
|
||||
txfragpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
|
||||
result = capwap_fragment_build_packet(buildpacket, txfragpacket, CAPWAP_DONT_FRAGMENT, 0);
|
||||
if (!result) {
|
||||
struct capwap_packet* txpacket;
|
||||
|
||||
ASSERT(txfragpacket->count == 1);
|
||||
|
||||
txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(txfragpacket, 0);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&g_wtp.datadtls, g_wtp.acdatasock.socket[g_wtp.acdatasock.type], txpacket->header, txpacket->packetsize, &g_wtp.wtpdataaddress, &g_wtp.acdataaddress)) {
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
capwap_header_set_keepalive_flag(&capwapheader, 1);
|
||||
txmngpacket = capwap_packet_txmng_create_data_message(&capwapheader, g_wtp.mtu); /* CAPWAP_DONT_FRAGMENT */
|
||||
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_SESSIONID, &g_wtp.sessionid);
|
||||
|
||||
/* Data keepalive complete, get fragment packets into local list */
|
||||
txfragpacket = capwap_list_create();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, 0);
|
||||
if (txfragpacket->count == 1) {
|
||||
/* Send Data keepalive to AC */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&g_wtp.datadtls, g_wtp.acdatasock.socket[g_wtp.acdatasock.type], txfragpacket, &g_wtp.wtpdataaddress, &g_wtp.acdataaddress)) {
|
||||
capwap_kill_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVE);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcDataChannelDeadInterval, timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD);
|
||||
} else {
|
||||
/* Error to send packets */
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet");
|
||||
result = -1;
|
||||
wtp_dfa_change_state(CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
capwap_fragment_free(txfragpacket);
|
||||
capwap_array_free(txfragpacket);
|
||||
capwap_build_packet_free(buildpacket);
|
||||
|
||||
/* Send Configuration Status request to AC */
|
||||
if (!result) {
|
||||
capwap_kill_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVE);
|
||||
capwap_set_timeout(g_wtp.dfa.rfcDataChannelDeadInterval, timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD);
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet, fragment packet");
|
||||
wtp_dfa_change_state(CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = WTP_DFA_NO_PACKET;
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_list_free(txfragpacket);
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
} else if (capwap_is_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD)) {
|
||||
/* Data Keep-Alive timeout */
|
||||
capwap_kill_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD);
|
||||
@ -322,7 +239,7 @@ int wtp_dfa_state_run(struct capwap_packet* packet, struct timeout_control* time
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_run_to_dtlsteardown(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_run_to_dtlsteardown(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(packet == NULL);
|
||||
ASSERT(timeout != NULL);
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "wtp_dfa.h"
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_sulking(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_sulking(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -13,7 +13,7 @@ int wtp_dfa_state_sulking(struct capwap_packet* packet, struct timeout_control*
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_dfa_state_sulking_to_idle(struct capwap_packet* packet, struct timeout_control* timeout) {
|
||||
int wtp_dfa_state_sulking_to_idle(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
|
||||
ASSERT(timeout != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
|
@ -1,10 +1,53 @@
|
||||
#include "wtp.h"
|
||||
|
||||
void wtp_create_80211_wtpradioinformation_element(struct capwap_build_packet* buildpacket) {
|
||||
/* */
|
||||
void wtp_create_radioopsstate_element(struct capwap_packet_txmng* txmngpacket) {
|
||||
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));
|
||||
struct capwap_radiooprstate_element radiooprstate;
|
||||
|
||||
radiooprstate.radioid = (unsigned char)(i + 1);
|
||||
radiooprstate.state = ((radio->status == WTP_RADIO_ENABLED) ? CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED : CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED);
|
||||
|
||||
if (radio->status == WTP_RADIO_ENABLED) {
|
||||
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_NORMAL;
|
||||
} else if (radio->status == WTP_RADIO_DISABLED) {
|
||||
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET;
|
||||
} else if (radio->status == WTP_RADIO_HWFAILURE) {
|
||||
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_RADIOFAILURE;
|
||||
} else if (radio->status == WTP_RADIO_SWFAILURE) {
|
||||
radiooprstate.cause = CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE;
|
||||
} else {
|
||||
/* Unknown value */
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RADIOOPRSTATE, &radiooprstate);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void wtp_create_radioadmstate_element(struct capwap_packet_txmng* txmngpacket) {
|
||||
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);
|
||||
struct capwap_radioadmstate_element radioadmstate;
|
||||
|
||||
radioadmstate.radioid = (unsigned char)(i + 1);
|
||||
radioadmstate.state = ((radio->status == WTP_RADIO_DISABLED) ? CAPWAP_RADIO_ADMIN_STATE_DISABLED : CAPWAP_RADIO_ADMIN_STATE_ENABLED);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RADIOADMSTATE, &radioadmstate);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void wtp_create_80211_wtpradioinformation_element(struct capwap_packet_txmng* txmngpacket) {
|
||||
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_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, &radio->radioinformation);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user