diff --git a/src/common/capwap_protocol.c b/src/common/capwap_protocol.c index 655d9e3..f20e9a4 100644 --- a/src/common/capwap_protocol.c +++ b/src/common/capwap_protocol.c @@ -315,11 +315,21 @@ void capwap_header_set_wireless_information(struct capwap_header_data* data, voi /* */ void capwap_header_set_keepalive_flag(struct capwap_header_data* data, int enable) { struct capwap_header* header; - + ASSERT(data != NULL); - + header = (struct capwap_header*)&data->headerbuffer[0]; - SET_FLAG_K_HEADER(header, ((enable != 0) ? 1 : 0)); + SET_FLAG_K_HEADER(header, (enable ? 1 : 0)); +} + +/* */ +void capwap_header_set_nativeframe_flag(struct capwap_header_data* data, int enable) { + struct capwap_header* header; + + ASSERT(data != NULL); + + header = (struct capwap_header*)&data->headerbuffer[0]; + SET_FLAG_T_HEADER(header, (enable ? 1 : 0)); } /* */ @@ -600,6 +610,14 @@ struct capwap_packet_txmng* capwap_packet_txmng_create_data_message(struct capwa return txmngpacket; } +/* */ +void capwap_packet_txmng_add_data(struct capwap_packet_txmng* txmngpacket, uint8_t* data, unsigned short length) { + ASSERT(txmngpacket != NULL); + ASSERT(txmngpacket->isctrlpacket == 0); + + txmngpacket->write_ops.write_block((capwap_message_elements_handle)txmngpacket, data, length); +} + /* */ void capwap_packet_txmng_add_message_element(struct capwap_packet_txmng* txmngpacket, unsigned short type, void* data) { struct capwap_message_elements_ops* func; diff --git a/src/common/capwap_protocol.h b/src/common/capwap_protocol.h index 6e1e9e5..202fd29 100644 --- a/src/common/capwap_protocol.h +++ b/src/common/capwap_protocol.h @@ -35,6 +35,7 @@ void capwap_header_init(struct capwap_header_data* data, unsigned short radioid, void capwap_header_set_radio_macaddress(struct capwap_header_data* data, int radiotype, char* macaddress); void capwap_header_set_wireless_information(struct capwap_header_data* data, void* buffer, unsigned char length); void capwap_header_set_keepalive_flag(struct capwap_header_data* data, int enable); +void capwap_header_set_nativeframe_flag(struct capwap_header_data* data, int enable); /* Management tx capwap packet */ struct write_block_from_pos { @@ -64,6 +65,7 @@ struct capwap_packet_txmng { /* */ struct capwap_packet_txmng* capwap_packet_txmng_create_ctrl_message(struct capwap_header_data* data, unsigned long type, unsigned char seq, unsigned short mtu); struct capwap_packet_txmng* capwap_packet_txmng_create_data_message(struct capwap_header_data* data, unsigned short mtu); +void capwap_packet_txmng_add_data(struct capwap_packet_txmng* txmngpacket, uint8_t* data, unsigned short length); void capwap_packet_txmng_add_message_element(struct capwap_packet_txmng* txmngpacket, unsigned short type, void* data); void capwap_packet_txmng_get_fragment_packets(struct capwap_packet_txmng* txmngpacket, struct capwap_list* fragmentlist, unsigned short fragmentid); void capwap_packet_txmng_free(struct capwap_packet_txmng* txmngpacket); diff --git a/src/wtp/wtp_dfa.h b/src/wtp/wtp_dfa.h index b824dd0..6df6c5d 100644 --- a/src/wtp/wtp_dfa.h +++ b/src/wtp/wtp_dfa.h @@ -48,4 +48,7 @@ void wtp_dfa_state_datacheck(struct capwap_parsed_packet* packet, struct timeout void wtp_dfa_state_run(struct capwap_parsed_packet* packet, struct timeout_control* timeout); void wtp_dfa_state_reset(struct capwap_parsed_packet* packet, struct timeout_control* timeout); +/* */ +void wtp_send_data_wireless_packet(uint8_t radioid, uint8_t wlanid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, int leavenativeframe); + #endif /* __WTP_DFA_HEADER__ */ diff --git a/src/wtp/wtp_dfa_run.c b/src/wtp/wtp_dfa_run.c index 39fa665..71a4393 100644 --- a/src/wtp/wtp_dfa_run.c +++ b/src/wtp/wtp_dfa_run.c @@ -5,7 +5,7 @@ #include "wtp_radio.h" /* */ -static int send_echo_request() { +static int send_echo_request(void) { int result = -1; struct capwap_header_data capwapheader; struct capwap_packet_txmng* txmngpacket; @@ -159,6 +159,73 @@ static void receive_ieee80211_wlan_configuration_request(struct capwap_parsed_pa } } +/* */ +static void send_data_keepalive_request(struct timeout_control* timeout) { + struct capwap_list* txfragpacket; + struct capwap_header_data capwapheader; + struct capwap_packet_txmng* txmngpacket; + + /* 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"); + wtp_teardown_connection(timeout); + } + } else { + capwap_logging_debug("Warning: error to send data channel keepalive packet, fragment packet"); + wtp_teardown_connection(timeout); + } + + /* Free packets manager */ + capwap_list_free(txfragpacket); + capwap_packet_txmng_free(txmngpacket); +} + +/* */ +void wtp_send_data_wireless_packet(uint8_t radioid, uint8_t wlanid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, int leavenativeframe) { + struct capwap_list* txfragpacket; + struct capwap_header_data capwapheader; + struct capwap_packet_txmng* txmngpacket; + + /* Build packet */ + capwap_header_init(&capwapheader, radioid, g_wtp.binding); + capwap_header_set_nativeframe_flag(&capwapheader, leavenativeframe); + txmngpacket = capwap_packet_txmng_create_data_message(&capwapheader, g_wtp.mtu); + + /* */ + if (leavenativeframe) { + capwap_packet_txmng_add_data(txmngpacket, (uint8_t*)mgmt, (unsigned short)mgmtlength); + } else { + /* TODO */ + } + + /* Data message complete, get fragment packets into local list */ + txfragpacket = capwap_list_create(); + capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, 0); + if (!capwap_crypt_sendto_fragmentpacket(&g_wtp.datadtls, g_wtp.acdatasock.socket[g_wtp.acdatasock.type], txfragpacket, &g_wtp.wtpdataaddress, &g_wtp.acdataaddress)) { + capwap_logging_debug("Warning: error to send data packet"); + } + + /* Free packets manager */ + capwap_list_free(txfragpacket); + capwap_packet_txmng_free(txmngpacket); +} + /* */ void wtp_dfa_state_run(struct capwap_parsed_packet* packet, struct timeout_control* timeout) { ASSERT(timeout != NULL); @@ -268,39 +335,7 @@ void wtp_dfa_state_run(struct capwap_parsed_packet* packet, struct timeout_contr wtp_teardown_connection(timeout); } } else if (capwap_is_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVE)) { - struct capwap_list* txfragpacket; - struct capwap_header_data capwapheader; - struct capwap_packet_txmng* txmngpacket; - - /* 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"); - wtp_teardown_connection(timeout); - } - } else { - capwap_logging_debug("Warning: error to send data channel keepalive packet, fragment packet"); - wtp_teardown_connection(timeout); - } - - /* Free packets manager */ - capwap_list_free(txfragpacket); - capwap_packet_txmng_free(txmngpacket); + send_data_keepalive_request(timeout); } else if (capwap_is_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD)) { /* Data Keep-Alive timeout */ capwap_kill_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD); diff --git a/src/wtp/wtp_radio.c b/src/wtp/wtp_radio.c index 0bec7dd..f58e209 100644 --- a/src/wtp/wtp_radio.c +++ b/src/wtp/wtp_radio.c @@ -2,6 +2,7 @@ #include "capwap_hash.h" #include "capwap_list.h" #include "wtp_radio.h" +#include "wtp_dfa.h" /* */ #define WTP_UPDATE_FREQUENCY_DSSS 1 @@ -51,13 +52,14 @@ static int wtp_radio_configure_phy(struct wtp_radio* radio) { /* */ static void wtp_radio_send_mgmtframe_to_ac(void* param, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, int leavenativeframe) { - //struct wtp_radio_wlan* wlan = (struct wtp_radio_wlan*)mgmt; + struct wtp_radio_wlan* wlan = (struct wtp_radio_wlan*)param; ASSERT(param != NULL); ASSERT(mgmt != NULL); - ASSERT(mgmtlength > sizeof(struct ieee80211_header_mgmt)); + ASSERT(mgmtlength >= sizeof(struct ieee80211_header)); - /* TODO */ + /* Send packet */ + wtp_send_data_wireless_packet(wlan->radio->radioid, wlan->wlanid, mgmt, mgmtlength, leavenativeframe); } /* */