From 78a8a75c6b010c362e9a807fc0dd5aa965083f50 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 7 Mar 2016 16:23:49 +0100 Subject: [PATCH] start 802.11n --- build/Makefile_common.am | 3 +- src/common/capwap_element.c | 5 +- src/common/capwap_element.h | 4 + src/common/capwap_element_80211n_radioconf.c | 92 ++++++++++++++++ src/common/capwap_element_80211n_radioconf.h | 25 +++++ ...apwap_element_80211n_station_information.c | 102 ++++++++++++++++++ ...apwap_element_80211n_station_information.h | 28 +++++ src/common/capwap_element_vendorpayload.c | 52 +++++++-- src/common/capwap_element_vendorpayload.h | 4 + 9 files changed, 304 insertions(+), 11 deletions(-) create mode 100644 src/common/capwap_element_80211n_radioconf.c create mode 100644 src/common/capwap_element_80211n_radioconf.h create mode 100644 src/common/capwap_element_80211n_station_information.c create mode 100644 src/common/capwap_element_80211n_station_information.h diff --git a/build/Makefile_common.am b/build/Makefile_common.am index 3a81018..10a7951 100755 --- a/build/Makefile_common.am +++ b/build/Makefile_common.am @@ -100,7 +100,8 @@ capwap_SOURCES = $(top_srcdir)/src/common/capwap.c \ $(top_srcdir)/src/common/capwap_element_80211_wtpqos.c \ $(top_srcdir)/src/common/capwap_element_80211_wtpradioconf.c \ $(top_srcdir)/src/common/capwap_element_80211_wtpradiofailalarm.c \ - $(top_srcdir)/src/common/capwap_element_80211_wtpradioinformation.c + $(top_srcdir)/src/common/capwap_element_80211_wtpradioinformation.c \ + $(top_srcdir)/src/common/capwap_element_80211n_radioconf.c if DEBUG_BUILD capwap_SOURCES += $(top_srcdir)/src/common/capwap_debug.c diff --git a/src/common/capwap_element.c b/src/common/capwap_element.c index fe0e99e..c8b1483 100644 --- a/src/common/capwap_element.c +++ b/src/common/capwap_element.c @@ -122,13 +122,14 @@ static struct capwap_message_elements_ops* capwap_80211_message_elements[] = { }; /* */ -struct capwap_message_elements_ops* capwap_get_message_element_ops(unsigned short code) { +struct capwap_message_elements_ops* capwap_get_message_element_ops(unsigned short code) +{ if (IS_MESSAGE_ELEMENTS(code)) { return capwap_message_elements[code - CAPWAP_MESSAGE_ELEMENTS_START]; } else if (IS_80211_MESSAGE_ELEMENTS(code)) { return capwap_80211_message_elements[code - CAPWAP_80211_MESSAGE_ELEMENTS_START]; } - + return NULL; } diff --git a/src/common/capwap_element.h b/src/common/capwap_element.h index 046a1a9..c905b4d 100644 --- a/src/common/capwap_element.h +++ b/src/common/capwap_element.h @@ -118,6 +118,10 @@ struct capwap_message_elements_ops* capwap_get_message_element_ops(unsigned shor #include "capwap_element_80211_wtpradiofailalarm.h" /* 01047 */ #include "capwap_element_80211_wtpradioinformation.h" /* 01048 */ +/* draft-ietf-opsawg-capwap-extension-06 */ +#include "capwap_element_80211n_radioconf.h" +#include "capwap_element_80211n_station_information.h" + /*********************************************************************************************************************/ #define CAPWAP_MESSAGE_ELEMENT_SINGLE 0 #define CAPWAP_MESSAGE_ELEMENT_ARRAY 1 diff --git a/src/common/capwap_element_80211n_radioconf.c b/src/common/capwap_element_80211n_radioconf.c new file mode 100644 index 0000000..b7bda07 --- /dev/null +++ b/src/common/capwap_element_80211n_radioconf.c @@ -0,0 +1,92 @@ +#include "capwap.h" +#include "capwap_element.h" + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Radio ID |S|P|N|G|B| | MaxSup MCS | Max MandMCS | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TxAntenna | RxAntenna | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Type: TBD1 for IEEE 802.11n WLAN Radio Configuration + * + */ + +/* */ +static void +capwap_80211n_radioconf_element_create(void *data, + capwap_message_elements_handle handle, + struct capwap_write_message_elements_ops *func) +{ + struct capwap_80211n_radioconf_element *element = (struct capwap_80211n_radioconf_element *)data; + + ASSERT(data != NULL); + + func->write_u8(handle, element->radioid); + func->write_u8(handle, element->flags & CAPWAP_80211N_RADIO_CONF_MASK); + func->write_u8(handle, element->maxsupmcs); + func->write_u8(handle, element->maxmandmcs); + func->write_u8(handle, element->txant); + func->write_u8(handle, element->rxant); + func->write_u16(handle, 0); +} + +/* */ +static void * +capwap_80211n_radioconf_element_parsing(capwap_message_elements_handle handle, + struct capwap_read_message_elements_ops *func) +{ + struct capwap_80211n_radioconf_element *data; + uint16_t reserved; + + ASSERT(handle != NULL); + ASSERT(func != NULL); + + if (func->read_ready(handle) != 8) { + capwap_logging_debug("Invalid IEEE 802.11n Radio Configuration element"); + return NULL; + } + + /* */ + data = (struct capwap_80211n_radioconf_element*)capwap_alloc(sizeof(struct capwap_80211n_radioconf_element)); + memset(data, 0, sizeof(struct capwap_80211n_radioconf_element)); + + /* Retrieve data */ + func->read_u8(handle, &data->radioid); + func->read_u8(handle, &data->flags); + func->read_u8(handle, &data->maxsupmcs); + func->read_u8(handle, &data->maxmandmcs); + func->read_u8(handle, &data->txant); + func->read_u8(handle, &data->rxant); + func->read_u16(handle, &reserved); + + return data; +} + +/* */ +static void * +capwap_80211n_radioconf_element_clone(void *data) +{ + ASSERT(data != NULL); + + return capwap_clone(data, sizeof(struct capwap_80211n_radioconf_element)); +} + +/* */ +static void +capwap_80211n_radioconf_element_free(void* data) +{ + ASSERT(data != NULL); + + capwap_free(data); +} + +/* */ +struct capwap_message_elements_ops capwap_element_80211n_radioconf_ops = { + .create_message_element = capwap_80211n_radioconf_element_create, + .parsing_message_element = capwap_80211n_radioconf_element_parsing, + .clone_message_element = capwap_80211n_radioconf_element_clone, + .free_message_element = capwap_80211n_radioconf_element_free +}; diff --git a/src/common/capwap_element_80211n_radioconf.h b/src/common/capwap_element_80211n_radioconf.h new file mode 100644 index 0000000..ba5e659 --- /dev/null +++ b/src/common/capwap_element_80211n_radioconf.h @@ -0,0 +1,25 @@ +#ifndef __CAPWAP_ELEMENT_80211N_RADIO_CONF_HEADER__ +#define __CAPWAP_ELEMENT_80211N_RADIO_CONF_HEADER__ + +#define CAPWAP_ELEMENT_80211N_RADIO_CONF 1046 + +#define CAPWAP_80211N_RADIO_CONF_A_MSDU (1 << 7) +#define CAPWAP_80211N_RADIO_CONF_A_MPDU (1 << 6) +#define CAPWAP_80211N_RADIO_CONF_11N_ONLY (1 << 5) +#define CAPWAP_80211N_RADIO_CONF_SHORT_GUARD_INTERVAL (1 << 4) +#define CAPWAP_80211N_RADIO_CONF_20MHZ_BANDWITH (1 << 3) + +#define CAPWAP_80211N_RADIO_CONF_MASK 0xF8 + +struct capwap_80211n_radioconf_element { + uint8_t radioid; + uint8_t flags; + uint8_t maxsupmcs; + uint8_t maxmandmcs; + uint8_t txant; + uint8_t rxant; +}; + +extern struct capwap_message_elements_ops capwap_element_80211n_radioconf_ops; + +#endif /* __CAPWAP_ELEMENT_80211N_RADIO_CONF_HEADER__ */ diff --git a/src/common/capwap_element_80211n_station_information.c b/src/common/capwap_element_80211n_station_information.c new file mode 100644 index 0000000..02007bb --- /dev/null +++ b/src/common/capwap_element_80211n_station_information.c @@ -0,0 +1,102 @@ +#include "capwap.h" +#include "capwap_element.h" + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MAC Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MAC Address |S| P |T|F|H|M| | Max RxFactor | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Min StaSpacing| HiSuppDataRate | AMPDUBufSize | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | AMPDUBufSize | HtcSupp | MCS Set | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MCS Set | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MCS Set | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Type: TBD2 for IEEE 802.11n Station Information + * + */ + +/* */ +static void +capwap_80211n_station_info_element_create(void *data, + capwap_message_elements_handle handle, + struct capwap_write_message_elements_ops *func) +{ + struct capwap_80211n_station_info_element *element = (struct capwap_80211n_station_info_element *)data; + + ASSERT(data != NULL); + + func->write_block(handle, &element->address, MACADDRESS_EUI48_LENGTH); + func->write_u8(handle, element->flags); + func->write_u8(handle, element->maxrxfactor); + func->write_u8(handle, element->minstaspaceing); + func->write_u16(handle, element->hisuppdatarate); + func->write_u16(handle, element->ampdubufsize); + func->write_u8(handle, element->htcsupp); + func->write_block(handle, &element->mcsset, MCS_SET_LENGTH); +} + +/* */ +static void * +capwap_80211n_station_info_element_parsing(capwap_message_elements_handle handle, + struct capwap_read_message_elements_ops *func) +{ + struct capwap_80211n_station_info_element *data; + uint16_t reserved; + + ASSERT(handle != NULL); + ASSERT(func != NULL); + + if (func->read_ready(handle) != 24) { + capwap_logging_debug("Invalid IEEE 802.11n Station Information"); + return NULL; + } + + /* */ + data = (struct capwap_80211n_station_info_element*)capwap_alloc(sizeof(struct capwap_80211n_station_info_element)); + memset(data, 0, sizeof(struct capwap_80211n_station_info_element)); + + /* Retrieve data */ + func->read_block(handle, &data->address, MACADDRESS_EUI48_LENGTH); + func->read_u8(handle, &data->flags); + func->read_u8(handle, &data->maxrxfactor); + func->read_u8(handle, &data->minstaspaceing); + func->read_u16(handle, &data->hisuppdatarate); + func->read_u16(handle, &data->ampdubufsize); + func->read_u8(handle, &data->htcsupp); + func->read_block(handle, &data->mcsset, MCS_SET_LENGTH); + + return data; +} + +/* */ +static void * +capwap_80211n_station_info_element_clone(void *data) +{ + ASSERT(data != NULL); + + return capwap_clone(data, sizeof(struct capwap_80211n_station_info_element)); +} + +/* */ +static void +capwap_80211n_station_info_element_free(void* data) +{ + ASSERT(data != NULL); + + capwap_free(data); +} + +/* */ +struct capwap_message_elements_ops capwap_element_80211n_station_info_ops = { + .create_message_element = capwap_80211n_station_info_element_create, + .parsing_message_element = capwap_80211n_station_info_element_parsing, + .clone_message_element = capwap_80211n_station_info_element_clone, + .free_message_element = capwap_80211n_station_info_element_free +}; diff --git a/src/common/capwap_element_80211n_station_information.h b/src/common/capwap_element_80211n_station_information.h new file mode 100644 index 0000000..107f1f2 --- /dev/null +++ b/src/common/capwap_element_80211n_station_information.h @@ -0,0 +1,28 @@ +#ifndef __CAPWAP_ELEMENT_80211N_STATION_INFO_HEADER__ +#define __CAPWAP_ELEMENT_80211N_STATION_INFO_HEADER__ + +#define CAPWAP_ELEMENT_80211N_STATION_INFO 1046 + +#define CAPWAP_80211N_STATION_INFO_40MHZ_BANDWITH (1 << 7) +#define CAPWAP_80211N_STATION_INFO_POWER_SAVE_MODE ((1 << 6) | (1 << 5)) +#define CAPWAP_80211N_STATION_INFO_SHORT_GUARD_INTERVAL_AT_20MHZ (1 << 4) +#define CAPWAP_80211N_STATION_INFO_SHORT_GUARD_INTERVAL_AT_40MHZ (1 << 3) +#define CAPWAP_80211N_STATION_INFO_BLOCK_ACK_DELAY_MODE (1 << 2) +#define CAPWAP_80211N_STATION_INFO_MAX_AMSDU_LENGTH_7935 (1 << 1) + +#define MCS_SET_LENGTH 10 + +struct capwap_80211n_station_info_element { + uint8_t address[MACADDRESS_EUI48_LENGTH]; + uint8_t flags; + uint8_t maxrxfactor; + uint8_t minstaspaceing; + uint16_t hisuppdatarate; + uint16_t ampdubufsize; + uint8_t htcsupp; + uint8_t mcsset[MCS_SET_LENGTH]; +}; + +extern struct capwap_message_elements_ops capwap_element_80211n_station_info_ops; + +#endif /* __CAPWAP_ELEMENT_80211N_STATION_INFO_HEADER__ */ diff --git a/src/common/capwap_element_vendorpayload.c b/src/common/capwap_element_vendorpayload.c index 161fb19..2626969 100644 --- a/src/common/capwap_element_vendorpayload.c +++ b/src/common/capwap_element_vendorpayload.c @@ -56,9 +56,33 @@ static void capwap_vendorpayload_element_free(void* data) { capwap_free(data); } + /* */ -static void* capwap_vendorpayload_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { +static void * +capwap_unknown_vendorpayload_element_parsing(capwap_message_elements_handle handle, + struct capwap_read_message_elements_ops *func, + unsigned short length, + uint32_t vendorid, uint16_t elementid) +{ + /* Retrieve data */ + data = (struct capwap_vendorpayload_element*)capwap_alloc(sizeof(struct capwap_vendorpayload_element)); + data->data = (uint8_t*)capwap_alloc(length); + data->vendorid = vendorid; + data->elementid = elementid; + data->datalength = length; + func->read_block(handle, data->data, length); + + return data; +} + +/* */ +static void * +capwap_vendorpayload_element_parsing(capwap_message_elements_handle handle, + struct capwap_read_message_elements_ops *func) +{ unsigned short length; + uint32_t vendorid; + uint16_t elementid; struct capwap_vendorpayload_element* data; ASSERT(handle != NULL); @@ -76,13 +100,25 @@ static void* capwap_vendorpayload_element_parsing(capwap_message_elements_handle return NULL; } - /* Retrieve data */ - data = (struct capwap_vendorpayload_element*)capwap_alloc(sizeof(struct capwap_vendorpayload_element)); - data->data = (uint8_t*)capwap_alloc(length); - func->read_u32(handle, &data->vendorid); - func->read_u16(handle, &data->elementid); - data->datalength = length; - func->read_block(handle, data->data, length); + func->read_u32(handle, &vendorid); + func->read_u16(handle, &elementid); + + switch (vendorid) { + case VENDOR_TRAVELPING: + switch (elementid) { + case VENDOR_TRAVELPING_ELEMENT_80211N_RADIO_CONF: + case VENDOR_TRAVELPING_ELEMENT_80211N_STATION_INFO: + default: + data = capwap_unknown_vendorpayload_element_parsing(handle, func, length, + vendorid, elementid); + break; + } + break; + default: + data = capwap_unknown_vendorpayload_element_parsing(handle, func, length, + vendorid, elementid); + break; + } return data; } diff --git a/src/common/capwap_element_vendorpayload.h b/src/common/capwap_element_vendorpayload.h index 03e9119..ef6ee9d 100644 --- a/src/common/capwap_element_vendorpayload.h +++ b/src/common/capwap_element_vendorpayload.h @@ -1,6 +1,10 @@ #ifndef __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__ #define __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__ +#define VENDOR_TRAVELPING 18681 +#define VENDOR_TRAVELPING_ELEMENT_80211N_RADIO_CONF 123 +#define VENDOR_TRAVELPING_ELEMENT_80211N_STATION_INFO 124 + #define CAPWAP_ELEMENT_VENDORPAYLOAD 37 #define CAPWAP_VENDORPAYLOAD_MAXLENGTH 2048