From bb449e7ec6c5cdb2ad4e08be0e38024791d636e2 Mon Sep 17 00:00:00 2001 From: vemax78 Date: Sat, 11 May 2013 15:07:30 +0200 Subject: [PATCH] implement several 80211 element --- build/Makefile_common.am | 9 ++ src/common/capwap_element.c | 26 ++-- src/common/capwap_element.h | 9 ++ src/common/capwap_element_80211_antenna.c | 114 ++++++++++++++++++ src/common/capwap_element_80211_antenna.h | 38 ++++++ ...pwap_element_80211_directsequencecontrol.c | 95 +++++++++++++++ ...pwap_element_80211_directsequencecontrol.h | 30 +++++ .../capwap_element_80211_macoperation.c | 108 +++++++++++++++++ .../capwap_element_80211_macoperation.h | 27 +++++ ...pwap_element_80211_multidomaincapability.c | 95 +++++++++++++++ ...pwap_element_80211_multidomaincapability.h | 24 ++++ src/common/capwap_element_80211_ofdmcontrol.c | 95 +++++++++++++++ src/common/capwap_element_80211_ofdmcontrol.h | 32 +++++ src/common/capwap_element_80211_rateset.c | 104 ++++++++++++++++ src/common/capwap_element_80211_rateset.h | 26 ++++ .../capwap_element_80211_supportedrates.c | 104 ++++++++++++++++ .../capwap_element_80211_supportedrates.h | 26 ++++ src/common/capwap_element_80211_txpower.c | 86 +++++++++++++ src/common/capwap_element_80211_txpower.h | 22 ++++ .../capwap_element_80211_txpowerlevel.c | 109 +++++++++++++++++ .../capwap_element_80211_txpowerlevel.h | 25 ++++ src/wtp/wtp.h | 12 +- 22 files changed, 1202 insertions(+), 14 deletions(-) create mode 100644 src/common/capwap_element_80211_antenna.c create mode 100644 src/common/capwap_element_80211_antenna.h create mode 100644 src/common/capwap_element_80211_directsequencecontrol.c create mode 100644 src/common/capwap_element_80211_directsequencecontrol.h create mode 100644 src/common/capwap_element_80211_macoperation.c create mode 100644 src/common/capwap_element_80211_macoperation.h create mode 100644 src/common/capwap_element_80211_multidomaincapability.c create mode 100644 src/common/capwap_element_80211_multidomaincapability.h create mode 100644 src/common/capwap_element_80211_ofdmcontrol.c create mode 100644 src/common/capwap_element_80211_ofdmcontrol.h create mode 100644 src/common/capwap_element_80211_rateset.c create mode 100644 src/common/capwap_element_80211_rateset.h create mode 100644 src/common/capwap_element_80211_supportedrates.c create mode 100644 src/common/capwap_element_80211_supportedrates.h create mode 100644 src/common/capwap_element_80211_txpower.c create mode 100644 src/common/capwap_element_80211_txpower.h create mode 100644 src/common/capwap_element_80211_txpowerlevel.c create mode 100644 src/common/capwap_element_80211_txpowerlevel.h diff --git a/build/Makefile_common.am b/build/Makefile_common.am index 59a9438..9b66a1f 100755 --- a/build/Makefile_common.am +++ b/build/Makefile_common.am @@ -62,6 +62,15 @@ capwap_SOURCES = \ $(top_srcdir)/src/common/capwap_element_idletimeout.c \ $(top_srcdir)/src/common/capwap_element_wtpfallback.c \ $(top_srcdir)/src/common/capwap_element_radiooprstate.c \ + $(top_srcdir)/src/common/capwap_element_80211_antenna.c \ + $(top_srcdir)/src/common/capwap_element_80211_directsequencecontrol.c \ + $(top_srcdir)/src/common/capwap_element_80211_macoperation.c \ + $(top_srcdir)/src/common/capwap_element_80211_multidomaincapability.c \ + $(top_srcdir)/src/common/capwap_element_80211_ofdmcontrol.c \ + $(top_srcdir)/src/common/capwap_element_80211_rateset.c \ + $(top_srcdir)/src/common/capwap_element_80211_supportedrates.c \ + $(top_srcdir)/src/common/capwap_element_80211_txpower.c \ + $(top_srcdir)/src/common/capwap_element_80211_txpowerlevel.c \ $(top_srcdir)/src/common/capwap_element_80211_wtpradioinformation.c if DEBUG_BUILD diff --git a/src/common/capwap_element.c b/src/common/capwap_element.c index 568073a..1a89fce 100644 --- a/src/common/capwap_element.c +++ b/src/common/capwap_element.c @@ -61,24 +61,24 @@ static struct capwap_message_elements_func standard_message_elements[CAPWAP_MESS static struct capwap_message_elements_func ieee80211_message_elements[CAPWAP_80211_MESSAGE_ELEMENTS_COUNT] = { /* */ { NULL, NULL }, + /* CAPWAP_ELEMENT_80211_ANTENNA */ { capwap_80211_antenna_element_create, capwap_80211_antenna_element_validate, capwap_80211_antenna_element_parsing, capwap_80211_antenna_element_free }, + /* */ { NULL, NULL }, + /* */ { NULL, NULL }, + /* CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL */ { capwap_80211_dscontrol_element_create, capwap_80211_dscontrol_element_validate, capwap_80211_dscontrol_element_parsing, capwap_80211_dscontrol_element_free }, + /* */ { NULL, NULL }, + /* CAPWAP_ELEMENT_80211_MACOPERATION */ { capwap_80211_macoperation_element_create, capwap_80211_macoperation_element_validate, capwap_80211_macoperation_element_parsing, capwap_80211_macoperation_element_free }, + /* */ { NULL, NULL }, + /* CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY */ { capwap_80211_multidomaincapability_element_create, capwap_80211_multidomaincapability_element_validate, capwap_80211_multidomaincapability_element_parsing, capwap_80211_multidomaincapability_element_free }, + /* CAPWAP_ELEMENT_80211_OFDMCONTROL */ { capwap_80211_ofdmcontrol_element_create, capwap_80211_ofdmcontrol_element_validate, capwap_80211_ofdmcontrol_element_parsing, capwap_80211_ofdmcontrol_element_free }, + /* CAPWAP_ELEMENT_80211_RATESET */ { capwap_80211_rateset_element_create, capwap_80211_rateset_element_validate, capwap_80211_rateset_element_parsing, capwap_80211_rateset_element_free }, /* */ { NULL, NULL }, /* */ { NULL, NULL }, /* */ { NULL, NULL }, /* */ { NULL, NULL }, /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, - /* */ { NULL, NULL }, + /* CAPWAP_ELEMENT_80211_SUPPORTEDRATES */ { capwap_80211_supportedrates_element_create, capwap_80211_supportedrates_element_validate, capwap_80211_supportedrates_element_parsing, capwap_80211_supportedrates_element_free }, + /* CAPWAP_ELEMENT_80211_TXPOWER */ { capwap_80211_txpower_element_create, capwap_80211_txpower_element_validate, capwap_80211_txpower_element_parsing, capwap_80211_txpower_element_free }, + /* CAPWAP_ELEMENT_80211_TXPOWERLEVEL */ { capwap_80211_txpowerlevel_element_create, capwap_80211_txpowerlevel_element_validate, capwap_80211_txpowerlevel_element_parsing, capwap_80211_txpowerlevel_element_free }, /* */ { NULL, NULL }, /* */ { NULL, NULL }, /* */ { NULL, NULL }, diff --git a/src/common/capwap_element.h b/src/common/capwap_element.h index aebd2d8..40bf21b 100644 --- a/src/common/capwap_element.h +++ b/src/common/capwap_element.h @@ -94,6 +94,15 @@ struct capwap_message_elements_func* capwap_get_message_element(unsigned long co #include "capwap_element_ecnsupport.h" /* 00053 */ /* IEEE 802.11 message elements */ +#include "capwap_element_80211_antenna.h" /* 01025 */ +#include "capwap_element_80211_directsequencecontrol.h" /* 01028 */ +#include "capwap_element_80211_macoperation.h" /* 01030 */ +#include "capwap_element_80211_multidomaincapability.h" /* 01032 */ +#include "capwap_element_80211_ofdmcontrol.h" /* 01033 */ +#include "capwap_element_80211_rateset.h" /* 01034 */ +#include "capwap_element_80211_supportedrates.h" /* 01040 */ +#include "capwap_element_80211_txpower.h" /* 01041 */ +#include "capwap_element_80211_txpowerlevel.h" /* 01042 */ #include "capwap_element_80211_wtpradioinformation.h" /* 01048 */ /*********************************************************************************************************************/ diff --git a/src/common/capwap_element_80211_antenna.c b/src/common/capwap_element_80211_antenna.c new file mode 100644 index 0000000..d6bf385 --- /dev/null +++ b/src/common/capwap_element_80211_antenna.c @@ -0,0 +1,114 @@ +#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 | Diversity | Combiner | Antenna Cnt | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Antenna Selection... ++-+-+-+-+-+-+-+-+ + +Type: 1025 for IEEE 802.11 Antenna + +Length: >= 5 + +********************************************************************/ + +struct capwap_80211_antenna_raw_element { + unsigned char radioid; + unsigned char diversity; + unsigned char combiner; + unsigned char antennacount; + unsigned char antennaselections[0]; +} __attribute__((__packed__)); + +/* */ +struct capwap_message_element* capwap_80211_antenna_element_create(void* data, unsigned long datalength) { + int i; + unsigned short antennalength; + struct capwap_message_element* element; + struct capwap_80211_antenna_raw_element* dataraw; + struct capwap_80211_antenna_element* dataelement = (struct capwap_80211_antenna_element*)data; + + ASSERT(data != NULL); + ASSERT(datalength >= sizeof(struct capwap_80211_antenna_element)); + + /* Alloc block of memory */ + antennalength = dataelement->antennacount * sizeof(unsigned char); + element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_antenna_raw_element) + antennalength); + if (!element) { + capwap_outofmemory(); + } + + /* Create message element */ + memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_antenna_raw_element) + antennalength); + element->type = htons(CAPWAP_ELEMENT_80211_ANTENNA); + element->length = htons(sizeof(struct capwap_80211_antenna_raw_element) + antennalength); + dataraw = (struct capwap_80211_antenna_raw_element*)element->data; + + dataraw->radioid = dataelement->radioid; + dataraw->diversity = dataelement->diversity; + dataraw->combiner = dataelement->combiner; + dataraw->antennacount = dataelement->antennacount; + for (i = 0; i < dataelement->antennacount; i++) { + dataraw->antennaselections[i] = dataelement->antennaselections[i]; + } + + return element; +} + +/* */ +int capwap_80211_antenna_element_validate(struct capwap_message_element* element) { + /* TODO */ + return 1; +} + +/* */ +void* capwap_80211_antenna_element_parsing(struct capwap_message_element* element) { + int i; + unsigned short antennalength; + struct capwap_80211_antenna_element* data; + struct capwap_80211_antenna_raw_element* dataraw; + + ASSERT(element); + ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_ANTENNA); + + antennalength = ntohs(element->length); + if (antennalength < 5) { + return NULL; + } + + antennalength -= sizeof(struct capwap_80211_antenna_raw_element); + if (antennalength > CAPWAP_ANTENNASELECTIONS_MAXLENGTH) { + return NULL; + } + + dataraw = (struct capwap_80211_antenna_raw_element*)element->data; + + /* */ + data = (struct capwap_80211_antenna_element*)capwap_alloc(sizeof(struct capwap_80211_antenna_element)); + if (!data) { + capwap_outofmemory(); + } + + /* */ + data->radioid = dataraw->radioid; + data->diversity = dataraw->diversity; + data->combiner = dataraw->combiner; + data->antennacount = dataraw->antennacount; + for (i = 0; i < dataraw->antennacount; i++) { + data->antennaselections[i] = dataraw->antennaselections[i]; + } + + return data; +} + +/* */ +void capwap_80211_antenna_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} diff --git a/src/common/capwap_element_80211_antenna.h b/src/common/capwap_element_80211_antenna.h new file mode 100644 index 0000000..98031ab --- /dev/null +++ b/src/common/capwap_element_80211_antenna.h @@ -0,0 +1,38 @@ +#ifndef __CAPWAP_ELEMENT_80211_ANTENNA_HEADER__ +#define __CAPWAP_ELEMENT_80211_ANTENNA_HEADER__ + +#define CAPWAP_ELEMENT_80211_ANTENNA 1025 + +#define CAPWAP_ANTENNASELECTIONS_MAXLENGTH 255 + +struct capwap_80211_antenna_element { + unsigned char radioid; + unsigned char diversity; + unsigned char combiner; + unsigned char antennacount; + unsigned char antennaselections[CAPWAP_ANTENNASELECTIONS_MAXLENGTH]; +}; + +#define CAPWAP_ANTENNA_DIVERSITY_DISABLE 0 +#define CAPWAP_ANTENNA_DIVERSITY_ENABLE 1 + +#define CAPWAP_ANTENNA_COMBINER_SECT_LEFT 1 +#define CAPWAP_ANTENNA_COMBINER_SECT_RIGHT 2 +#define CAPWAP_ANTENNA_COMBINER_SECT_OMNI 3 +#define CAPWAP_ANTENNA_COMBINER_SECT_MIMO 4 + +#define CAPWAP_ANTENNA_INTERNAL 1 +#define CAPWAP_ANTENNA_EXTERNAL 2 + +struct capwap_message_element* capwap_80211_antenna_element_create(void* data, unsigned long length); +int capwap_80211_antenna_element_validate(struct capwap_message_element* element); +void* capwap_80211_antenna_element_parsing(struct capwap_message_element* element); +void capwap_80211_antenna_element_free(void* data); + +/* Helper */ +#define CAPWAP_CREATE_80211_ANTENNA_ELEMENT(x) ({ \ + struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_ANTENNA); \ + f->create(x, sizeof(struct capwap_80211_antenna_element)); \ + }) + +#endif /* __CAPWAP_ELEMENT_80211_ANTENNA_HEADER__ */ diff --git a/src/common/capwap_element_80211_directsequencecontrol.c b/src/common/capwap_element_80211_directsequencecontrol.c new file mode 100644 index 0000000..6316915 --- /dev/null +++ b/src/common/capwap_element_80211_directsequencecontrol.c @@ -0,0 +1,95 @@ +#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 | Reserved | Current Chan | Current CCA | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Energy Detect Threshold | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 1028 for IEEE 802.11 Direct Sequence Control + +Length: 8 + +********************************************************************/ + +struct capwap_80211_directsequencecontrol_raw_element { + unsigned char radioid; + unsigned char reserved; + unsigned char currentchannel; + unsigned char currentcca; + unsigned long enerydetectthreshold; +} __attribute__((__packed__)); + +/* */ +struct capwap_message_element* capwap_80211_dscontrol_element_create(void* data, unsigned long datalength) { + struct capwap_message_element* element; + struct capwap_80211_directsequencecontrol_raw_element* dataraw; + struct capwap_80211_directsequencecontrol_element* dataelement = (struct capwap_80211_directsequencecontrol_element*)data; + + ASSERT(data != NULL); + ASSERT(datalength >= sizeof(struct capwap_80211_directsequencecontrol_element)); + + /* Alloc block of memory */ + element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_directsequencecontrol_raw_element)); + if (!element) { + capwap_outofmemory(); + } + + /* Create message element */ + memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_directsequencecontrol_raw_element)); + element->type = htons(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL); + element->length = htons(sizeof(struct capwap_80211_directsequencecontrol_raw_element)); + dataraw = (struct capwap_80211_directsequencecontrol_raw_element*)element->data; + + dataraw->radioid = dataelement->radioid; + dataraw->currentchannel = dataelement->currentchannel; + dataraw->currentcca = dataelement->currentcca; + dataraw->enerydetectthreshold = htonl(dataelement->enerydetectthreshold); + return element; +} + +/* */ +int capwap_80211_dscontrol_element_validate(struct capwap_message_element* element) { + /* TODO */ + return 1; +} + +/* */ +void* capwap_80211_dscontrol_element_parsing(struct capwap_message_element* element) { + struct capwap_80211_directsequencecontrol_element* data; + struct capwap_80211_directsequencecontrol_raw_element* dataraw; + + ASSERT(element); + ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL); + + if (ntohs(element->length) != 8) { + return NULL; + } + + dataraw = (struct capwap_80211_directsequencecontrol_raw_element*)element->data; + + /* */ + data = (struct capwap_80211_directsequencecontrol_element*)capwap_alloc(sizeof(struct capwap_80211_directsequencecontrol_element)); + if (!data) { + capwap_outofmemory(); + } + + /* */ + data->radioid = dataraw->radioid; + data->currentchannel = dataraw->currentchannel; + data->currentcca = dataraw->currentcca; + data->enerydetectthreshold = ntohl(dataraw->enerydetectthreshold); + return data; +} + +/* */ +void capwap_80211_dscontrol_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} diff --git a/src/common/capwap_element_80211_directsequencecontrol.h b/src/common/capwap_element_80211_directsequencecontrol.h new file mode 100644 index 0000000..db99ddf --- /dev/null +++ b/src/common/capwap_element_80211_directsequencecontrol.h @@ -0,0 +1,30 @@ +#ifndef __CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL_HEADER__ +#define __CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL_HEADER__ + +#define CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL 1028 + +struct capwap_80211_directsequencecontrol_element { + unsigned char radioid; + unsigned char currentchannel; + unsigned char currentcca; + unsigned long enerydetectthreshold; +}; + +#define CAPWAP_DSCONTROL_CCA_EDONLY 1 +#define CAPWAP_DSCONTROL_CCA_CSONLY 2 +#define CAPWAP_DSCONTROL_CCA_EDANDCS 4 +#define CAPWAP_DSCONTROL_CCA_CSWITHTIME 8 +#define CAPWAP_DSCONTROL_CCA_HRCSANDED 16 + +struct capwap_message_element* capwap_80211_dscontrol_element_create(void* data, unsigned long length); +int capwap_80211_dscontrol_element_validate(struct capwap_message_element* element); +void* capwap_80211_dscontrol_element_parsing(struct capwap_message_element* element); +void capwap_80211_dscontrol_element_free(void* data); + +/* Helper */ +#define CAPWAP_CREATE_80211_DIRECTSEQUENCECONTROL_ELEMENT(x) ({ \ + struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL); \ + f->create(x, sizeof(struct capwap_80211_directsequencecontrol_element)); \ + }) + +#endif /* __CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL_HEADER__ */ diff --git a/src/common/capwap_element_80211_macoperation.c b/src/common/capwap_element_80211_macoperation.c new file mode 100644 index 0000000..ceca243 --- /dev/null +++ b/src/common/capwap_element_80211_macoperation.c @@ -0,0 +1,108 @@ +#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 | Reserved | RTS Threshold | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Short Retry | Long Retry | Fragmentation Threshold | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Tx MSDU Lifetime | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Rx MSDU Lifetime | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 1030 for IEEE 802.11 MAC Operation + +Length: 16 + +********************************************************************/ + +struct capwap_80211_macoperation_raw_element { + unsigned char radioid; + unsigned char reserved; + unsigned short rtsthreshold; + unsigned char shortretry; + unsigned char longretry; + unsigned short fragthreshold; + unsigned long txmsdulifetime; + unsigned long rxmsdulifetime; +} __attribute__((__packed__)); + +/* */ +struct capwap_message_element* capwap_80211_macoperation_element_create(void* data, unsigned long datalength) { + struct capwap_message_element* element; + struct capwap_80211_macoperation_raw_element* dataraw; + struct capwap_80211_macoperation_element* dataelement = (struct capwap_80211_macoperation_element*)data; + + ASSERT(data != NULL); + ASSERT(datalength >= sizeof(struct capwap_80211_macoperation_element)); + + /* Alloc block of memory */ + element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_macoperation_raw_element)); + if (!element) { + capwap_outofmemory(); + } + + /* Create message element */ + memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_macoperation_raw_element)); + element->type = htons(CAPWAP_ELEMENT_80211_MACOPERATION); + element->length = htons(sizeof(struct capwap_80211_macoperation_raw_element)); + dataraw = (struct capwap_80211_macoperation_raw_element*)element->data; + + dataraw->radioid = dataelement->radioid; + dataraw->rtsthreshold = htons(dataelement->rtsthreshold); + dataraw->shortretry = dataelement->shortretry; + dataraw->longretry = dataelement->longretry; + dataraw->fragthreshold = htons(dataelement->fragthreshold); + dataraw->txmsdulifetime = htonl(dataelement->txmsdulifetime); + dataraw->rxmsdulifetime = htonl(dataelement->rxmsdulifetime); + return element; +} + +/* */ +int capwap_80211_macoperation_element_validate(struct capwap_message_element* element) { + /* TODO */ + return 1; +} + +/* */ +void* capwap_80211_macoperation_element_parsing(struct capwap_message_element* element) { + struct capwap_80211_macoperation_element* data; + struct capwap_80211_macoperation_raw_element* dataraw; + + ASSERT(element); + ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_MACOPERATION); + + if (ntohs(element->length) != 16) { + return NULL; + } + + dataraw = (struct capwap_80211_macoperation_raw_element*)element->data; + + /* */ + data = (struct capwap_80211_macoperation_element*)capwap_alloc(sizeof(struct capwap_80211_macoperation_element)); + if (!data) { + capwap_outofmemory(); + } + + /* */ + data->radioid = dataraw->radioid; + data->rtsthreshold = ntohs(dataraw->rtsthreshold); + data->shortretry = dataraw->shortretry; + data->longretry = dataraw->longretry; + data->fragthreshold = ntohs(dataraw->fragthreshold); + data->txmsdulifetime = ntohl(dataraw->txmsdulifetime); + data->rxmsdulifetime = ntohl(dataraw->rxmsdulifetime); + return data; +} + +/* */ +void capwap_80211_macoperation_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} diff --git a/src/common/capwap_element_80211_macoperation.h b/src/common/capwap_element_80211_macoperation.h new file mode 100644 index 0000000..cf9656a --- /dev/null +++ b/src/common/capwap_element_80211_macoperation.h @@ -0,0 +1,27 @@ +#ifndef __CAPWAP_ELEMENT_80211_MACOPERATION_HEADER__ +#define __CAPWAP_ELEMENT_80211_MACOPERATION_HEADER__ + +#define CAPWAP_ELEMENT_80211_MACOPERATION 1030 + +struct capwap_80211_macoperation_element { + unsigned char radioid; + unsigned short rtsthreshold; + unsigned char shortretry; + unsigned char longretry; + unsigned short fragthreshold; + unsigned long txmsdulifetime; + unsigned long rxmsdulifetime; +}; + +struct capwap_message_element* capwap_80211_macoperation_element_create(void* data, unsigned long length); +int capwap_80211_macoperation_element_validate(struct capwap_message_element* element); +void* capwap_80211_macoperation_element_parsing(struct capwap_message_element* element); +void capwap_80211_macoperation_element_free(void* data); + +/* Helper */ +#define CAPWAP_CREATE_80211_MACOPERATION_ELEMENT(x) ({ \ + struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_MACOPERATION); \ + f->create(x, sizeof(struct capwap_80211_macoperation_element)); \ + }) + +#endif /* __CAPWAP_ELEMENT_80211_MACOPERATION_HEADER__ */ diff --git a/src/common/capwap_element_80211_multidomaincapability.c b/src/common/capwap_element_80211_multidomaincapability.c new file mode 100644 index 0000000..3073ab2 --- /dev/null +++ b/src/common/capwap_element_80211_multidomaincapability.c @@ -0,0 +1,95 @@ +#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 | Reserved | First Channel # | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Number of Channels | Max Tx Power Level | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 1032 for IEEE 802.11 Multi-Domain Capability + +Length: 8 + +********************************************************************/ + +struct capwap_80211_multidomaincapability_raw_element { + unsigned char radioid; + unsigned char reserved; + unsigned short firstchannel; + unsigned short numberchannels; + unsigned short maxtxpowerlevel; +} __attribute__((__packed__)); + +/* */ +struct capwap_message_element* capwap_80211_multidomaincapability_element_create(void* data, unsigned long datalength) { + struct capwap_message_element* element; + struct capwap_80211_multidomaincapability_raw_element* dataraw; + struct capwap_80211_multidomaincapability_element* dataelement = (struct capwap_80211_multidomaincapability_element*)data; + + ASSERT(data != NULL); + ASSERT(datalength >= sizeof(struct capwap_80211_multidomaincapability_element)); + + /* Alloc block of memory */ + element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_multidomaincapability_raw_element)); + if (!element) { + capwap_outofmemory(); + } + + /* Create message element */ + memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_multidomaincapability_raw_element)); + element->type = htons(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY); + element->length = htons(sizeof(struct capwap_80211_multidomaincapability_raw_element)); + dataraw = (struct capwap_80211_multidomaincapability_raw_element*)element->data; + + dataraw->radioid = dataelement->radioid; + dataraw->firstchannel = htons(dataelement->firstchannel); + dataraw->numberchannels = htons(dataelement->numberchannels); + dataraw->maxtxpowerlevel = htons(dataelement->maxtxpowerlevel); + return element; +} + +/* */ +int capwap_80211_multidomaincapability_element_validate(struct capwap_message_element* element) { + /* TODO */ + return 1; +} + +/* */ +void* capwap_80211_multidomaincapability_element_parsing(struct capwap_message_element* element) { + struct capwap_80211_multidomaincapability_element* data; + struct capwap_80211_multidomaincapability_raw_element* dataraw; + + ASSERT(element); + ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY); + + if (ntohs(element->length) != 8) { + return NULL; + } + + dataraw = (struct capwap_80211_multidomaincapability_raw_element*)element->data; + + /* */ + data = (struct capwap_80211_multidomaincapability_element*)capwap_alloc(sizeof(struct capwap_80211_multidomaincapability_element)); + if (!data) { + capwap_outofmemory(); + } + + /* */ + data->radioid = dataraw->radioid; + data->firstchannel = ntohs(dataraw->firstchannel); + data->numberchannels = htons(dataraw->numberchannels); + data->maxtxpowerlevel = htons(dataraw->maxtxpowerlevel); + return data; +} + +/* */ +void capwap_80211_multidomaincapability_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} diff --git a/src/common/capwap_element_80211_multidomaincapability.h b/src/common/capwap_element_80211_multidomaincapability.h new file mode 100644 index 0000000..af446a1 --- /dev/null +++ b/src/common/capwap_element_80211_multidomaincapability.h @@ -0,0 +1,24 @@ +#ifndef __CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY_HEADER__ +#define __CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY_HEADER__ + +#define CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY 1032 + +struct capwap_80211_multidomaincapability_element { + unsigned char radioid; + unsigned short firstchannel; + unsigned short numberchannels; + unsigned short maxtxpowerlevel; +}; + +struct capwap_message_element* capwap_80211_multidomaincapability_element_create(void* data, unsigned long length); +int capwap_80211_multidomaincapability_element_validate(struct capwap_message_element* element); +void* capwap_80211_multidomaincapability_element_parsing(struct capwap_message_element* element); +void capwap_80211_multidomaincapability_element_free(void* data); + +/* Helper */ +#define CAPWAP_CREATE_80211_MULTIDOMAINCAPABILITY_ELEMENT(x) ({ \ + struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY); \ + f->create(x, sizeof(struct capwap_80211_multidomaincapability_element)); \ + }) + +#endif /* __CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY_HEADER__ */ diff --git a/src/common/capwap_element_80211_ofdmcontrol.c b/src/common/capwap_element_80211_ofdmcontrol.c new file mode 100644 index 0000000..015acb1 --- /dev/null +++ b/src/common/capwap_element_80211_ofdmcontrol.c @@ -0,0 +1,95 @@ +#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 | Reserved | Current Chan | Band Support | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| TI Threshold | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 1033 for IEEE 802.11 OFDM Control + +Length: 8 + +********************************************************************/ + +struct capwap_80211_ofdmcontrol_raw_element { + unsigned char radioid; + unsigned char reserved; + unsigned char currentchannel; + unsigned char bandsupport; + unsigned long tithreshold; +} __attribute__((__packed__)); + +/* */ +struct capwap_message_element* capwap_80211_ofdmcontrol_element_create(void* data, unsigned long datalength) { + struct capwap_message_element* element; + struct capwap_80211_ofdmcontrol_raw_element* dataraw; + struct capwap_80211_ofdmcontrol_element* dataelement = (struct capwap_80211_ofdmcontrol_element*)data; + + ASSERT(data != NULL); + ASSERT(datalength >= sizeof(struct capwap_80211_ofdmcontrol_element)); + + /* Alloc block of memory */ + element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_ofdmcontrol_raw_element)); + if (!element) { + capwap_outofmemory(); + } + + /* Create message element */ + memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_ofdmcontrol_raw_element)); + element->type = htons(CAPWAP_ELEMENT_80211_OFDMCONTROL); + element->length = htons(sizeof(struct capwap_80211_ofdmcontrol_raw_element)); + dataraw = (struct capwap_80211_ofdmcontrol_raw_element*)element->data; + + dataraw->radioid = dataelement->radioid; + dataraw->currentchannel = dataelement->currentchannel; + dataraw->bandsupport = dataelement->bandsupport; + dataraw->tithreshold = htonl(dataelement->tithreshold); + return element; +} + +/* */ +int capwap_80211_ofdmcontrol_element_validate(struct capwap_message_element* element) { + /* TODO */ + return 1; +} + +/* */ +void* capwap_80211_ofdmcontrol_element_parsing(struct capwap_message_element* element) { + struct capwap_80211_ofdmcontrol_element* data; + struct capwap_80211_ofdmcontrol_raw_element* dataraw; + + ASSERT(element); + ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_OFDMCONTROL); + + if (ntohs(element->length) != 8) { + return NULL; + } + + dataraw = (struct capwap_80211_ofdmcontrol_raw_element*)element->data; + + /* */ + data = (struct capwap_80211_ofdmcontrol_element*)capwap_alloc(sizeof(struct capwap_80211_ofdmcontrol_element)); + if (!data) { + capwap_outofmemory(); + } + + /* */ + data->radioid = dataraw->radioid; + data->currentchannel = ntohs(dataraw->currentchannel); + data->bandsupport = ntohs(dataraw->bandsupport); + data->tithreshold = ntohl(dataraw->tithreshold); + return data; +} + +/* */ +void capwap_80211_ofdmcontrol_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} diff --git a/src/common/capwap_element_80211_ofdmcontrol.h b/src/common/capwap_element_80211_ofdmcontrol.h new file mode 100644 index 0000000..3ceafab --- /dev/null +++ b/src/common/capwap_element_80211_ofdmcontrol.h @@ -0,0 +1,32 @@ +#ifndef __CAPWAP_ELEMENT_80211_OFDMCONTROL_HEADER__ +#define __CAPWAP_ELEMENT_80211_OFDMCONTROL_HEADER__ + +#define CAPWAP_ELEMENT_80211_OFDMCONTROL 1033 + +struct capwap_80211_ofdmcontrol_element { + unsigned char radioid; + unsigned char currentchannel; + unsigned char bandsupport; + unsigned long tithreshold; +}; + +#define CAPWAP_OFDMCONTROL_BAND_515_525 0x01 +#define CAPWAP_OFDMCONTROL_BAND_525_535 0x02 +#define CAPWAP_OFDMCONTROL_BAND_5725_5825 0x04 +#define CAPWAP_OFDMCONTROL_BAND_547_5725 0x08 +#define CAPWAP_OFDMCONTROL_BAND_JP_525 0x10 +#define CAPWAP_OFDMCONTROL_BAND_503_5091 0x20 +#define CAPWAP_OFDMCONTROL_BAND_494_499 0x40 + +struct capwap_message_element* capwap_80211_ofdmcontrol_element_create(void* data, unsigned long length); +int capwap_80211_ofdmcontrol_element_validate(struct capwap_message_element* element); +void* capwap_80211_ofdmcontrol_element_parsing(struct capwap_message_element* element); +void capwap_80211_ofdmcontrol_element_free(void* data); + +/* Helper */ +#define CAPWAP_CREATE_80211_OFDMCONTROL_ELEMENT(x) ({ \ + struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_OFDMCONTROL); \ + f->create(x, sizeof(struct capwap_80211_ofdmcontrol_element)); \ + }) + +#endif /* __CAPWAP_ELEMENT_80211_OFDMCONTROL_HEADER__ */ diff --git a/src/common/capwap_element_80211_rateset.c b/src/common/capwap_element_80211_rateset.c new file mode 100644 index 0000000..5eabc7b --- /dev/null +++ b/src/common/capwap_element_80211_rateset.c @@ -0,0 +1,104 @@ +#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 | Rate Set... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 1034 for IEEE 802.11 Rate Set + +Length: >= 3 + +********************************************************************/ + +struct capwap_80211_rateset_raw_element { + unsigned char radioid; + unsigned char rateset[0]; +} __attribute__((__packed__)); + +/* */ +struct capwap_message_element* capwap_80211_rateset_element_create(void* data, unsigned long datalength) { + int i; + unsigned short ratesetlength; + struct capwap_message_element* element; + struct capwap_80211_rateset_raw_element* dataraw; + struct capwap_80211_rateset_element* dataelement = (struct capwap_80211_rateset_element*)data; + + ASSERT(data != NULL); + ASSERT(datalength >= sizeof(struct capwap_80211_rateset_element)); + + /* Alloc block of memory */ + ratesetlength = dataelement->ratesetcount * sizeof(unsigned char); + element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_rateset_raw_element) + ratesetlength); + if (!element) { + capwap_outofmemory(); + } + + /* Create message element */ + memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_rateset_raw_element) + ratesetlength); + element->type = htons(CAPWAP_ELEMENT_80211_RATESET); + element->length = htons(sizeof(struct capwap_80211_rateset_raw_element) + ratesetlength); + dataraw = (struct capwap_80211_rateset_raw_element*)element->data; + + dataraw->radioid = dataelement->radioid; + for (i = 0; i < dataelement->ratesetcount; i++) { + dataraw->rateset[i] = dataelement->rateset[i]; + } + + return element; +} + +/* */ +int capwap_80211_rateset_element_validate(struct capwap_message_element* element) { + /* TODO */ + return 1; +} + +/* */ +void* capwap_80211_rateset_element_parsing(struct capwap_message_element* element) { + int i; + unsigned short ratesetlength; + struct capwap_80211_rateset_element* data; + struct capwap_80211_rateset_raw_element* dataraw; + + ASSERT(element); + ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_RATESET); + + ratesetlength = ntohs(element->length); + if (ratesetlength < 3) { + return NULL; + } + + ratesetlength -= sizeof(struct capwap_80211_rateset_raw_element); + if (ratesetlength > CAPWAP_SUPPORTEDRATES_MAXLENGTH) { + return NULL; + } + + dataraw = (struct capwap_80211_rateset_raw_element*)element->data; + + /* */ + data = (struct capwap_80211_rateset_element*)capwap_alloc(sizeof(struct capwap_80211_rateset_element)); + if (!data) { + capwap_outofmemory(); + } + + /* */ + data->radioid = dataraw->radioid; + data->ratesetcount = ratesetlength; + for (i = 0; i < ratesetlength; i++) { + data->rateset[i] = dataraw->rateset[i]; + } + + return data; +} + +/* */ +void capwap_80211_rateset_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} diff --git a/src/common/capwap_element_80211_rateset.h b/src/common/capwap_element_80211_rateset.h new file mode 100644 index 0000000..bfd4d75 --- /dev/null +++ b/src/common/capwap_element_80211_rateset.h @@ -0,0 +1,26 @@ +#ifndef __CAPWAP_ELEMENT_80211_RATESET_HEADER__ +#define __CAPWAP_ELEMENT_80211_RATESET_HEADER__ + +#define CAPWAP_ELEMENT_80211_RATESET 1034 + +#define CAPWAP_RATESET_MINLENGTH 2 +#define CAPWAP_RATESET_MAXLENGTH 8 + +struct capwap_80211_rateset_element { + unsigned char radioid; + unsigned char ratesetcount; + unsigned char rateset[CAPWAP_RATESET_MAXLENGTH]; +}; + +struct capwap_message_element* capwap_80211_rateset_element_create(void* data, unsigned long length); +int capwap_80211_rateset_element_validate(struct capwap_message_element* element); +void* capwap_80211_rateset_element_parsing(struct capwap_message_element* element); +void capwap_80211_rateset_element_free(void* data); + +/* Helper */ +#define CAPWAP_CREATE_80211_RATESET_ELEMENT(x) ({ \ + struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_RATESET); \ + f->create(x, sizeof(struct capwap_80211_rateset_element)); \ + }) + +#endif /* __CAPWAP_ELEMENT_80211_RATESET_HEADER__ */ diff --git a/src/common/capwap_element_80211_supportedrates.c b/src/common/capwap_element_80211_supportedrates.c new file mode 100644 index 0000000..7be22d3 --- /dev/null +++ b/src/common/capwap_element_80211_supportedrates.c @@ -0,0 +1,104 @@ +#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 | Supported Rates... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 1040 for IEEE 802.11 Supported Rates + +Length: >= 3 + +********************************************************************/ + +struct capwap_80211_supportedrates_raw_element { + unsigned char radioid; + unsigned char supportedrates[0]; +} __attribute__((__packed__)); + +/* */ +struct capwap_message_element* capwap_80211_supportedrates_element_create(void* data, unsigned long datalength) { + int i; + unsigned short supportedrateslength; + struct capwap_message_element* element; + struct capwap_80211_supportedrates_raw_element* dataraw; + struct capwap_80211_supportedrates_element* dataelement = (struct capwap_80211_supportedrates_element*)data; + + ASSERT(data != NULL); + ASSERT(datalength >= sizeof(struct capwap_80211_supportedrates_element)); + + /* Alloc block of memory */ + supportedrateslength = dataelement->supportedratescount * sizeof(unsigned char); + element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_supportedrates_raw_element) + supportedrateslength); + if (!element) { + capwap_outofmemory(); + } + + /* Create message element */ + memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_supportedrates_raw_element) + supportedrateslength); + element->type = htons(CAPWAP_ELEMENT_80211_SUPPORTEDRATES); + element->length = htons(sizeof(struct capwap_80211_supportedrates_raw_element) + supportedrateslength); + dataraw = (struct capwap_80211_supportedrates_raw_element*)element->data; + + dataraw->radioid = dataelement->radioid; + for (i = 0; i < dataelement->supportedratescount; i++) { + dataraw->supportedrates[i] = dataelement->supportedrates[i]; + } + + return element; +} + +/* */ +int capwap_80211_supportedrates_element_validate(struct capwap_message_element* element) { + /* TODO */ + return 1; +} + +/* */ +void* capwap_80211_supportedrates_element_parsing(struct capwap_message_element* element) { + int i; + unsigned short supportedrateslength; + struct capwap_80211_supportedrates_element* data; + struct capwap_80211_supportedrates_raw_element* dataraw; + + ASSERT(element); + ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_SUPPORTEDRATES); + + supportedrateslength = ntohs(element->length); + if (supportedrateslength < 3) { + return NULL; + } + + supportedrateslength -= sizeof(struct capwap_80211_supportedrates_raw_element); + if (supportedrateslength > CAPWAP_SUPPORTEDRATES_MAXLENGTH) { + return NULL; + } + + dataraw = (struct capwap_80211_supportedrates_raw_element*)element->data; + + /* */ + data = (struct capwap_80211_supportedrates_element*)capwap_alloc(sizeof(struct capwap_80211_supportedrates_element)); + if (!data) { + capwap_outofmemory(); + } + + /* */ + data->radioid = dataraw->radioid; + data->supportedratescount = supportedrateslength; + for (i = 0; i < supportedrateslength; i++) { + data->supportedrates[i] = dataraw->supportedrates[i]; + } + + return data; +} + +/* */ +void capwap_80211_supportedrates_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} diff --git a/src/common/capwap_element_80211_supportedrates.h b/src/common/capwap_element_80211_supportedrates.h new file mode 100644 index 0000000..75bb8cd --- /dev/null +++ b/src/common/capwap_element_80211_supportedrates.h @@ -0,0 +1,26 @@ +#ifndef __CAPWAP_ELEMENT_80211_SUPPORTEDRATES_HEADER__ +#define __CAPWAP_ELEMENT_80211_SUPPORTEDRATES_HEADER__ + +#define CAPWAP_ELEMENT_80211_SUPPORTEDRATES 1040 + +#define CAPWAP_SUPPORTEDRATES_MINLENGTH 2 +#define CAPWAP_SUPPORTEDRATES_MAXLENGTH 8 + +struct capwap_80211_supportedrates_element { + unsigned char radioid; + unsigned char supportedratescount; + unsigned char supportedrates[CAPWAP_SUPPORTEDRATES_MAXLENGTH]; +}; + +struct capwap_message_element* capwap_80211_supportedrates_element_create(void* data, unsigned long length); +int capwap_80211_supportedrates_element_validate(struct capwap_message_element* element); +void* capwap_80211_supportedrates_element_parsing(struct capwap_message_element* element); +void capwap_80211_supportedrates_element_free(void* data); + +/* Helper */ +#define CAPWAP_CREATE_80211_SUPPORTEDRATES_ELEMENT(x) ({ \ + struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_SUPPORTEDRATES); \ + f->create(x, sizeof(struct capwap_80211_supportedrates_element)); \ + }) + +#endif /* __CAPWAP_ELEMENT_80211_SUPPORTEDRATES_HEADER__ */ diff --git a/src/common/capwap_element_80211_txpower.c b/src/common/capwap_element_80211_txpower.c new file mode 100644 index 0000000..8b4fd18 --- /dev/null +++ b/src/common/capwap_element_80211_txpower.c @@ -0,0 +1,86 @@ +#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 | Reserved | Current Tx Power | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 1041 for IEEE 802.11 Tx Power + +Length: 4 + +********************************************************************/ + +struct capwap_80211_txpower_raw_element { + unsigned char radioid; + unsigned short currenttxpower; +} __attribute__((__packed__)); + +/* */ +struct capwap_message_element* capwap_80211_txpower_element_create(void* data, unsigned long datalength) { + struct capwap_message_element* element; + struct capwap_80211_txpower_raw_element* dataraw; + struct capwap_80211_txpower_element* dataelement = (struct capwap_80211_txpower_element*)data; + + ASSERT(data != NULL); + ASSERT(datalength >= sizeof(struct capwap_80211_txpower_element)); + + /* Alloc block of memory */ + element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_txpower_raw_element)); + if (!element) { + capwap_outofmemory(); + } + + /* Create message element */ + memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_txpower_raw_element)); + element->type = htons(CAPWAP_ELEMENT_80211_TXPOWER); + element->length = htons(sizeof(struct capwap_80211_txpower_raw_element)); + dataraw = (struct capwap_80211_txpower_raw_element*)element->data; + + dataraw->radioid = dataelement->radioid; + dataraw->currenttxpower = htons(dataelement->currenttxpower); + return element; +} + +/* */ +int capwap_80211_txpower_element_validate(struct capwap_message_element* element) { + /* TODO */ + return 1; +} + +/* */ +void* capwap_80211_txpower_element_parsing(struct capwap_message_element* element) { + struct capwap_80211_txpower_element* data; + struct capwap_80211_txpower_raw_element* dataraw; + + ASSERT(element); + ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_TXPOWER); + + if (ntohs(element->length) != 4) { + return NULL; + } + + dataraw = (struct capwap_80211_txpower_raw_element*)element->data; + + /* */ + data = (struct capwap_80211_txpower_element*)capwap_alloc(sizeof(struct capwap_80211_txpower_element)); + if (!data) { + capwap_outofmemory(); + } + + /* */ + data->radioid = dataraw->radioid; + data->currenttxpower = ntohs(dataraw->currenttxpower); + return data; +} + +/* */ +void capwap_80211_txpower_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} diff --git a/src/common/capwap_element_80211_txpower.h b/src/common/capwap_element_80211_txpower.h new file mode 100644 index 0000000..e3f8526 --- /dev/null +++ b/src/common/capwap_element_80211_txpower.h @@ -0,0 +1,22 @@ +#ifndef __CAPWAP_ELEMENT_80211_TXPOWER_HEADER__ +#define __CAPWAP_ELEMENT_80211_TXPOWER_HEADER__ + +#define CAPWAP_ELEMENT_80211_TXPOWER 1041 + +struct capwap_80211_txpower_element { + unsigned char radioid; + unsigned short currenttxpower; +}; + +struct capwap_message_element* capwap_80211_txpower_element_create(void* data, unsigned long length); +int capwap_80211_txpower_element_validate(struct capwap_message_element* element); +void* capwap_80211_txpower_element_parsing(struct capwap_message_element* element); +void capwap_80211_txpower_element_free(void* data); + +/* Helper */ +#define CAPWAP_CREATE_80211_TXPOWER_ELEMENT(x) ({ \ + struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_TXPOWER); \ + f->create(x, sizeof(struct capwap_80211_txpower_element)); \ + }) + +#endif /* __CAPWAP_ELEMENT_80211_TXPOWER_HEADER__ */ diff --git a/src/common/capwap_element_80211_txpowerlevel.c b/src/common/capwap_element_80211_txpowerlevel.c new file mode 100644 index 0000000..95d447b --- /dev/null +++ b/src/common/capwap_element_80211_txpowerlevel.c @@ -0,0 +1,109 @@ +#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 | Num Levels | Power Level [n] | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 1042 for IEEE 802.11 Tx Power Level + +Length: >= 4 + +********************************************************************/ + +struct capwap_80211_txpowerlevel_raw_element { + unsigned char radioid; + unsigned char numlevels; + unsigned short powerlevel[0]; +} __attribute__((__packed__)); + +/* */ +struct capwap_message_element* capwap_80211_txpowerlevel_element_create(void* data, unsigned long datalength) { + int i; + unsigned short txpowerlength; + struct capwap_message_element* element; + struct capwap_80211_txpowerlevel_raw_element* dataraw; + struct capwap_80211_txpowerlevel_element* dataelement = (struct capwap_80211_txpowerlevel_element*)data; + + ASSERT(data != NULL); + ASSERT(datalength >= sizeof(struct capwap_80211_txpowerlevel_element)); + + /* Alloc block of memory */ + txpowerlength = dataelement->numlevels * sizeof(unsigned char); + element = capwap_alloc(sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_txpowerlevel_raw_element) + txpowerlength); + if (!element) { + capwap_outofmemory(); + } + + /* Create message element */ + memset(element, 0, sizeof(struct capwap_message_element) + sizeof(struct capwap_80211_txpowerlevel_raw_element) + txpowerlength); + element->type = htons(CAPWAP_ELEMENT_80211_TXPOWERLEVEL); + element->length = htons(sizeof(struct capwap_80211_txpowerlevel_raw_element) + txpowerlength); + dataraw = (struct capwap_80211_txpowerlevel_raw_element*)element->data; + + dataraw->radioid = dataelement->radioid; + dataraw->numlevels = dataelement->numlevels; + for (i = 0; i < dataelement->numlevels; i++) { + dataraw->powerlevel[i] = htons(dataelement->powerlevel[i]); + } + + return element; +} + +/* */ +int capwap_80211_txpowerlevel_element_validate(struct capwap_message_element* element) { + /* TODO */ + return 1; +} + +/* */ +void* capwap_80211_txpowerlevel_element_parsing(struct capwap_message_element* element) { + int i; + unsigned short txpowerlength; + struct capwap_80211_txpowerlevel_element* data; + struct capwap_80211_txpowerlevel_raw_element* dataraw; + + ASSERT(element); + ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_80211_TXPOWERLEVEL); + + txpowerlength = ntohs(element->length); + if (txpowerlength < 4) { + return NULL; + } + + txpowerlength -= sizeof(struct capwap_80211_txpowerlevel_raw_element); + if (txpowerlength > (CAPWAP_TXPOWERLEVEL_MAXLENGTH * sizeof(unsigned short))) { + return NULL; + } + + dataraw = (struct capwap_80211_txpowerlevel_raw_element*)element->data; + if ((dataraw->numlevels < 1) || (dataraw->numlevels > CAPWAP_TXPOWERLEVEL_MAXLENGTH)) { + return NULL; + } + + /* */ + data = (struct capwap_80211_txpowerlevel_element*)capwap_alloc(sizeof(struct capwap_80211_txpowerlevel_element)); + if (!data) { + capwap_outofmemory(); + } + + /* */ + data->radioid = dataraw->radioid; + data->numlevels = dataraw->numlevels; + for (i = 0; i < dataraw->numlevels; i++) { + data->powerlevel[i] = dataraw->powerlevel[i]; + } + + return data; +} + +/* */ +void capwap_80211_txpowerlevel_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} diff --git a/src/common/capwap_element_80211_txpowerlevel.h b/src/common/capwap_element_80211_txpowerlevel.h new file mode 100644 index 0000000..3ee39e3 --- /dev/null +++ b/src/common/capwap_element_80211_txpowerlevel.h @@ -0,0 +1,25 @@ +#ifndef __CAPWAP_ELEMENT_80211_TXPOWERLEVEL_HEADER__ +#define __CAPWAP_ELEMENT_80211_TXPOWERLEVEL_HEADER__ + +#define CAPWAP_ELEMENT_80211_TXPOWERLEVEL 1042 + +#define CAPWAP_TXPOWERLEVEL_MAXLENGTH 8 + +struct capwap_80211_txpowerlevel_element { + unsigned char radioid; + unsigned char numlevels; + unsigned short powerlevel[CAPWAP_TXPOWERLEVEL_MAXLENGTH]; +}; + +struct capwap_message_element* capwap_80211_txpowerlevel_element_create(void* data, unsigned long length); +int capwap_80211_txpowerlevel_element_validate(struct capwap_message_element* element); +void* capwap_80211_txpowerlevel_element_parsing(struct capwap_message_element* element); +void capwap_80211_txpowerlevel_element_free(void* data); + +/* Helper */ +#define CAPWAP_CREATE_80211_TXPOWERLEVEL_ELEMENT(x) ({ \ + struct capwap_message_elements_func* f = capwap_get_message_element(CAPWAP_ELEMENT_80211_TXPOWERLEVEL); \ + f->create(x, sizeof(struct capwap_80211_txpowerlevel_element)); \ + }) + +#endif /* __CAPWAP_ELEMENT_80211_TXPOWERLEVEL_HEADER__ */ diff --git a/src/wtp/wtp.h b/src/wtp/wtp.h index 633b370..8b35997 100644 --- a/src/wtp/wtp.h +++ b/src/wtp/wtp.h @@ -137,8 +137,15 @@ struct wtp_t { struct wtp_radio { char device[IFNAMSIZ]; - struct capwap_80211_wtpradioinformation_element radioinformation; int status; + + struct capwap_80211_antenna_element antenna; + struct capwap_80211_directsequencecontrol_element directsequencecontrol; + struct capwap_80211_macoperation_element macoperation; + struct capwap_80211_multidomaincapability_element multidomaincapability; + struct capwap_80211_ofdmcontrol_element ofdmcontrol; + struct capwap_80211_supportedrates_element supportedrates; + struct capwap_80211_wtpradioinformation_element radioinformation; }; extern struct wtp_t g_wtp; @@ -146,4 +153,7 @@ 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); + #endif /* __CAPWAP_WTP_HEADER__ */