remove dos style newlines
This commit is contained in:
@ -1,470 +1,470 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static struct ac_json_ieee80211_ops* ac_json_80211_message_elements[] = {
|
||||
/* CAPWAP_ELEMENT_80211_ADD_WLAN */ &ac_json_80211_addwlan_ops,
|
||||
/* CAPWAP_ELEMENT_80211_ANTENNA */ &ac_json_80211_antenna_ops,
|
||||
/* CAPWAP_ELEMENT_80211_ASSIGN_BSSID */ &ac_json_80211_assignbssid_ops,
|
||||
/* CAPWAP_ELEMENT_80211_DELETE_WLAN */ &ac_json_80211_deletewlan_ops,
|
||||
/* CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL */ &ac_json_80211_directsequencecontrol_ops,
|
||||
/* CAPWAP_ELEMENT_80211_IE */ &ac_json_80211_ie_ops,
|
||||
/* CAPWAP_ELEMENT_80211_MACOPERATION */ &ac_json_80211_macoperation_ops,
|
||||
/* CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES */ &ac_json_80211_miccountermeasures_ops,
|
||||
/* CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY */ &ac_json_80211_multidomaincapability_ops,
|
||||
/* CAPWAP_ELEMENT_80211_OFDMCONTROL */ &ac_json_80211_ofdmcontrol_ops,
|
||||
/* CAPWAP_ELEMENT_80211_RATESET */ &ac_json_80211_rateset_ops,
|
||||
/* CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT */ &ac_json_80211_rsnaerrorreport_ops,
|
||||
/* CAPWAP_ELEMENT_80211_STATION */ NULL,
|
||||
/* CAPWAP_ELEMENT_80211_STATION_QOS_PROFILE */ NULL,
|
||||
/* CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_PROFILE */ NULL,
|
||||
/* CAPWAP_ELEMENT_80211_STATISTICS */ &ac_json_80211_statistics_ops,
|
||||
/* CAPWAP_ELEMENT_80211_SUPPORTEDRATES */ &ac_json_80211_supportedrates_ops,
|
||||
/* CAPWAP_ELEMENT_80211_TXPOWER */ &ac_json_80211_txpower_ops,
|
||||
/* CAPWAP_ELEMENT_80211_TXPOWERLEVEL */ &ac_json_80211_txpowerlevel_ops,
|
||||
/* CAPWAP_ELEMENT_80211_UPDATE_STATION_QOS */ NULL,
|
||||
/* CAPWAP_ELEMENT_80211_UPDATE_WLAN */ &ac_json_80211_updatewlan_ops,
|
||||
/* CAPWAP_ELEMENT_80211_WTP_QOS */ &ac_json_80211_wtpqos_ops,
|
||||
/* CAPWAP_ELEMENT_80211_WTP_RADIO_CONF */ &ac_json_80211_wtpradioconf_ops,
|
||||
/* CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM */ &ac_json_80211_wtpradiofailalarm_ops,
|
||||
/* CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION */ &ac_json_80211_wtpradioinformation_ops
|
||||
};
|
||||
|
||||
/* */
|
||||
static struct ac_json_ieee80211_ops* ac_json_80211_getops_by_capwaptype(uint16_t type) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CAPWAP_80211_MESSAGE_ELEMENTS_COUNT; i++) {
|
||||
if (ac_json_80211_message_elements[i] && (ac_json_80211_message_elements[i]->type == type)) {
|
||||
return ac_json_80211_message_elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
static struct ac_json_ieee80211_ops* ac_json_80211_getops_by_jsontype(char* type) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CAPWAP_80211_MESSAGE_ELEMENTS_COUNT; i++) {
|
||||
if (ac_json_80211_message_elements[i] && !strcmp(ac_json_80211_message_elements[i]->json_type, type)) {
|
||||
return ac_json_80211_message_elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_json_ieee80211_init(struct ac_json_ieee80211_wtpradio* wtpradio) {
|
||||
ASSERT(wtpradio != NULL);
|
||||
|
||||
memset(wtpradio, 0, sizeof(struct ac_json_ieee80211_wtpradio));
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_json_ieee80211_free(struct ac_json_ieee80211_wtpradio* wtpradio) {
|
||||
int i, j;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
|
||||
|
||||
if (item->valid) {
|
||||
if (item->addwlan) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ADD_WLAN)->free_message_element(item->addwlan);
|
||||
}
|
||||
|
||||
if (item->antenna) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ANTENNA)->free_message_element(item->antenna);
|
||||
}
|
||||
|
||||
if (item->assignbssid) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ASSIGN_BSSID)->free_message_element(item->assignbssid);
|
||||
}
|
||||
|
||||
if (item->deletewlan) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DELETE_WLAN)->free_message_element(item->deletewlan);
|
||||
}
|
||||
|
||||
if (item->directsequencecontrol) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL)->free_message_element(item->directsequencecontrol);
|
||||
}
|
||||
|
||||
if (item->iearray) {
|
||||
struct capwap_message_elements_ops* ieops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_IE);
|
||||
|
||||
for (j = 0; j < item->iearray->count; j++) {
|
||||
ieops->free_message_element(*(struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, j));
|
||||
}
|
||||
|
||||
capwap_array_free(item->iearray);
|
||||
}
|
||||
|
||||
if (item->macoperation) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MACOPERATION)->free_message_element(item->macoperation);
|
||||
}
|
||||
|
||||
if (item->miccountermeasures) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES)->free_message_element(item->miccountermeasures);
|
||||
}
|
||||
|
||||
if (item->multidomaincapability) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY)->free_message_element(item->multidomaincapability);
|
||||
}
|
||||
|
||||
if (item->ofdmcontrol) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_OFDMCONTROL)->free_message_element(item->ofdmcontrol);
|
||||
}
|
||||
|
||||
if (item->rateset) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RATESET)->free_message_element(item->rateset);
|
||||
}
|
||||
|
||||
if (item->rsnaerrorreport) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT)->free_message_element(item->rsnaerrorreport);
|
||||
}
|
||||
|
||||
if (item->statistics) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_STATISTICS)->free_message_element(item->statistics);
|
||||
}
|
||||
|
||||
if (item->supportedrates) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_SUPPORTEDRATES)->free_message_element(item->supportedrates);
|
||||
}
|
||||
|
||||
if (item->txpower) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWER)->free_message_element(item->txpower);
|
||||
}
|
||||
|
||||
if (item->txpowerlevel) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWERLEVEL)->free_message_element(item->txpowerlevel);
|
||||
}
|
||||
|
||||
if (item->updatewlan) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_UPDATE_WLAN)->free_message_element(item->updatewlan);
|
||||
}
|
||||
|
||||
if (item->wtpqos) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_QOS)->free_message_element(item->wtpqos);
|
||||
}
|
||||
|
||||
if (item->wtpradioconf) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF)->free_message_element(item->wtpradioconf);
|
||||
}
|
||||
|
||||
if (item->wtpradiofailalarm) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM)->free_message_element(item->wtpradiofailalarm);
|
||||
}
|
||||
|
||||
if (item->wtpradioinformation) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)->free_message_element(item->wtpradioinformation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_json_ieee80211_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, uint16_t type, void* data, int overwrite) {
|
||||
struct ac_json_ieee80211_ops* ops;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
ASSERT(IS_80211_MESSAGE_ELEMENTS(type));
|
||||
ASSERT(data != NULL);
|
||||
|
||||
/* */
|
||||
ops = ac_json_80211_getops_by_capwaptype(type);
|
||||
if (!ops) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ops->add_message_element(wtpradio, data, overwrite);
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_json_ieee80211_parsingmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_message_element_itemlist* messageelement) {
|
||||
int i;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
ASSERT(messageelement != NULL);
|
||||
ASSERT(IS_80211_MESSAGE_ELEMENTS(messageelement->type));
|
||||
|
||||
if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_SINGLE) {
|
||||
if (!ac_json_ieee80211_addmessageelement(wtpradio, messageelement->type, messageelement->data, 0)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_ARRAY) {
|
||||
struct capwap_array* items = (struct capwap_array*)messageelement->data;
|
||||
|
||||
for (i = 0; i < items->count; i++) {
|
||||
if (!ac_json_ieee80211_addmessageelement(wtpradio, messageelement->type, *(void**)capwap_array_get_item_pointer(items, i), 0)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_json_ieee80211_parsingjson(struct ac_json_ieee80211_wtpradio* wtpradio, struct json_object* jsonroot) {
|
||||
int i;
|
||||
int length;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
ASSERT(jsonroot != NULL);
|
||||
|
||||
if (json_object_get_type(jsonroot) != json_type_array) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
length = json_object_array_length(jsonroot);
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonitem;
|
||||
struct json_object* jsonradio = json_object_array_get_idx(jsonroot, i);
|
||||
|
||||
/* Get RadioID */
|
||||
jsonitem = compat_json_object_object_get(jsonradio, "RadioID");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
int radioid = json_object_get_int(jsonitem);
|
||||
if (IS_VALID_RADIOID(radioid)) {
|
||||
struct lh_entry* entry;
|
||||
|
||||
/* Parsing every entry */
|
||||
for(entry = json_object_get_object(jsonradio)->head; entry != NULL; entry = entry->next) {
|
||||
struct ac_json_ieee80211_ops* ops = ac_json_80211_getops_by_jsontype((char*)entry->k); /* Retrieve JSON handler */
|
||||
if (ops) {
|
||||
void* data = ops->create_message_element((struct json_object*)entry->v, radioid);
|
||||
if (data) {
|
||||
/* Message element complete */
|
||||
ac_json_ieee80211_addmessageelement(wtpradio, ops->type, data, 1);
|
||||
|
||||
/* Free resource */
|
||||
capwap_get_message_element_ops(ops->type)->free_message_element(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct json_object* ac_json_ieee80211_getjson(struct ac_json_ieee80211_wtpradio* wtpradio) {
|
||||
int i;
|
||||
struct json_object* jsonarray;
|
||||
struct json_object* jsonitems;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
|
||||
jsonarray = json_object_new_array();
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
|
||||
|
||||
if (!item->valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* */
|
||||
jsonitems = json_object_new_object();
|
||||
|
||||
/* Radio Id */
|
||||
json_object_object_add(jsonitems, "RadioID", json_object_new_int(i + 1));
|
||||
|
||||
if (item->addwlan) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ADD_WLAN)->create_json(jsonitems, item->addwlan);
|
||||
}
|
||||
|
||||
if (item->antenna) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ANTENNA)->create_json(jsonitems, item->antenna);
|
||||
}
|
||||
|
||||
if (item->assignbssid) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ASSIGN_BSSID)->create_json(jsonitems, item->assignbssid);
|
||||
}
|
||||
|
||||
if (item->deletewlan) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_DELETE_WLAN)->create_json(jsonitems, item->deletewlan);
|
||||
}
|
||||
|
||||
if (item->directsequencecontrol) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL)->create_json(jsonitems, item->directsequencecontrol);
|
||||
}
|
||||
|
||||
if (item->iearray) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_IE)->create_json(jsonitems, item->iearray);
|
||||
}
|
||||
|
||||
if (item->macoperation) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MACOPERATION)->create_json(jsonitems, item->macoperation);
|
||||
}
|
||||
|
||||
if (item->miccountermeasures) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES)->create_json(jsonitems, item->miccountermeasures);
|
||||
}
|
||||
|
||||
if (item->multidomaincapability) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY)->create_json(jsonitems, item->multidomaincapability);
|
||||
}
|
||||
|
||||
if (item->ofdmcontrol) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_OFDMCONTROL)->create_json(jsonitems, item->ofdmcontrol);
|
||||
}
|
||||
|
||||
if (item->rateset) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_RATESET)->create_json(jsonitems, item->rateset);
|
||||
}
|
||||
|
||||
if (item->rsnaerrorreport) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT)->create_json(jsonitems, item->rsnaerrorreport);
|
||||
}
|
||||
|
||||
if (item->statistics) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_STATISTICS)->create_json(jsonitems, item->statistics);
|
||||
}
|
||||
|
||||
if (item->supportedrates) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_SUPPORTEDRATES)->create_json(jsonitems, item->supportedrates);
|
||||
}
|
||||
|
||||
if (item->txpower) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_TXPOWER)->create_json(jsonitems, item->txpower);
|
||||
}
|
||||
|
||||
if (item->txpowerlevel) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_TXPOWERLEVEL)->create_json(jsonitems, item->txpowerlevel);
|
||||
}
|
||||
|
||||
if (item->updatewlan) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_UPDATE_WLAN)->create_json(jsonitems, item->updatewlan);
|
||||
}
|
||||
|
||||
if (item->wtpqos) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_QOS)->create_json(jsonitems, item->wtpqos);
|
||||
}
|
||||
|
||||
if (item->wtpradioconf) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF)->create_json(jsonitems, item->wtpradioconf);
|
||||
}
|
||||
|
||||
if (item->wtpradiofailalarm) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM)->create_json(jsonitems, item->wtpradiofailalarm);
|
||||
}
|
||||
|
||||
if (item->wtpradioinformation) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)->create_json(jsonitems, item->wtpradioinformation);
|
||||
}
|
||||
|
||||
/* */
|
||||
json_object_array_add(jsonarray, jsonitems);
|
||||
}
|
||||
|
||||
return jsonarray;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_json_ieee80211_buildpacket(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_packet_txmng* txmngpacket) {
|
||||
int i, j;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
ASSERT(txmngpacket != NULL);
|
||||
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
|
||||
|
||||
if (item->valid) {
|
||||
if (item->addwlan) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ADD_WLAN, item->addwlan);
|
||||
}
|
||||
|
||||
if (item->antenna) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ANTENNA, item->antenna);
|
||||
}
|
||||
|
||||
if (item->assignbssid) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ASSIGN_BSSID, item->assignbssid);
|
||||
}
|
||||
|
||||
if (item->deletewlan) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_DELETE_WLAN, item->deletewlan);
|
||||
}
|
||||
|
||||
if (item->directsequencecontrol) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL, item->directsequencecontrol);
|
||||
}
|
||||
|
||||
if (item->iearray) {
|
||||
for (j = 0; j < item->iearray->count; j++) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_IE, *(struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, j));
|
||||
}
|
||||
}
|
||||
|
||||
if (item->macoperation) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MACOPERATION, item->macoperation);
|
||||
}
|
||||
|
||||
if (item->miccountermeasures) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES, item->miccountermeasures);
|
||||
}
|
||||
|
||||
if (item->multidomaincapability) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY, item->multidomaincapability);
|
||||
}
|
||||
|
||||
if (item->ofdmcontrol) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_OFDMCONTROL, item->ofdmcontrol);
|
||||
}
|
||||
|
||||
if (item->rateset) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_RATESET, item->rateset);
|
||||
}
|
||||
|
||||
if (item->rsnaerrorreport) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT, item->rsnaerrorreport);
|
||||
}
|
||||
|
||||
if (item->statistics) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_STATISTICS, item->statistics);
|
||||
}
|
||||
|
||||
if (item->supportedrates) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_SUPPORTEDRATES, item->supportedrates);
|
||||
}
|
||||
|
||||
if (item->txpower) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_TXPOWER, item->txpower);
|
||||
}
|
||||
|
||||
if (item->txpowerlevel) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_TXPOWERLEVEL, item->txpowerlevel);
|
||||
}
|
||||
|
||||
if (item->updatewlan) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_UPDATE_WLAN, item->updatewlan);
|
||||
}
|
||||
|
||||
if (item->wtpqos) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_QOS, item->wtpqos);
|
||||
}
|
||||
|
||||
if (item->wtpradioconf) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_RADIO_CONF, item->wtpradioconf);
|
||||
}
|
||||
|
||||
if (item->wtpradiofailalarm) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM, item->wtpradiofailalarm);
|
||||
}
|
||||
|
||||
if (item->wtpradioinformation) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, item->wtpradioinformation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static struct ac_json_ieee80211_ops* ac_json_80211_message_elements[] = {
|
||||
/* CAPWAP_ELEMENT_80211_ADD_WLAN */ &ac_json_80211_addwlan_ops,
|
||||
/* CAPWAP_ELEMENT_80211_ANTENNA */ &ac_json_80211_antenna_ops,
|
||||
/* CAPWAP_ELEMENT_80211_ASSIGN_BSSID */ &ac_json_80211_assignbssid_ops,
|
||||
/* CAPWAP_ELEMENT_80211_DELETE_WLAN */ &ac_json_80211_deletewlan_ops,
|
||||
/* CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL */ &ac_json_80211_directsequencecontrol_ops,
|
||||
/* CAPWAP_ELEMENT_80211_IE */ &ac_json_80211_ie_ops,
|
||||
/* CAPWAP_ELEMENT_80211_MACOPERATION */ &ac_json_80211_macoperation_ops,
|
||||
/* CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES */ &ac_json_80211_miccountermeasures_ops,
|
||||
/* CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY */ &ac_json_80211_multidomaincapability_ops,
|
||||
/* CAPWAP_ELEMENT_80211_OFDMCONTROL */ &ac_json_80211_ofdmcontrol_ops,
|
||||
/* CAPWAP_ELEMENT_80211_RATESET */ &ac_json_80211_rateset_ops,
|
||||
/* CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT */ &ac_json_80211_rsnaerrorreport_ops,
|
||||
/* CAPWAP_ELEMENT_80211_STATION */ NULL,
|
||||
/* CAPWAP_ELEMENT_80211_STATION_QOS_PROFILE */ NULL,
|
||||
/* CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_PROFILE */ NULL,
|
||||
/* CAPWAP_ELEMENT_80211_STATISTICS */ &ac_json_80211_statistics_ops,
|
||||
/* CAPWAP_ELEMENT_80211_SUPPORTEDRATES */ &ac_json_80211_supportedrates_ops,
|
||||
/* CAPWAP_ELEMENT_80211_TXPOWER */ &ac_json_80211_txpower_ops,
|
||||
/* CAPWAP_ELEMENT_80211_TXPOWERLEVEL */ &ac_json_80211_txpowerlevel_ops,
|
||||
/* CAPWAP_ELEMENT_80211_UPDATE_STATION_QOS */ NULL,
|
||||
/* CAPWAP_ELEMENT_80211_UPDATE_WLAN */ &ac_json_80211_updatewlan_ops,
|
||||
/* CAPWAP_ELEMENT_80211_WTP_QOS */ &ac_json_80211_wtpqos_ops,
|
||||
/* CAPWAP_ELEMENT_80211_WTP_RADIO_CONF */ &ac_json_80211_wtpradioconf_ops,
|
||||
/* CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM */ &ac_json_80211_wtpradiofailalarm_ops,
|
||||
/* CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION */ &ac_json_80211_wtpradioinformation_ops
|
||||
};
|
||||
|
||||
/* */
|
||||
static struct ac_json_ieee80211_ops* ac_json_80211_getops_by_capwaptype(uint16_t type) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CAPWAP_80211_MESSAGE_ELEMENTS_COUNT; i++) {
|
||||
if (ac_json_80211_message_elements[i] && (ac_json_80211_message_elements[i]->type == type)) {
|
||||
return ac_json_80211_message_elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
static struct ac_json_ieee80211_ops* ac_json_80211_getops_by_jsontype(char* type) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CAPWAP_80211_MESSAGE_ELEMENTS_COUNT; i++) {
|
||||
if (ac_json_80211_message_elements[i] && !strcmp(ac_json_80211_message_elements[i]->json_type, type)) {
|
||||
return ac_json_80211_message_elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_json_ieee80211_init(struct ac_json_ieee80211_wtpradio* wtpradio) {
|
||||
ASSERT(wtpradio != NULL);
|
||||
|
||||
memset(wtpradio, 0, sizeof(struct ac_json_ieee80211_wtpradio));
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_json_ieee80211_free(struct ac_json_ieee80211_wtpradio* wtpradio) {
|
||||
int i, j;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
|
||||
|
||||
if (item->valid) {
|
||||
if (item->addwlan) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ADD_WLAN)->free_message_element(item->addwlan);
|
||||
}
|
||||
|
||||
if (item->antenna) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ANTENNA)->free_message_element(item->antenna);
|
||||
}
|
||||
|
||||
if (item->assignbssid) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ASSIGN_BSSID)->free_message_element(item->assignbssid);
|
||||
}
|
||||
|
||||
if (item->deletewlan) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DELETE_WLAN)->free_message_element(item->deletewlan);
|
||||
}
|
||||
|
||||
if (item->directsequencecontrol) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL)->free_message_element(item->directsequencecontrol);
|
||||
}
|
||||
|
||||
if (item->iearray) {
|
||||
struct capwap_message_elements_ops* ieops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_IE);
|
||||
|
||||
for (j = 0; j < item->iearray->count; j++) {
|
||||
ieops->free_message_element(*(struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, j));
|
||||
}
|
||||
|
||||
capwap_array_free(item->iearray);
|
||||
}
|
||||
|
||||
if (item->macoperation) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MACOPERATION)->free_message_element(item->macoperation);
|
||||
}
|
||||
|
||||
if (item->miccountermeasures) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES)->free_message_element(item->miccountermeasures);
|
||||
}
|
||||
|
||||
if (item->multidomaincapability) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY)->free_message_element(item->multidomaincapability);
|
||||
}
|
||||
|
||||
if (item->ofdmcontrol) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_OFDMCONTROL)->free_message_element(item->ofdmcontrol);
|
||||
}
|
||||
|
||||
if (item->rateset) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RATESET)->free_message_element(item->rateset);
|
||||
}
|
||||
|
||||
if (item->rsnaerrorreport) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT)->free_message_element(item->rsnaerrorreport);
|
||||
}
|
||||
|
||||
if (item->statistics) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_STATISTICS)->free_message_element(item->statistics);
|
||||
}
|
||||
|
||||
if (item->supportedrates) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_SUPPORTEDRATES)->free_message_element(item->supportedrates);
|
||||
}
|
||||
|
||||
if (item->txpower) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWER)->free_message_element(item->txpower);
|
||||
}
|
||||
|
||||
if (item->txpowerlevel) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWERLEVEL)->free_message_element(item->txpowerlevel);
|
||||
}
|
||||
|
||||
if (item->updatewlan) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_UPDATE_WLAN)->free_message_element(item->updatewlan);
|
||||
}
|
||||
|
||||
if (item->wtpqos) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_QOS)->free_message_element(item->wtpqos);
|
||||
}
|
||||
|
||||
if (item->wtpradioconf) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF)->free_message_element(item->wtpradioconf);
|
||||
}
|
||||
|
||||
if (item->wtpradiofailalarm) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM)->free_message_element(item->wtpradiofailalarm);
|
||||
}
|
||||
|
||||
if (item->wtpradioinformation) {
|
||||
capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)->free_message_element(item->wtpradioinformation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_json_ieee80211_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, uint16_t type, void* data, int overwrite) {
|
||||
struct ac_json_ieee80211_ops* ops;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
ASSERT(IS_80211_MESSAGE_ELEMENTS(type));
|
||||
ASSERT(data != NULL);
|
||||
|
||||
/* */
|
||||
ops = ac_json_80211_getops_by_capwaptype(type);
|
||||
if (!ops) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ops->add_message_element(wtpradio, data, overwrite);
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_json_ieee80211_parsingmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_message_element_itemlist* messageelement) {
|
||||
int i;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
ASSERT(messageelement != NULL);
|
||||
ASSERT(IS_80211_MESSAGE_ELEMENTS(messageelement->type));
|
||||
|
||||
if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_SINGLE) {
|
||||
if (!ac_json_ieee80211_addmessageelement(wtpradio, messageelement->type, messageelement->data, 0)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_ARRAY) {
|
||||
struct capwap_array* items = (struct capwap_array*)messageelement->data;
|
||||
|
||||
for (i = 0; i < items->count; i++) {
|
||||
if (!ac_json_ieee80211_addmessageelement(wtpradio, messageelement->type, *(void**)capwap_array_get_item_pointer(items, i), 0)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_json_ieee80211_parsingjson(struct ac_json_ieee80211_wtpradio* wtpradio, struct json_object* jsonroot) {
|
||||
int i;
|
||||
int length;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
ASSERT(jsonroot != NULL);
|
||||
|
||||
if (json_object_get_type(jsonroot) != json_type_array) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
length = json_object_array_length(jsonroot);
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonitem;
|
||||
struct json_object* jsonradio = json_object_array_get_idx(jsonroot, i);
|
||||
|
||||
/* Get RadioID */
|
||||
jsonitem = compat_json_object_object_get(jsonradio, "RadioID");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
int radioid = json_object_get_int(jsonitem);
|
||||
if (IS_VALID_RADIOID(radioid)) {
|
||||
struct lh_entry* entry;
|
||||
|
||||
/* Parsing every entry */
|
||||
for(entry = json_object_get_object(jsonradio)->head; entry != NULL; entry = entry->next) {
|
||||
struct ac_json_ieee80211_ops* ops = ac_json_80211_getops_by_jsontype((char*)entry->k); /* Retrieve JSON handler */
|
||||
if (ops) {
|
||||
void* data = ops->create_message_element((struct json_object*)entry->v, radioid);
|
||||
if (data) {
|
||||
/* Message element complete */
|
||||
ac_json_ieee80211_addmessageelement(wtpradio, ops->type, data, 1);
|
||||
|
||||
/* Free resource */
|
||||
capwap_get_message_element_ops(ops->type)->free_message_element(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct json_object* ac_json_ieee80211_getjson(struct ac_json_ieee80211_wtpradio* wtpradio) {
|
||||
int i;
|
||||
struct json_object* jsonarray;
|
||||
struct json_object* jsonitems;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
|
||||
jsonarray = json_object_new_array();
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
|
||||
|
||||
if (!item->valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* */
|
||||
jsonitems = json_object_new_object();
|
||||
|
||||
/* Radio Id */
|
||||
json_object_object_add(jsonitems, "RadioID", json_object_new_int(i + 1));
|
||||
|
||||
if (item->addwlan) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ADD_WLAN)->create_json(jsonitems, item->addwlan);
|
||||
}
|
||||
|
||||
if (item->antenna) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ANTENNA)->create_json(jsonitems, item->antenna);
|
||||
}
|
||||
|
||||
if (item->assignbssid) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_ASSIGN_BSSID)->create_json(jsonitems, item->assignbssid);
|
||||
}
|
||||
|
||||
if (item->deletewlan) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_DELETE_WLAN)->create_json(jsonitems, item->deletewlan);
|
||||
}
|
||||
|
||||
if (item->directsequencecontrol) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL)->create_json(jsonitems, item->directsequencecontrol);
|
||||
}
|
||||
|
||||
if (item->iearray) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_IE)->create_json(jsonitems, item->iearray);
|
||||
}
|
||||
|
||||
if (item->macoperation) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MACOPERATION)->create_json(jsonitems, item->macoperation);
|
||||
}
|
||||
|
||||
if (item->miccountermeasures) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES)->create_json(jsonitems, item->miccountermeasures);
|
||||
}
|
||||
|
||||
if (item->multidomaincapability) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY)->create_json(jsonitems, item->multidomaincapability);
|
||||
}
|
||||
|
||||
if (item->ofdmcontrol) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_OFDMCONTROL)->create_json(jsonitems, item->ofdmcontrol);
|
||||
}
|
||||
|
||||
if (item->rateset) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_RATESET)->create_json(jsonitems, item->rateset);
|
||||
}
|
||||
|
||||
if (item->rsnaerrorreport) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT)->create_json(jsonitems, item->rsnaerrorreport);
|
||||
}
|
||||
|
||||
if (item->statistics) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_STATISTICS)->create_json(jsonitems, item->statistics);
|
||||
}
|
||||
|
||||
if (item->supportedrates) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_SUPPORTEDRATES)->create_json(jsonitems, item->supportedrates);
|
||||
}
|
||||
|
||||
if (item->txpower) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_TXPOWER)->create_json(jsonitems, item->txpower);
|
||||
}
|
||||
|
||||
if (item->txpowerlevel) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_TXPOWERLEVEL)->create_json(jsonitems, item->txpowerlevel);
|
||||
}
|
||||
|
||||
if (item->updatewlan) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_UPDATE_WLAN)->create_json(jsonitems, item->updatewlan);
|
||||
}
|
||||
|
||||
if (item->wtpqos) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_QOS)->create_json(jsonitems, item->wtpqos);
|
||||
}
|
||||
|
||||
if (item->wtpradioconf) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF)->create_json(jsonitems, item->wtpradioconf);
|
||||
}
|
||||
|
||||
if (item->wtpradiofailalarm) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM)->create_json(jsonitems, item->wtpradiofailalarm);
|
||||
}
|
||||
|
||||
if (item->wtpradioinformation) {
|
||||
ac_json_80211_getops_by_capwaptype(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)->create_json(jsonitems, item->wtpradioinformation);
|
||||
}
|
||||
|
||||
/* */
|
||||
json_object_array_add(jsonarray, jsonitems);
|
||||
}
|
||||
|
||||
return jsonarray;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_json_ieee80211_buildpacket(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_packet_txmng* txmngpacket) {
|
||||
int i, j;
|
||||
|
||||
ASSERT(wtpradio != NULL);
|
||||
ASSERT(txmngpacket != NULL);
|
||||
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
|
||||
|
||||
if (item->valid) {
|
||||
if (item->addwlan) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ADD_WLAN, item->addwlan);
|
||||
}
|
||||
|
||||
if (item->antenna) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ANTENNA, item->antenna);
|
||||
}
|
||||
|
||||
if (item->assignbssid) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ASSIGN_BSSID, item->assignbssid);
|
||||
}
|
||||
|
||||
if (item->deletewlan) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_DELETE_WLAN, item->deletewlan);
|
||||
}
|
||||
|
||||
if (item->directsequencecontrol) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL, item->directsequencecontrol);
|
||||
}
|
||||
|
||||
if (item->iearray) {
|
||||
for (j = 0; j < item->iearray->count; j++) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_IE, *(struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, j));
|
||||
}
|
||||
}
|
||||
|
||||
if (item->macoperation) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MACOPERATION, item->macoperation);
|
||||
}
|
||||
|
||||
if (item->miccountermeasures) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES, item->miccountermeasures);
|
||||
}
|
||||
|
||||
if (item->multidomaincapability) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY, item->multidomaincapability);
|
||||
}
|
||||
|
||||
if (item->ofdmcontrol) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_OFDMCONTROL, item->ofdmcontrol);
|
||||
}
|
||||
|
||||
if (item->rateset) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_RATESET, item->rateset);
|
||||
}
|
||||
|
||||
if (item->rsnaerrorreport) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT, item->rsnaerrorreport);
|
||||
}
|
||||
|
||||
if (item->statistics) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_STATISTICS, item->statistics);
|
||||
}
|
||||
|
||||
if (item->supportedrates) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_SUPPORTEDRATES, item->supportedrates);
|
||||
}
|
||||
|
||||
if (item->txpower) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_TXPOWER, item->txpower);
|
||||
}
|
||||
|
||||
if (item->txpowerlevel) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_TXPOWERLEVEL, item->txpowerlevel);
|
||||
}
|
||||
|
||||
if (item->updatewlan) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_UPDATE_WLAN, item->updatewlan);
|
||||
}
|
||||
|
||||
if (item->wtpqos) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_QOS, item->wtpqos);
|
||||
}
|
||||
|
||||
if (item->wtpradioconf) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_RADIO_CONF, item->wtpradioconf);
|
||||
}
|
||||
|
||||
if (item->wtpradiofailalarm) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM, item->wtpradiofailalarm);
|
||||
}
|
||||
|
||||
if (item->wtpradioinformation) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, item->wtpradioinformation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +1,41 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_addwlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_addwlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_addwlan_element* addwlan = (struct capwap_80211_addwlan_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[addwlan->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ADD_WLAN);
|
||||
|
||||
if (item->addwlan) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->addwlan);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->addwlan = (struct capwap_80211_addwlan_element*)ops->clone_message_element(addwlan);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_addwlan_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_addwlan_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_ADD_WLAN,
|
||||
.json_type = "IEEE80211AddWLAN",
|
||||
.create_message_element = ac_json_80211_addwlan_createmessageelement,
|
||||
.add_message_element = ac_json_80211_addwlan_addmessageelement,
|
||||
.create_json = ac_json_80211_addwlan_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_addwlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_addwlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_addwlan_element* addwlan = (struct capwap_80211_addwlan_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[addwlan->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ADD_WLAN);
|
||||
|
||||
if (item->addwlan) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->addwlan);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->addwlan = (struct capwap_80211_addwlan_element*)ops->clone_message_element(addwlan);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_addwlan_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_addwlan_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_ADD_WLAN,
|
||||
.json_type = "IEEE80211AddWLAN",
|
||||
.create_message_element = ac_json_80211_addwlan_createmessageelement,
|
||||
.add_message_element = ac_json_80211_addwlan_addmessageelement,
|
||||
.create_json = ac_json_80211_addwlan_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_ADDWLAN_HEADER__
|
||||
#define __AC_JSON_80211_ADDWLAN_HEADER__
|
||||
|
||||
#include "capwap_element_80211_addwlan.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_addwlan_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_ADDWLAN_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_ADDWLAN_HEADER__
|
||||
#define __AC_JSON_80211_ADDWLAN_HEADER__
|
||||
|
||||
#include "capwap_element_80211_addwlan.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_addwlan_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_ADDWLAN_HEADER__ */
|
||||
|
@ -1,109 +1,109 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211Antenna: {
|
||||
Diversity: [bool],
|
||||
Combiner: [int],
|
||||
AntennaSelection: [
|
||||
[int]
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_antenna_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_antenna_element* antenna;
|
||||
|
||||
antenna = (struct capwap_80211_antenna_element*)capwap_alloc(sizeof(struct capwap_80211_antenna_element));
|
||||
memset(antenna, 0, sizeof(struct capwap_80211_antenna_element));
|
||||
antenna->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Diversity");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_boolean)) {
|
||||
antenna->diversity = (json_object_get_boolean(jsonitem) ? CAPWAP_ANTENNA_DIVERSITY_ENABLE : CAPWAP_ANTENNA_DIVERSITY_DISABLE);
|
||||
} else {
|
||||
capwap_free(antenna);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Combiner");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
antenna->combiner = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(antenna);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "AntennaSelection");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_array)) {
|
||||
int i;
|
||||
int length;
|
||||
|
||||
antenna->selections = capwap_array_create(sizeof(uint8_t), 0, 1);
|
||||
|
||||
length = json_object_array_length(jsonitem);
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonvalue = json_object_array_get_idx(jsonitem, i);
|
||||
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
|
||||
uint8_t* value = (uint8_t*)capwap_array_get_item_pointer(antenna->selections, antenna->selections->count);
|
||||
*value = (uint8_t)json_object_get_int(jsonvalue);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
capwap_free(antenna);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return antenna;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_antenna_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_antenna_element* antenna = (struct capwap_80211_antenna_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[antenna->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ANTENNA);
|
||||
|
||||
if (item->antenna) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->antenna);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->antenna = (struct capwap_80211_antenna_element*)ops->clone_message_element(antenna);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_antenna_createjson(struct json_object* jsonparent, void* data) {
|
||||
int i;
|
||||
struct json_object* jsonantenna;
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_antenna_element* antenna = (struct capwap_80211_antenna_element*)data;
|
||||
|
||||
jsonantenna = json_object_new_array();
|
||||
for (i = 0; i < antenna->selections->count; i++) {
|
||||
json_object_array_add(jsonantenna, json_object_new_int((int)*(uint8_t*)capwap_array_get_item_pointer(antenna->selections, i)));
|
||||
}
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "Diversity", json_object_new_boolean((antenna->diversity == CAPWAP_ANTENNA_DIVERSITY_ENABLE) ? 1 : 0));
|
||||
json_object_object_add(jsonitem, "Combiner", json_object_new_int((int)antenna->combiner));
|
||||
json_object_object_add(jsonitem, "AntennaSelection", jsonantenna);
|
||||
json_object_object_add(jsonparent, "IEEE80211Antenna", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_antenna_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_ANTENNA,
|
||||
.json_type = "IEEE80211Antenna",
|
||||
.create_message_element = ac_json_80211_antenna_createmessageelement,
|
||||
.add_message_element = ac_json_80211_antenna_addmessageelement,
|
||||
.create_json = ac_json_80211_antenna_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211Antenna: {
|
||||
Diversity: [bool],
|
||||
Combiner: [int],
|
||||
AntennaSelection: [
|
||||
[int]
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_antenna_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_antenna_element* antenna;
|
||||
|
||||
antenna = (struct capwap_80211_antenna_element*)capwap_alloc(sizeof(struct capwap_80211_antenna_element));
|
||||
memset(antenna, 0, sizeof(struct capwap_80211_antenna_element));
|
||||
antenna->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Diversity");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_boolean)) {
|
||||
antenna->diversity = (json_object_get_boolean(jsonitem) ? CAPWAP_ANTENNA_DIVERSITY_ENABLE : CAPWAP_ANTENNA_DIVERSITY_DISABLE);
|
||||
} else {
|
||||
capwap_free(antenna);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Combiner");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
antenna->combiner = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(antenna);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "AntennaSelection");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_array)) {
|
||||
int i;
|
||||
int length;
|
||||
|
||||
antenna->selections = capwap_array_create(sizeof(uint8_t), 0, 1);
|
||||
|
||||
length = json_object_array_length(jsonitem);
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonvalue = json_object_array_get_idx(jsonitem, i);
|
||||
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
|
||||
uint8_t* value = (uint8_t*)capwap_array_get_item_pointer(antenna->selections, antenna->selections->count);
|
||||
*value = (uint8_t)json_object_get_int(jsonvalue);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
capwap_free(antenna);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return antenna;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_antenna_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_antenna_element* antenna = (struct capwap_80211_antenna_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[antenna->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ANTENNA);
|
||||
|
||||
if (item->antenna) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->antenna);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->antenna = (struct capwap_80211_antenna_element*)ops->clone_message_element(antenna);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_antenna_createjson(struct json_object* jsonparent, void* data) {
|
||||
int i;
|
||||
struct json_object* jsonantenna;
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_antenna_element* antenna = (struct capwap_80211_antenna_element*)data;
|
||||
|
||||
jsonantenna = json_object_new_array();
|
||||
for (i = 0; i < antenna->selections->count; i++) {
|
||||
json_object_array_add(jsonantenna, json_object_new_int((int)*(uint8_t*)capwap_array_get_item_pointer(antenna->selections, i)));
|
||||
}
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "Diversity", json_object_new_boolean((antenna->diversity == CAPWAP_ANTENNA_DIVERSITY_ENABLE) ? 1 : 0));
|
||||
json_object_object_add(jsonitem, "Combiner", json_object_new_int((int)antenna->combiner));
|
||||
json_object_object_add(jsonitem, "AntennaSelection", jsonantenna);
|
||||
json_object_object_add(jsonparent, "IEEE80211Antenna", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_antenna_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_ANTENNA,
|
||||
.json_type = "IEEE80211Antenna",
|
||||
.create_message_element = ac_json_80211_antenna_createmessageelement,
|
||||
.add_message_element = ac_json_80211_antenna_addmessageelement,
|
||||
.create_json = ac_json_80211_antenna_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_ANTENNA_HEADER__
|
||||
#define __AC_JSON_80211_ANTENNA_HEADER__
|
||||
|
||||
#include "capwap_element_80211_antenna.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_antenna_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_ANTENNA_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_ANTENNA_HEADER__
|
||||
#define __AC_JSON_80211_ANTENNA_HEADER__
|
||||
|
||||
#include "capwap_element_80211_antenna.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_antenna_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_ANTENNA_HEADER__ */
|
||||
|
@ -1,41 +1,41 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_assignbssid_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_assignbssid_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_assignbssid_element* assignbssid = (struct capwap_80211_assignbssid_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[assignbssid->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ASSIGN_BSSID);
|
||||
|
||||
if (item->assignbssid) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->assignbssid);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->assignbssid = (struct capwap_80211_assignbssid_element*)ops->clone_message_element(assignbssid);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_assignbssid_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_assignbssid_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_ASSIGN_BSSID,
|
||||
.json_type = "IEEE80211AssignBSSID",
|
||||
.create_message_element = ac_json_80211_assignbssid_createmessageelement,
|
||||
.add_message_element = ac_json_80211_assignbssid_addmessageelement,
|
||||
.create_json = ac_json_80211_assignbssid_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_assignbssid_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_assignbssid_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_assignbssid_element* assignbssid = (struct capwap_80211_assignbssid_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[assignbssid->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_ASSIGN_BSSID);
|
||||
|
||||
if (item->assignbssid) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->assignbssid);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->assignbssid = (struct capwap_80211_assignbssid_element*)ops->clone_message_element(assignbssid);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_assignbssid_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_assignbssid_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_ASSIGN_BSSID,
|
||||
.json_type = "IEEE80211AssignBSSID",
|
||||
.create_message_element = ac_json_80211_assignbssid_createmessageelement,
|
||||
.add_message_element = ac_json_80211_assignbssid_addmessageelement,
|
||||
.create_json = ac_json_80211_assignbssid_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_ASSIGNBSSID_HEADER__
|
||||
#define __AC_JSON_80211_ASSIGNBSSID_HEADER__
|
||||
|
||||
#include "capwap_element_80211_assignbssid.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_assignbssid_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_ASSIGNBSSID_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_ASSIGNBSSID_HEADER__
|
||||
#define __AC_JSON_80211_ASSIGNBSSID_HEADER__
|
||||
|
||||
#include "capwap_element_80211_assignbssid.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_assignbssid_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_ASSIGNBSSID_HEADER__ */
|
||||
|
@ -1,41 +1,41 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_deletewlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_deletewlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_deletewlan_element* deletewlan = (struct capwap_80211_deletewlan_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[deletewlan->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DELETE_WLAN);
|
||||
|
||||
if (item->deletewlan) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->deletewlan);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->deletewlan = (struct capwap_80211_deletewlan_element*)ops->clone_message_element(deletewlan);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_deletewlan_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_deletewlan_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_DELETE_WLAN,
|
||||
.json_type = "IEEE80211DeleteWLAN",
|
||||
.create_message_element = ac_json_80211_deletewlan_createmessageelement,
|
||||
.add_message_element = ac_json_80211_deletewlan_addmessageelement,
|
||||
.create_json = ac_json_80211_deletewlan_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_deletewlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_deletewlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_deletewlan_element* deletewlan = (struct capwap_80211_deletewlan_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[deletewlan->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DELETE_WLAN);
|
||||
|
||||
if (item->deletewlan) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->deletewlan);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->deletewlan = (struct capwap_80211_deletewlan_element*)ops->clone_message_element(deletewlan);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_deletewlan_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_deletewlan_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_DELETE_WLAN,
|
||||
.json_type = "IEEE80211DeleteWLAN",
|
||||
.create_message_element = ac_json_80211_deletewlan_createmessageelement,
|
||||
.add_message_element = ac_json_80211_deletewlan_addmessageelement,
|
||||
.create_json = ac_json_80211_deletewlan_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_DELETEWLAN_HEADER__
|
||||
#define __AC_JSON_80211_DELETEWLAN_HEADER__
|
||||
|
||||
#include "capwap_element_80211_deletewlan.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_deletewlan_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_DELETEWLAN_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_DELETEWLAN_HEADER__
|
||||
#define __AC_JSON_80211_DELETEWLAN_HEADER__
|
||||
|
||||
#include "capwap_element_80211_deletewlan.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_deletewlan_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_DELETEWLAN_HEADER__ */
|
||||
|
@ -1,88 +1,88 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211DirectSequenceControl: {
|
||||
CurrentChan: [int],
|
||||
CurrentCCA: [int],
|
||||
EnergyDetectThreshold: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_directsequencecontrol_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_directsequencecontrol_element* directsequencecontrol;
|
||||
|
||||
directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)capwap_alloc(sizeof(struct capwap_80211_directsequencecontrol_element));
|
||||
memset(directsequencecontrol, 0, sizeof(struct capwap_80211_directsequencecontrol_element));
|
||||
directsequencecontrol->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CurrentChan");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
directsequencecontrol->currentchannel = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(directsequencecontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CurrentCCA");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
directsequencecontrol->currentcca = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(directsequencecontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "EnergyDetectThreshold");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
directsequencecontrol->enerydetectthreshold = (uint32_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(directsequencecontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return directsequencecontrol;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_directsequencecontrol_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_directsequencecontrol_element* directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[directsequencecontrol->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL);
|
||||
|
||||
if (item->directsequencecontrol) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->directsequencecontrol);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)ops->clone_message_element(directsequencecontrol);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_directsequencecontrol_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_directsequencecontrol_element* directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "CurrentChan", json_object_new_int((int)directsequencecontrol->currentchannel));
|
||||
json_object_object_add(jsonitem, "CurrentCCA", json_object_new_int((int)directsequencecontrol->currentcca));
|
||||
json_object_object_add(jsonitem, "EnergyDetectThreshold", json_object_new_int((int)directsequencecontrol->enerydetectthreshold));
|
||||
json_object_object_add(jsonparent, "IEEE80211DirectSequenceControl", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_directsequencecontrol_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL,
|
||||
.json_type = "IEEE80211DirectSequenceControl",
|
||||
.create_message_element = ac_json_80211_directsequencecontrol_createmessageelement,
|
||||
.add_message_element = ac_json_80211_directsequencecontrol_addmessageelement,
|
||||
.create_json = ac_json_80211_directsequencecontrol_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211DirectSequenceControl: {
|
||||
CurrentChan: [int],
|
||||
CurrentCCA: [int],
|
||||
EnergyDetectThreshold: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_directsequencecontrol_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_directsequencecontrol_element* directsequencecontrol;
|
||||
|
||||
directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)capwap_alloc(sizeof(struct capwap_80211_directsequencecontrol_element));
|
||||
memset(directsequencecontrol, 0, sizeof(struct capwap_80211_directsequencecontrol_element));
|
||||
directsequencecontrol->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CurrentChan");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
directsequencecontrol->currentchannel = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(directsequencecontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CurrentCCA");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
directsequencecontrol->currentcca = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(directsequencecontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "EnergyDetectThreshold");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
directsequencecontrol->enerydetectthreshold = (uint32_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(directsequencecontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return directsequencecontrol;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_directsequencecontrol_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_directsequencecontrol_element* directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[directsequencecontrol->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL);
|
||||
|
||||
if (item->directsequencecontrol) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->directsequencecontrol);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)ops->clone_message_element(directsequencecontrol);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_directsequencecontrol_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_directsequencecontrol_element* directsequencecontrol = (struct capwap_80211_directsequencecontrol_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "CurrentChan", json_object_new_int((int)directsequencecontrol->currentchannel));
|
||||
json_object_object_add(jsonitem, "CurrentCCA", json_object_new_int((int)directsequencecontrol->currentcca));
|
||||
json_object_object_add(jsonitem, "EnergyDetectThreshold", json_object_new_int((int)directsequencecontrol->enerydetectthreshold));
|
||||
json_object_object_add(jsonparent, "IEEE80211DirectSequenceControl", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_directsequencecontrol_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL,
|
||||
.json_type = "IEEE80211DirectSequenceControl",
|
||||
.create_message_element = ac_json_80211_directsequencecontrol_createmessageelement,
|
||||
.add_message_element = ac_json_80211_directsequencecontrol_addmessageelement,
|
||||
.create_json = ac_json_80211_directsequencecontrol_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__
|
||||
#define __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__
|
||||
|
||||
#include "capwap_element_80211_directsequencecontrol.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_directsequencecontrol_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__
|
||||
#define __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__
|
||||
|
||||
#include "capwap_element_80211_directsequencecontrol.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_directsequencecontrol_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_DIRECTSEQUENCECONTROL_HEADER__ */
|
||||
|
@ -1,39 +1,39 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_ie_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_ie_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_ie_element** ieclone;
|
||||
struct capwap_80211_ie_element* ie = (struct capwap_80211_ie_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[ie->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_IE);
|
||||
|
||||
if (!item->iearray) {
|
||||
item->iearray = capwap_array_create(sizeof(struct capwap_80211_ie_element*), 0, 0);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
ieclone = (struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, item->iearray->count);
|
||||
*ieclone = (struct capwap_80211_ie_element*)ops->clone_message_element(ie);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_ie_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_ie_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_IE,
|
||||
.json_type = "IEEE80211IE",
|
||||
.create_message_element = ac_json_80211_ie_createmessageelement,
|
||||
.add_message_element = ac_json_80211_ie_addmessageelement,
|
||||
.create_json = ac_json_80211_ie_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_ie_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_ie_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_ie_element** ieclone;
|
||||
struct capwap_80211_ie_element* ie = (struct capwap_80211_ie_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[ie->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_IE);
|
||||
|
||||
if (!item->iearray) {
|
||||
item->iearray = capwap_array_create(sizeof(struct capwap_80211_ie_element*), 0, 0);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
ieclone = (struct capwap_80211_ie_element**)capwap_array_get_item_pointer(item->iearray, item->iearray->count);
|
||||
*ieclone = (struct capwap_80211_ie_element*)ops->clone_message_element(ie);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_ie_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_ie_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_IE,
|
||||
.json_type = "IEEE80211IE",
|
||||
.create_message_element = ac_json_80211_ie_createmessageelement,
|
||||
.add_message_element = ac_json_80211_ie_addmessageelement,
|
||||
.create_json = ac_json_80211_ie_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_IE_HEADER__
|
||||
#define __AC_JSON_80211_IE_HEADER__
|
||||
|
||||
#include "capwap_element_80211_ie.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_ie_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_IE_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_IE_HEADER__
|
||||
#define __AC_JSON_80211_IE_HEADER__
|
||||
|
||||
#include "capwap_element_80211_ie.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_ie_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_IE_HEADER__ */
|
||||
|
@ -1,118 +1,118 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211MACOperation: {
|
||||
RTSThreshold: [int],
|
||||
ShortRetry: [int],
|
||||
LongRetry: [int],
|
||||
FragmentationThreshold: [int],
|
||||
TxMSDULifetime: [int],
|
||||
RxMSDULifetime: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_macoperation_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_macoperation_element* macoperation;
|
||||
|
||||
macoperation = (struct capwap_80211_macoperation_element*)capwap_alloc(sizeof(struct capwap_80211_macoperation_element));
|
||||
memset(macoperation, 0, sizeof(struct capwap_80211_macoperation_element));
|
||||
macoperation->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "RTSThreshold");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->rtsthreshold = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "ShortRetry");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->shortretry = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "LongRetry");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->longretry = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "FragmentationThreshold");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->fragthreshold = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "TxMSDULifetime");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->txmsdulifetime = (uint32_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "RxMSDULifetime");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->rxmsdulifetime = (uint32_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return macoperation;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_macoperation_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_macoperation_element* macoperation = (struct capwap_80211_macoperation_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[macoperation->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MACOPERATION);
|
||||
|
||||
if (item->macoperation) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->macoperation);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->macoperation = (struct capwap_80211_macoperation_element*)ops->clone_message_element(macoperation);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_macoperation_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_macoperation_element* macoperation = (struct capwap_80211_macoperation_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "RTSThreshold", json_object_new_int((int)macoperation->rtsthreshold));
|
||||
json_object_object_add(jsonitem, "ShortRetry", json_object_new_int((int)macoperation->shortretry));
|
||||
json_object_object_add(jsonitem, "LongRetry", json_object_new_int((int)macoperation->longretry));
|
||||
json_object_object_add(jsonitem, "FragmentationThreshold", json_object_new_int((int)macoperation->fragthreshold));
|
||||
json_object_object_add(jsonitem, "TxMSDULifetime", json_object_new_int((int)macoperation->txmsdulifetime));
|
||||
json_object_object_add(jsonitem, "RxMSDULifetime", json_object_new_int((int)macoperation->rxmsdulifetime));
|
||||
json_object_object_add(jsonparent, "IEEE80211MACOperation", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_macoperation_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_MACOPERATION,
|
||||
.json_type = "IEEE80211MACOperation",
|
||||
.create_message_element = ac_json_80211_macoperation_createmessageelement,
|
||||
.add_message_element = ac_json_80211_macoperation_addmessageelement,
|
||||
.create_json = ac_json_80211_macoperation_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211MACOperation: {
|
||||
RTSThreshold: [int],
|
||||
ShortRetry: [int],
|
||||
LongRetry: [int],
|
||||
FragmentationThreshold: [int],
|
||||
TxMSDULifetime: [int],
|
||||
RxMSDULifetime: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_macoperation_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_macoperation_element* macoperation;
|
||||
|
||||
macoperation = (struct capwap_80211_macoperation_element*)capwap_alloc(sizeof(struct capwap_80211_macoperation_element));
|
||||
memset(macoperation, 0, sizeof(struct capwap_80211_macoperation_element));
|
||||
macoperation->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "RTSThreshold");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->rtsthreshold = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "ShortRetry");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->shortretry = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "LongRetry");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->longretry = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "FragmentationThreshold");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->fragthreshold = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "TxMSDULifetime");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->txmsdulifetime = (uint32_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "RxMSDULifetime");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
macoperation->rxmsdulifetime = (uint32_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(macoperation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return macoperation;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_macoperation_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_macoperation_element* macoperation = (struct capwap_80211_macoperation_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[macoperation->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MACOPERATION);
|
||||
|
||||
if (item->macoperation) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->macoperation);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->macoperation = (struct capwap_80211_macoperation_element*)ops->clone_message_element(macoperation);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_macoperation_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_macoperation_element* macoperation = (struct capwap_80211_macoperation_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "RTSThreshold", json_object_new_int((int)macoperation->rtsthreshold));
|
||||
json_object_object_add(jsonitem, "ShortRetry", json_object_new_int((int)macoperation->shortretry));
|
||||
json_object_object_add(jsonitem, "LongRetry", json_object_new_int((int)macoperation->longretry));
|
||||
json_object_object_add(jsonitem, "FragmentationThreshold", json_object_new_int((int)macoperation->fragthreshold));
|
||||
json_object_object_add(jsonitem, "TxMSDULifetime", json_object_new_int((int)macoperation->txmsdulifetime));
|
||||
json_object_object_add(jsonitem, "RxMSDULifetime", json_object_new_int((int)macoperation->rxmsdulifetime));
|
||||
json_object_object_add(jsonparent, "IEEE80211MACOperation", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_macoperation_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_MACOPERATION,
|
||||
.json_type = "IEEE80211MACOperation",
|
||||
.create_message_element = ac_json_80211_macoperation_createmessageelement,
|
||||
.add_message_element = ac_json_80211_macoperation_addmessageelement,
|
||||
.create_json = ac_json_80211_macoperation_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_MACOPERATION_HEADER__
|
||||
#define __AC_JSON_80211_MACOPERATION_HEADER__
|
||||
|
||||
#include "capwap_element_80211_macoperation.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_macoperation_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_MACOPERATION_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_MACOPERATION_HEADER__
|
||||
#define __AC_JSON_80211_MACOPERATION_HEADER__
|
||||
|
||||
#include "capwap_element_80211_macoperation.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_macoperation_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_MACOPERATION_HEADER__ */
|
||||
|
@ -1,41 +1,41 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_miccountermeasures_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_miccountermeasures_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_miccountermeasures_element* miccountermeasures = (struct capwap_80211_miccountermeasures_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[miccountermeasures->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES);
|
||||
|
||||
if (item->miccountermeasures) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->miccountermeasures);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->miccountermeasures = (struct capwap_80211_miccountermeasures_element*)ops->clone_message_element(miccountermeasures);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_miccountermeasures_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_miccountermeasures_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES,
|
||||
.json_type = "IEEE80211MicCounterMeasures",
|
||||
.create_message_element = ac_json_80211_miccountermeasures_createmessageelement,
|
||||
.add_message_element = ac_json_80211_miccountermeasures_addmessageelement,
|
||||
.create_json = ac_json_80211_miccountermeasures_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_miccountermeasures_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_miccountermeasures_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_miccountermeasures_element* miccountermeasures = (struct capwap_80211_miccountermeasures_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[miccountermeasures->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES);
|
||||
|
||||
if (item->miccountermeasures) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->miccountermeasures);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->miccountermeasures = (struct capwap_80211_miccountermeasures_element*)ops->clone_message_element(miccountermeasures);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_miccountermeasures_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_miccountermeasures_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES,
|
||||
.json_type = "IEEE80211MicCounterMeasures",
|
||||
.create_message_element = ac_json_80211_miccountermeasures_createmessageelement,
|
||||
.add_message_element = ac_json_80211_miccountermeasures_addmessageelement,
|
||||
.create_json = ac_json_80211_miccountermeasures_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__
|
||||
#define __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__
|
||||
|
||||
#include "capwap_element_80211_miccountermeasures.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_miccountermeasures_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__
|
||||
#define __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__
|
||||
|
||||
#include "capwap_element_80211_miccountermeasures.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_miccountermeasures_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_MICCOUNTERMEASURES_HEADER__ */
|
||||
|
@ -1,88 +1,88 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211MultiDomainCapability: {
|
||||
FirstChannel: [int],
|
||||
NumberChannels: [int],
|
||||
MaxTxPowerLevel: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_multidomaincapability_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_multidomaincapability_element* multidomaincapability;
|
||||
|
||||
multidomaincapability = (struct capwap_80211_multidomaincapability_element*)capwap_alloc(sizeof(struct capwap_80211_multidomaincapability_element));
|
||||
memset(multidomaincapability, 0, sizeof(struct capwap_80211_multidomaincapability_element));
|
||||
multidomaincapability->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "FirstChannel");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
multidomaincapability->firstchannel = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(multidomaincapability);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "NumberChannels");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
multidomaincapability->numberchannels = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(multidomaincapability);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "MaxTxPowerLevel");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
multidomaincapability->maxtxpowerlevel = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(multidomaincapability);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return multidomaincapability;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_multidomaincapability_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_multidomaincapability_element* multidomaincapability = (struct capwap_80211_multidomaincapability_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[multidomaincapability->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY);
|
||||
|
||||
if (item->multidomaincapability) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->multidomaincapability);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->multidomaincapability = (struct capwap_80211_multidomaincapability_element*)ops->clone_message_element(multidomaincapability);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_multidomaincapability_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_multidomaincapability_element* multidomaincapability = (struct capwap_80211_multidomaincapability_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "FirstChannel", json_object_new_int((int)multidomaincapability->firstchannel));
|
||||
json_object_object_add(jsonitem, "NumberChannels", json_object_new_int((int)multidomaincapability->numberchannels));
|
||||
json_object_object_add(jsonitem, "MaxTxPowerLevel", json_object_new_int((int)multidomaincapability->maxtxpowerlevel));
|
||||
json_object_object_add(jsonparent, "IEEE80211MultiDomainCapability", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_multidomaincapability_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY,
|
||||
.json_type = "IEEE80211MultiDomainCapability",
|
||||
.create_message_element = ac_json_80211_multidomaincapability_createmessageelement,
|
||||
.add_message_element = ac_json_80211_multidomaincapability_addmessageelement,
|
||||
.create_json = ac_json_80211_multidomaincapability_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211MultiDomainCapability: {
|
||||
FirstChannel: [int],
|
||||
NumberChannels: [int],
|
||||
MaxTxPowerLevel: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_multidomaincapability_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_multidomaincapability_element* multidomaincapability;
|
||||
|
||||
multidomaincapability = (struct capwap_80211_multidomaincapability_element*)capwap_alloc(sizeof(struct capwap_80211_multidomaincapability_element));
|
||||
memset(multidomaincapability, 0, sizeof(struct capwap_80211_multidomaincapability_element));
|
||||
multidomaincapability->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "FirstChannel");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
multidomaincapability->firstchannel = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(multidomaincapability);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "NumberChannels");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
multidomaincapability->numberchannels = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(multidomaincapability);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "MaxTxPowerLevel");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
multidomaincapability->maxtxpowerlevel = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(multidomaincapability);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return multidomaincapability;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_multidomaincapability_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_multidomaincapability_element* multidomaincapability = (struct capwap_80211_multidomaincapability_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[multidomaincapability->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY);
|
||||
|
||||
if (item->multidomaincapability) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->multidomaincapability);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->multidomaincapability = (struct capwap_80211_multidomaincapability_element*)ops->clone_message_element(multidomaincapability);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_multidomaincapability_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_multidomaincapability_element* multidomaincapability = (struct capwap_80211_multidomaincapability_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "FirstChannel", json_object_new_int((int)multidomaincapability->firstchannel));
|
||||
json_object_object_add(jsonitem, "NumberChannels", json_object_new_int((int)multidomaincapability->numberchannels));
|
||||
json_object_object_add(jsonitem, "MaxTxPowerLevel", json_object_new_int((int)multidomaincapability->maxtxpowerlevel));
|
||||
json_object_object_add(jsonparent, "IEEE80211MultiDomainCapability", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_multidomaincapability_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY,
|
||||
.json_type = "IEEE80211MultiDomainCapability",
|
||||
.create_message_element = ac_json_80211_multidomaincapability_createmessageelement,
|
||||
.add_message_element = ac_json_80211_multidomaincapability_addmessageelement,
|
||||
.create_json = ac_json_80211_multidomaincapability_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__
|
||||
#define __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__
|
||||
|
||||
#include "capwap_element_80211_multidomaincapability.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_multidomaincapability_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__
|
||||
#define __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__
|
||||
|
||||
#include "capwap_element_80211_multidomaincapability.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_multidomaincapability_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_MULTIDOMAINCAPABILITY_HEADER__ */
|
||||
|
@ -1,88 +1,88 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211OFDMControl: {
|
||||
CurrentChan: [int],
|
||||
BandSupport: [int],
|
||||
TIThreshold: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_ofdmcontrol_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_ofdmcontrol_element* ofdmcontrol;
|
||||
|
||||
ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)capwap_alloc(sizeof(struct capwap_80211_ofdmcontrol_element));
|
||||
memset(ofdmcontrol, 0, sizeof(struct capwap_80211_ofdmcontrol_element));
|
||||
ofdmcontrol->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CurrentChan");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
ofdmcontrol->currentchannel = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(ofdmcontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "BandSupport");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
ofdmcontrol->bandsupport = (uint8_t)json_object_get_int(jsonitem) & CAPWAP_OFDMCONTROL_BAND_MASK;
|
||||
} else {
|
||||
capwap_free(ofdmcontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "TIThreshold");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
ofdmcontrol->tithreshold = (uint32_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(ofdmcontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ofdmcontrol;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_ofdmcontrol_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_ofdmcontrol_element* ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[ofdmcontrol->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_OFDMCONTROL);
|
||||
|
||||
if (item->ofdmcontrol) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->ofdmcontrol);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)ops->clone_message_element(ofdmcontrol);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_ofdmcontrol_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_ofdmcontrol_element* ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "CurrentChan", json_object_new_int((int)ofdmcontrol->currentchannel));
|
||||
json_object_object_add(jsonitem, "BandSupport", json_object_new_int((int)ofdmcontrol->bandsupport));
|
||||
json_object_object_add(jsonitem, "TIThreshold", json_object_new_int((int)ofdmcontrol->tithreshold));
|
||||
json_object_object_add(jsonparent, "IEEE80211OFDMControl", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_ofdmcontrol_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_OFDMCONTROL,
|
||||
.json_type = "IEEE80211OFDMControl",
|
||||
.create_message_element = ac_json_80211_ofdmcontrol_createmessageelement,
|
||||
.add_message_element = ac_json_80211_ofdmcontrol_addmessageelement,
|
||||
.create_json = ac_json_80211_ofdmcontrol_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211OFDMControl: {
|
||||
CurrentChan: [int],
|
||||
BandSupport: [int],
|
||||
TIThreshold: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_ofdmcontrol_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_ofdmcontrol_element* ofdmcontrol;
|
||||
|
||||
ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)capwap_alloc(sizeof(struct capwap_80211_ofdmcontrol_element));
|
||||
memset(ofdmcontrol, 0, sizeof(struct capwap_80211_ofdmcontrol_element));
|
||||
ofdmcontrol->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CurrentChan");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
ofdmcontrol->currentchannel = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(ofdmcontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "BandSupport");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
ofdmcontrol->bandsupport = (uint8_t)json_object_get_int(jsonitem) & CAPWAP_OFDMCONTROL_BAND_MASK;
|
||||
} else {
|
||||
capwap_free(ofdmcontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "TIThreshold");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
ofdmcontrol->tithreshold = (uint32_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(ofdmcontrol);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ofdmcontrol;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_ofdmcontrol_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_ofdmcontrol_element* ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[ofdmcontrol->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_OFDMCONTROL);
|
||||
|
||||
if (item->ofdmcontrol) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->ofdmcontrol);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)ops->clone_message_element(ofdmcontrol);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_ofdmcontrol_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_ofdmcontrol_element* ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "CurrentChan", json_object_new_int((int)ofdmcontrol->currentchannel));
|
||||
json_object_object_add(jsonitem, "BandSupport", json_object_new_int((int)ofdmcontrol->bandsupport));
|
||||
json_object_object_add(jsonitem, "TIThreshold", json_object_new_int((int)ofdmcontrol->tithreshold));
|
||||
json_object_object_add(jsonparent, "IEEE80211OFDMControl", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_ofdmcontrol_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_OFDMCONTROL,
|
||||
.json_type = "IEEE80211OFDMControl",
|
||||
.create_message_element = ac_json_80211_ofdmcontrol_createmessageelement,
|
||||
.add_message_element = ac_json_80211_ofdmcontrol_addmessageelement,
|
||||
.create_json = ac_json_80211_ofdmcontrol_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_OFDMCONTROL_HEADER__
|
||||
#define __AC_JSON_80211_OFDMCONTROL_HEADER__
|
||||
|
||||
#include "capwap_element_80211_ofdmcontrol.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_ofdmcontrol_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_OFDMCONTROL_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_OFDMCONTROL_HEADER__
|
||||
#define __AC_JSON_80211_OFDMCONTROL_HEADER__
|
||||
|
||||
#include "capwap_element_80211_ofdmcontrol.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_ofdmcontrol_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_OFDMCONTROL_HEADER__ */
|
||||
|
@ -1,81 +1,81 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211Rateset: [
|
||||
[int]
|
||||
]
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_rateset_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
int i;
|
||||
int length;
|
||||
struct capwap_80211_rateset_element* rateset;
|
||||
|
||||
if (json_object_get_type(jsonparent) != json_type_array) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
length = json_object_array_length(jsonparent);
|
||||
if ((length < CAPWAP_RATESET_MINLENGTH) || (length > CAPWAP_RATESET_MAXLENGTH)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rateset = (struct capwap_80211_rateset_element*)capwap_alloc(sizeof(struct capwap_80211_rateset_element));
|
||||
memset(rateset, 0, sizeof(struct capwap_80211_rateset_element));
|
||||
rateset->radioid = radioid;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
|
||||
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
|
||||
rateset->ratesetcount++;
|
||||
rateset->rateset[i] = (uint8_t)json_object_get_int(jsonvalue);
|
||||
}
|
||||
}
|
||||
|
||||
return rateset;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_rateset_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_rateset_element* rateset = (struct capwap_80211_rateset_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[rateset->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RATESET);
|
||||
|
||||
if (item->rateset) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->rateset);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->rateset = (struct capwap_80211_rateset_element*)ops->clone_message_element(rateset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_rateset_createjson(struct json_object* jsonparent, void* data) {
|
||||
int i;
|
||||
struct json_object* jsonrates;
|
||||
struct capwap_80211_rateset_element* rateset = (struct capwap_80211_rateset_element*)data;
|
||||
|
||||
jsonrates = json_object_new_array();
|
||||
for (i = 0; i < rateset->ratesetcount; i++) {
|
||||
json_object_array_add(jsonrates, json_object_new_int((int)rateset->rateset[i]));
|
||||
}
|
||||
|
||||
json_object_object_add(jsonparent, "IEEE80211Rateset", jsonrates);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_rateset_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_RATESET,
|
||||
.json_type = "IEEE80211Rateset",
|
||||
.create_message_element = ac_json_80211_rateset_createmessageelement,
|
||||
.add_message_element = ac_json_80211_rateset_addmessageelement,
|
||||
.create_json = ac_json_80211_rateset_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211Rateset: [
|
||||
[int]
|
||||
]
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_rateset_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
int i;
|
||||
int length;
|
||||
struct capwap_80211_rateset_element* rateset;
|
||||
|
||||
if (json_object_get_type(jsonparent) != json_type_array) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
length = json_object_array_length(jsonparent);
|
||||
if ((length < CAPWAP_RATESET_MINLENGTH) || (length > CAPWAP_RATESET_MAXLENGTH)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rateset = (struct capwap_80211_rateset_element*)capwap_alloc(sizeof(struct capwap_80211_rateset_element));
|
||||
memset(rateset, 0, sizeof(struct capwap_80211_rateset_element));
|
||||
rateset->radioid = radioid;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
|
||||
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
|
||||
rateset->ratesetcount++;
|
||||
rateset->rateset[i] = (uint8_t)json_object_get_int(jsonvalue);
|
||||
}
|
||||
}
|
||||
|
||||
return rateset;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_rateset_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_rateset_element* rateset = (struct capwap_80211_rateset_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[rateset->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RATESET);
|
||||
|
||||
if (item->rateset) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->rateset);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->rateset = (struct capwap_80211_rateset_element*)ops->clone_message_element(rateset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_rateset_createjson(struct json_object* jsonparent, void* data) {
|
||||
int i;
|
||||
struct json_object* jsonrates;
|
||||
struct capwap_80211_rateset_element* rateset = (struct capwap_80211_rateset_element*)data;
|
||||
|
||||
jsonrates = json_object_new_array();
|
||||
for (i = 0; i < rateset->ratesetcount; i++) {
|
||||
json_object_array_add(jsonrates, json_object_new_int((int)rateset->rateset[i]));
|
||||
}
|
||||
|
||||
json_object_object_add(jsonparent, "IEEE80211Rateset", jsonrates);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_rateset_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_RATESET,
|
||||
.json_type = "IEEE80211Rateset",
|
||||
.create_message_element = ac_json_80211_rateset_createmessageelement,
|
||||
.add_message_element = ac_json_80211_rateset_addmessageelement,
|
||||
.create_json = ac_json_80211_rateset_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_RATESET_HEADER__
|
||||
#define __AC_JSON_80211_RATESET_HEADER__
|
||||
|
||||
#include "capwap_element_80211_rateset.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_rateset_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_RATESET_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_RATESET_HEADER__
|
||||
#define __AC_JSON_80211_RATESET_HEADER__
|
||||
|
||||
#include "capwap_element_80211_rateset.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_rateset_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_RATESET_HEADER__ */
|
||||
|
@ -1,41 +1,41 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_rsnaerrorreport_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_rsnaerrorreport_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_rsnaerrorreport_element* rsnaerrorreport = (struct capwap_80211_rsnaerrorreport_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[rsnaerrorreport->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT);
|
||||
|
||||
if (item->rsnaerrorreport) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->rsnaerrorreport);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->rsnaerrorreport = (struct capwap_80211_rsnaerrorreport_element*)ops->clone_message_element(rsnaerrorreport);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_rsnaerrorreport_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_rsnaerrorreport_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT,
|
||||
.json_type = "IEEE80211RSNAErrorReport",
|
||||
.create_message_element = ac_json_80211_rsnaerrorreport_createmessageelement,
|
||||
.add_message_element = ac_json_80211_rsnaerrorreport_addmessageelement,
|
||||
.create_json = ac_json_80211_rsnaerrorreport_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_rsnaerrorreport_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_rsnaerrorreport_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_rsnaerrorreport_element* rsnaerrorreport = (struct capwap_80211_rsnaerrorreport_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[rsnaerrorreport->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT);
|
||||
|
||||
if (item->rsnaerrorreport) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->rsnaerrorreport);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->rsnaerrorreport = (struct capwap_80211_rsnaerrorreport_element*)ops->clone_message_element(rsnaerrorreport);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_rsnaerrorreport_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_rsnaerrorreport_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT,
|
||||
.json_type = "IEEE80211RSNAErrorReport",
|
||||
.create_message_element = ac_json_80211_rsnaerrorreport_createmessageelement,
|
||||
.add_message_element = ac_json_80211_rsnaerrorreport_addmessageelement,
|
||||
.create_json = ac_json_80211_rsnaerrorreport_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_RSNAERRORREPORT_HEADER__
|
||||
#define __AC_JSON_80211_RSNAERRORREPORT_HEADER__
|
||||
|
||||
#include "capwap_element_80211_rsnaerrorreport.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_rsnaerrorreport_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_RSNAERRORREPORT_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_RSNAERRORREPORT_HEADER__
|
||||
#define __AC_JSON_80211_RSNAERRORREPORT_HEADER__
|
||||
|
||||
#include "capwap_element_80211_rsnaerrorreport.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_rsnaerrorreport_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_RSNAERRORREPORT_HEADER__ */
|
||||
|
@ -1,41 +1,41 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_statistics_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_statistics_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_statistics_element* statistics = (struct capwap_80211_statistics_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[statistics->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_STATISTICS);
|
||||
|
||||
if (item->statistics) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->statistics);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->statistics = (struct capwap_80211_statistics_element*)ops->clone_message_element(statistics);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_statistics_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_statistics_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_STATISTICS,
|
||||
.json_type = "IEEE80211Statistics",
|
||||
.create_message_element = ac_json_80211_statistics_createmessageelement,
|
||||
.add_message_element = ac_json_80211_statistics_addmessageelement,
|
||||
.create_json = ac_json_80211_statistics_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_statistics_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_statistics_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_statistics_element* statistics = (struct capwap_80211_statistics_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[statistics->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_STATISTICS);
|
||||
|
||||
if (item->statistics) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->statistics);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->statistics = (struct capwap_80211_statistics_element*)ops->clone_message_element(statistics);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_statistics_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_statistics_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_STATISTICS,
|
||||
.json_type = "IEEE80211Statistics",
|
||||
.create_message_element = ac_json_80211_statistics_createmessageelement,
|
||||
.add_message_element = ac_json_80211_statistics_addmessageelement,
|
||||
.create_json = ac_json_80211_statistics_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_STATISTICS_HEADER__
|
||||
#define __AC_JSON_80211_STATISTICS_HEADER__
|
||||
|
||||
#include "capwap_element_80211_statistics.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_statistics_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_STATISTICS_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_STATISTICS_HEADER__
|
||||
#define __AC_JSON_80211_STATISTICS_HEADER__
|
||||
|
||||
#include "capwap_element_80211_statistics.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_statistics_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_STATISTICS_HEADER__ */
|
||||
|
@ -1,81 +1,81 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211SupportedRates: [
|
||||
[int]
|
||||
]
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_supportedrates_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
int i;
|
||||
int length;
|
||||
struct capwap_80211_supportedrates_element* supportedrates;
|
||||
|
||||
if (json_object_get_type(jsonparent) != json_type_array) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
length = json_object_array_length(jsonparent);
|
||||
if ((length < CAPWAP_SUPPORTEDRATES_MINLENGTH) || (length > CAPWAP_SUPPORTEDRATES_MAXLENGTH)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
supportedrates = (struct capwap_80211_supportedrates_element*)capwap_alloc(sizeof(struct capwap_80211_supportedrates_element));
|
||||
memset(supportedrates, 0, sizeof(struct capwap_80211_supportedrates_element));
|
||||
supportedrates->radioid = radioid;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
|
||||
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
|
||||
supportedrates->supportedratescount++;
|
||||
supportedrates->supportedrates[i] = (uint8_t)json_object_get_int(jsonvalue);
|
||||
}
|
||||
}
|
||||
|
||||
return supportedrates;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_supportedrates_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_supportedrates_element* supportedrates = (struct capwap_80211_supportedrates_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[supportedrates->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_SUPPORTEDRATES);
|
||||
|
||||
if (item->supportedrates) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->supportedrates);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->supportedrates = (struct capwap_80211_supportedrates_element*)ops->clone_message_element(supportedrates);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_supportedrates_createjson(struct json_object* jsonparent, void* data) {
|
||||
int i;
|
||||
struct json_object* jsonrates;
|
||||
struct capwap_80211_supportedrates_element* supportedrates = (struct capwap_80211_supportedrates_element*)data;
|
||||
|
||||
jsonrates = json_object_new_array();
|
||||
for (i = 0; i < supportedrates->supportedratescount; i++) {
|
||||
json_object_array_add(jsonrates, json_object_new_int((int)supportedrates->supportedrates[i]));
|
||||
}
|
||||
|
||||
json_object_object_add(jsonparent, "IEEE80211SupportedRates", jsonrates);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_supportedrates_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_SUPPORTEDRATES,
|
||||
.json_type = "IEEE80211SupportedRates",
|
||||
.create_message_element = ac_json_80211_supportedrates_createmessageelement,
|
||||
.add_message_element = ac_json_80211_supportedrates_addmessageelement,
|
||||
.create_json = ac_json_80211_supportedrates_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211SupportedRates: [
|
||||
[int]
|
||||
]
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_supportedrates_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
int i;
|
||||
int length;
|
||||
struct capwap_80211_supportedrates_element* supportedrates;
|
||||
|
||||
if (json_object_get_type(jsonparent) != json_type_array) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
length = json_object_array_length(jsonparent);
|
||||
if ((length < CAPWAP_SUPPORTEDRATES_MINLENGTH) || (length > CAPWAP_SUPPORTEDRATES_MAXLENGTH)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
supportedrates = (struct capwap_80211_supportedrates_element*)capwap_alloc(sizeof(struct capwap_80211_supportedrates_element));
|
||||
memset(supportedrates, 0, sizeof(struct capwap_80211_supportedrates_element));
|
||||
supportedrates->radioid = radioid;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
|
||||
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
|
||||
supportedrates->supportedratescount++;
|
||||
supportedrates->supportedrates[i] = (uint8_t)json_object_get_int(jsonvalue);
|
||||
}
|
||||
}
|
||||
|
||||
return supportedrates;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_supportedrates_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_supportedrates_element* supportedrates = (struct capwap_80211_supportedrates_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[supportedrates->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_SUPPORTEDRATES);
|
||||
|
||||
if (item->supportedrates) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->supportedrates);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->supportedrates = (struct capwap_80211_supportedrates_element*)ops->clone_message_element(supportedrates);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_supportedrates_createjson(struct json_object* jsonparent, void* data) {
|
||||
int i;
|
||||
struct json_object* jsonrates;
|
||||
struct capwap_80211_supportedrates_element* supportedrates = (struct capwap_80211_supportedrates_element*)data;
|
||||
|
||||
jsonrates = json_object_new_array();
|
||||
for (i = 0; i < supportedrates->supportedratescount; i++) {
|
||||
json_object_array_add(jsonrates, json_object_new_int((int)supportedrates->supportedrates[i]));
|
||||
}
|
||||
|
||||
json_object_object_add(jsonparent, "IEEE80211SupportedRates", jsonrates);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_supportedrates_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_SUPPORTEDRATES,
|
||||
.json_type = "IEEE80211SupportedRates",
|
||||
.create_message_element = ac_json_80211_supportedrates_createmessageelement,
|
||||
.add_message_element = ac_json_80211_supportedrates_addmessageelement,
|
||||
.create_json = ac_json_80211_supportedrates_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_SUPPORTEDRATES_HEADER__
|
||||
#define __AC_JSON_80211_SUPPORTEDRATES_HEADER__
|
||||
|
||||
#include "capwap_element_80211_supportedrates.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_supportedrates_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_SUPPORTEDRATES_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_SUPPORTEDRATES_HEADER__
|
||||
#define __AC_JSON_80211_SUPPORTEDRATES_HEADER__
|
||||
|
||||
#include "capwap_element_80211_supportedrates.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_supportedrates_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_SUPPORTEDRATES_HEADER__ */
|
||||
|
@ -1,68 +1,68 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211TxPower: {
|
||||
CurrentTxPower: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_txpower_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_txpower_element* txpower;
|
||||
|
||||
txpower = (struct capwap_80211_txpower_element*)capwap_alloc(sizeof(struct capwap_80211_txpower_element));
|
||||
memset(txpower, 0, sizeof(struct capwap_80211_txpower_element));
|
||||
txpower->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CurrentTxPower");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
txpower->currenttxpower = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(txpower);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return txpower;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_txpower_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_txpower_element* txpower = (struct capwap_80211_txpower_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[txpower->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWER);
|
||||
|
||||
if (item->txpower) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->txpower);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->txpower = (struct capwap_80211_txpower_element*)ops->clone_message_element(txpower);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_txpower_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_txpower_element* txpower = (struct capwap_80211_txpower_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "CurrentTxPower", json_object_new_int((int)txpower->currenttxpower));
|
||||
json_object_object_add(jsonparent, "IEEE80211TxPower", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_txpower_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_TXPOWER,
|
||||
.json_type = "IEEE80211TxPower",
|
||||
.create_message_element = ac_json_80211_txpower_createmessageelement,
|
||||
.add_message_element = ac_json_80211_txpower_addmessageelement,
|
||||
.create_json = ac_json_80211_txpower_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211TxPower: {
|
||||
CurrentTxPower: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_txpower_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_txpower_element* txpower;
|
||||
|
||||
txpower = (struct capwap_80211_txpower_element*)capwap_alloc(sizeof(struct capwap_80211_txpower_element));
|
||||
memset(txpower, 0, sizeof(struct capwap_80211_txpower_element));
|
||||
txpower->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CurrentTxPower");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
txpower->currenttxpower = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(txpower);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return txpower;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_txpower_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_txpower_element* txpower = (struct capwap_80211_txpower_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[txpower->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWER);
|
||||
|
||||
if (item->txpower) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->txpower);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->txpower = (struct capwap_80211_txpower_element*)ops->clone_message_element(txpower);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_txpower_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_txpower_element* txpower = (struct capwap_80211_txpower_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "CurrentTxPower", json_object_new_int((int)txpower->currenttxpower));
|
||||
json_object_object_add(jsonparent, "IEEE80211TxPower", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_txpower_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_TXPOWER,
|
||||
.json_type = "IEEE80211TxPower",
|
||||
.create_message_element = ac_json_80211_txpower_createmessageelement,
|
||||
.add_message_element = ac_json_80211_txpower_addmessageelement,
|
||||
.create_json = ac_json_80211_txpower_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_TXPOWER_HEADER__
|
||||
#define __AC_JSON_80211_TXPOWER_HEADER__
|
||||
|
||||
#include "capwap_element_80211_txpower.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_txpower_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_TXPOWER_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_TXPOWER_HEADER__
|
||||
#define __AC_JSON_80211_TXPOWER_HEADER__
|
||||
|
||||
#include "capwap_element_80211_txpower.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_txpower_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_TXPOWER_HEADER__ */
|
||||
|
@ -1,81 +1,81 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211TXPowerLevel: [
|
||||
[int]
|
||||
]
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_txpowerlevel_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
int i;
|
||||
int length;
|
||||
struct capwap_80211_txpowerlevel_element* txpowerlevel;
|
||||
|
||||
if (json_object_get_type(jsonparent) != json_type_array) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
length = json_object_array_length(jsonparent);
|
||||
if (length > CAPWAP_TXPOWERLEVEL_MAXLENGTH) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
txpowerlevel = (struct capwap_80211_txpowerlevel_element*)capwap_alloc(sizeof(struct capwap_80211_txpowerlevel_element));
|
||||
memset(txpowerlevel, 0, sizeof(struct capwap_80211_txpowerlevel_element));
|
||||
txpowerlevel->radioid = radioid;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
|
||||
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
|
||||
txpowerlevel->numlevels++;
|
||||
txpowerlevel->powerlevel[i] = (uint16_t)json_object_get_int(jsonvalue);
|
||||
}
|
||||
}
|
||||
|
||||
return txpowerlevel;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_txpowerlevel_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_txpowerlevel_element* txpowerlevel = (struct capwap_80211_txpowerlevel_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[txpowerlevel->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWERLEVEL);
|
||||
|
||||
if (item->txpowerlevel) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->txpowerlevel);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->txpowerlevel = (struct capwap_80211_txpowerlevel_element*)ops->clone_message_element(txpowerlevel);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_txpowerlevel_createjson(struct json_object* jsonparent, void* data) {
|
||||
int i;
|
||||
struct json_object* jsontxpower;
|
||||
struct capwap_80211_txpowerlevel_element* txpowerlevel = (struct capwap_80211_txpowerlevel_element*)data;
|
||||
|
||||
jsontxpower = json_object_new_array();
|
||||
for (i = 0; i < txpowerlevel->numlevels; i++) {
|
||||
json_object_array_add(jsontxpower, json_object_new_int((int)txpowerlevel->powerlevel[i]));
|
||||
}
|
||||
|
||||
json_object_object_add(jsonparent, "IEEE80211TXPowerLevel", jsontxpower);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_txpowerlevel_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_TXPOWERLEVEL,
|
||||
.json_type = "IEEE80211TXPowerLevel",
|
||||
.create_message_element = ac_json_80211_txpowerlevel_createmessageelement,
|
||||
.add_message_element = ac_json_80211_txpowerlevel_addmessageelement,
|
||||
.create_json = ac_json_80211_txpowerlevel_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211TXPowerLevel: [
|
||||
[int]
|
||||
]
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_txpowerlevel_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
int i;
|
||||
int length;
|
||||
struct capwap_80211_txpowerlevel_element* txpowerlevel;
|
||||
|
||||
if (json_object_get_type(jsonparent) != json_type_array) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
length = json_object_array_length(jsonparent);
|
||||
if (length > CAPWAP_TXPOWERLEVEL_MAXLENGTH) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
txpowerlevel = (struct capwap_80211_txpowerlevel_element*)capwap_alloc(sizeof(struct capwap_80211_txpowerlevel_element));
|
||||
memset(txpowerlevel, 0, sizeof(struct capwap_80211_txpowerlevel_element));
|
||||
txpowerlevel->radioid = radioid;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
struct json_object* jsonvalue = json_object_array_get_idx(jsonparent, i);
|
||||
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_int)) {
|
||||
txpowerlevel->numlevels++;
|
||||
txpowerlevel->powerlevel[i] = (uint16_t)json_object_get_int(jsonvalue);
|
||||
}
|
||||
}
|
||||
|
||||
return txpowerlevel;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_txpowerlevel_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_txpowerlevel_element* txpowerlevel = (struct capwap_80211_txpowerlevel_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[txpowerlevel->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_TXPOWERLEVEL);
|
||||
|
||||
if (item->txpowerlevel) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->txpowerlevel);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->txpowerlevel = (struct capwap_80211_txpowerlevel_element*)ops->clone_message_element(txpowerlevel);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_txpowerlevel_createjson(struct json_object* jsonparent, void* data) {
|
||||
int i;
|
||||
struct json_object* jsontxpower;
|
||||
struct capwap_80211_txpowerlevel_element* txpowerlevel = (struct capwap_80211_txpowerlevel_element*)data;
|
||||
|
||||
jsontxpower = json_object_new_array();
|
||||
for (i = 0; i < txpowerlevel->numlevels; i++) {
|
||||
json_object_array_add(jsontxpower, json_object_new_int((int)txpowerlevel->powerlevel[i]));
|
||||
}
|
||||
|
||||
json_object_object_add(jsonparent, "IEEE80211TXPowerLevel", jsontxpower);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_txpowerlevel_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_TXPOWERLEVEL,
|
||||
.json_type = "IEEE80211TXPowerLevel",
|
||||
.create_message_element = ac_json_80211_txpowerlevel_createmessageelement,
|
||||
.add_message_element = ac_json_80211_txpowerlevel_addmessageelement,
|
||||
.create_json = ac_json_80211_txpowerlevel_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_TXPOWERLEVEL_HEADER__
|
||||
#define __AC_JSON_80211_TXPOWERLEVEL_HEADER__
|
||||
|
||||
#include "capwap_element_80211_txpowerlevel.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_txpowerlevel_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_TXPOWERLEVEL_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_TXPOWERLEVEL_HEADER__
|
||||
#define __AC_JSON_80211_TXPOWERLEVEL_HEADER__
|
||||
|
||||
#include "capwap_element_80211_txpowerlevel.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_txpowerlevel_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_TXPOWERLEVEL_HEADER__ */
|
||||
|
@ -1,41 +1,41 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_updatewlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_updatewlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_updatewlan_element* updatewlan = (struct capwap_80211_updatewlan_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[updatewlan->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_UPDATE_WLAN);
|
||||
|
||||
if (item->updatewlan) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->updatewlan);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->updatewlan = (struct capwap_80211_updatewlan_element*)ops->clone_message_element(updatewlan);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_updatewlan_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_updatewlan_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_UPDATE_WLAN,
|
||||
.json_type = "IEEE80211UpdateWLAN",
|
||||
.create_message_element = ac_json_80211_updatewlan_createmessageelement,
|
||||
.add_message_element = ac_json_80211_updatewlan_addmessageelement,
|
||||
.create_json = ac_json_80211_updatewlan_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_updatewlan_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_updatewlan_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_updatewlan_element* updatewlan = (struct capwap_80211_updatewlan_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[updatewlan->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_UPDATE_WLAN);
|
||||
|
||||
if (item->updatewlan) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->updatewlan);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->updatewlan = (struct capwap_80211_updatewlan_element*)ops->clone_message_element(updatewlan);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_updatewlan_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_updatewlan_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_UPDATE_WLAN,
|
||||
.json_type = "IEEE80211UpdateWLAN",
|
||||
.create_message_element = ac_json_80211_updatewlan_createmessageelement,
|
||||
.add_message_element = ac_json_80211_updatewlan_addmessageelement,
|
||||
.create_json = ac_json_80211_updatewlan_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_UPDATEWLAN_HEADER__
|
||||
#define __AC_JSON_80211_UPDATEWLAN_HEADER__
|
||||
|
||||
#include "capwap_element_80211_updatewlan.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_updatewlan_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_UPDATEWLAN_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_UPDATEWLAN_HEADER__
|
||||
#define __AC_JSON_80211_UPDATEWLAN_HEADER__
|
||||
|
||||
#include "capwap_element_80211_updatewlan.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_updatewlan_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_UPDATEWLAN_HEADER__ */
|
||||
|
@ -1,79 +1,79 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211WTPQoS: {
|
||||
TaggingPolicy: [int],
|
||||
Voice: {
|
||||
QueueDepth: [int],
|
||||
CWMin: [int],
|
||||
CWMax: [int],
|
||||
AIFS: [int],
|
||||
Priority8021p: [int],
|
||||
DSCP: [int]
|
||||
}
|
||||
Video: {
|
||||
QueueDepth: [int],
|
||||
CWMin: [int],
|
||||
CWMax: [int],
|
||||
AIFS: [int],
|
||||
Priority8021p: [int],
|
||||
DSCP: [int]
|
||||
}
|
||||
BestEffort: {
|
||||
QueueDepth: [int],
|
||||
CWMin: [int],
|
||||
CWMax: [int],
|
||||
AIFS: [int],
|
||||
Priority8021p: [int],
|
||||
DSCP: [int]
|
||||
}
|
||||
Background: {
|
||||
QueueDepth: [int],
|
||||
CWMin: [int],
|
||||
CWMax: [int],
|
||||
AIFS: [int],
|
||||
Priority8021p: [int],
|
||||
DSCP: [int]
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_wtpqos_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_wtpqos_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_wtpqos_element* wtpqos = (struct capwap_80211_wtpqos_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpqos->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_QOS);
|
||||
|
||||
if (item->wtpqos) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->wtpqos);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->wtpqos = (struct capwap_80211_wtpqos_element*)ops->clone_message_element(wtpqos);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_wtpqos_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_wtpqos_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_WTP_QOS,
|
||||
.json_type = "IEEE80211WTPQoS",
|
||||
.create_message_element = ac_json_80211_wtpqos_createmessageelement,
|
||||
.add_message_element = ac_json_80211_wtpqos_addmessageelement,
|
||||
.create_json = ac_json_80211_wtpqos_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211WTPQoS: {
|
||||
TaggingPolicy: [int],
|
||||
Voice: {
|
||||
QueueDepth: [int],
|
||||
CWMin: [int],
|
||||
CWMax: [int],
|
||||
AIFS: [int],
|
||||
Priority8021p: [int],
|
||||
DSCP: [int]
|
||||
}
|
||||
Video: {
|
||||
QueueDepth: [int],
|
||||
CWMin: [int],
|
||||
CWMax: [int],
|
||||
AIFS: [int],
|
||||
Priority8021p: [int],
|
||||
DSCP: [int]
|
||||
}
|
||||
BestEffort: {
|
||||
QueueDepth: [int],
|
||||
CWMin: [int],
|
||||
CWMax: [int],
|
||||
AIFS: [int],
|
||||
Priority8021p: [int],
|
||||
DSCP: [int]
|
||||
}
|
||||
Background: {
|
||||
QueueDepth: [int],
|
||||
CWMin: [int],
|
||||
CWMax: [int],
|
||||
AIFS: [int],
|
||||
Priority8021p: [int],
|
||||
DSCP: [int]
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_wtpqos_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
return NULL; /* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_wtpqos_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_wtpqos_element* wtpqos = (struct capwap_80211_wtpqos_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpqos->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_QOS);
|
||||
|
||||
if (item->wtpqos) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->wtpqos);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->wtpqos = (struct capwap_80211_wtpqos_element*)ops->clone_message_element(wtpqos);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_wtpqos_createjson(struct json_object* jsonparent, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_wtpqos_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_WTP_QOS,
|
||||
.json_type = "IEEE80211WTPQoS",
|
||||
.create_message_element = ac_json_80211_wtpqos_createmessageelement,
|
||||
.add_message_element = ac_json_80211_wtpqos_addmessageelement,
|
||||
.create_json = ac_json_80211_wtpqos_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_WTPQOS_HEADER__
|
||||
#define __AC_JSON_80211_WTPQOS_HEADER__
|
||||
|
||||
#include "capwap_element_80211_wtpqos.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_wtpqos_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_WTPQOS_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_WTPQOS_HEADER__
|
||||
#define __AC_JSON_80211_WTPQOS_HEADER__
|
||||
|
||||
#include "capwap_element_80211_wtpqos.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_wtpqos_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_WTPQOS_HEADER__ */
|
||||
|
@ -1,128 +1,128 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211WTPRadioConfiguration: {
|
||||
ShortPreamble: [int],
|
||||
NumBSSIDs: [int],
|
||||
DTIMPeriod: [int],
|
||||
BSSID: [string],
|
||||
BeaconPeriod: [int],
|
||||
CountryString: [string]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_wtpradioconf_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradioconf_element* wtpradioconf;
|
||||
|
||||
wtpradioconf = (struct capwap_80211_wtpradioconf_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioconf_element));
|
||||
memset(wtpradioconf, 0, sizeof(struct capwap_80211_wtpradioconf_element));
|
||||
wtpradioconf->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "ShortPreamble");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioconf->shortpreamble = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "NumBSSIDs");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioconf->maxbssid = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "DTIMPeriod");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioconf->dtimperiod = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "BSSID");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
|
||||
if (!capwap_scanf_macaddress((unsigned char*)wtpradioconf->bssid, json_object_get_string(jsonitem), MACADDRESS_EUI48_LENGTH)) {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "BeaconPeriod");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioconf->beaconperiod = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CountryString");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
|
||||
const char* country = json_object_get_string(jsonitem);
|
||||
if (strlen(country) == (CAPWAP_WTP_RADIO_CONF_COUNTRY_LENGTH - 1)) {
|
||||
strcpy((char*)wtpradioconf->country, country);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wtpradioconf;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_wtpradioconf_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_wtpradioconf_element* wtpradioconf = (struct capwap_80211_wtpradioconf_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradioconf->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF);
|
||||
|
||||
if (item->wtpradioconf) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->wtpradioconf);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->wtpradioconf = (struct capwap_80211_wtpradioconf_element*)ops->clone_message_element(wtpradioconf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_wtpradioconf_createjson(struct json_object* jsonparent, void* data) {
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradioconf_element* wtpradioconf = (struct capwap_80211_wtpradioconf_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "ShortPreamble", json_object_new_int((int)wtpradioconf->shortpreamble));
|
||||
json_object_object_add(jsonitem, "NumBSSIDs", json_object_new_int((int)wtpradioconf->maxbssid));
|
||||
json_object_object_add(jsonitem, "DTIMPeriod", json_object_new_int((int)wtpradioconf->dtimperiod));
|
||||
json_object_object_add(jsonitem, "BSSID", json_object_new_string(capwap_printf_macaddress(buffer, wtpradioconf->bssid, MACADDRESS_EUI48_LENGTH)));
|
||||
json_object_object_add(jsonitem, "BeaconPeriod", json_object_new_int((int)wtpradioconf->beaconperiod));
|
||||
json_object_object_add(jsonitem, "CountryString", json_object_new_string((char*)wtpradioconf->country));
|
||||
json_object_object_add(jsonparent, "IEEE80211WTPRadioConfiguration", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_wtpradioconf_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_WTP_RADIO_CONF,
|
||||
.json_type = "IEEE80211WTPRadioConfiguration",
|
||||
.create_message_element = ac_json_80211_wtpradioconf_createmessageelement,
|
||||
.add_message_element = ac_json_80211_wtpradioconf_addmessageelement,
|
||||
.create_json = ac_json_80211_wtpradioconf_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211WTPRadioConfiguration: {
|
||||
ShortPreamble: [int],
|
||||
NumBSSIDs: [int],
|
||||
DTIMPeriod: [int],
|
||||
BSSID: [string],
|
||||
BeaconPeriod: [int],
|
||||
CountryString: [string]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_wtpradioconf_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradioconf_element* wtpradioconf;
|
||||
|
||||
wtpradioconf = (struct capwap_80211_wtpradioconf_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioconf_element));
|
||||
memset(wtpradioconf, 0, sizeof(struct capwap_80211_wtpradioconf_element));
|
||||
wtpradioconf->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "ShortPreamble");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioconf->shortpreamble = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "NumBSSIDs");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioconf->maxbssid = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "DTIMPeriod");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioconf->dtimperiod = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "BSSID");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
|
||||
if (!capwap_scanf_macaddress((unsigned char*)wtpradioconf->bssid, json_object_get_string(jsonitem), MACADDRESS_EUI48_LENGTH)) {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "BeaconPeriod");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioconf->beaconperiod = (uint16_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "CountryString");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
|
||||
const char* country = json_object_get_string(jsonitem);
|
||||
if (strlen(country) == (CAPWAP_WTP_RADIO_CONF_COUNTRY_LENGTH - 1)) {
|
||||
strcpy((char*)wtpradioconf->country, country);
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
capwap_free(wtpradioconf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wtpradioconf;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_wtpradioconf_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_wtpradioconf_element* wtpradioconf = (struct capwap_80211_wtpradioconf_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradioconf->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_CONF);
|
||||
|
||||
if (item->wtpradioconf) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->wtpradioconf);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->wtpradioconf = (struct capwap_80211_wtpradioconf_element*)ops->clone_message_element(wtpradioconf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_wtpradioconf_createjson(struct json_object* jsonparent, void* data) {
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradioconf_element* wtpradioconf = (struct capwap_80211_wtpradioconf_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "ShortPreamble", json_object_new_int((int)wtpradioconf->shortpreamble));
|
||||
json_object_object_add(jsonitem, "NumBSSIDs", json_object_new_int((int)wtpradioconf->maxbssid));
|
||||
json_object_object_add(jsonitem, "DTIMPeriod", json_object_new_int((int)wtpradioconf->dtimperiod));
|
||||
json_object_object_add(jsonitem, "BSSID", json_object_new_string(capwap_printf_macaddress(buffer, wtpradioconf->bssid, MACADDRESS_EUI48_LENGTH)));
|
||||
json_object_object_add(jsonitem, "BeaconPeriod", json_object_new_int((int)wtpradioconf->beaconperiod));
|
||||
json_object_object_add(jsonitem, "CountryString", json_object_new_string((char*)wtpradioconf->country));
|
||||
json_object_object_add(jsonparent, "IEEE80211WTPRadioConfiguration", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_wtpradioconf_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_WTP_RADIO_CONF,
|
||||
.json_type = "IEEE80211WTPRadioConfiguration",
|
||||
.create_message_element = ac_json_80211_wtpradioconf_createmessageelement,
|
||||
.add_message_element = ac_json_80211_wtpradioconf_addmessageelement,
|
||||
.create_json = ac_json_80211_wtpradioconf_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_WTPRADIOCONF_HEADER__
|
||||
#define __AC_JSON_80211_WTPRADIOCONF_HEADER__
|
||||
|
||||
#include "capwap_element_80211_wtpradioconf.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradioconf_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_WTPRADIOCONF_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_WTPRADIOCONF_HEADER__
|
||||
#define __AC_JSON_80211_WTPRADIOCONF_HEADER__
|
||||
|
||||
#include "capwap_element_80211_wtpradioconf.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradioconf_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_WTPRADIOCONF_HEADER__ */
|
||||
|
@ -1,79 +1,79 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211WTPRadioFailAlarm: {
|
||||
Type: [int],
|
||||
Status: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_wtpradiofailalarm_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm;
|
||||
|
||||
wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradiofailalarm_element));
|
||||
memset(wtpradiofailalarm, 0, sizeof(struct capwap_80211_wtpradiofailalarm_element));
|
||||
wtpradiofailalarm->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Type");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradiofailalarm->type = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradiofailalarm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Status");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradiofailalarm->status = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradiofailalarm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wtpradiofailalarm;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_wtpradiofailalarm_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradiofailalarm->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM);
|
||||
|
||||
if (item->wtpradiofailalarm) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->wtpradiofailalarm);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)ops->clone_message_element(wtpradiofailalarm);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_wtpradiofailalarm_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "Type", json_object_new_int((int)wtpradiofailalarm->type));
|
||||
json_object_object_add(jsonitem, "Status", json_object_new_int((int)wtpradiofailalarm->status));
|
||||
json_object_object_add(jsonparent, "IEEE80211WTPRadioFailAlarm", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_wtpradiofailalarm_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM,
|
||||
.json_type = "IEEE80211WTPRadioFailAlarm",
|
||||
.create_message_element = ac_json_80211_wtpradiofailalarm_createmessageelement,
|
||||
.add_message_element = ac_json_80211_wtpradiofailalarm_addmessageelement,
|
||||
.create_json = ac_json_80211_wtpradiofailalarm_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211WTPRadioFailAlarm: {
|
||||
Type: [int],
|
||||
Status: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_wtpradiofailalarm_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm;
|
||||
|
||||
wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradiofailalarm_element));
|
||||
memset(wtpradiofailalarm, 0, sizeof(struct capwap_80211_wtpradiofailalarm_element));
|
||||
wtpradiofailalarm->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Type");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradiofailalarm->type = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradiofailalarm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Status");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradiofailalarm->status = (uint8_t)json_object_get_int(jsonitem);
|
||||
} else {
|
||||
capwap_free(wtpradiofailalarm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wtpradiofailalarm;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_wtpradiofailalarm_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradiofailalarm->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM);
|
||||
|
||||
if (item->wtpradiofailalarm) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->wtpradiofailalarm);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)ops->clone_message_element(wtpradiofailalarm);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_wtpradiofailalarm_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "Type", json_object_new_int((int)wtpradiofailalarm->type));
|
||||
json_object_object_add(jsonitem, "Status", json_object_new_int((int)wtpradiofailalarm->status));
|
||||
json_object_object_add(jsonparent, "IEEE80211WTPRadioFailAlarm", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_wtpradiofailalarm_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_WTP_RADIO_FAIL_ALARM,
|
||||
.json_type = "IEEE80211WTPRadioFailAlarm",
|
||||
.create_message_element = ac_json_80211_wtpradiofailalarm_createmessageelement,
|
||||
.add_message_element = ac_json_80211_wtpradiofailalarm_addmessageelement,
|
||||
.create_json = ac_json_80211_wtpradiofailalarm_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__
|
||||
#define __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__
|
||||
|
||||
#include "capwap_element_80211_wtpradiofailalarm.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradiofailalarm_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__
|
||||
#define __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__
|
||||
|
||||
#include "capwap_element_80211_wtpradiofailalarm.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradiofailalarm_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_WTPRADIOFAILALARM_HEADER__ */
|
||||
|
@ -1,68 +1,68 @@
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211WTPRadioInformation: {
|
||||
Mode: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_wtpradioinformation_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradioinformation_element* wtpradioinformation;
|
||||
|
||||
wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioinformation_element));
|
||||
memset(wtpradioinformation, 0, sizeof(struct capwap_80211_wtpradioinformation_element));
|
||||
wtpradioinformation->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Mode");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioinformation->radiotype = (uint32_t)json_object_get_int(jsonitem) & CAPWAP_RADIO_TYPE_MASK;
|
||||
} else {
|
||||
capwap_free(wtpradioinformation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wtpradioinformation;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_wtpradioinformation_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_wtpradioinformation_element* wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradioinformation->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);
|
||||
|
||||
if (item->wtpradioinformation) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->wtpradioinformation);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)ops->clone_message_element(wtpradioinformation);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_wtpradioinformation_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradioinformation_element* wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "Mode", json_object_new_int((int)wtpradioinformation->radiotype));
|
||||
json_object_object_add(jsonparent, "IEEE80211WTPRadioInformation", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_wtpradioinformation_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION,
|
||||
.json_type = "IEEE80211WTPRadioInformation",
|
||||
.create_message_element = ac_json_80211_wtpradioinformation_createmessageelement,
|
||||
.add_message_element = ac_json_80211_wtpradioinformation_addmessageelement,
|
||||
.create_json = ac_json_80211_wtpradioinformation_createjson
|
||||
};
|
||||
#include "ac.h"
|
||||
#include "ac_json.h"
|
||||
|
||||
/*
|
||||
IEEE80211WTPRadioInformation: {
|
||||
Mode: [int]
|
||||
}
|
||||
*/
|
||||
|
||||
/* */
|
||||
static void* ac_json_80211_wtpradioinformation_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradioinformation_element* wtpradioinformation;
|
||||
|
||||
wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioinformation_element));
|
||||
memset(wtpradioinformation, 0, sizeof(struct capwap_80211_wtpradioinformation_element));
|
||||
wtpradioinformation->radioid = radioid;
|
||||
|
||||
/* */
|
||||
jsonitem = compat_json_object_object_get(jsonparent, "Mode");
|
||||
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
|
||||
wtpradioinformation->radiotype = (uint32_t)json_object_get_int(jsonitem) & CAPWAP_RADIO_TYPE_MASK;
|
||||
} else {
|
||||
capwap_free(wtpradioinformation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wtpradioinformation;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_json_80211_wtpradioinformation_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite) {
|
||||
struct capwap_80211_wtpradioinformation_element* wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)data;
|
||||
struct ac_json_ieee80211_item* item = &wtpradio->items[wtpradioinformation->radioid - 1];
|
||||
struct capwap_message_elements_ops* ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);
|
||||
|
||||
if (item->wtpradioinformation) {
|
||||
if (!overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->free_message_element(item->wtpradioinformation);
|
||||
}
|
||||
|
||||
item->valid = 1;
|
||||
item->wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)ops->clone_message_element(wtpradioinformation);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_json_80211_wtpradioinformation_createjson(struct json_object* jsonparent, void* data) {
|
||||
struct json_object* jsonitem;
|
||||
struct capwap_80211_wtpradioinformation_element* wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)data;
|
||||
|
||||
jsonitem = json_object_new_object();
|
||||
json_object_object_add(jsonitem, "Mode", json_object_new_int((int)wtpradioinformation->radiotype));
|
||||
json_object_object_add(jsonparent, "IEEE80211WTPRadioInformation", jsonitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops ac_json_80211_wtpradioinformation_ops = {
|
||||
.type = CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION,
|
||||
.json_type = "IEEE80211WTPRadioInformation",
|
||||
.create_message_element = ac_json_80211_wtpradioinformation_createmessageelement,
|
||||
.add_message_element = ac_json_80211_wtpradioinformation_addmessageelement,
|
||||
.create_json = ac_json_80211_wtpradioinformation_createjson
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__
|
||||
#define __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__
|
||||
|
||||
#include "capwap_element_80211_wtpradioinformation.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradioinformation_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__ */
|
||||
#ifndef __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__
|
||||
#define __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__
|
||||
|
||||
#include "capwap_element_80211_wtpradioinformation.h"
|
||||
|
||||
extern struct ac_json_ieee80211_ops ac_json_80211_wtpradioinformation_ops;
|
||||
|
||||
#endif /* __AC_JSON_80211_WTPRADIOINFORMATION_HEADER__ */
|
||||
|
1794
src/ac/ac_backend.c
1794
src/ac/ac_backend.c
File diff suppressed because it is too large
Load Diff
@ -1,22 +1,22 @@
|
||||
#ifndef __AC_BACKEND_HEADER__
|
||||
#define __AC_BACKEND_HEADER__
|
||||
|
||||
/* */
|
||||
#define SOAP_NAMESPACE_URI "http://smartcapwap/namespace"
|
||||
|
||||
/* SOAP event status*/
|
||||
#define SOAP_EVENT_STATUS_GENERIC_ERROR -1
|
||||
#define SOAP_EVENT_STATUS_CANCEL -2
|
||||
#define SOAP_EVENT_STATUS_RUNNING 0
|
||||
#define SOAP_EVENT_STATUS_COMPLETE 1
|
||||
|
||||
/* */
|
||||
int ac_backend_start(void);
|
||||
void ac_backend_stop(void);
|
||||
void ac_backend_free(void);
|
||||
|
||||
/* */
|
||||
int ac_backend_isconnect(void);
|
||||
struct ac_http_soap_request* ac_backend_createrequest_with_session(char* method, char* uri);
|
||||
|
||||
#endif /* __AC_BACKEND_HEADER__ */
|
||||
#ifndef __AC_BACKEND_HEADER__
|
||||
#define __AC_BACKEND_HEADER__
|
||||
|
||||
/* */
|
||||
#define SOAP_NAMESPACE_URI "http://smartcapwap/namespace"
|
||||
|
||||
/* SOAP event status*/
|
||||
#define SOAP_EVENT_STATUS_GENERIC_ERROR -1
|
||||
#define SOAP_EVENT_STATUS_CANCEL -2
|
||||
#define SOAP_EVENT_STATUS_RUNNING 0
|
||||
#define SOAP_EVENT_STATUS_COMPLETE 1
|
||||
|
||||
/* */
|
||||
int ac_backend_start(void);
|
||||
void ac_backend_stop(void);
|
||||
void ac_backend_free(void);
|
||||
|
||||
/* */
|
||||
int ac_backend_isconnect(void);
|
||||
struct ac_http_soap_request* ac_backend_createrequest_with_session(char* method, char* uri);
|
||||
|
||||
#endif /* __AC_BACKEND_HEADER__ */
|
||||
|
@ -1,459 +1,459 @@
|
||||
#include "ac.h"
|
||||
#include "ac_session.h"
|
||||
#include "ac_wlans.h"
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_probe_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Accept probe request only if not sent by WTP */
|
||||
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ac_station* station;
|
||||
struct ac_wlan* wlan;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_create_station(session, radioid, mgmt->bssid, mgmt->sa);
|
||||
if (!station || !station->wlan) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Receive IEEE802.11 Authentication Request from %s station", station->addrtext);
|
||||
|
||||
/* A station is removed if the association does not complete within a given period of time */
|
||||
station->timeoutaction = AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
|
||||
station->idtimeout = capwap_timeout_set(session->timeout, station->idtimeout, AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE, ac_stations_timeout, station, session);
|
||||
|
||||
/* */
|
||||
wlan = station->wlan;
|
||||
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
|
||||
/* TODO */
|
||||
} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
uint16_t algorithm;
|
||||
uint16_t transactionseqnumber;
|
||||
uint16_t responsestatuscode;
|
||||
uint8_t buffer[IEEE80211_MTU];
|
||||
struct ieee80211_authentication_params ieee80211_params;
|
||||
int responselength;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
|
||||
capwap_logging_info("Invalid IEEE802.11 Authentication Request from %s station", station->addrtext);
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
|
||||
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
|
||||
|
||||
/* */
|
||||
responsestatuscode = IEEE80211_STATUS_NOT_SUPPORTED_AUTHENTICATION_ALGORITHM;
|
||||
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (wlan->authmode == CAPWAP_ADD_WLAN_AUTHTYPE_OPEN)) {
|
||||
if (transactionseqnumber == 1) {
|
||||
responsestatuscode = IEEE80211_STATUS_SUCCESS;
|
||||
station->authalgorithm = IEEE80211_AUTHENTICATION_ALGORITHM_OPEN;
|
||||
} else {
|
||||
responsestatuscode = IEEE80211_STATUS_UNKNOWN_AUTHENTICATION_TRANSACTION;
|
||||
}
|
||||
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (wlan->authmode == CAPWAP_ADD_WLAN_AUTHTYPE_WEP)) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* Create authentication packet */
|
||||
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
|
||||
memcpy(ieee80211_params.bssid, wlan->address, MACADDRESS_EUI48_LENGTH);
|
||||
memcpy(ieee80211_params.station, mgmt->sa, MACADDRESS_EUI48_LENGTH);
|
||||
ieee80211_params.algorithm = algorithm;
|
||||
ieee80211_params.transactionseqnumber = transactionseqnumber + 1;
|
||||
ieee80211_params.statuscode = responsestatuscode;
|
||||
|
||||
responselength = ieee80211_create_authentication_response(buffer, sizeof(buffer), &ieee80211_params);
|
||||
if (responselength > 0) {
|
||||
/* Send authentication response */
|
||||
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
|
||||
capwap_logging_info("Sent IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)responsestatuscode);
|
||||
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
|
||||
} else {
|
||||
capwap_logging_warning("Unable to send IEEE802.11 Authentication Response to %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
} else {
|
||||
capwap_logging_warning("Unable to create IEEE802.11 Authentication Response to %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
}
|
||||
} else if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->da);
|
||||
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
|
||||
uint16_t algorithm;
|
||||
uint16_t transactionseqnumber;
|
||||
uint16_t statuscode;
|
||||
|
||||
/* */
|
||||
statuscode = __le16_to_cpu(mgmt->authetication.statuscode);
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Receive IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)statuscode);
|
||||
|
||||
if (statuscode == IEEE80211_STATUS_SUCCESS) {
|
||||
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
|
||||
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
|
||||
|
||||
/* Check if authenticate */
|
||||
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (transactionseqnumber == 2)) {
|
||||
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
|
||||
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (transactionseqnumber == 4)) {
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ac_station* station;
|
||||
struct ac_wlan* wlan;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get station */
|
||||
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->sa);
|
||||
if (!station || !station->wlan) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Receive IEEE802.11 Association Request from %s station", station->addrtext);
|
||||
|
||||
/* */
|
||||
wlan = station->wlan;
|
||||
if (!(station->flags & AC_STATION_FLAGS_AUTHENTICATED)) {
|
||||
/* Invalid station, delete station */
|
||||
capwap_logging_info("Receive IEEE802.11 Association Request from %s unauthorized station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get Station Info */
|
||||
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
|
||||
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
|
||||
|
||||
/* Get supported rates */
|
||||
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
|
||||
station->supportedratescount = ieitems.supported_rates->len;
|
||||
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
|
||||
if (ieitems.extended_supported_rates) {
|
||||
station->supportedratescount += ieitems.extended_supported_rates->len;
|
||||
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
|
||||
}
|
||||
|
||||
/* */
|
||||
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
|
||||
/* TODO */
|
||||
} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
int responselength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ieee80211_associationresponse_params ieee80211_params;
|
||||
uint16_t resultstatuscode;
|
||||
uint8_t buffer[IEEE80211_MTU];
|
||||
|
||||
/* Parsing Information Elements */
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
|
||||
capwap_logging_info("Invalid IEEE802.11 Association Request from %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify SSID */
|
||||
if (ieee80211_is_valid_ssid(wlan->ssid, ieitems.ssid, NULL) != IEEE80211_VALID_SSID) {
|
||||
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
|
||||
} else {
|
||||
/* Check supported rates */
|
||||
if (!ieitems.supported_rates || ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) > sizeof(station->supportedrates))) {
|
||||
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
|
||||
} else {
|
||||
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
|
||||
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
|
||||
if (ieee80211_aid_create(wlan->aidbitfield, &station->aid)) {
|
||||
resultstatuscode = IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
|
||||
} else {
|
||||
/* Get supported rates */
|
||||
station->supportedratescount = ieitems.supported_rates->len;
|
||||
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
|
||||
if (ieitems.extended_supported_rates) {
|
||||
station->supportedratescount += ieitems.extended_supported_rates->len;
|
||||
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
|
||||
}
|
||||
|
||||
/* */
|
||||
resultstatuscode = IEEE80211_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create association response packet */
|
||||
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
|
||||
memcpy(ieee80211_params.bssid, wlan->address, ETH_ALEN);
|
||||
memcpy(ieee80211_params.station, mgmt->sa, ETH_ALEN);
|
||||
ieee80211_params.capability = wlan->capability;
|
||||
ieee80211_params.statuscode = resultstatuscode;
|
||||
ieee80211_params.aid = IEEE80211_AID_FIELD | station->aid;
|
||||
memcpy(ieee80211_params.supportedrates, wlan->device->supportedrates, wlan->device->supportedratescount);
|
||||
ieee80211_params.supportedratescount = wlan->device->supportedratescount;
|
||||
|
||||
responselength = ieee80211_create_associationresponse_response(buffer, sizeof(buffer), &ieee80211_params);
|
||||
if (responselength > 0) {
|
||||
/* Send association response */
|
||||
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
|
||||
capwap_logging_info("Sent IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)resultstatuscode);
|
||||
|
||||
/* Active Station */
|
||||
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
|
||||
ac_stations_authorize_station(session, station);
|
||||
} else {
|
||||
capwap_logging_warning("Unable to send IEEE802.11 Association Response to %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
} else {
|
||||
capwap_logging_warning("Unable to create IEEE802.11 Association Response to %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ac_station* station;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationresponse.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get station */
|
||||
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->da);
|
||||
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
|
||||
capwap_logging_info("Receive IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)mgmt->associationresponse.statuscode);
|
||||
|
||||
if (mgmt->associationresponse.statuscode == IEEE80211_STATUS_SUCCESS) {
|
||||
/* Get Station Info */
|
||||
station->capability = __le16_to_cpu(mgmt->associationresponse.capability);
|
||||
station->aid = __le16_to_cpu(mgmt->associationresponse.aid);
|
||||
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
|
||||
|
||||
/* Get supported rates */
|
||||
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
|
||||
station->supportedratescount = ieitems.supported_rates->len;
|
||||
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
|
||||
if (ieitems.extended_supported_rates) {
|
||||
station->supportedratescount += ieitems.extended_supported_rates->len;
|
||||
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
|
||||
}
|
||||
|
||||
/* Active Station */
|
||||
ac_stations_authorize_station(session, station);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_reassociation_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->reassociationrequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_reassociation_response_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->reassociationresponse.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_disassociation_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->disassociation.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_deauthentication_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
const uint8_t* stationaddress;
|
||||
struct ac_station* station;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->deauthetication));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->deauthetication.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get station address */
|
||||
stationaddress = (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) ? mgmt->sa : mgmt->da);
|
||||
|
||||
/* Delete station */
|
||||
station = ac_stations_get_station(session, radioid, NULL, stationaddress);
|
||||
if (station) {
|
||||
/* Delete station without forward another IEEE802.11 deauthentication message */
|
||||
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, uint16_t framecontrol_subtype) {
|
||||
switch (framecontrol_subtype) {
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQUEST: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest))) {
|
||||
ac_ieee80211_mgmt_probe_request_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication))) {
|
||||
ac_ieee80211_mgmt_authentication_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest))) {
|
||||
ac_ieee80211_mgmt_association_request_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_RESPONSE: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse))) {
|
||||
ac_ieee80211_mgmt_association_response_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest))) {
|
||||
ac_ieee80211_mgmt_reassociation_request_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_RESPONSE: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse))) {
|
||||
ac_ieee80211_mgmt_reassociation_response_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation))) {
|
||||
ac_ieee80211_mgmt_disassociation_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTHENTICATION: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->deauthetication))) {
|
||||
ac_ieee80211_mgmt_deauthentication_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_ieee80211_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header* header, int length) {
|
||||
uint16_t framecontrol;
|
||||
uint16_t framecontrol_type;
|
||||
uint16_t framecontrol_subtype;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(header != NULL);
|
||||
ASSERT(length >= sizeof(struct ieee80211_header));
|
||||
|
||||
/* Get type frame */
|
||||
framecontrol = __le16_to_cpu(header->framecontrol);
|
||||
framecontrol_type = IEEE80211_FRAME_CONTROL_GET_TYPE(framecontrol);
|
||||
framecontrol_subtype = IEEE80211_FRAME_CONTROL_GET_SUBTYPE(framecontrol);
|
||||
|
||||
/* Parsing frame */
|
||||
if (framecontrol_type == IEEE80211_FRAMECONTROL_TYPE_MGMT) {
|
||||
ac_ieee80211_mgmt_packet(session, radioid, (const struct ieee80211_header_mgmt*)header, length, framecontrol_subtype);
|
||||
}
|
||||
}
|
||||
#include "ac.h"
|
||||
#include "ac_session.h"
|
||||
#include "ac_wlans.h"
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_probe_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Accept probe request only if not sent by WTP */
|
||||
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ac_station* station;
|
||||
struct ac_wlan* wlan;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_create_station(session, radioid, mgmt->bssid, mgmt->sa);
|
||||
if (!station || !station->wlan) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Receive IEEE802.11 Authentication Request from %s station", station->addrtext);
|
||||
|
||||
/* A station is removed if the association does not complete within a given period of time */
|
||||
station->timeoutaction = AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
|
||||
station->idtimeout = capwap_timeout_set(session->timeout, station->idtimeout, AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE, ac_stations_timeout, station, session);
|
||||
|
||||
/* */
|
||||
wlan = station->wlan;
|
||||
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
|
||||
/* TODO */
|
||||
} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
uint16_t algorithm;
|
||||
uint16_t transactionseqnumber;
|
||||
uint16_t responsestatuscode;
|
||||
uint8_t buffer[IEEE80211_MTU];
|
||||
struct ieee80211_authentication_params ieee80211_params;
|
||||
int responselength;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
|
||||
capwap_logging_info("Invalid IEEE802.11 Authentication Request from %s station", station->addrtext);
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
|
||||
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
|
||||
|
||||
/* */
|
||||
responsestatuscode = IEEE80211_STATUS_NOT_SUPPORTED_AUTHENTICATION_ALGORITHM;
|
||||
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (wlan->authmode == CAPWAP_ADD_WLAN_AUTHTYPE_OPEN)) {
|
||||
if (transactionseqnumber == 1) {
|
||||
responsestatuscode = IEEE80211_STATUS_SUCCESS;
|
||||
station->authalgorithm = IEEE80211_AUTHENTICATION_ALGORITHM_OPEN;
|
||||
} else {
|
||||
responsestatuscode = IEEE80211_STATUS_UNKNOWN_AUTHENTICATION_TRANSACTION;
|
||||
}
|
||||
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (wlan->authmode == CAPWAP_ADD_WLAN_AUTHTYPE_WEP)) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* Create authentication packet */
|
||||
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
|
||||
memcpy(ieee80211_params.bssid, wlan->address, MACADDRESS_EUI48_LENGTH);
|
||||
memcpy(ieee80211_params.station, mgmt->sa, MACADDRESS_EUI48_LENGTH);
|
||||
ieee80211_params.algorithm = algorithm;
|
||||
ieee80211_params.transactionseqnumber = transactionseqnumber + 1;
|
||||
ieee80211_params.statuscode = responsestatuscode;
|
||||
|
||||
responselength = ieee80211_create_authentication_response(buffer, sizeof(buffer), &ieee80211_params);
|
||||
if (responselength > 0) {
|
||||
/* Send authentication response */
|
||||
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
|
||||
capwap_logging_info("Sent IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)responsestatuscode);
|
||||
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
|
||||
} else {
|
||||
capwap_logging_warning("Unable to send IEEE802.11 Authentication Response to %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
} else {
|
||||
capwap_logging_warning("Unable to create IEEE802.11 Authentication Response to %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
}
|
||||
} else if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->da);
|
||||
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
|
||||
uint16_t algorithm;
|
||||
uint16_t transactionseqnumber;
|
||||
uint16_t statuscode;
|
||||
|
||||
/* */
|
||||
statuscode = __le16_to_cpu(mgmt->authetication.statuscode);
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Receive IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)statuscode);
|
||||
|
||||
if (statuscode == IEEE80211_STATUS_SUCCESS) {
|
||||
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
|
||||
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
|
||||
|
||||
/* Check if authenticate */
|
||||
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (transactionseqnumber == 2)) {
|
||||
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
|
||||
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (transactionseqnumber == 4)) {
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ac_station* station;
|
||||
struct ac_wlan* wlan;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get station */
|
||||
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->sa);
|
||||
if (!station || !station->wlan) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Receive IEEE802.11 Association Request from %s station", station->addrtext);
|
||||
|
||||
/* */
|
||||
wlan = station->wlan;
|
||||
if (!(station->flags & AC_STATION_FLAGS_AUTHENTICATED)) {
|
||||
/* Invalid station, delete station */
|
||||
capwap_logging_info("Receive IEEE802.11 Association Request from %s unauthorized station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get Station Info */
|
||||
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
|
||||
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
|
||||
|
||||
/* Get supported rates */
|
||||
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
|
||||
station->supportedratescount = ieitems.supported_rates->len;
|
||||
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
|
||||
if (ieitems.extended_supported_rates) {
|
||||
station->supportedratescount += ieitems.extended_supported_rates->len;
|
||||
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
|
||||
}
|
||||
|
||||
/* */
|
||||
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
|
||||
/* TODO */
|
||||
} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
int responselength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ieee80211_associationresponse_params ieee80211_params;
|
||||
uint16_t resultstatuscode;
|
||||
uint8_t buffer[IEEE80211_MTU];
|
||||
|
||||
/* Parsing Information Elements */
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
|
||||
capwap_logging_info("Invalid IEEE802.11 Association Request from %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify SSID */
|
||||
if (ieee80211_is_valid_ssid(wlan->ssid, ieitems.ssid, NULL) != IEEE80211_VALID_SSID) {
|
||||
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
|
||||
} else {
|
||||
/* Check supported rates */
|
||||
if (!ieitems.supported_rates || ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) > sizeof(station->supportedrates))) {
|
||||
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
|
||||
} else {
|
||||
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
|
||||
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
|
||||
if (ieee80211_aid_create(wlan->aidbitfield, &station->aid)) {
|
||||
resultstatuscode = IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
|
||||
} else {
|
||||
/* Get supported rates */
|
||||
station->supportedratescount = ieitems.supported_rates->len;
|
||||
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
|
||||
if (ieitems.extended_supported_rates) {
|
||||
station->supportedratescount += ieitems.extended_supported_rates->len;
|
||||
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
|
||||
}
|
||||
|
||||
/* */
|
||||
resultstatuscode = IEEE80211_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create association response packet */
|
||||
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
|
||||
memcpy(ieee80211_params.bssid, wlan->address, ETH_ALEN);
|
||||
memcpy(ieee80211_params.station, mgmt->sa, ETH_ALEN);
|
||||
ieee80211_params.capability = wlan->capability;
|
||||
ieee80211_params.statuscode = resultstatuscode;
|
||||
ieee80211_params.aid = IEEE80211_AID_FIELD | station->aid;
|
||||
memcpy(ieee80211_params.supportedrates, wlan->device->supportedrates, wlan->device->supportedratescount);
|
||||
ieee80211_params.supportedratescount = wlan->device->supportedratescount;
|
||||
|
||||
responselength = ieee80211_create_associationresponse_response(buffer, sizeof(buffer), &ieee80211_params);
|
||||
if (responselength > 0) {
|
||||
/* Send association response */
|
||||
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
|
||||
capwap_logging_info("Sent IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)resultstatuscode);
|
||||
|
||||
/* Active Station */
|
||||
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
|
||||
ac_stations_authorize_station(session, station);
|
||||
} else {
|
||||
capwap_logging_warning("Unable to send IEEE802.11 Association Response to %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
} else {
|
||||
capwap_logging_warning("Unable to create IEEE802.11 Association Response to %s station", station->addrtext);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ac_station* station;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationresponse.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get station */
|
||||
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->da);
|
||||
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
|
||||
capwap_logging_info("Receive IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)mgmt->associationresponse.statuscode);
|
||||
|
||||
if (mgmt->associationresponse.statuscode == IEEE80211_STATUS_SUCCESS) {
|
||||
/* Get Station Info */
|
||||
station->capability = __le16_to_cpu(mgmt->associationresponse.capability);
|
||||
station->aid = __le16_to_cpu(mgmt->associationresponse.aid);
|
||||
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
|
||||
|
||||
/* Get supported rates */
|
||||
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
|
||||
station->supportedratescount = ieitems.supported_rates->len;
|
||||
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
|
||||
if (ieitems.extended_supported_rates) {
|
||||
station->supportedratescount += ieitems.extended_supported_rates->len;
|
||||
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
|
||||
}
|
||||
|
||||
/* Active Station */
|
||||
ac_stations_authorize_station(session, station);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_reassociation_request_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->reassociationrequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_reassociation_response_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->reassociationresponse.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_disassociation_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->disassociation.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_deauthentication_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
const uint8_t* stationaddress;
|
||||
struct ac_station* station;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->deauthetication));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->deauthetication.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get station address */
|
||||
stationaddress = (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) ? mgmt->sa : mgmt->da);
|
||||
|
||||
/* Delete station */
|
||||
station = ac_stations_get_station(session, radioid, NULL, stationaddress);
|
||||
if (station) {
|
||||
/* Delete station without forward another IEEE802.11 deauthentication message */
|
||||
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, uint16_t framecontrol_subtype) {
|
||||
switch (framecontrol_subtype) {
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQUEST: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest))) {
|
||||
ac_ieee80211_mgmt_probe_request_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication))) {
|
||||
ac_ieee80211_mgmt_authentication_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest))) {
|
||||
ac_ieee80211_mgmt_association_request_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_RESPONSE: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse))) {
|
||||
ac_ieee80211_mgmt_association_response_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest))) {
|
||||
ac_ieee80211_mgmt_reassociation_request_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_RESPONSE: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse))) {
|
||||
ac_ieee80211_mgmt_reassociation_response_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation))) {
|
||||
ac_ieee80211_mgmt_disassociation_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTHENTICATION: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->deauthetication))) {
|
||||
ac_ieee80211_mgmt_deauthentication_packet(session, radioid, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_ieee80211_packet(struct ac_session_t* session, uint8_t radioid, const struct ieee80211_header* header, int length) {
|
||||
uint16_t framecontrol;
|
||||
uint16_t framecontrol_type;
|
||||
uint16_t framecontrol_subtype;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(header != NULL);
|
||||
ASSERT(length >= sizeof(struct ieee80211_header));
|
||||
|
||||
/* Get type frame */
|
||||
framecontrol = __le16_to_cpu(header->framecontrol);
|
||||
framecontrol_type = IEEE80211_FRAME_CONTROL_GET_TYPE(framecontrol);
|
||||
framecontrol_subtype = IEEE80211_FRAME_CONTROL_GET_SUBTYPE(framecontrol);
|
||||
|
||||
/* Parsing frame */
|
||||
if (framecontrol_type == IEEE80211_FRAMECONTROL_TYPE_MGMT) {
|
||||
ac_ieee80211_mgmt_packet(session, radioid, (const struct ieee80211_header_mgmt*)header, length, framecontrol_subtype);
|
||||
}
|
||||
}
|
||||
|
184
src/ac/ac_json.h
184
src/ac/ac_json.h
@ -1,92 +1,92 @@
|
||||
#ifndef __AC_JSON_HEADER__
|
||||
#define __AC_JSON_HEADER__
|
||||
|
||||
#include "capwap_array.h"
|
||||
#include <json/json.h>
|
||||
|
||||
#define IEEE80211_BINDING_JSON_ROOT "WTPRadio"
|
||||
|
||||
struct ac_json_ieee80211_item {
|
||||
int valid;
|
||||
struct capwap_80211_addwlan_element* addwlan;
|
||||
struct capwap_80211_antenna_element* antenna;
|
||||
struct capwap_80211_assignbssid_element* assignbssid;
|
||||
struct capwap_80211_deletewlan_element* deletewlan;
|
||||
struct capwap_80211_directsequencecontrol_element* directsequencecontrol;
|
||||
struct capwap_array* iearray;
|
||||
struct capwap_80211_macoperation_element* macoperation;
|
||||
struct capwap_80211_miccountermeasures_element* miccountermeasures;
|
||||
struct capwap_80211_multidomaincapability_element* multidomaincapability;
|
||||
struct capwap_80211_ofdmcontrol_element* ofdmcontrol;
|
||||
struct capwap_80211_rateset_element* rateset;
|
||||
struct capwap_80211_rsnaerrorreport_element* rsnaerrorreport;
|
||||
struct capwap_80211_statistics_element* statistics;
|
||||
struct capwap_80211_supportedrates_element* supportedrates;
|
||||
struct capwap_80211_txpower_element* txpower;
|
||||
struct capwap_80211_txpowerlevel_element* txpowerlevel;
|
||||
struct capwap_80211_updatewlan_element* updatewlan;
|
||||
struct capwap_80211_wtpqos_element* wtpqos;
|
||||
struct capwap_80211_wtpradioconf_element* wtpradioconf;
|
||||
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm;
|
||||
struct capwap_80211_wtpradioinformation_element* wtpradioinformation;
|
||||
};
|
||||
|
||||
struct ac_json_ieee80211_wtpradio {
|
||||
struct ac_json_ieee80211_item items[RADIOID_MAX_COUNT];
|
||||
};
|
||||
|
||||
/* JSON IEEE 802.11 message elements */
|
||||
#include "ac_80211_json_addwlan.h"
|
||||
#include "ac_80211_json_antenna.h"
|
||||
#include "ac_80211_json_assignbssid.h"
|
||||
#include "ac_80211_json_deletewlan.h"
|
||||
#include "ac_80211_json_directsequencecontrol.h"
|
||||
#include "ac_80211_json_ie.h"
|
||||
#include "ac_80211_json_macoperation.h"
|
||||
#include "ac_80211_json_miccountermeasures.h"
|
||||
#include "ac_80211_json_multidomaincapability.h"
|
||||
#include "ac_80211_json_ofdmcontrol.h"
|
||||
#include "ac_80211_json_rateset.h"
|
||||
#include "ac_80211_json_rsnaerrorreport.h"
|
||||
#include "ac_80211_json_statistics.h"
|
||||
#include "ac_80211_json_supportedrates.h"
|
||||
#include "ac_80211_json_txpower.h"
|
||||
#include "ac_80211_json_txpowerlevel.h"
|
||||
#include "ac_80211_json_updatewlan.h"
|
||||
#include "ac_80211_json_wtpqos.h"
|
||||
#include "ac_80211_json_wtpradioconf.h"
|
||||
#include "ac_80211_json_wtpradiofailalarm.h"
|
||||
#include "ac_80211_json_wtpradioinformation.h"
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops {
|
||||
/* Message Element Type */
|
||||
uint16_t type;
|
||||
|
||||
/* Message Element JSON Type */
|
||||
char* json_type;
|
||||
|
||||
/* Build message element */
|
||||
void* (*create_message_element)(struct json_object* jsonparent, uint16_t radioid);
|
||||
int (*add_message_element)(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite);
|
||||
|
||||
/* Build JSON */
|
||||
void (*create_json)(struct json_object* jsonparent, void* data);
|
||||
};
|
||||
|
||||
/* */
|
||||
void ac_json_ieee80211_init(struct ac_json_ieee80211_wtpradio* wtpradio);
|
||||
void ac_json_ieee80211_free(struct ac_json_ieee80211_wtpradio* wtpradio);
|
||||
|
||||
/* */
|
||||
int ac_json_ieee80211_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, uint16_t type, void* data, int overwrite);
|
||||
int ac_json_ieee80211_parsingmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_message_element_itemlist* messageelement);
|
||||
int ac_json_ieee80211_parsingjson(struct ac_json_ieee80211_wtpradio* wtpradio, struct json_object* jsonroot);
|
||||
|
||||
/* */
|
||||
struct json_object* ac_json_ieee80211_getjson(struct ac_json_ieee80211_wtpradio* wtpradio);
|
||||
void ac_json_ieee80211_buildpacket(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_packet_txmng* txmngpacket);
|
||||
|
||||
|
||||
|
||||
#endif /* __AC_JSON_HEADER__ */
|
||||
#ifndef __AC_JSON_HEADER__
|
||||
#define __AC_JSON_HEADER__
|
||||
|
||||
#include "capwap_array.h"
|
||||
#include <json/json.h>
|
||||
|
||||
#define IEEE80211_BINDING_JSON_ROOT "WTPRadio"
|
||||
|
||||
struct ac_json_ieee80211_item {
|
||||
int valid;
|
||||
struct capwap_80211_addwlan_element* addwlan;
|
||||
struct capwap_80211_antenna_element* antenna;
|
||||
struct capwap_80211_assignbssid_element* assignbssid;
|
||||
struct capwap_80211_deletewlan_element* deletewlan;
|
||||
struct capwap_80211_directsequencecontrol_element* directsequencecontrol;
|
||||
struct capwap_array* iearray;
|
||||
struct capwap_80211_macoperation_element* macoperation;
|
||||
struct capwap_80211_miccountermeasures_element* miccountermeasures;
|
||||
struct capwap_80211_multidomaincapability_element* multidomaincapability;
|
||||
struct capwap_80211_ofdmcontrol_element* ofdmcontrol;
|
||||
struct capwap_80211_rateset_element* rateset;
|
||||
struct capwap_80211_rsnaerrorreport_element* rsnaerrorreport;
|
||||
struct capwap_80211_statistics_element* statistics;
|
||||
struct capwap_80211_supportedrates_element* supportedrates;
|
||||
struct capwap_80211_txpower_element* txpower;
|
||||
struct capwap_80211_txpowerlevel_element* txpowerlevel;
|
||||
struct capwap_80211_updatewlan_element* updatewlan;
|
||||
struct capwap_80211_wtpqos_element* wtpqos;
|
||||
struct capwap_80211_wtpradioconf_element* wtpradioconf;
|
||||
struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm;
|
||||
struct capwap_80211_wtpradioinformation_element* wtpradioinformation;
|
||||
};
|
||||
|
||||
struct ac_json_ieee80211_wtpradio {
|
||||
struct ac_json_ieee80211_item items[RADIOID_MAX_COUNT];
|
||||
};
|
||||
|
||||
/* JSON IEEE 802.11 message elements */
|
||||
#include "ac_80211_json_addwlan.h"
|
||||
#include "ac_80211_json_antenna.h"
|
||||
#include "ac_80211_json_assignbssid.h"
|
||||
#include "ac_80211_json_deletewlan.h"
|
||||
#include "ac_80211_json_directsequencecontrol.h"
|
||||
#include "ac_80211_json_ie.h"
|
||||
#include "ac_80211_json_macoperation.h"
|
||||
#include "ac_80211_json_miccountermeasures.h"
|
||||
#include "ac_80211_json_multidomaincapability.h"
|
||||
#include "ac_80211_json_ofdmcontrol.h"
|
||||
#include "ac_80211_json_rateset.h"
|
||||
#include "ac_80211_json_rsnaerrorreport.h"
|
||||
#include "ac_80211_json_statistics.h"
|
||||
#include "ac_80211_json_supportedrates.h"
|
||||
#include "ac_80211_json_txpower.h"
|
||||
#include "ac_80211_json_txpowerlevel.h"
|
||||
#include "ac_80211_json_updatewlan.h"
|
||||
#include "ac_80211_json_wtpqos.h"
|
||||
#include "ac_80211_json_wtpradioconf.h"
|
||||
#include "ac_80211_json_wtpradiofailalarm.h"
|
||||
#include "ac_80211_json_wtpradioinformation.h"
|
||||
|
||||
/* */
|
||||
struct ac_json_ieee80211_ops {
|
||||
/* Message Element Type */
|
||||
uint16_t type;
|
||||
|
||||
/* Message Element JSON Type */
|
||||
char* json_type;
|
||||
|
||||
/* Build message element */
|
||||
void* (*create_message_element)(struct json_object* jsonparent, uint16_t radioid);
|
||||
int (*add_message_element)(struct ac_json_ieee80211_wtpradio* wtpradio, void* data, int overwrite);
|
||||
|
||||
/* Build JSON */
|
||||
void (*create_json)(struct json_object* jsonparent, void* data);
|
||||
};
|
||||
|
||||
/* */
|
||||
void ac_json_ieee80211_init(struct ac_json_ieee80211_wtpradio* wtpradio);
|
||||
void ac_json_ieee80211_free(struct ac_json_ieee80211_wtpradio* wtpradio);
|
||||
|
||||
/* */
|
||||
int ac_json_ieee80211_addmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, uint16_t type, void* data, int overwrite);
|
||||
int ac_json_ieee80211_parsingmessageelement(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_message_element_itemlist* messageelement);
|
||||
int ac_json_ieee80211_parsingjson(struct ac_json_ieee80211_wtpradio* wtpradio, struct json_object* jsonroot);
|
||||
|
||||
/* */
|
||||
struct json_object* ac_json_ieee80211_getjson(struct ac_json_ieee80211_wtpradio* wtpradio);
|
||||
void ac_json_ieee80211_buildpacket(struct ac_json_ieee80211_wtpradio* wtpradio, struct capwap_packet_txmng* txmngpacket);
|
||||
|
||||
|
||||
|
||||
#endif /* __AC_JSON_HEADER__ */
|
||||
|
1406
src/ac/ac_kmod.c
1406
src/ac/ac_kmod.c
File diff suppressed because it is too large
Load Diff
142
src/ac/ac_kmod.h
142
src/ac/ac_kmod.h
@ -1,71 +1,71 @@
|
||||
#ifndef __AC_KMOD_HEADER__
|
||||
#define __AC_KMOD_HEADER__
|
||||
|
||||
/* */
|
||||
#ifdef HAVE_LIBNL_10
|
||||
#define nl_sock nl_handle
|
||||
#endif
|
||||
|
||||
/* */
|
||||
#define AC_KMOD_MODE_LOCAL 0x00000001
|
||||
#define AC_KMOD_MODE_TUNNEL_USERMODE 0x00000002
|
||||
#define AC_KMOD_MODE_TUNNEL_KERNELMODE 0x00000003
|
||||
|
||||
/* */
|
||||
#define AC_KMOD_FLAGS_TUNNEL_NATIVE 0x00000000
|
||||
#define AC_KMOD_FLAGS_TUNNEL_8023 0x00000001
|
||||
|
||||
/* */
|
||||
struct ac_kmod_handle {
|
||||
/* Callback */
|
||||
struct nl_sock* nl;
|
||||
int nl_fd;
|
||||
struct nl_cb* nl_cb;
|
||||
int nlsmartcapwap_id;
|
||||
|
||||
/* Send message */
|
||||
capwap_lock_t msglock;
|
||||
struct nl_sock* nlmsg;
|
||||
struct nl_cb* nlmsg_cb;
|
||||
};
|
||||
|
||||
/* */
|
||||
#define AC_KMOD_EVENT_MAX_ITEMS 2
|
||||
struct ac_kmod_event {
|
||||
void (*event_handler)(int fd, void** params, int paramscount);
|
||||
int paramscount;
|
||||
void* params[AC_KMOD_EVENT_MAX_ITEMS];
|
||||
};
|
||||
|
||||
/* */
|
||||
int ac_kmod_init(void);
|
||||
void ac_kmod_free(void);
|
||||
|
||||
/* */
|
||||
int ac_kmod_isconnected(void);
|
||||
int ac_kmod_getfd(struct pollfd* fds, struct ac_kmod_event* events, int count);
|
||||
|
||||
/* */
|
||||
int ac_kmod_createdatachannel(int family, unsigned short port);
|
||||
|
||||
/* */
|
||||
int ac_kmod_send_keepalive(struct capwap_sessionid_element* sessionid);
|
||||
int ac_kmod_send_data(struct capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t binding, const uint8_t* data, int length);
|
||||
|
||||
/* */
|
||||
int ac_kmod_create_iface(const char* ifname, uint16_t mtu);
|
||||
int ac_kmod_delete_iface(int ifindex);
|
||||
|
||||
/* */
|
||||
int ac_kmod_new_datasession(struct capwap_sessionid_element* sessionid, uint8_t binding, uint16_t mtu);
|
||||
int ac_kmod_delete_datasession(struct capwap_sessionid_element* sessionid);
|
||||
|
||||
/* */
|
||||
int ac_kmod_addwlan(struct capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, uint8_t macmode, uint8_t tunnelmode);
|
||||
int ac_kmod_removewlan(struct capwap_sessionid_element* sessionid);
|
||||
|
||||
/* */
|
||||
int ac_kmod_authorize_station(struct capwap_sessionid_element* sessionid, const uint8_t* macaddress, int ifindex, uint8_t radioid, uint8_t wlanid, uint16_t vlan);
|
||||
int ac_kmod_deauthorize_station(struct capwap_sessionid_element* sessionid, const uint8_t* macaddress);
|
||||
|
||||
#endif /* __AC_KMOD_HEADER__ */
|
||||
#ifndef __AC_KMOD_HEADER__
|
||||
#define __AC_KMOD_HEADER__
|
||||
|
||||
/* */
|
||||
#ifdef HAVE_LIBNL_10
|
||||
#define nl_sock nl_handle
|
||||
#endif
|
||||
|
||||
/* */
|
||||
#define AC_KMOD_MODE_LOCAL 0x00000001
|
||||
#define AC_KMOD_MODE_TUNNEL_USERMODE 0x00000002
|
||||
#define AC_KMOD_MODE_TUNNEL_KERNELMODE 0x00000003
|
||||
|
||||
/* */
|
||||
#define AC_KMOD_FLAGS_TUNNEL_NATIVE 0x00000000
|
||||
#define AC_KMOD_FLAGS_TUNNEL_8023 0x00000001
|
||||
|
||||
/* */
|
||||
struct ac_kmod_handle {
|
||||
/* Callback */
|
||||
struct nl_sock* nl;
|
||||
int nl_fd;
|
||||
struct nl_cb* nl_cb;
|
||||
int nlsmartcapwap_id;
|
||||
|
||||
/* Send message */
|
||||
capwap_lock_t msglock;
|
||||
struct nl_sock* nlmsg;
|
||||
struct nl_cb* nlmsg_cb;
|
||||
};
|
||||
|
||||
/* */
|
||||
#define AC_KMOD_EVENT_MAX_ITEMS 2
|
||||
struct ac_kmod_event {
|
||||
void (*event_handler)(int fd, void** params, int paramscount);
|
||||
int paramscount;
|
||||
void* params[AC_KMOD_EVENT_MAX_ITEMS];
|
||||
};
|
||||
|
||||
/* */
|
||||
int ac_kmod_init(void);
|
||||
void ac_kmod_free(void);
|
||||
|
||||
/* */
|
||||
int ac_kmod_isconnected(void);
|
||||
int ac_kmod_getfd(struct pollfd* fds, struct ac_kmod_event* events, int count);
|
||||
|
||||
/* */
|
||||
int ac_kmod_createdatachannel(int family, unsigned short port);
|
||||
|
||||
/* */
|
||||
int ac_kmod_send_keepalive(struct capwap_sessionid_element* sessionid);
|
||||
int ac_kmod_send_data(struct capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t binding, const uint8_t* data, int length);
|
||||
|
||||
/* */
|
||||
int ac_kmod_create_iface(const char* ifname, uint16_t mtu);
|
||||
int ac_kmod_delete_iface(int ifindex);
|
||||
|
||||
/* */
|
||||
int ac_kmod_new_datasession(struct capwap_sessionid_element* sessionid, uint8_t binding, uint16_t mtu);
|
||||
int ac_kmod_delete_datasession(struct capwap_sessionid_element* sessionid);
|
||||
|
||||
/* */
|
||||
int ac_kmod_addwlan(struct capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, uint8_t macmode, uint8_t tunnelmode);
|
||||
int ac_kmod_removewlan(struct capwap_sessionid_element* sessionid);
|
||||
|
||||
/* */
|
||||
int ac_kmod_authorize_station(struct capwap_sessionid_element* sessionid, const uint8_t* macaddress, int ifindex, uint8_t radioid, uint8_t wlanid, uint16_t vlan);
|
||||
int ac_kmod_deauthorize_station(struct capwap_sessionid_element* sessionid, const uint8_t* macaddress);
|
||||
|
||||
#endif /* __AC_KMOD_HEADER__ */
|
||||
|
1736
src/ac/ac_soap.c
1736
src/ac/ac_soap.c
File diff suppressed because it is too large
Load Diff
228
src/ac/ac_soap.h
228
src/ac/ac_soap.h
@ -1,114 +1,114 @@
|
||||
#ifndef __AC_SOAP_HEADER__
|
||||
#define __AC_SOAP_HEADER__
|
||||
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
/* */
|
||||
#define SOAP_HTTP_PROTOCOL 1
|
||||
#define SOAP_HTTPS_PROTOCOL 2
|
||||
|
||||
#define SOAP_HTTP_PORT 80
|
||||
#define SOAP_HTTPS_PORT 443
|
||||
|
||||
#define HTTP_RESULT_CONTINUE 100
|
||||
#define HTTP_RESULT_OK 200
|
||||
|
||||
#define SOAP_PROTOCOL_REQUEST_TIMEOUT 10000
|
||||
#define SOAP_PROTOCOL_RESPONSE_TIMEOUT 10000
|
||||
#define SOAP_PROTOCOL_CLOSE_TIMEOUT 10000
|
||||
|
||||
/* */
|
||||
struct ac_http_soap_server {
|
||||
int protocol;
|
||||
union sockaddr_capwap address;
|
||||
|
||||
char* host;
|
||||
char* path;
|
||||
|
||||
/* SSL/TLS context */
|
||||
void* sslcontext;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_soap_request {
|
||||
xmlDocPtr xmlDocument;
|
||||
xmlNodePtr xmlRoot;
|
||||
xmlNodePtr xmlBody;
|
||||
xmlNodePtr xmlRequest;
|
||||
|
||||
char* method;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_http_soap_request {
|
||||
struct ac_http_soap_server* server;
|
||||
struct ac_soap_request* request;
|
||||
|
||||
int sock;
|
||||
int requesttimeout;
|
||||
int responsetimeout;
|
||||
|
||||
/* SSL info */
|
||||
struct capwap_socket_ssl* sslsock;
|
||||
|
||||
/* Information for SOAP Response */
|
||||
int httpstate;
|
||||
int responsecode;
|
||||
int contentlength;
|
||||
int contentxml;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_soap_response {
|
||||
int responsecode;
|
||||
xmlDocPtr xmlDocument;
|
||||
xmlNodePtr xmlRoot;
|
||||
xmlNodePtr xmlBody;
|
||||
|
||||
/* Valid response */
|
||||
xmlNodePtr xmlResponse;
|
||||
xmlNodePtr xmlResponseReturn;
|
||||
|
||||
/* Fault response */
|
||||
xmlNodePtr xmlFault;
|
||||
xmlNodePtr xmlFaultCode;
|
||||
xmlNodePtr xmlFaultString;
|
||||
};
|
||||
|
||||
/* */
|
||||
void ac_soapclient_init(void);
|
||||
void ac_soapclient_free(void);
|
||||
|
||||
/* */
|
||||
struct ac_http_soap_server* ac_soapclient_create_server(const char* url);
|
||||
void ac_soapclient_free_server(struct ac_http_soap_server* server);
|
||||
|
||||
/* Request */
|
||||
struct ac_soap_request* ac_soapclient_create_request(char* method, char* urinamespace);
|
||||
int ac_soapclient_add_param(struct ac_soap_request* request, const char* type, const char* name, const char* value);
|
||||
char* ac_soapclient_get_request(struct ac_soap_request* request);
|
||||
void ac_soapclient_free_request(struct ac_soap_request* request);
|
||||
|
||||
/* Transport Request */
|
||||
struct ac_http_soap_request* ac_soapclient_prepare_request(struct ac_soap_request* request, struct ac_http_soap_server* server);
|
||||
int ac_soapclient_send_request(struct ac_http_soap_request* httprequest, char* soapaction);
|
||||
struct ac_soap_response* ac_soapclient_recv_response(struct ac_http_soap_request* httprequest);
|
||||
|
||||
struct json_object* ac_soapclient_parse_json_response(struct ac_soap_response* response);
|
||||
|
||||
void ac_soapclient_shutdown_request(struct ac_http_soap_request* httprequest);
|
||||
void ac_soapclient_close_request(struct ac_http_soap_request* httprequest, int closerequest);
|
||||
|
||||
/* Response */
|
||||
void ac_soapclient_free_response(struct ac_soap_response* response);
|
||||
|
||||
/* Base64 */
|
||||
#define AC_BASE64_ENCODE_LENGTH(x) ((((x) + 2) / 3) * 4 + 1)
|
||||
#define AC_BASE64_DECODE_LENGTH(x) (((x) / 4) * 3 + 1)
|
||||
void ac_base64_string_encode(const char* plain, char* encoded);
|
||||
int ac_base64_binary_encode(const char* plain, int length, char* encoded);
|
||||
void ac_base64_string_decode(const char* encoded, char* plain);
|
||||
int ac_base64_binary_decode(const char* encoded, int length, char* plain);
|
||||
|
||||
#endif /* __AC_SOAP_HEADER__ */
|
||||
#ifndef __AC_SOAP_HEADER__
|
||||
#define __AC_SOAP_HEADER__
|
||||
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
/* */
|
||||
#define SOAP_HTTP_PROTOCOL 1
|
||||
#define SOAP_HTTPS_PROTOCOL 2
|
||||
|
||||
#define SOAP_HTTP_PORT 80
|
||||
#define SOAP_HTTPS_PORT 443
|
||||
|
||||
#define HTTP_RESULT_CONTINUE 100
|
||||
#define HTTP_RESULT_OK 200
|
||||
|
||||
#define SOAP_PROTOCOL_REQUEST_TIMEOUT 10000
|
||||
#define SOAP_PROTOCOL_RESPONSE_TIMEOUT 10000
|
||||
#define SOAP_PROTOCOL_CLOSE_TIMEOUT 10000
|
||||
|
||||
/* */
|
||||
struct ac_http_soap_server {
|
||||
int protocol;
|
||||
union sockaddr_capwap address;
|
||||
|
||||
char* host;
|
||||
char* path;
|
||||
|
||||
/* SSL/TLS context */
|
||||
void* sslcontext;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_soap_request {
|
||||
xmlDocPtr xmlDocument;
|
||||
xmlNodePtr xmlRoot;
|
||||
xmlNodePtr xmlBody;
|
||||
xmlNodePtr xmlRequest;
|
||||
|
||||
char* method;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_http_soap_request {
|
||||
struct ac_http_soap_server* server;
|
||||
struct ac_soap_request* request;
|
||||
|
||||
int sock;
|
||||
int requesttimeout;
|
||||
int responsetimeout;
|
||||
|
||||
/* SSL info */
|
||||
struct capwap_socket_ssl* sslsock;
|
||||
|
||||
/* Information for SOAP Response */
|
||||
int httpstate;
|
||||
int responsecode;
|
||||
int contentlength;
|
||||
int contentxml;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_soap_response {
|
||||
int responsecode;
|
||||
xmlDocPtr xmlDocument;
|
||||
xmlNodePtr xmlRoot;
|
||||
xmlNodePtr xmlBody;
|
||||
|
||||
/* Valid response */
|
||||
xmlNodePtr xmlResponse;
|
||||
xmlNodePtr xmlResponseReturn;
|
||||
|
||||
/* Fault response */
|
||||
xmlNodePtr xmlFault;
|
||||
xmlNodePtr xmlFaultCode;
|
||||
xmlNodePtr xmlFaultString;
|
||||
};
|
||||
|
||||
/* */
|
||||
void ac_soapclient_init(void);
|
||||
void ac_soapclient_free(void);
|
||||
|
||||
/* */
|
||||
struct ac_http_soap_server* ac_soapclient_create_server(const char* url);
|
||||
void ac_soapclient_free_server(struct ac_http_soap_server* server);
|
||||
|
||||
/* Request */
|
||||
struct ac_soap_request* ac_soapclient_create_request(char* method, char* urinamespace);
|
||||
int ac_soapclient_add_param(struct ac_soap_request* request, const char* type, const char* name, const char* value);
|
||||
char* ac_soapclient_get_request(struct ac_soap_request* request);
|
||||
void ac_soapclient_free_request(struct ac_soap_request* request);
|
||||
|
||||
/* Transport Request */
|
||||
struct ac_http_soap_request* ac_soapclient_prepare_request(struct ac_soap_request* request, struct ac_http_soap_server* server);
|
||||
int ac_soapclient_send_request(struct ac_http_soap_request* httprequest, char* soapaction);
|
||||
struct ac_soap_response* ac_soapclient_recv_response(struct ac_http_soap_request* httprequest);
|
||||
|
||||
struct json_object* ac_soapclient_parse_json_response(struct ac_soap_response* response);
|
||||
|
||||
void ac_soapclient_shutdown_request(struct ac_http_soap_request* httprequest);
|
||||
void ac_soapclient_close_request(struct ac_http_soap_request* httprequest, int closerequest);
|
||||
|
||||
/* Response */
|
||||
void ac_soapclient_free_response(struct ac_soap_response* response);
|
||||
|
||||
/* Base64 */
|
||||
#define AC_BASE64_ENCODE_LENGTH(x) ((((x) + 2) / 3) * 4 + 1)
|
||||
#define AC_BASE64_DECODE_LENGTH(x) (((x) / 4) * 3 + 1)
|
||||
void ac_base64_string_encode(const char* plain, char* encoded);
|
||||
int ac_base64_binary_encode(const char* plain, int length, char* encoded);
|
||||
void ac_base64_string_decode(const char* encoded, char* plain);
|
||||
int ac_base64_binary_decode(const char* encoded, int length, char* plain);
|
||||
|
||||
#endif /* __AC_SOAP_HEADER__ */
|
||||
|
@ -1,488 +1,488 @@
|
||||
#include "ac.h"
|
||||
#include "ac_session.h"
|
||||
#include "ac_wlans.h"
|
||||
#include "ac_backend.h"
|
||||
|
||||
/* */
|
||||
static void ac_stations_reset_station(struct ac_session_t* session, struct ac_station* station, struct ac_wlan* wlan) {
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
if (station->wlan) {
|
||||
if (station->aid) {
|
||||
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
ieee80211_aid_free(station->wlan->aidbitfield, station->aid);
|
||||
}
|
||||
|
||||
station->aid = 0;
|
||||
}
|
||||
|
||||
/* Remove reference from current WLAN */
|
||||
capwap_itemlist_remove(station->wlan->stations, station->wlanitem);
|
||||
}
|
||||
|
||||
/* Remove timers */
|
||||
if (station->idtimeout != CAPWAP_TIMEOUT_INDEX_NO_SET) {
|
||||
capwap_timeout_deletetimer(session->timeout, station->idtimeout);
|
||||
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
|
||||
}
|
||||
|
||||
/* */
|
||||
station->flags = 0;
|
||||
|
||||
/* Set WLAN */
|
||||
station->wlan = wlan;
|
||||
if (station->wlan) {
|
||||
capwap_itemlist_insert_after(wlan->stations, NULL, station->wlanitem);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_stations_destroy_station(struct ac_session_t* session, struct ac_station* station) {
|
||||
struct ac_station* authoritativestation;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Destroy station: %s", station->addrtext);
|
||||
|
||||
/* Remove reference from Authoritative Stations List */
|
||||
capwap_rwlock_wrlock(&g_ac.authstationslock);
|
||||
|
||||
/* Can delete global reference only if match session handler */
|
||||
authoritativestation = (struct ac_station*)capwap_hash_search(g_ac.authstations, station->address);
|
||||
if (authoritativestation && (authoritativestation->session == session)) {
|
||||
capwap_hash_delete(g_ac.authstations, station->address);
|
||||
}
|
||||
|
||||
capwap_rwlock_unlock(&g_ac.authstationslock);
|
||||
|
||||
/* Remove reference from WLAN */
|
||||
ac_stations_reset_station(session, station, NULL);
|
||||
|
||||
/* */
|
||||
capwap_hash_delete(session->wlans->stations, station->address);
|
||||
|
||||
/* Free station reference with itemlist */
|
||||
capwap_itemlist_free(station->wlanitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
static unsigned long ac_wlans_item_gethash(const void* key, unsigned long hashsize) {
|
||||
uint8_t* macaddress = (uint8_t*)key;
|
||||
|
||||
return ((unsigned long)(macaddress[3] ^ macaddress[4] ^ macaddress[5]) % AC_WLANS_STATIONS_HASH_SIZE);
|
||||
}
|
||||
|
||||
/* */
|
||||
static const void* ac_wlans_item_getkey(const void* data) {
|
||||
return (const void*)((struct ac_station*)data)->address;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_wlans_item_cmp(const void* key1, const void* key2) {
|
||||
return memcmp(key1, key2, MACADDRESS_EUI48_LENGTH);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_init(struct ac_session_t* session) {
|
||||
int i;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans == NULL);
|
||||
|
||||
/* */
|
||||
session->wlans = (struct ac_wlans*)capwap_alloc(sizeof(struct ac_wlans));
|
||||
memset(session->wlans, 0, sizeof(struct ac_wlans));
|
||||
|
||||
/* */
|
||||
session->wlans->stations = capwap_hash_create(AC_WLANS_STATIONS_HASH_SIZE);
|
||||
session->wlans->stations->item_gethash = ac_wlans_item_gethash;
|
||||
session->wlans->stations->item_getkey = ac_wlans_item_getkey;
|
||||
session->wlans->stations->item_cmp = ac_wlans_item_cmp;
|
||||
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
session->wlans->devices[i].radioid = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_destroy(struct ac_session_t* session) {
|
||||
int i;
|
||||
struct capwap_list* items;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
|
||||
/* */
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
if (session->wlans->devices[i].wlans) {
|
||||
items = session->wlans->devices[i].wlans;
|
||||
|
||||
/* Delete WLANS */
|
||||
while (items->first) {
|
||||
ac_wlans_delete_bssid(session, i + 1, ((struct ac_wlan*)items->first->item)->address);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_list_free(items);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
ASSERT(session->wlans->stations->count == 0);
|
||||
|
||||
/* */
|
||||
capwap_hash_free(session->wlans->stations);
|
||||
capwap_free(session->wlans);
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan) {
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(wlan != NULL);
|
||||
ASSERT(wlan->device != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(wlan->device->radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlan->wlanid));
|
||||
|
||||
/* */
|
||||
if (ac_wlans_get_bssid(session, wlan->device->radioid, wlan->address)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* */
|
||||
wlan->session = session;
|
||||
|
||||
/* Create WLAN list */
|
||||
if (!session->wlans->devices[wlan->device->radioid - 1].wlans) {
|
||||
session->wlans->devices[wlan->device->radioid - 1].wlans = capwap_list_create();
|
||||
}
|
||||
|
||||
/* Append WLAN to list */
|
||||
capwap_itemlist_insert_after(session->wlans->devices[wlan->device->radioid - 1].wlans, NULL, wlan->wlanitem);
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Added new wlan with radioid: %d, wlanid: %d, bssid: %s", (int)wlan->device->radioid, (int)wlan->wlanid, capwap_printf_macaddress(buffer, wlan->address, MACADDRESS_EUI48_LENGTH));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan) {
|
||||
struct ac_wlan* wlan;
|
||||
struct capwap_list_item* wlanitem;
|
||||
|
||||
ASSERT(device != NULL);
|
||||
ASSERT(IS_VALID_WLANID(wlanid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
wlanitem = capwap_itemlist_create(sizeof(struct ac_wlan));
|
||||
wlan = (struct ac_wlan*)wlanitem->item;
|
||||
memset(wlan, 0, sizeof(struct ac_wlan));
|
||||
|
||||
/* Init WLAN */
|
||||
wlan->wlanitem = wlanitem;
|
||||
memcpy(wlan->address, bssid, MACADDRESS_EUI48_LENGTH);
|
||||
wlan->device = device;
|
||||
wlan->wlanid = wlanid;
|
||||
wlan->stations = capwap_list_create();
|
||||
|
||||
/* Set capability */
|
||||
wlan->capability = addwlan->capability;
|
||||
|
||||
wlan->keyindex = addwlan->keyindex;
|
||||
wlan->keystatus = addwlan->keystatus;
|
||||
wlan->keylength = addwlan->keylength;
|
||||
if (addwlan->key && (addwlan->keylength > 0)) {
|
||||
wlan->key = (uint8_t*)capwap_clone(addwlan->key, wlan->keylength);
|
||||
}
|
||||
|
||||
memcpy(wlan->grouptsc, addwlan->grouptsc, CAPWAP_ADD_WLAN_GROUPTSC_LENGTH);
|
||||
|
||||
wlan->qos = addwlan->qos;
|
||||
wlan->authmode = addwlan->authmode;
|
||||
wlan->macmode = addwlan->macmode;
|
||||
wlan->tunnelmode = addwlan->tunnelmode;
|
||||
|
||||
wlan->suppressssid = addwlan->suppressssid;
|
||||
strcpy(wlan->ssid, (const char*)addwlan->ssid);
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (session->wlans->devices[radioid - 1].wlans) {
|
||||
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (!memcmp(bssid, item->address, MACADDRESS_EUI48_LENGTH)) {
|
||||
wlan = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlanid));
|
||||
|
||||
/* */
|
||||
if (session->wlans->devices[radioid - 1].wlans) {
|
||||
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (wlanid == item->wlanid) {
|
||||
wlan = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_free_bssid(struct ac_wlan* wlan) {
|
||||
ASSERT(wlan != NULL);
|
||||
|
||||
/* Free capability */
|
||||
if (wlan->key) {
|
||||
capwap_free(wlan->key);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_list_free(wlan->stations);
|
||||
capwap_itemlist_free(wlan->wlanitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (session->wlans->devices[radioid - 1].wlans) {
|
||||
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
|
||||
struct ac_wlan* wlan = (struct ac_wlan*)search->item;
|
||||
|
||||
if (!memcmp(bssid, wlan->address, MACADDRESS_EUI48_LENGTH)) {
|
||||
/* Remove stations */
|
||||
while (wlan->stations->first) {
|
||||
ac_stations_destroy_station(session, (struct ac_station*)wlan->stations->first->item);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_itemlist_remove(session->wlans->devices[radioid - 1].wlans, search);
|
||||
ac_wlans_free_bssid(wlan);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
|
||||
struct ac_station* station;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(address != NULL);
|
||||
|
||||
/* Get station */
|
||||
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
|
||||
if (station && (station->flags & AC_STATION_FLAGS_ENABLED) && ((radioid == RADIOID_ANY) || (radioid == station->wlan->device->radioid)) && (!bssid || !memcmp(bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH))) {
|
||||
return station;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
|
||||
char buffer1[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
char buffer2[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
struct ac_wlan* wlan;
|
||||
struct ac_station* authoritativestation;
|
||||
struct ac_station* station = NULL;
|
||||
struct ac_session_t* authoritativesession = NULL;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
ASSERT(address != NULL);
|
||||
|
||||
/* */
|
||||
capwap_printf_macaddress(buffer1, bssid, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_printf_macaddress(buffer2, address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_logging_info("Create station to radioid: %d, bssid: %s, station address: %s", (int)radioid, buffer1, buffer2);
|
||||
|
||||
/* */
|
||||
wlan = ac_wlans_get_bssid(session, radioid, bssid);
|
||||
if (wlan) {
|
||||
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
|
||||
if (!station) {
|
||||
struct capwap_list_item* stationitem = capwap_itemlist_create(sizeof(struct ac_station));
|
||||
|
||||
station = (struct ac_station*)stationitem->item;
|
||||
memset(station, 0, sizeof(struct ac_station));
|
||||
|
||||
/* */
|
||||
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
|
||||
memcpy(station->address, address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_printf_macaddress(station->addrtext, address, MACADDRESS_EUI48_LENGTH);
|
||||
station->wlanitem = stationitem;
|
||||
station->session = session;
|
||||
|
||||
/* */
|
||||
capwap_hash_add(session->wlans->stations, (void*)station);
|
||||
}
|
||||
|
||||
/* Set station to WLAN */
|
||||
ac_stations_reset_station(session, station, wlan);
|
||||
station->flags |= AC_STATION_FLAGS_ENABLED;
|
||||
|
||||
/* Check Authoritative Stations List */
|
||||
capwap_rwlock_rdlock(&g_ac.authstationslock);
|
||||
|
||||
authoritativestation = (struct ac_station*)capwap_hash_search(g_ac.authstations, address);
|
||||
if (authoritativestation && authoritativestation->session) {
|
||||
authoritativesession = authoritativestation->session;
|
||||
}
|
||||
|
||||
capwap_rwlock_unlock(&g_ac.authstationslock);
|
||||
|
||||
/* Check Authoritative Session */
|
||||
if (authoritativesession != session) {
|
||||
/* Update Authoritative Stations List */
|
||||
capwap_rwlock_wrlock(&g_ac.authstationslock);
|
||||
capwap_hash_add(g_ac.authstations, (void*)station);
|
||||
capwap_rwlock_unlock(&g_ac.authstationslock);
|
||||
|
||||
/* Release Station from old Authoritative Session */
|
||||
if (authoritativesession) {
|
||||
ac_session_send_action(authoritativesession, AC_SESSION_ACTION_STATION_ROAMING, 0, (void*)address, MACADDRESS_EUI48_LENGTH);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
capwap_logging_warning("Unable to find radioid: %d, bssid: %s", (int)radioid, buffer1);
|
||||
}
|
||||
|
||||
return station;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station) {
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* Deauthorize station */
|
||||
ac_stations_deauthorize_station(session, station);
|
||||
|
||||
/* Destroy station reference */
|
||||
ac_stations_destroy_station(session, station);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station) {
|
||||
struct ac_notify_station_configuration_ieee8011_add_station notify;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* Active Station only if Authenticated, Associated and not Authorizated */
|
||||
if ((station->flags & AC_STATION_FLAGS_AUTHENTICATED) && (station->flags & AC_STATION_FLAGS_ASSOCIATE) && !(station->flags & AC_STATION_FLAGS_AUTHORIZED)) {
|
||||
memset(¬ify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
|
||||
notify.radioid = station->wlan->device->radioid;
|
||||
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
notify.wlanid = station->wlan->wlanid;
|
||||
notify.associationid = station->aid;
|
||||
notify.capabilities = station->capability;
|
||||
notify.supportedratescount = station->supportedratescount;
|
||||
memcpy(notify.supportedrates, station->supportedrates, station->supportedratescount);
|
||||
|
||||
ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station) {
|
||||
int responselength;
|
||||
uint8_t buffer[IEEE80211_MTU];
|
||||
struct ieee80211_deauthentication_params ieee80211_params;
|
||||
struct ac_notify_station_configuration_ieee8011_delete_station notify;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
if (station->flags & AC_STATION_FLAGS_AUTHORIZED) {
|
||||
/* Deauthorize station */
|
||||
memset(¬ify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
|
||||
notify.radioid = station->wlan->device->radioid;
|
||||
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
|
||||
/* */
|
||||
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE | AC_STATION_FLAGS_AUTHORIZED);
|
||||
ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
|
||||
} else if (station->flags & AC_STATION_FLAGS_AUTHENTICATED) {
|
||||
/* Create deauthentication packet */
|
||||
memset(&ieee80211_params, 0, sizeof(struct ieee80211_deauthentication_params));
|
||||
memcpy(ieee80211_params.bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH);
|
||||
memcpy(ieee80211_params.station, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
ieee80211_params.reasoncode = IEEE80211_REASON_PREV_AUTH_NOT_VALID;
|
||||
|
||||
/* */
|
||||
responselength = ieee80211_create_deauthentication(buffer, IEEE80211_MTU, &ieee80211_params);
|
||||
if (responselength > 0) {
|
||||
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
|
||||
ac_kmod_send_data(&session->sessionid, station->wlan->device->radioid, session->binding, buffer, responselength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param) {
|
||||
struct ac_station* station = (struct ac_station*)context;
|
||||
|
||||
ASSERT(station != NULL);
|
||||
|
||||
if (station->idtimeout == index) {
|
||||
switch (station->timeoutaction) {
|
||||
case AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE: {
|
||||
capwap_logging_warning("The %s station has not completed the association in time", station->addrtext);
|
||||
ac_stations_delete_station((struct ac_session_t*)param, station);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "ac.h"
|
||||
#include "ac_session.h"
|
||||
#include "ac_wlans.h"
|
||||
#include "ac_backend.h"
|
||||
|
||||
/* */
|
||||
static void ac_stations_reset_station(struct ac_session_t* session, struct ac_station* station, struct ac_wlan* wlan) {
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
if (station->wlan) {
|
||||
if (station->aid) {
|
||||
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
ieee80211_aid_free(station->wlan->aidbitfield, station->aid);
|
||||
}
|
||||
|
||||
station->aid = 0;
|
||||
}
|
||||
|
||||
/* Remove reference from current WLAN */
|
||||
capwap_itemlist_remove(station->wlan->stations, station->wlanitem);
|
||||
}
|
||||
|
||||
/* Remove timers */
|
||||
if (station->idtimeout != CAPWAP_TIMEOUT_INDEX_NO_SET) {
|
||||
capwap_timeout_deletetimer(session->timeout, station->idtimeout);
|
||||
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
|
||||
}
|
||||
|
||||
/* */
|
||||
station->flags = 0;
|
||||
|
||||
/* Set WLAN */
|
||||
station->wlan = wlan;
|
||||
if (station->wlan) {
|
||||
capwap_itemlist_insert_after(wlan->stations, NULL, station->wlanitem);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_stations_destroy_station(struct ac_session_t* session, struct ac_station* station) {
|
||||
struct ac_station* authoritativestation;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Destroy station: %s", station->addrtext);
|
||||
|
||||
/* Remove reference from Authoritative Stations List */
|
||||
capwap_rwlock_wrlock(&g_ac.authstationslock);
|
||||
|
||||
/* Can delete global reference only if match session handler */
|
||||
authoritativestation = (struct ac_station*)capwap_hash_search(g_ac.authstations, station->address);
|
||||
if (authoritativestation && (authoritativestation->session == session)) {
|
||||
capwap_hash_delete(g_ac.authstations, station->address);
|
||||
}
|
||||
|
||||
capwap_rwlock_unlock(&g_ac.authstationslock);
|
||||
|
||||
/* Remove reference from WLAN */
|
||||
ac_stations_reset_station(session, station, NULL);
|
||||
|
||||
/* */
|
||||
capwap_hash_delete(session->wlans->stations, station->address);
|
||||
|
||||
/* Free station reference with itemlist */
|
||||
capwap_itemlist_free(station->wlanitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
static unsigned long ac_wlans_item_gethash(const void* key, unsigned long hashsize) {
|
||||
uint8_t* macaddress = (uint8_t*)key;
|
||||
|
||||
return ((unsigned long)(macaddress[3] ^ macaddress[4] ^ macaddress[5]) % AC_WLANS_STATIONS_HASH_SIZE);
|
||||
}
|
||||
|
||||
/* */
|
||||
static const void* ac_wlans_item_getkey(const void* data) {
|
||||
return (const void*)((struct ac_station*)data)->address;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_wlans_item_cmp(const void* key1, const void* key2) {
|
||||
return memcmp(key1, key2, MACADDRESS_EUI48_LENGTH);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_init(struct ac_session_t* session) {
|
||||
int i;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans == NULL);
|
||||
|
||||
/* */
|
||||
session->wlans = (struct ac_wlans*)capwap_alloc(sizeof(struct ac_wlans));
|
||||
memset(session->wlans, 0, sizeof(struct ac_wlans));
|
||||
|
||||
/* */
|
||||
session->wlans->stations = capwap_hash_create(AC_WLANS_STATIONS_HASH_SIZE);
|
||||
session->wlans->stations->item_gethash = ac_wlans_item_gethash;
|
||||
session->wlans->stations->item_getkey = ac_wlans_item_getkey;
|
||||
session->wlans->stations->item_cmp = ac_wlans_item_cmp;
|
||||
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
session->wlans->devices[i].radioid = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_destroy(struct ac_session_t* session) {
|
||||
int i;
|
||||
struct capwap_list* items;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
|
||||
/* */
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
if (session->wlans->devices[i].wlans) {
|
||||
items = session->wlans->devices[i].wlans;
|
||||
|
||||
/* Delete WLANS */
|
||||
while (items->first) {
|
||||
ac_wlans_delete_bssid(session, i + 1, ((struct ac_wlan*)items->first->item)->address);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_list_free(items);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
ASSERT(session->wlans->stations->count == 0);
|
||||
|
||||
/* */
|
||||
capwap_hash_free(session->wlans->stations);
|
||||
capwap_free(session->wlans);
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan) {
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(wlan != NULL);
|
||||
ASSERT(wlan->device != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(wlan->device->radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlan->wlanid));
|
||||
|
||||
/* */
|
||||
if (ac_wlans_get_bssid(session, wlan->device->radioid, wlan->address)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* */
|
||||
wlan->session = session;
|
||||
|
||||
/* Create WLAN list */
|
||||
if (!session->wlans->devices[wlan->device->radioid - 1].wlans) {
|
||||
session->wlans->devices[wlan->device->radioid - 1].wlans = capwap_list_create();
|
||||
}
|
||||
|
||||
/* Append WLAN to list */
|
||||
capwap_itemlist_insert_after(session->wlans->devices[wlan->device->radioid - 1].wlans, NULL, wlan->wlanitem);
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Added new wlan with radioid: %d, wlanid: %d, bssid: %s", (int)wlan->device->radioid, (int)wlan->wlanid, capwap_printf_macaddress(buffer, wlan->address, MACADDRESS_EUI48_LENGTH));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan) {
|
||||
struct ac_wlan* wlan;
|
||||
struct capwap_list_item* wlanitem;
|
||||
|
||||
ASSERT(device != NULL);
|
||||
ASSERT(IS_VALID_WLANID(wlanid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
wlanitem = capwap_itemlist_create(sizeof(struct ac_wlan));
|
||||
wlan = (struct ac_wlan*)wlanitem->item;
|
||||
memset(wlan, 0, sizeof(struct ac_wlan));
|
||||
|
||||
/* Init WLAN */
|
||||
wlan->wlanitem = wlanitem;
|
||||
memcpy(wlan->address, bssid, MACADDRESS_EUI48_LENGTH);
|
||||
wlan->device = device;
|
||||
wlan->wlanid = wlanid;
|
||||
wlan->stations = capwap_list_create();
|
||||
|
||||
/* Set capability */
|
||||
wlan->capability = addwlan->capability;
|
||||
|
||||
wlan->keyindex = addwlan->keyindex;
|
||||
wlan->keystatus = addwlan->keystatus;
|
||||
wlan->keylength = addwlan->keylength;
|
||||
if (addwlan->key && (addwlan->keylength > 0)) {
|
||||
wlan->key = (uint8_t*)capwap_clone(addwlan->key, wlan->keylength);
|
||||
}
|
||||
|
||||
memcpy(wlan->grouptsc, addwlan->grouptsc, CAPWAP_ADD_WLAN_GROUPTSC_LENGTH);
|
||||
|
||||
wlan->qos = addwlan->qos;
|
||||
wlan->authmode = addwlan->authmode;
|
||||
wlan->macmode = addwlan->macmode;
|
||||
wlan->tunnelmode = addwlan->tunnelmode;
|
||||
|
||||
wlan->suppressssid = addwlan->suppressssid;
|
||||
strcpy(wlan->ssid, (const char*)addwlan->ssid);
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (session->wlans->devices[radioid - 1].wlans) {
|
||||
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (!memcmp(bssid, item->address, MACADDRESS_EUI48_LENGTH)) {
|
||||
wlan = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlanid));
|
||||
|
||||
/* */
|
||||
if (session->wlans->devices[radioid - 1].wlans) {
|
||||
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (wlanid == item->wlanid) {
|
||||
wlan = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_free_bssid(struct ac_wlan* wlan) {
|
||||
ASSERT(wlan != NULL);
|
||||
|
||||
/* Free capability */
|
||||
if (wlan->key) {
|
||||
capwap_free(wlan->key);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_list_free(wlan->stations);
|
||||
capwap_itemlist_free(wlan->wlanitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (session->wlans->devices[radioid - 1].wlans) {
|
||||
for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
|
||||
struct ac_wlan* wlan = (struct ac_wlan*)search->item;
|
||||
|
||||
if (!memcmp(bssid, wlan->address, MACADDRESS_EUI48_LENGTH)) {
|
||||
/* Remove stations */
|
||||
while (wlan->stations->first) {
|
||||
ac_stations_destroy_station(session, (struct ac_station*)wlan->stations->first->item);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_itemlist_remove(session->wlans->devices[radioid - 1].wlans, search);
|
||||
ac_wlans_free_bssid(wlan);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
|
||||
struct ac_station* station;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(address != NULL);
|
||||
|
||||
/* Get station */
|
||||
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
|
||||
if (station && (station->flags & AC_STATION_FLAGS_ENABLED) && ((radioid == RADIOID_ANY) || (radioid == station->wlan->device->radioid)) && (!bssid || !memcmp(bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH))) {
|
||||
return station;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
|
||||
char buffer1[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
char buffer2[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
struct ac_wlan* wlan;
|
||||
struct ac_station* authoritativestation;
|
||||
struct ac_station* station = NULL;
|
||||
struct ac_session_t* authoritativesession = NULL;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
ASSERT(address != NULL);
|
||||
|
||||
/* */
|
||||
capwap_printf_macaddress(buffer1, bssid, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_printf_macaddress(buffer2, address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_logging_info("Create station to radioid: %d, bssid: %s, station address: %s", (int)radioid, buffer1, buffer2);
|
||||
|
||||
/* */
|
||||
wlan = ac_wlans_get_bssid(session, radioid, bssid);
|
||||
if (wlan) {
|
||||
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
|
||||
if (!station) {
|
||||
struct capwap_list_item* stationitem = capwap_itemlist_create(sizeof(struct ac_station));
|
||||
|
||||
station = (struct ac_station*)stationitem->item;
|
||||
memset(station, 0, sizeof(struct ac_station));
|
||||
|
||||
/* */
|
||||
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
|
||||
memcpy(station->address, address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_printf_macaddress(station->addrtext, address, MACADDRESS_EUI48_LENGTH);
|
||||
station->wlanitem = stationitem;
|
||||
station->session = session;
|
||||
|
||||
/* */
|
||||
capwap_hash_add(session->wlans->stations, (void*)station);
|
||||
}
|
||||
|
||||
/* Set station to WLAN */
|
||||
ac_stations_reset_station(session, station, wlan);
|
||||
station->flags |= AC_STATION_FLAGS_ENABLED;
|
||||
|
||||
/* Check Authoritative Stations List */
|
||||
capwap_rwlock_rdlock(&g_ac.authstationslock);
|
||||
|
||||
authoritativestation = (struct ac_station*)capwap_hash_search(g_ac.authstations, address);
|
||||
if (authoritativestation && authoritativestation->session) {
|
||||
authoritativesession = authoritativestation->session;
|
||||
}
|
||||
|
||||
capwap_rwlock_unlock(&g_ac.authstationslock);
|
||||
|
||||
/* Check Authoritative Session */
|
||||
if (authoritativesession != session) {
|
||||
/* Update Authoritative Stations List */
|
||||
capwap_rwlock_wrlock(&g_ac.authstationslock);
|
||||
capwap_hash_add(g_ac.authstations, (void*)station);
|
||||
capwap_rwlock_unlock(&g_ac.authstationslock);
|
||||
|
||||
/* Release Station from old Authoritative Session */
|
||||
if (authoritativesession) {
|
||||
ac_session_send_action(authoritativesession, AC_SESSION_ACTION_STATION_ROAMING, 0, (void*)address, MACADDRESS_EUI48_LENGTH);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
capwap_logging_warning("Unable to find radioid: %d, bssid: %s", (int)radioid, buffer1);
|
||||
}
|
||||
|
||||
return station;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station) {
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* Deauthorize station */
|
||||
ac_stations_deauthorize_station(session, station);
|
||||
|
||||
/* Destroy station reference */
|
||||
ac_stations_destroy_station(session, station);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station) {
|
||||
struct ac_notify_station_configuration_ieee8011_add_station notify;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* Active Station only if Authenticated, Associated and not Authorizated */
|
||||
if ((station->flags & AC_STATION_FLAGS_AUTHENTICATED) && (station->flags & AC_STATION_FLAGS_ASSOCIATE) && !(station->flags & AC_STATION_FLAGS_AUTHORIZED)) {
|
||||
memset(¬ify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
|
||||
notify.radioid = station->wlan->device->radioid;
|
||||
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
notify.wlanid = station->wlan->wlanid;
|
||||
notify.associationid = station->aid;
|
||||
notify.capabilities = station->capability;
|
||||
notify.supportedratescount = station->supportedratescount;
|
||||
memcpy(notify.supportedrates, station->supportedrates, station->supportedratescount);
|
||||
|
||||
ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station) {
|
||||
int responselength;
|
||||
uint8_t buffer[IEEE80211_MTU];
|
||||
struct ieee80211_deauthentication_params ieee80211_params;
|
||||
struct ac_notify_station_configuration_ieee8011_delete_station notify;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
if (station->flags & AC_STATION_FLAGS_AUTHORIZED) {
|
||||
/* Deauthorize station */
|
||||
memset(¬ify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
|
||||
notify.radioid = station->wlan->device->radioid;
|
||||
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
|
||||
/* */
|
||||
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE | AC_STATION_FLAGS_AUTHORIZED);
|
||||
ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
|
||||
} else if (station->flags & AC_STATION_FLAGS_AUTHENTICATED) {
|
||||
/* Create deauthentication packet */
|
||||
memset(&ieee80211_params, 0, sizeof(struct ieee80211_deauthentication_params));
|
||||
memcpy(ieee80211_params.bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH);
|
||||
memcpy(ieee80211_params.station, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
ieee80211_params.reasoncode = IEEE80211_REASON_PREV_AUTH_NOT_VALID;
|
||||
|
||||
/* */
|
||||
responselength = ieee80211_create_deauthentication(buffer, IEEE80211_MTU, &ieee80211_params);
|
||||
if (responselength > 0) {
|
||||
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
|
||||
ac_kmod_send_data(&session->sessionid, station->wlan->device->radioid, session->binding, buffer, responselength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param) {
|
||||
struct ac_station* station = (struct ac_station*)context;
|
||||
|
||||
ASSERT(station != NULL);
|
||||
|
||||
if (station->idtimeout == index) {
|
||||
switch (station->timeoutaction) {
|
||||
case AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE: {
|
||||
capwap_logging_warning("The %s station has not completed the association in time", station->addrtext);
|
||||
ac_stations_delete_station((struct ac_session_t*)param, station);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,128 +1,128 @@
|
||||
#ifndef __AC_WLANS_HEADER__
|
||||
#define __AC_WLANS_HEADER__
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
/* */
|
||||
#define RADIOID_ANY 0
|
||||
|
||||
/* */
|
||||
#define AC_WLANS_STATIONS_HASH_SIZE 256
|
||||
#define AC_WLANS_STATIONS_KEY_SIZE MACADDRESS_EUI48_LENGTH
|
||||
|
||||
/* AC WLAN */
|
||||
struct ac_wlan {
|
||||
struct capwap_list_item* wlanitem;
|
||||
struct ac_device* device;
|
||||
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t wlanid;
|
||||
|
||||
/* CAPWAP Session */
|
||||
struct ac_session_t* session;
|
||||
|
||||
uint32_t aidbitfield[IEEE80211_AID_BITFIELD_SIZE];
|
||||
|
||||
/* Stations reference */
|
||||
struct capwap_list* stations;
|
||||
|
||||
/* Capability */
|
||||
uint16_t capability;
|
||||
uint8_t keyindex;
|
||||
uint8_t keystatus;
|
||||
uint16_t keylength;
|
||||
uint8_t* key;
|
||||
uint8_t grouptsc[CAPWAP_ADD_WLAN_GROUPTSC_LENGTH];
|
||||
uint8_t qos;
|
||||
uint8_t authmode;
|
||||
uint8_t macmode;
|
||||
uint8_t tunnelmode;
|
||||
uint8_t suppressssid;
|
||||
char ssid[IEEE80211_SSID_MAX_LENGTH + 1];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_device {
|
||||
uint8_t radioid;
|
||||
struct capwap_list* wlans;
|
||||
|
||||
/* Rates */
|
||||
unsigned long supportedratescount;
|
||||
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_wlans {
|
||||
struct ac_device devices[RADIOID_MAX_COUNT];
|
||||
|
||||
/* Stations */
|
||||
struct capwap_hash* stations;
|
||||
};
|
||||
|
||||
/* */
|
||||
#define AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE 30000
|
||||
|
||||
/* */
|
||||
#define AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE 0x00000001
|
||||
|
||||
/* */
|
||||
#define AC_STATION_FLAGS_ENABLED 0x00000001
|
||||
#define AC_STATION_FLAGS_AUTHENTICATED 0x00000002
|
||||
#define AC_STATION_FLAGS_ASSOCIATE 0x00000004
|
||||
#define AC_STATION_FLAGS_AUTHORIZED 0x00000008
|
||||
|
||||
/* AC Station */
|
||||
struct ac_station {
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
char addrtext[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
/* */
|
||||
unsigned long flags;
|
||||
|
||||
/* Reference of WLAN */
|
||||
struct ac_wlan* wlan;
|
||||
struct capwap_list_item* wlanitem;
|
||||
|
||||
/* Reference of Session */
|
||||
struct ac_session_t* session;
|
||||
|
||||
/* Timers */
|
||||
int timeoutaction;
|
||||
unsigned long idtimeout;
|
||||
|
||||
/* */
|
||||
uint16_t capability;
|
||||
uint16_t listeninterval;
|
||||
uint16_t aid;
|
||||
|
||||
/* */
|
||||
int supportedratescount;
|
||||
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
|
||||
|
||||
/* Authentication */
|
||||
uint16_t authalgorithm;
|
||||
};
|
||||
|
||||
/* Management WLANS */
|
||||
void ac_wlans_init(struct ac_session_t* session);
|
||||
void ac_wlans_destroy(struct ac_session_t* session);
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan);
|
||||
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan);
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
|
||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid);
|
||||
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
|
||||
void ac_wlans_free_bssid(struct ac_wlan* wlan);
|
||||
|
||||
/* Management Stations */
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
|
||||
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
|
||||
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station);
|
||||
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station);
|
||||
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station);
|
||||
|
||||
/* */
|
||||
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
|
||||
|
||||
#endif /* __AC_WLANS_HEADER__ */
|
||||
#ifndef __AC_WLANS_HEADER__
|
||||
#define __AC_WLANS_HEADER__
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
/* */
|
||||
#define RADIOID_ANY 0
|
||||
|
||||
/* */
|
||||
#define AC_WLANS_STATIONS_HASH_SIZE 256
|
||||
#define AC_WLANS_STATIONS_KEY_SIZE MACADDRESS_EUI48_LENGTH
|
||||
|
||||
/* AC WLAN */
|
||||
struct ac_wlan {
|
||||
struct capwap_list_item* wlanitem;
|
||||
struct ac_device* device;
|
||||
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t wlanid;
|
||||
|
||||
/* CAPWAP Session */
|
||||
struct ac_session_t* session;
|
||||
|
||||
uint32_t aidbitfield[IEEE80211_AID_BITFIELD_SIZE];
|
||||
|
||||
/* Stations reference */
|
||||
struct capwap_list* stations;
|
||||
|
||||
/* Capability */
|
||||
uint16_t capability;
|
||||
uint8_t keyindex;
|
||||
uint8_t keystatus;
|
||||
uint16_t keylength;
|
||||
uint8_t* key;
|
||||
uint8_t grouptsc[CAPWAP_ADD_WLAN_GROUPTSC_LENGTH];
|
||||
uint8_t qos;
|
||||
uint8_t authmode;
|
||||
uint8_t macmode;
|
||||
uint8_t tunnelmode;
|
||||
uint8_t suppressssid;
|
||||
char ssid[IEEE80211_SSID_MAX_LENGTH + 1];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_device {
|
||||
uint8_t radioid;
|
||||
struct capwap_list* wlans;
|
||||
|
||||
/* Rates */
|
||||
unsigned long supportedratescount;
|
||||
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_wlans {
|
||||
struct ac_device devices[RADIOID_MAX_COUNT];
|
||||
|
||||
/* Stations */
|
||||
struct capwap_hash* stations;
|
||||
};
|
||||
|
||||
/* */
|
||||
#define AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE 30000
|
||||
|
||||
/* */
|
||||
#define AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE 0x00000001
|
||||
|
||||
/* */
|
||||
#define AC_STATION_FLAGS_ENABLED 0x00000001
|
||||
#define AC_STATION_FLAGS_AUTHENTICATED 0x00000002
|
||||
#define AC_STATION_FLAGS_ASSOCIATE 0x00000004
|
||||
#define AC_STATION_FLAGS_AUTHORIZED 0x00000008
|
||||
|
||||
/* AC Station */
|
||||
struct ac_station {
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
char addrtext[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
/* */
|
||||
unsigned long flags;
|
||||
|
||||
/* Reference of WLAN */
|
||||
struct ac_wlan* wlan;
|
||||
struct capwap_list_item* wlanitem;
|
||||
|
||||
/* Reference of Session */
|
||||
struct ac_session_t* session;
|
||||
|
||||
/* Timers */
|
||||
int timeoutaction;
|
||||
unsigned long idtimeout;
|
||||
|
||||
/* */
|
||||
uint16_t capability;
|
||||
uint16_t listeninterval;
|
||||
uint16_t aid;
|
||||
|
||||
/* */
|
||||
int supportedratescount;
|
||||
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
|
||||
|
||||
/* Authentication */
|
||||
uint16_t authalgorithm;
|
||||
};
|
||||
|
||||
/* Management WLANS */
|
||||
void ac_wlans_init(struct ac_session_t* session);
|
||||
void ac_wlans_destroy(struct ac_session_t* session);
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan);
|
||||
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan);
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
|
||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid);
|
||||
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
|
||||
void ac_wlans_free_bssid(struct ac_wlan* wlan);
|
||||
|
||||
/* Management Stations */
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
|
||||
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
|
||||
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station);
|
||||
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station);
|
||||
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station);
|
||||
|
||||
/* */
|
||||
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
|
||||
|
||||
#endif /* __AC_WLANS_HEADER__ */
|
||||
|
@ -1,18 +1,18 @@
|
||||
KVERSION = $(shell uname -r)
|
||||
|
||||
obj-m += smartcapwap.o
|
||||
|
||||
smartcapwap-y := \
|
||||
main.o \
|
||||
netlinkapp.o \
|
||||
capwap.o \
|
||||
capwap_private.o \
|
||||
station.o \
|
||||
socket.o \
|
||||
iface.o
|
||||
|
||||
all:
|
||||
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" modules
|
||||
|
||||
clean:
|
||||
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" clean
|
||||
KVERSION = $(shell uname -r)
|
||||
|
||||
obj-m += smartcapwap.o
|
||||
|
||||
smartcapwap-y := \
|
||||
main.o \
|
||||
netlinkapp.o \
|
||||
capwap.o \
|
||||
capwap_private.o \
|
||||
station.o \
|
||||
socket.o \
|
||||
iface.o
|
||||
|
||||
all:
|
||||
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" modules
|
||||
|
||||
clean:
|
||||
make -C /lib/modules/$(KVERSION)/build M="$(PWD)" clean
|
||||
|
1578
src/ac/kmod/capwap.c
1578
src/ac/kmod/capwap.c
File diff suppressed because it is too large
Load Diff
@ -1,124 +1,124 @@
|
||||
#ifndef __KMOD_CAPWAP_HEADER__
|
||||
#define __KMOD_CAPWAP_HEADER__
|
||||
|
||||
#include "capwap_rfc.h"
|
||||
#include "socket.h"
|
||||
|
||||
/* */
|
||||
#define MAX_MTU 9000
|
||||
#define DEFAULT_MTU 1450
|
||||
#define MIN_MTU 500
|
||||
#define IEEE80211_MTU 7981
|
||||
|
||||
/* */
|
||||
#define CAPWAP_FRAGMENT_QUEUE 16
|
||||
|
||||
/* */
|
||||
#define CAPWAP_FRAGMENT_ENABLE 0x0001
|
||||
#define CAPWAP_FRAGMENT_LRUQUEUE 0x0002
|
||||
#define CAPWAP_FRAGMENT_LAST 0x0004
|
||||
|
||||
/* */
|
||||
#define SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL 0x0001
|
||||
#define SKB_CAPWAP_FLAG_FROM_USER_SPACE 0x0002
|
||||
#define SKB_CAPWAP_FLAG_FROM_AC_TAP 0x0004
|
||||
#define SKB_CAPWAP_FLAG_FROM_IEEE80211 0x0008
|
||||
|
||||
#define SKB_CAPWAP_FLAG_SESSIONID 0x0100
|
||||
#define SKB_CAPWAP_FLAG_RADIOID 0x0200
|
||||
#define SKB_CAPWAP_FLAG_BINDING 0x0400
|
||||
#define SKB_CAPWAP_FLAG_WIRELESSINFORMATION 0x0800
|
||||
#define SKB_CAPWAP_FLAG_FRAGMENT 0x1000
|
||||
|
||||
struct sc_skb_capwap_cb {
|
||||
uint16_t flags;
|
||||
|
||||
/* Session ID */
|
||||
struct sc_capwap_sessionid_element sessionid;
|
||||
|
||||
/* Capwap information */
|
||||
uint8_t radioid;
|
||||
uint8_t binding;
|
||||
|
||||
/* Wireless Information */
|
||||
uint8_t winfo_rssi;
|
||||
uint8_t winfo_snr;
|
||||
uint16_t winfo_rate;
|
||||
|
||||
/* Fragment */
|
||||
uint16_t frag_offset;
|
||||
uint16_t frag_length;
|
||||
};
|
||||
|
||||
#define CAPWAP_SKB_CB(skb) ((struct sc_skb_capwap_cb*)((skb)->cb))
|
||||
|
||||
/* */
|
||||
struct sc_capwap_fragment {
|
||||
struct list_head lru_list;
|
||||
|
||||
uint8_t flags;
|
||||
ktime_t tstamp;
|
||||
|
||||
uint16_t fragmentid;
|
||||
|
||||
struct sk_buff* fragments;
|
||||
struct sk_buff* lastfragment;
|
||||
int recvlength;
|
||||
int totallength;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_fragment_queue {
|
||||
spinlock_t lock;
|
||||
|
||||
struct list_head lru_list;
|
||||
struct sc_capwap_fragment queues[CAPWAP_FRAGMENT_QUEUE];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_session {
|
||||
uint16_t mtu;
|
||||
union capwap_addr peeraddr;
|
||||
struct sc_capwap_sessionid_element sessionid;
|
||||
|
||||
uint16_t fragmentid;
|
||||
spinlock_t fragmentid_lock;
|
||||
|
||||
struct sc_capwap_fragment_queue fragments;
|
||||
};
|
||||
|
||||
/* */
|
||||
extern union capwap_addr sc_localaddr;
|
||||
|
||||
/* Dipendent implementation function */
|
||||
void sc_capwap_recvpacket(struct sk_buff* skb);
|
||||
struct sc_capwap_session* sc_capwap_recvunknownkeepalive(const union capwap_addr* sockaddr, const struct sc_capwap_sessionid_element* sessionid);
|
||||
|
||||
void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_buff* skb);
|
||||
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb);
|
||||
|
||||
/* Indipendent implementation function */
|
||||
int sc_capwap_bind(union capwap_addr* sockaddr);
|
||||
|
||||
void sc_capwap_initsession(struct sc_capwap_session* session);
|
||||
void sc_capwap_freesession(struct sc_capwap_session* session);
|
||||
uint16_t sc_capwap_newfragmentid(struct sc_capwap_session* session);
|
||||
|
||||
int sc_capwap_8023_to_80211(struct sk_buff* skb, const uint8_t* bssid);
|
||||
int sc_capwap_80211_to_8023(struct sk_buff* skb);
|
||||
|
||||
void sc_capwap_sessionid_printf(const struct sc_capwap_sessionid_element* sessionid, char* string);
|
||||
|
||||
int sc_capwap_createkeepalive(struct sc_capwap_sessionid_element* sessionid, uint8_t* buffer, int size);
|
||||
int sc_capwap_parsingpacket(struct sc_capwap_session* session, const union capwap_addr* sockaddr, struct sk_buff* skb);
|
||||
|
||||
struct sc_capwap_radio_addr* sc_capwap_setradiomacaddress(uint8_t* buffer, int size, uint8_t* bssid);
|
||||
struct sc_capwap_wireless_information* sc_capwap_setwinfo_frameinfo(uint8_t* buffer, int size, uint8_t rssi, uint8_t snr, uint16_t rate);
|
||||
struct sc_capwap_wireless_information* sc_capwap_setwinfo_destwlans(uint8_t* buffer, int size, uint16_t wlanidbitmap);
|
||||
|
||||
int sc_capwap_forwarddata(struct sc_capwap_session* session, uint8_t radioid, uint8_t binding, struct sk_buff* skb, uint32_t flags, struct sc_capwap_radio_addr* radioaddr, int radioaddrlength, struct sc_capwap_wireless_information* winfo, int winfolength);
|
||||
|
||||
/* Private funciotn */
|
||||
#include "capwap_private.h"
|
||||
|
||||
#endif /* __KMOD_CAPWAP_HEADER__ */
|
||||
#ifndef __KMOD_CAPWAP_HEADER__
|
||||
#define __KMOD_CAPWAP_HEADER__
|
||||
|
||||
#include "capwap_rfc.h"
|
||||
#include "socket.h"
|
||||
|
||||
/* */
|
||||
#define MAX_MTU 9000
|
||||
#define DEFAULT_MTU 1450
|
||||
#define MIN_MTU 500
|
||||
#define IEEE80211_MTU 7981
|
||||
|
||||
/* */
|
||||
#define CAPWAP_FRAGMENT_QUEUE 16
|
||||
|
||||
/* */
|
||||
#define CAPWAP_FRAGMENT_ENABLE 0x0001
|
||||
#define CAPWAP_FRAGMENT_LRUQUEUE 0x0002
|
||||
#define CAPWAP_FRAGMENT_LAST 0x0004
|
||||
|
||||
/* */
|
||||
#define SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL 0x0001
|
||||
#define SKB_CAPWAP_FLAG_FROM_USER_SPACE 0x0002
|
||||
#define SKB_CAPWAP_FLAG_FROM_AC_TAP 0x0004
|
||||
#define SKB_CAPWAP_FLAG_FROM_IEEE80211 0x0008
|
||||
|
||||
#define SKB_CAPWAP_FLAG_SESSIONID 0x0100
|
||||
#define SKB_CAPWAP_FLAG_RADIOID 0x0200
|
||||
#define SKB_CAPWAP_FLAG_BINDING 0x0400
|
||||
#define SKB_CAPWAP_FLAG_WIRELESSINFORMATION 0x0800
|
||||
#define SKB_CAPWAP_FLAG_FRAGMENT 0x1000
|
||||
|
||||
struct sc_skb_capwap_cb {
|
||||
uint16_t flags;
|
||||
|
||||
/* Session ID */
|
||||
struct sc_capwap_sessionid_element sessionid;
|
||||
|
||||
/* Capwap information */
|
||||
uint8_t radioid;
|
||||
uint8_t binding;
|
||||
|
||||
/* Wireless Information */
|
||||
uint8_t winfo_rssi;
|
||||
uint8_t winfo_snr;
|
||||
uint16_t winfo_rate;
|
||||
|
||||
/* Fragment */
|
||||
uint16_t frag_offset;
|
||||
uint16_t frag_length;
|
||||
};
|
||||
|
||||
#define CAPWAP_SKB_CB(skb) ((struct sc_skb_capwap_cb*)((skb)->cb))
|
||||
|
||||
/* */
|
||||
struct sc_capwap_fragment {
|
||||
struct list_head lru_list;
|
||||
|
||||
uint8_t flags;
|
||||
ktime_t tstamp;
|
||||
|
||||
uint16_t fragmentid;
|
||||
|
||||
struct sk_buff* fragments;
|
||||
struct sk_buff* lastfragment;
|
||||
int recvlength;
|
||||
int totallength;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_fragment_queue {
|
||||
spinlock_t lock;
|
||||
|
||||
struct list_head lru_list;
|
||||
struct sc_capwap_fragment queues[CAPWAP_FRAGMENT_QUEUE];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_session {
|
||||
uint16_t mtu;
|
||||
union capwap_addr peeraddr;
|
||||
struct sc_capwap_sessionid_element sessionid;
|
||||
|
||||
uint16_t fragmentid;
|
||||
spinlock_t fragmentid_lock;
|
||||
|
||||
struct sc_capwap_fragment_queue fragments;
|
||||
};
|
||||
|
||||
/* */
|
||||
extern union capwap_addr sc_localaddr;
|
||||
|
||||
/* Dipendent implementation function */
|
||||
void sc_capwap_recvpacket(struct sk_buff* skb);
|
||||
struct sc_capwap_session* sc_capwap_recvunknownkeepalive(const union capwap_addr* sockaddr, const struct sc_capwap_sessionid_element* sessionid);
|
||||
|
||||
void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_buff* skb);
|
||||
void sc_capwap_parsingmgmtpacket(struct sc_capwap_session* session, struct sk_buff* skb);
|
||||
|
||||
/* Indipendent implementation function */
|
||||
int sc_capwap_bind(union capwap_addr* sockaddr);
|
||||
|
||||
void sc_capwap_initsession(struct sc_capwap_session* session);
|
||||
void sc_capwap_freesession(struct sc_capwap_session* session);
|
||||
uint16_t sc_capwap_newfragmentid(struct sc_capwap_session* session);
|
||||
|
||||
int sc_capwap_8023_to_80211(struct sk_buff* skb, const uint8_t* bssid);
|
||||
int sc_capwap_80211_to_8023(struct sk_buff* skb);
|
||||
|
||||
void sc_capwap_sessionid_printf(const struct sc_capwap_sessionid_element* sessionid, char* string);
|
||||
|
||||
int sc_capwap_createkeepalive(struct sc_capwap_sessionid_element* sessionid, uint8_t* buffer, int size);
|
||||
int sc_capwap_parsingpacket(struct sc_capwap_session* session, const union capwap_addr* sockaddr, struct sk_buff* skb);
|
||||
|
||||
struct sc_capwap_radio_addr* sc_capwap_setradiomacaddress(uint8_t* buffer, int size, uint8_t* bssid);
|
||||
struct sc_capwap_wireless_information* sc_capwap_setwinfo_frameinfo(uint8_t* buffer, int size, uint8_t rssi, uint8_t snr, uint16_t rate);
|
||||
struct sc_capwap_wireless_information* sc_capwap_setwinfo_destwlans(uint8_t* buffer, int size, uint16_t wlanidbitmap);
|
||||
|
||||
int sc_capwap_forwarddata(struct sc_capwap_session* session, uint8_t radioid, uint8_t binding, struct sk_buff* skb, uint32_t flags, struct sc_capwap_radio_addr* radioaddr, int radioaddrlength, struct sc_capwap_wireless_information* winfo, int winfolength);
|
||||
|
||||
/* Private funciotn */
|
||||
#include "capwap_private.h"
|
||||
|
||||
#endif /* __KMOD_CAPWAP_HEADER__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,67 +1,67 @@
|
||||
#ifndef __KMOD_CAPWAP_PRIVATE_HEADER__
|
||||
#define __KMOD_CAPWAP_PRIVATE_HEADER__
|
||||
|
||||
/* */
|
||||
struct sc_capwap_wlan {
|
||||
int used;
|
||||
|
||||
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t macmode;
|
||||
uint8_t tunnelmode;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_session_priv {
|
||||
struct sc_capwap_session session;
|
||||
|
||||
struct list_head list;
|
||||
struct sc_capwap_session_priv* __rcu next_ipaddr;
|
||||
struct sc_capwap_session_priv* __rcu next_sessionid;
|
||||
|
||||
struct list_head list_stations;
|
||||
struct list_head list_connections;
|
||||
|
||||
/* */
|
||||
int isolation;
|
||||
uint8_t binding;
|
||||
struct sc_capwap_wlan wlans[CAPWAP_RADIOID_MAX_COUNT][CAPWAP_WLANID_MAX_COUNT];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_workthread {
|
||||
struct task_struct* thread;
|
||||
|
||||
struct sk_buff_head queue;
|
||||
wait_queue_head_t waitevent;
|
||||
};
|
||||
|
||||
/* */
|
||||
int sc_capwap_init(void);
|
||||
void sc_capwap_close(void);
|
||||
|
||||
/* */
|
||||
void sc_capwap_update_lock(void);
|
||||
void sc_capwap_update_unlock(void);
|
||||
|
||||
#ifdef CONFIG_PROVE_LOCKING
|
||||
int sc_capwap_update_lock_is_locked(void);
|
||||
#else
|
||||
static inline int sc_capwap_update_lock_is_locked(void) { return 1; }
|
||||
#endif
|
||||
|
||||
/* */
|
||||
int sc_capwap_sendkeepalive(const struct sc_capwap_sessionid_element* sessionid);
|
||||
|
||||
/* */
|
||||
int sc_capwap_newsession(const struct sc_capwap_sessionid_element* sessionid, uint8_t binding, uint16_t mtu);
|
||||
int sc_capwap_deletesession(const struct sc_capwap_sessionid_element* sessionid);
|
||||
|
||||
/* */
|
||||
int sc_capwap_addwlan(const struct sc_capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, uint8_t macmode, uint8_t tunnelmode);
|
||||
int sc_capwap_removewlan(const struct sc_capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid);
|
||||
|
||||
/* */
|
||||
int sc_capwap_authstation(const struct sc_capwap_sessionid_element* sessionid, const uint8_t* address, uint32_t ifindex, uint8_t radioid, uint8_t wlanid, uint16_t vlan);
|
||||
int sc_capwap_deauthstation(const struct sc_capwap_sessionid_element* sessionid, const uint8_t* address);
|
||||
|
||||
#endif /* __KMOD_CAPWAP_PRIVATE_HEADER__ */
|
||||
#ifndef __KMOD_CAPWAP_PRIVATE_HEADER__
|
||||
#define __KMOD_CAPWAP_PRIVATE_HEADER__
|
||||
|
||||
/* */
|
||||
struct sc_capwap_wlan {
|
||||
int used;
|
||||
|
||||
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t macmode;
|
||||
uint8_t tunnelmode;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_session_priv {
|
||||
struct sc_capwap_session session;
|
||||
|
||||
struct list_head list;
|
||||
struct sc_capwap_session_priv* __rcu next_ipaddr;
|
||||
struct sc_capwap_session_priv* __rcu next_sessionid;
|
||||
|
||||
struct list_head list_stations;
|
||||
struct list_head list_connections;
|
||||
|
||||
/* */
|
||||
int isolation;
|
||||
uint8_t binding;
|
||||
struct sc_capwap_wlan wlans[CAPWAP_RADIOID_MAX_COUNT][CAPWAP_WLANID_MAX_COUNT];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_workthread {
|
||||
struct task_struct* thread;
|
||||
|
||||
struct sk_buff_head queue;
|
||||
wait_queue_head_t waitevent;
|
||||
};
|
||||
|
||||
/* */
|
||||
int sc_capwap_init(void);
|
||||
void sc_capwap_close(void);
|
||||
|
||||
/* */
|
||||
void sc_capwap_update_lock(void);
|
||||
void sc_capwap_update_unlock(void);
|
||||
|
||||
#ifdef CONFIG_PROVE_LOCKING
|
||||
int sc_capwap_update_lock_is_locked(void);
|
||||
#else
|
||||
static inline int sc_capwap_update_lock_is_locked(void) { return 1; }
|
||||
#endif
|
||||
|
||||
/* */
|
||||
int sc_capwap_sendkeepalive(const struct sc_capwap_sessionid_element* sessionid);
|
||||
|
||||
/* */
|
||||
int sc_capwap_newsession(const struct sc_capwap_sessionid_element* sessionid, uint8_t binding, uint16_t mtu);
|
||||
int sc_capwap_deletesession(const struct sc_capwap_sessionid_element* sessionid);
|
||||
|
||||
/* */
|
||||
int sc_capwap_addwlan(const struct sc_capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, uint8_t macmode, uint8_t tunnelmode);
|
||||
int sc_capwap_removewlan(const struct sc_capwap_sessionid_element* sessionid, uint8_t radioid, uint8_t wlanid);
|
||||
|
||||
/* */
|
||||
int sc_capwap_authstation(const struct sc_capwap_sessionid_element* sessionid, const uint8_t* address, uint32_t ifindex, uint8_t radioid, uint8_t wlanid, uint16_t vlan);
|
||||
int sc_capwap_deauthstation(const struct sc_capwap_sessionid_element* sessionid, const uint8_t* address);
|
||||
|
||||
#endif /* __KMOD_CAPWAP_PRIVATE_HEADER__ */
|
||||
|
@ -1,187 +1,187 @@
|
||||
#ifndef __KMOD_CAPWAP_RFC_HEADER__
|
||||
#define __KMOD_CAPWAP_RFC_HEADER__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
/* */
|
||||
#define CAPWAP_RADIOID_MAX_COUNT 31
|
||||
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= CAPWAP_RADIOID_MAX_COUNT))
|
||||
|
||||
#define CAPWAP_WLANID_MAX_COUNT 16
|
||||
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= CAPWAP_WLANID_MAX_COUNT))
|
||||
|
||||
/* */
|
||||
#define CAPWAP_WIRELESS_BINDING_NONE 0
|
||||
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
|
||||
|
||||
/* */
|
||||
#define CAPWAP_ELEMENT_SESSIONID 35
|
||||
|
||||
/* */
|
||||
#define CAPWAP_KEEPALIVE_SIZE (sizeof(struct sc_capwap_dtls_header) + \
|
||||
sizeof(struct sc_capwap_header) + \
|
||||
sizeof(struct sc_capwap_data_message) + \
|
||||
sizeof(struct sc_capwap_message_element) + \
|
||||
sizeof(struct sc_capwap_sessionid_element))
|
||||
|
||||
/* Preamble */
|
||||
struct sc_capwap_preamble {
|
||||
#if defined(__BIG_ENDIAN_BITFIELD)
|
||||
uint8_t version: 4,
|
||||
type: 4;
|
||||
#elif defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
uint8_t type: 4,
|
||||
version: 4;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/* DTLS header */
|
||||
struct sc_capwap_dtls_header {
|
||||
struct sc_capwap_preamble preamble;
|
||||
uint8_t reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* Plain header */
|
||||
struct sc_capwap_header {
|
||||
struct sc_capwap_preamble preamble;
|
||||
#if defined(__BIG_ENDIAN_BITFIELD)
|
||||
uint16_t hlen: 5,
|
||||
rid: 5,
|
||||
wbid: 5,
|
||||
flag_t: 1;
|
||||
uint8_t flag_f: 1,
|
||||
flag_l: 1,
|
||||
flag_w: 1,
|
||||
flag_m: 1,
|
||||
flag_k: 1,
|
||||
flag_res: 3;
|
||||
#elif defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
uint16_t _rid_hi: 3,
|
||||
hlen: 5,
|
||||
flag_t: 1,
|
||||
wbid: 5,
|
||||
_rid_lo: 2;
|
||||
uint8_t flag_res: 3,
|
||||
flag_k: 1,
|
||||
flag_m: 1,
|
||||
flag_w: 1,
|
||||
flag_l: 1,
|
||||
flag_f: 1;
|
||||
#endif
|
||||
__be16 frag_id;
|
||||
__be16 frag_off;
|
||||
} __packed;
|
||||
|
||||
/* Mac Address */
|
||||
#define CAPWAP_RADIO_EUI48_LENGTH_PADDED 8
|
||||
#define CAPWAP_RADIO_EUI64_LENGTH_PADDED 12
|
||||
#define CAPWAP_RADIO_MAX_LENGTH_PADDED 12
|
||||
struct sc_capwap_radio_addr {
|
||||
uint8_t length;
|
||||
uint8_t addr[0];
|
||||
} __packed;
|
||||
|
||||
/* Wireless Information */
|
||||
#define CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED 8
|
||||
#define CAPWAP_WINFO_DESTWLAN_LENGTH_PADDED 8
|
||||
#define CAPWAP_WINFO_MAX_LENGTH_PADDED 8
|
||||
struct sc_capwap_wireless_information {
|
||||
uint8_t length;
|
||||
} __packed;
|
||||
|
||||
/* IEEE802.11 Wireless Information */
|
||||
struct sc_capwap_ieee80211_frame_info {
|
||||
uint8_t rssi;
|
||||
uint8_t snr;
|
||||
__be16 rate;
|
||||
} __packed;
|
||||
|
||||
/* Destination WLANs */
|
||||
struct sc_capwap_destination_wlans {
|
||||
__be16 wlanidbitmap;
|
||||
__be16 reserved;
|
||||
} __packed;
|
||||
|
||||
/* */
|
||||
#define CAPWAP_HEADER_MAX_LENGTH (sizeof(struct sc_capwap_header) + CAPWAP_RADIO_MAX_LENGTH_PADDED + CAPWAP_WINFO_MAX_LENGTH_PADDED)
|
||||
|
||||
/* Data channel message */
|
||||
struct sc_capwap_data_message {
|
||||
__be16 length;
|
||||
} __packed;
|
||||
|
||||
/* Message element */
|
||||
struct sc_capwap_message_element {
|
||||
__be16 type;
|
||||
__be16 length;
|
||||
} __packed;
|
||||
|
||||
/* Session id message element */
|
||||
struct sc_capwap_sessionid_element {
|
||||
union {
|
||||
uint8_t id[16];
|
||||
uint32_t id32[4];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
/* */
|
||||
#define MACADDRESS_EUI48_LENGTH 6
|
||||
struct sc_capwap_macaddress_eui48 {
|
||||
uint8_t addr[MACADDRESS_EUI48_LENGTH];
|
||||
} __packed;
|
||||
|
||||
/* */
|
||||
#define MACADDRESS_EUI64_LENGTH 8
|
||||
struct sc_capwap_macaddress_eui64 {
|
||||
uint8_t addr[MACADDRESS_EUI64_LENGTH];
|
||||
} __packed;
|
||||
|
||||
/* Capwap preamble */
|
||||
#define CAPWAP_PROTOCOL_VERSION 0
|
||||
#define CAPWAP_PREAMBLE_HEADER 0
|
||||
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
|
||||
|
||||
#define CAPWAP_WIRELESS_BINDING_NONE 0
|
||||
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
|
||||
|
||||
/* */
|
||||
#define CAPWAP_KEEP_ALIVE_MAX_SIZE (sizeof(struct sc_capwap_header) + sizeof(struct sc_capwap_data_message) + sizeof(struct sc_capwap_message_element) + sizeof(struct sc_capwap_sessionid_element))
|
||||
|
||||
/* */
|
||||
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
|
||||
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
|
||||
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
|
||||
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
|
||||
|
||||
#define GET_HLEN_HEADER(x) ((x)->hlen)
|
||||
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
|
||||
#if defined(__BIG_ENDIAN_BITFIELD)
|
||||
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
|
||||
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
|
||||
#elif defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
|
||||
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
|
||||
#endif
|
||||
#define GET_WBID_HEADER(x) ((uint8_t)((x)->wbid))
|
||||
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
|
||||
|
||||
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
|
||||
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
|
||||
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
|
||||
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
|
||||
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
|
||||
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
|
||||
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
|
||||
|
||||
/* IEEE 802.11 Add WLAN */
|
||||
#define CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL 0
|
||||
#define CAPWAP_ADD_WLAN_TUNNELMODE_8023 1
|
||||
#define CAPWAP_ADD_WLAN_TUNNELMODE_80211 2
|
||||
|
||||
#endif /* __KMOD_CAPWAP_RFC_HEADER__ */
|
||||
#ifndef __KMOD_CAPWAP_RFC_HEADER__
|
||||
#define __KMOD_CAPWAP_RFC_HEADER__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
/* */
|
||||
#define CAPWAP_RADIOID_MAX_COUNT 31
|
||||
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= CAPWAP_RADIOID_MAX_COUNT))
|
||||
|
||||
#define CAPWAP_WLANID_MAX_COUNT 16
|
||||
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= CAPWAP_WLANID_MAX_COUNT))
|
||||
|
||||
/* */
|
||||
#define CAPWAP_WIRELESS_BINDING_NONE 0
|
||||
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
|
||||
|
||||
/* */
|
||||
#define CAPWAP_ELEMENT_SESSIONID 35
|
||||
|
||||
/* */
|
||||
#define CAPWAP_KEEPALIVE_SIZE (sizeof(struct sc_capwap_dtls_header) + \
|
||||
sizeof(struct sc_capwap_header) + \
|
||||
sizeof(struct sc_capwap_data_message) + \
|
||||
sizeof(struct sc_capwap_message_element) + \
|
||||
sizeof(struct sc_capwap_sessionid_element))
|
||||
|
||||
/* Preamble */
|
||||
struct sc_capwap_preamble {
|
||||
#if defined(__BIG_ENDIAN_BITFIELD)
|
||||
uint8_t version: 4,
|
||||
type: 4;
|
||||
#elif defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
uint8_t type: 4,
|
||||
version: 4;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/* DTLS header */
|
||||
struct sc_capwap_dtls_header {
|
||||
struct sc_capwap_preamble preamble;
|
||||
uint8_t reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* Plain header */
|
||||
struct sc_capwap_header {
|
||||
struct sc_capwap_preamble preamble;
|
||||
#if defined(__BIG_ENDIAN_BITFIELD)
|
||||
uint16_t hlen: 5,
|
||||
rid: 5,
|
||||
wbid: 5,
|
||||
flag_t: 1;
|
||||
uint8_t flag_f: 1,
|
||||
flag_l: 1,
|
||||
flag_w: 1,
|
||||
flag_m: 1,
|
||||
flag_k: 1,
|
||||
flag_res: 3;
|
||||
#elif defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
uint16_t _rid_hi: 3,
|
||||
hlen: 5,
|
||||
flag_t: 1,
|
||||
wbid: 5,
|
||||
_rid_lo: 2;
|
||||
uint8_t flag_res: 3,
|
||||
flag_k: 1,
|
||||
flag_m: 1,
|
||||
flag_w: 1,
|
||||
flag_l: 1,
|
||||
flag_f: 1;
|
||||
#endif
|
||||
__be16 frag_id;
|
||||
__be16 frag_off;
|
||||
} __packed;
|
||||
|
||||
/* Mac Address */
|
||||
#define CAPWAP_RADIO_EUI48_LENGTH_PADDED 8
|
||||
#define CAPWAP_RADIO_EUI64_LENGTH_PADDED 12
|
||||
#define CAPWAP_RADIO_MAX_LENGTH_PADDED 12
|
||||
struct sc_capwap_radio_addr {
|
||||
uint8_t length;
|
||||
uint8_t addr[0];
|
||||
} __packed;
|
||||
|
||||
/* Wireless Information */
|
||||
#define CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED 8
|
||||
#define CAPWAP_WINFO_DESTWLAN_LENGTH_PADDED 8
|
||||
#define CAPWAP_WINFO_MAX_LENGTH_PADDED 8
|
||||
struct sc_capwap_wireless_information {
|
||||
uint8_t length;
|
||||
} __packed;
|
||||
|
||||
/* IEEE802.11 Wireless Information */
|
||||
struct sc_capwap_ieee80211_frame_info {
|
||||
uint8_t rssi;
|
||||
uint8_t snr;
|
||||
__be16 rate;
|
||||
} __packed;
|
||||
|
||||
/* Destination WLANs */
|
||||
struct sc_capwap_destination_wlans {
|
||||
__be16 wlanidbitmap;
|
||||
__be16 reserved;
|
||||
} __packed;
|
||||
|
||||
/* */
|
||||
#define CAPWAP_HEADER_MAX_LENGTH (sizeof(struct sc_capwap_header) + CAPWAP_RADIO_MAX_LENGTH_PADDED + CAPWAP_WINFO_MAX_LENGTH_PADDED)
|
||||
|
||||
/* Data channel message */
|
||||
struct sc_capwap_data_message {
|
||||
__be16 length;
|
||||
} __packed;
|
||||
|
||||
/* Message element */
|
||||
struct sc_capwap_message_element {
|
||||
__be16 type;
|
||||
__be16 length;
|
||||
} __packed;
|
||||
|
||||
/* Session id message element */
|
||||
struct sc_capwap_sessionid_element {
|
||||
union {
|
||||
uint8_t id[16];
|
||||
uint32_t id32[4];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
/* */
|
||||
#define MACADDRESS_EUI48_LENGTH 6
|
||||
struct sc_capwap_macaddress_eui48 {
|
||||
uint8_t addr[MACADDRESS_EUI48_LENGTH];
|
||||
} __packed;
|
||||
|
||||
/* */
|
||||
#define MACADDRESS_EUI64_LENGTH 8
|
||||
struct sc_capwap_macaddress_eui64 {
|
||||
uint8_t addr[MACADDRESS_EUI64_LENGTH];
|
||||
} __packed;
|
||||
|
||||
/* Capwap preamble */
|
||||
#define CAPWAP_PROTOCOL_VERSION 0
|
||||
#define CAPWAP_PREAMBLE_HEADER 0
|
||||
#define CAPWAP_PREAMBLE_DTLS_HEADER 1
|
||||
|
||||
#define CAPWAP_WIRELESS_BINDING_NONE 0
|
||||
#define CAPWAP_WIRELESS_BINDING_IEEE80211 1
|
||||
|
||||
/* */
|
||||
#define CAPWAP_KEEP_ALIVE_MAX_SIZE (sizeof(struct sc_capwap_header) + sizeof(struct sc_capwap_data_message) + sizeof(struct sc_capwap_message_element) + sizeof(struct sc_capwap_sessionid_element))
|
||||
|
||||
/* */
|
||||
#define GET_VERSION_HEADER(x) ((x)->preamble.version)
|
||||
#define SET_VERSION_HEADER(x, y) ((x)->preamble.version = (uint8_t)(y))
|
||||
#define GET_TYPE_HEADER(x) ((x)->preamble.type)
|
||||
#define SET_TYPE_HEADER(x, y) ((x)->preamble.type = (uint8_t)(y))
|
||||
|
||||
#define GET_HLEN_HEADER(x) ((x)->hlen)
|
||||
#define SET_HLEN_HEADER(x, y) ((x)->hlen = (uint16_t)(y))
|
||||
#if defined(__BIG_ENDIAN_BITFIELD)
|
||||
#define GET_RID_HEADER(x) ((uint8_t)((x)->rid))
|
||||
#define SET_RID_HEADER(x, y) ((x)->rid = (uint16_t)(y))
|
||||
#elif defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
#define GET_RID_HEADER(x) ((uint8_t)((uint16_t)((x)->_rid_hi << 2 | (x)->_rid_lo)))
|
||||
#define SET_RID_HEADER(x, y) ({ (x)->_rid_hi = (uint16_t)((y) >> 2); (x)->_rid_lo = (uint16_t)((y) & 0x0003); })
|
||||
#endif
|
||||
#define GET_WBID_HEADER(x) ((uint8_t)((x)->wbid))
|
||||
#define SET_WBID_HEADER(x, y) ((x)->wbid = (uint16_t)(y))
|
||||
|
||||
#define IS_FLAG_T_HEADER(x) ((x)->flag_t)
|
||||
#define SET_FLAG_T_HEADER(x, y) ((x)->flag_t = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_F_HEADER(x) ((x)->flag_f)
|
||||
#define SET_FLAG_F_HEADER(x, y) ((x)->flag_f = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_L_HEADER(x) ((x)->flag_l)
|
||||
#define SET_FLAG_L_HEADER(x, y) ((x)->flag_l = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_W_HEADER(x) ((x)->flag_w)
|
||||
#define SET_FLAG_W_HEADER(x, y) ((x)->flag_w = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_M_HEADER(x) ((x)->flag_m)
|
||||
#define SET_FLAG_M_HEADER(x, y) ((x)->flag_m = ((y) ? 1 : 0))
|
||||
#define IS_FLAG_K_HEADER(x) ((x)->flag_k)
|
||||
#define SET_FLAG_K_HEADER(x, y) ((x)->flag_k = ((y) ? 1 : 0))
|
||||
|
||||
/* IEEE 802.11 Add WLAN */
|
||||
#define CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL 0
|
||||
#define CAPWAP_ADD_WLAN_TUNNELMODE_8023 1
|
||||
#define CAPWAP_ADD_WLAN_TUNNELMODE_80211 2
|
||||
|
||||
#endif /* __KMOD_CAPWAP_RFC_HEADER__ */
|
||||
|
@ -1,13 +1,13 @@
|
||||
#ifndef __KMOD_CONFIG_HEADER__
|
||||
#define __KMOD_CONFIG_HEADER__
|
||||
|
||||
#define DEBUGKMOD 1
|
||||
|
||||
#ifdef DEBUGKMOD
|
||||
#define TRACEKMOD(s, args...) printk("(%d) " s, smp_processor_id(), ##args)
|
||||
#else
|
||||
#define TRACEKMOD(s, args...)
|
||||
#endif
|
||||
|
||||
#endif /* __KMOD_CONFIG_HEADER__ */
|
||||
|
||||
#ifndef __KMOD_CONFIG_HEADER__
|
||||
#define __KMOD_CONFIG_HEADER__
|
||||
|
||||
#define DEBUGKMOD 1
|
||||
|
||||
#ifdef DEBUGKMOD
|
||||
#define TRACEKMOD(s, args...) printk("(%d) " s, smp_processor_id(), ##args)
|
||||
#else
|
||||
#define TRACEKMOD(s, args...)
|
||||
#endif
|
||||
|
||||
#endif /* __KMOD_CONFIG_HEADER__ */
|
||||
|
||||
|
@ -1,300 +1,300 @@
|
||||
#include "config.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/smp.h>
|
||||
#include "iface.h"
|
||||
#include "station.h"
|
||||
#include "capwap.h"
|
||||
|
||||
/* */
|
||||
#define CAPWAP_IFACE_COUNT 8
|
||||
#define CAPWAP_IFACE_HASH(x) ((x) % CAPWAP_IFACE_COUNT)
|
||||
|
||||
static LIST_HEAD(sc_iface_list);
|
||||
static struct sc_netdev_priv* __rcu sc_iface_hash[CAPWAP_IFACE_COUNT];
|
||||
|
||||
/* */
|
||||
static void sc_iface_netdev_uninit(struct net_device* dev) {
|
||||
struct sc_netdev_priv* search;
|
||||
struct sc_capwap_station* temp;
|
||||
struct sc_capwap_station* station;
|
||||
int hash = CAPWAP_IFACE_HASH(dev->ifindex);
|
||||
struct sc_netdev_priv* priv = (struct sc_netdev_priv*)netdev_priv(dev);
|
||||
|
||||
TRACEKMOD("### sc_iface_netdev_uninit\n");
|
||||
|
||||
sc_capwap_update_lock();
|
||||
|
||||
/* Close stations */
|
||||
list_for_each_entry_safe(station, temp, &priv->list_stations, list_dev) {
|
||||
sc_stations_releaseconnection(station);
|
||||
sc_stations_free(station);
|
||||
}
|
||||
|
||||
/* */
|
||||
if (!list_empty(&priv->list_stations)) {
|
||||
TRACEKMOD("*** Bug: the list stations of interface is not empty\n");
|
||||
}
|
||||
|
||||
if (!list_empty(&priv->list_connections)) {
|
||||
TRACEKMOD("*** Bug: the list connections of interface is not empty\n");
|
||||
}
|
||||
|
||||
/* Remove interface from hash */
|
||||
search = rcu_dereference_protected(sc_iface_hash[hash], sc_capwap_update_lock_is_locked());
|
||||
if (search) {
|
||||
if (priv == search) {
|
||||
netif_tx_lock_bh(dev);
|
||||
netif_carrier_off(dev);
|
||||
netif_tx_unlock_bh(dev);
|
||||
|
||||
rcu_assign_pointer(sc_iface_hash[hash], priv->next);
|
||||
|
||||
list_del_rcu(&priv->list);
|
||||
synchronize_net();
|
||||
|
||||
dev_put(dev);
|
||||
} else {
|
||||
while (rcu_access_pointer(search->next) && (rcu_access_pointer(search->next) != priv)) {
|
||||
search = rcu_dereference_protected(search->next, sc_capwap_update_lock_is_locked());
|
||||
}
|
||||
|
||||
if (rcu_access_pointer(search->next)) {
|
||||
netif_tx_lock_bh(dev);
|
||||
netif_carrier_off(dev);
|
||||
netif_tx_unlock_bh(dev);
|
||||
|
||||
rcu_assign_pointer(search->next, priv->next);
|
||||
|
||||
list_del_rcu(&priv->list);
|
||||
synchronize_net();
|
||||
|
||||
dev_put(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sc_capwap_update_unlock();
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_iface_netdev_open(struct net_device* dev) {
|
||||
TRACEKMOD("### sc_iface_netdev_open\n");
|
||||
|
||||
netif_start_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_iface_netdev_stop(struct net_device* dev) {
|
||||
TRACEKMOD("### sc_iface_netdev_stop\n");
|
||||
|
||||
netif_stop_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_iface_netdev_tx(struct sk_buff* skb, struct net_device* dev) {
|
||||
struct sc_netdev_priv* priv = (struct sc_netdev_priv*)netdev_priv(dev);
|
||||
|
||||
TRACEKMOD("### sc_iface_netdev_tx %d\n", smp_processor_id());
|
||||
|
||||
if (dev->flags & IFF_UP) {
|
||||
/* Ignore 802.1ad */
|
||||
if (skb->vlan_proto == htons(ETH_P_8021AD) || (eth_hdr(skb)->h_proto == htons(ETH_P_8021AD))) {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* */
|
||||
spin_lock(&priv->lock);
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
spin_unlock(&priv->lock);
|
||||
|
||||
/* */
|
||||
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_AC_TAP;
|
||||
sc_capwap_recvpacket(skb);
|
||||
} else {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
drop:
|
||||
/* Drop packet */
|
||||
kfree_skb(skb);
|
||||
|
||||
/* */
|
||||
spin_lock(&priv->lock);
|
||||
dev->stats.rx_dropped++;
|
||||
spin_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_iface_netdev_change_mtu(struct net_device* dev, int new_mtu) {
|
||||
TRACEKMOD("### sc_iface_netdev_change_mtu\n");
|
||||
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void sc_iface_netdev_setup(struct net_device* dev) {
|
||||
struct sc_netdev_priv* devpriv = (struct sc_netdev_priv*)netdev_priv(dev);
|
||||
|
||||
TRACEKMOD("### sc_iface_netdev_setup\n");
|
||||
|
||||
/* */
|
||||
memset(devpriv, 0, sizeof(struct sc_netdev_priv));
|
||||
devpriv->dev = dev;
|
||||
spin_lock_init(&devpriv->lock);
|
||||
INIT_LIST_HEAD(&devpriv->list_stations);
|
||||
INIT_LIST_HEAD(&devpriv->list_connections);
|
||||
}
|
||||
|
||||
/* */
|
||||
static const struct net_device_ops capwap_netdev_ops = {
|
||||
.ndo_uninit = sc_iface_netdev_uninit,
|
||||
.ndo_open = sc_iface_netdev_open,
|
||||
.ndo_stop = sc_iface_netdev_stop,
|
||||
.ndo_start_xmit = sc_iface_netdev_tx,
|
||||
.ndo_change_mtu = sc_iface_netdev_change_mtu,
|
||||
};
|
||||
|
||||
/* */
|
||||
int sc_iface_create(const char* ifname, uint16_t mtu) {
|
||||
int err;
|
||||
int hash;
|
||||
struct net_device* dev;
|
||||
struct sc_netdev_priv* priv;
|
||||
|
||||
TRACEKMOD("### sc_iface_create\n");
|
||||
|
||||
/* Create interface */
|
||||
dev = alloc_netdev(sizeof(struct sc_netdev_priv), ifname, sc_iface_netdev_setup);
|
||||
if (!dev) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* */
|
||||
priv = (struct sc_netdev_priv*)netdev_priv(dev);
|
||||
dev->netdev_ops = &capwap_netdev_ops;
|
||||
ether_setup(dev);
|
||||
|
||||
eth_hw_addr_random(dev);
|
||||
|
||||
dev->mtu = mtu;
|
||||
|
||||
dev->hw_features = NETIF_F_HW_CSUM;
|
||||
dev->features = dev->hw_features;
|
||||
|
||||
/* */
|
||||
err = register_netdev(dev);
|
||||
if (err) {
|
||||
free_netdev(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* */
|
||||
hash = CAPWAP_IFACE_HASH(dev->ifindex);
|
||||
|
||||
/* */
|
||||
sc_capwap_update_lock();
|
||||
|
||||
list_add_rcu(&priv->list, &sc_iface_list);
|
||||
|
||||
priv->next = rcu_dereference_protected(sc_iface_hash[hash], sc_capwap_update_lock_is_locked());
|
||||
rcu_assign_pointer(sc_iface_hash[hash], priv);
|
||||
dev_hold(dev);
|
||||
|
||||
sc_capwap_update_unlock();
|
||||
|
||||
/* Enable carrier */
|
||||
netif_tx_lock_bh(dev);
|
||||
netif_carrier_on(dev);
|
||||
netif_tx_unlock_bh(dev);
|
||||
|
||||
return dev->ifindex;
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_iface_delete(uint32_t ifindex) {
|
||||
struct sc_netdev_priv* priv;
|
||||
struct net_device* dev = NULL;
|
||||
|
||||
TRACEKMOD("### sc_iface_delete\n");
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
/* Search device */
|
||||
priv = sc_iface_search(ifindex);
|
||||
if (priv) {
|
||||
dev = priv->dev;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
/* */
|
||||
if (!dev) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Unregister device */
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct sc_netdev_priv* sc_iface_search(uint32_t ifindex) {
|
||||
struct sc_netdev_priv* priv;
|
||||
|
||||
TRACEKMOD("### sc_iface_search\n");
|
||||
|
||||
priv = rcu_dereference_check(sc_iface_hash[CAPWAP_IFACE_HASH(ifindex)], lockdep_is_held(&sc_iface_mutex));
|
||||
while (priv) {
|
||||
if (priv->dev->ifindex == ifindex) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* */
|
||||
priv = rcu_dereference_check(priv->next, lockdep_is_held(&sc_iface_mutex));
|
||||
}
|
||||
|
||||
return priv;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_iface_closeall(void) {
|
||||
struct sc_netdev_priv* priv;
|
||||
|
||||
TRACEKMOD("### sc_iface_closeall\n");
|
||||
|
||||
for (;;) {
|
||||
struct net_device* dev = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
/* Get device */
|
||||
priv = list_first_or_null_rcu(&sc_iface_list, struct sc_netdev_priv, list);
|
||||
if (priv) {
|
||||
dev = priv->dev;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
/* */
|
||||
if (!dev) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unregister device */
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
}
|
||||
}
|
||||
#include "config.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/smp.h>
|
||||
#include "iface.h"
|
||||
#include "station.h"
|
||||
#include "capwap.h"
|
||||
|
||||
/* */
|
||||
#define CAPWAP_IFACE_COUNT 8
|
||||
#define CAPWAP_IFACE_HASH(x) ((x) % CAPWAP_IFACE_COUNT)
|
||||
|
||||
static LIST_HEAD(sc_iface_list);
|
||||
static struct sc_netdev_priv* __rcu sc_iface_hash[CAPWAP_IFACE_COUNT];
|
||||
|
||||
/* */
|
||||
static void sc_iface_netdev_uninit(struct net_device* dev) {
|
||||
struct sc_netdev_priv* search;
|
||||
struct sc_capwap_station* temp;
|
||||
struct sc_capwap_station* station;
|
||||
int hash = CAPWAP_IFACE_HASH(dev->ifindex);
|
||||
struct sc_netdev_priv* priv = (struct sc_netdev_priv*)netdev_priv(dev);
|
||||
|
||||
TRACEKMOD("### sc_iface_netdev_uninit\n");
|
||||
|
||||
sc_capwap_update_lock();
|
||||
|
||||
/* Close stations */
|
||||
list_for_each_entry_safe(station, temp, &priv->list_stations, list_dev) {
|
||||
sc_stations_releaseconnection(station);
|
||||
sc_stations_free(station);
|
||||
}
|
||||
|
||||
/* */
|
||||
if (!list_empty(&priv->list_stations)) {
|
||||
TRACEKMOD("*** Bug: the list stations of interface is not empty\n");
|
||||
}
|
||||
|
||||
if (!list_empty(&priv->list_connections)) {
|
||||
TRACEKMOD("*** Bug: the list connections of interface is not empty\n");
|
||||
}
|
||||
|
||||
/* Remove interface from hash */
|
||||
search = rcu_dereference_protected(sc_iface_hash[hash], sc_capwap_update_lock_is_locked());
|
||||
if (search) {
|
||||
if (priv == search) {
|
||||
netif_tx_lock_bh(dev);
|
||||
netif_carrier_off(dev);
|
||||
netif_tx_unlock_bh(dev);
|
||||
|
||||
rcu_assign_pointer(sc_iface_hash[hash], priv->next);
|
||||
|
||||
list_del_rcu(&priv->list);
|
||||
synchronize_net();
|
||||
|
||||
dev_put(dev);
|
||||
} else {
|
||||
while (rcu_access_pointer(search->next) && (rcu_access_pointer(search->next) != priv)) {
|
||||
search = rcu_dereference_protected(search->next, sc_capwap_update_lock_is_locked());
|
||||
}
|
||||
|
||||
if (rcu_access_pointer(search->next)) {
|
||||
netif_tx_lock_bh(dev);
|
||||
netif_carrier_off(dev);
|
||||
netif_tx_unlock_bh(dev);
|
||||
|
||||
rcu_assign_pointer(search->next, priv->next);
|
||||
|
||||
list_del_rcu(&priv->list);
|
||||
synchronize_net();
|
||||
|
||||
dev_put(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sc_capwap_update_unlock();
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_iface_netdev_open(struct net_device* dev) {
|
||||
TRACEKMOD("### sc_iface_netdev_open\n");
|
||||
|
||||
netif_start_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_iface_netdev_stop(struct net_device* dev) {
|
||||
TRACEKMOD("### sc_iface_netdev_stop\n");
|
||||
|
||||
netif_stop_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_iface_netdev_tx(struct sk_buff* skb, struct net_device* dev) {
|
||||
struct sc_netdev_priv* priv = (struct sc_netdev_priv*)netdev_priv(dev);
|
||||
|
||||
TRACEKMOD("### sc_iface_netdev_tx %d\n", smp_processor_id());
|
||||
|
||||
if (dev->flags & IFF_UP) {
|
||||
/* Ignore 802.1ad */
|
||||
if (skb->vlan_proto == htons(ETH_P_8021AD) || (eth_hdr(skb)->h_proto == htons(ETH_P_8021AD))) {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* */
|
||||
spin_lock(&priv->lock);
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
spin_unlock(&priv->lock);
|
||||
|
||||
/* */
|
||||
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_AC_TAP;
|
||||
sc_capwap_recvpacket(skb);
|
||||
} else {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
drop:
|
||||
/* Drop packet */
|
||||
kfree_skb(skb);
|
||||
|
||||
/* */
|
||||
spin_lock(&priv->lock);
|
||||
dev->stats.rx_dropped++;
|
||||
spin_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_iface_netdev_change_mtu(struct net_device* dev, int new_mtu) {
|
||||
TRACEKMOD("### sc_iface_netdev_change_mtu\n");
|
||||
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void sc_iface_netdev_setup(struct net_device* dev) {
|
||||
struct sc_netdev_priv* devpriv = (struct sc_netdev_priv*)netdev_priv(dev);
|
||||
|
||||
TRACEKMOD("### sc_iface_netdev_setup\n");
|
||||
|
||||
/* */
|
||||
memset(devpriv, 0, sizeof(struct sc_netdev_priv));
|
||||
devpriv->dev = dev;
|
||||
spin_lock_init(&devpriv->lock);
|
||||
INIT_LIST_HEAD(&devpriv->list_stations);
|
||||
INIT_LIST_HEAD(&devpriv->list_connections);
|
||||
}
|
||||
|
||||
/* */
|
||||
static const struct net_device_ops capwap_netdev_ops = {
|
||||
.ndo_uninit = sc_iface_netdev_uninit,
|
||||
.ndo_open = sc_iface_netdev_open,
|
||||
.ndo_stop = sc_iface_netdev_stop,
|
||||
.ndo_start_xmit = sc_iface_netdev_tx,
|
||||
.ndo_change_mtu = sc_iface_netdev_change_mtu,
|
||||
};
|
||||
|
||||
/* */
|
||||
int sc_iface_create(const char* ifname, uint16_t mtu) {
|
||||
int err;
|
||||
int hash;
|
||||
struct net_device* dev;
|
||||
struct sc_netdev_priv* priv;
|
||||
|
||||
TRACEKMOD("### sc_iface_create\n");
|
||||
|
||||
/* Create interface */
|
||||
dev = alloc_netdev(sizeof(struct sc_netdev_priv), ifname, sc_iface_netdev_setup);
|
||||
if (!dev) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* */
|
||||
priv = (struct sc_netdev_priv*)netdev_priv(dev);
|
||||
dev->netdev_ops = &capwap_netdev_ops;
|
||||
ether_setup(dev);
|
||||
|
||||
eth_hw_addr_random(dev);
|
||||
|
||||
dev->mtu = mtu;
|
||||
|
||||
dev->hw_features = NETIF_F_HW_CSUM;
|
||||
dev->features = dev->hw_features;
|
||||
|
||||
/* */
|
||||
err = register_netdev(dev);
|
||||
if (err) {
|
||||
free_netdev(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* */
|
||||
hash = CAPWAP_IFACE_HASH(dev->ifindex);
|
||||
|
||||
/* */
|
||||
sc_capwap_update_lock();
|
||||
|
||||
list_add_rcu(&priv->list, &sc_iface_list);
|
||||
|
||||
priv->next = rcu_dereference_protected(sc_iface_hash[hash], sc_capwap_update_lock_is_locked());
|
||||
rcu_assign_pointer(sc_iface_hash[hash], priv);
|
||||
dev_hold(dev);
|
||||
|
||||
sc_capwap_update_unlock();
|
||||
|
||||
/* Enable carrier */
|
||||
netif_tx_lock_bh(dev);
|
||||
netif_carrier_on(dev);
|
||||
netif_tx_unlock_bh(dev);
|
||||
|
||||
return dev->ifindex;
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_iface_delete(uint32_t ifindex) {
|
||||
struct sc_netdev_priv* priv;
|
||||
struct net_device* dev = NULL;
|
||||
|
||||
TRACEKMOD("### sc_iface_delete\n");
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
/* Search device */
|
||||
priv = sc_iface_search(ifindex);
|
||||
if (priv) {
|
||||
dev = priv->dev;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
/* */
|
||||
if (!dev) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Unregister device */
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct sc_netdev_priv* sc_iface_search(uint32_t ifindex) {
|
||||
struct sc_netdev_priv* priv;
|
||||
|
||||
TRACEKMOD("### sc_iface_search\n");
|
||||
|
||||
priv = rcu_dereference_check(sc_iface_hash[CAPWAP_IFACE_HASH(ifindex)], lockdep_is_held(&sc_iface_mutex));
|
||||
while (priv) {
|
||||
if (priv->dev->ifindex == ifindex) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* */
|
||||
priv = rcu_dereference_check(priv->next, lockdep_is_held(&sc_iface_mutex));
|
||||
}
|
||||
|
||||
return priv;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_iface_closeall(void) {
|
||||
struct sc_netdev_priv* priv;
|
||||
|
||||
TRACEKMOD("### sc_iface_closeall\n");
|
||||
|
||||
for (;;) {
|
||||
struct net_device* dev = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
/* Get device */
|
||||
priv = list_first_or_null_rcu(&sc_iface_list, struct sc_netdev_priv, list);
|
||||
if (priv) {
|
||||
dev = priv->dev;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
/* */
|
||||
if (!dev) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unregister device */
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
#ifndef __KMOD_AC_IFACE_HEADER__
|
||||
#define __KMOD_AC_IFACE_HEADER__
|
||||
|
||||
/* */
|
||||
struct sc_netdev_priv {
|
||||
struct list_head list;
|
||||
struct net_device* dev;
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
struct list_head list_stations;
|
||||
struct list_head list_connections;
|
||||
|
||||
struct sc_netdev_priv* __rcu next;
|
||||
};
|
||||
|
||||
/* */
|
||||
int sc_iface_create(const char* ifname, uint16_t mtu);
|
||||
int sc_iface_delete(uint32_t ifindex);
|
||||
|
||||
/* */
|
||||
struct sc_netdev_priv* sc_iface_search(uint32_t ifindex);
|
||||
|
||||
/* */
|
||||
void sc_iface_closeall(void);
|
||||
|
||||
#endif /* __KMOD_AC_IFACE_HEADER__ */
|
||||
#ifndef __KMOD_AC_IFACE_HEADER__
|
||||
#define __KMOD_AC_IFACE_HEADER__
|
||||
|
||||
/* */
|
||||
struct sc_netdev_priv {
|
||||
struct list_head list;
|
||||
struct net_device* dev;
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
struct list_head list_stations;
|
||||
struct list_head list_connections;
|
||||
|
||||
struct sc_netdev_priv* __rcu next;
|
||||
};
|
||||
|
||||
/* */
|
||||
int sc_iface_create(const char* ifname, uint16_t mtu);
|
||||
int sc_iface_delete(uint32_t ifindex);
|
||||
|
||||
/* */
|
||||
struct sc_netdev_priv* sc_iface_search(uint32_t ifindex);
|
||||
|
||||
/* */
|
||||
void sc_iface_closeall(void);
|
||||
|
||||
#endif /* __KMOD_AC_IFACE_HEADER__ */
|
||||
|
@ -1,32 +1,32 @@
|
||||
#include "config.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "netlinkapp.h"
|
||||
|
||||
/* */
|
||||
static int __init smartcapwap_ac_init(void) {
|
||||
int ret;
|
||||
|
||||
TRACEKMOD("### smartcapwap_ac_init\n");
|
||||
|
||||
/* Initialize netlink */
|
||||
ret = sc_netlink_init();
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
module_init(smartcapwap_ac_init);
|
||||
|
||||
/* */
|
||||
static void __exit smartcapwap_ac_exit(void) {
|
||||
TRACEKMOD("### smartcapwap_ac_exit\n");
|
||||
|
||||
sc_netlink_exit();
|
||||
}
|
||||
module_exit(smartcapwap_ac_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Massimo Vellucci <vemax78@gmail.com>");
|
||||
MODULE_DESCRIPTION("SmartCAPWAP AC Data Channel Module");
|
||||
#include "config.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "netlinkapp.h"
|
||||
|
||||
/* */
|
||||
static int __init smartcapwap_ac_init(void) {
|
||||
int ret;
|
||||
|
||||
TRACEKMOD("### smartcapwap_ac_init\n");
|
||||
|
||||
/* Initialize netlink */
|
||||
ret = sc_netlink_init();
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
module_init(smartcapwap_ac_init);
|
||||
|
||||
/* */
|
||||
static void __exit smartcapwap_ac_exit(void) {
|
||||
TRACEKMOD("### smartcapwap_ac_exit\n");
|
||||
|
||||
sc_netlink_exit();
|
||||
}
|
||||
module_exit(smartcapwap_ac_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Massimo Vellucci <vemax78@gmail.com>");
|
||||
MODULE_DESCRIPTION("SmartCAPWAP AC Data Channel Module");
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,15 @@
|
||||
#ifndef __KMOD_AC_NETLINKAPP_HEADER__
|
||||
#define __KMOD_AC_NETLINKAPP_HEADER__
|
||||
|
||||
#include "capwap_rfc.h"
|
||||
#include "socket.h"
|
||||
|
||||
/* */
|
||||
int sc_netlink_init(void);
|
||||
void sc_netlink_exit(void);
|
||||
|
||||
/* */
|
||||
int sc_netlink_notify_recv_keepalive(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid);
|
||||
int sc_netlink_notify_recv_data(struct sc_capwap_sessionid_element* sessionid, uint8_t* packet, int length);
|
||||
|
||||
#endif /* __KMOD_AC_NETLINKAPP_HEADER__ */
|
||||
#ifndef __KMOD_AC_NETLINKAPP_HEADER__
|
||||
#define __KMOD_AC_NETLINKAPP_HEADER__
|
||||
|
||||
#include "capwap_rfc.h"
|
||||
#include "socket.h"
|
||||
|
||||
/* */
|
||||
int sc_netlink_init(void);
|
||||
void sc_netlink_exit(void);
|
||||
|
||||
/* */
|
||||
int sc_netlink_notify_recv_keepalive(const union capwap_addr* sockaddr, struct sc_capwap_sessionid_element* sessionid);
|
||||
int sc_netlink_notify_recv_data(struct sc_capwap_sessionid_element* sessionid, uint8_t* packet, int length);
|
||||
|
||||
#endif /* __KMOD_AC_NETLINKAPP_HEADER__ */
|
||||
|
@ -1,73 +1,73 @@
|
||||
#ifndef __AC_NLSMARTCAPWAP_HEADER__
|
||||
#define __AC_NLSMARTCAPWAP_HEADER__
|
||||
|
||||
/* */
|
||||
#define NLSMARTCAPWAP_GENL_NAME "smartcapwap_ac"
|
||||
|
||||
/* */
|
||||
#define NLSMARTCAPWAP_FLAGS_TUNNEL_8023 0x00000001
|
||||
|
||||
/* */
|
||||
enum sc_netlink_attrs {
|
||||
NLSMARTCAPWAP_ATTR_UNSPEC,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_FLAGS,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_SESSION_ID,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_RADIOID,
|
||||
NLSMARTCAPWAP_ATTR_WLANID,
|
||||
NLSMARTCAPWAP_ATTR_BINDING,
|
||||
NLSMARTCAPWAP_ATTR_MACMODE,
|
||||
NLSMARTCAPWAP_ATTR_TUNNELMODE,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_ADDRESS,
|
||||
NLSMARTCAPWAP_ATTR_MTU,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_DATA_FRAME,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_IFPHY_NAME,
|
||||
NLSMARTCAPWAP_ATTR_IFPHY_INDEX,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_MACADDRESS,
|
||||
NLSMARTCAPWAP_ATTR_BSSID,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_VLAN,
|
||||
|
||||
/* Last attribute */
|
||||
__NLSMARTCAPWAP_ATTR_AFTER_LAST,
|
||||
NLSMARTCAPWAP_ATTR_MAX = __NLSMARTCAPWAP_ATTR_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/* */
|
||||
enum sc_netlink_commands {
|
||||
NLSMARTCAPWAP_CMD_UNSPEC,
|
||||
|
||||
NLSMARTCAPWAP_CMD_LINK,
|
||||
|
||||
NLSMARTCAPWAP_CMD_ADD_IFACE,
|
||||
NLSMARTCAPWAP_CMD_DELETE_IFACE,
|
||||
|
||||
NLSMARTCAPWAP_CMD_BIND,
|
||||
|
||||
NLSMARTCAPWAP_CMD_SEND_KEEPALIVE,
|
||||
NLSMARTCAPWAP_CMD_RECV_KEEPALIVE,
|
||||
|
||||
NLSMARTCAPWAP_CMD_NEW_SESSION,
|
||||
NLSMARTCAPWAP_CMD_DELETE_SESSION,
|
||||
|
||||
NLSMARTCAPWAP_CMD_ADD_WLAN,
|
||||
NLSMARTCAPWAP_CMD_REMOVE_WLAN,
|
||||
|
||||
NLSMARTCAPWAP_CMD_SEND_DATA,
|
||||
NLSMARTCAPWAP_CMD_RECV_DATA,
|
||||
|
||||
NLSMARTCAPWAP_CMD_AUTH_STATION,
|
||||
NLSMARTCAPWAP_CMD_DEAUTH_STATION,
|
||||
|
||||
/* Last command */
|
||||
__NLSMARTCAPWAP_CMD_AFTER_LAST,
|
||||
NLSMARTCAPWAP_CMD_MAX = __NLSMARTCAPWAP_CMD_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
#endif /* __AC_NLSMARTCAPWAP_HEADER__ */
|
||||
#ifndef __AC_NLSMARTCAPWAP_HEADER__
|
||||
#define __AC_NLSMARTCAPWAP_HEADER__
|
||||
|
||||
/* */
|
||||
#define NLSMARTCAPWAP_GENL_NAME "smartcapwap_ac"
|
||||
|
||||
/* */
|
||||
#define NLSMARTCAPWAP_FLAGS_TUNNEL_8023 0x00000001
|
||||
|
||||
/* */
|
||||
enum sc_netlink_attrs {
|
||||
NLSMARTCAPWAP_ATTR_UNSPEC,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_FLAGS,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_SESSION_ID,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_RADIOID,
|
||||
NLSMARTCAPWAP_ATTR_WLANID,
|
||||
NLSMARTCAPWAP_ATTR_BINDING,
|
||||
NLSMARTCAPWAP_ATTR_MACMODE,
|
||||
NLSMARTCAPWAP_ATTR_TUNNELMODE,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_ADDRESS,
|
||||
NLSMARTCAPWAP_ATTR_MTU,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_DATA_FRAME,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_IFPHY_NAME,
|
||||
NLSMARTCAPWAP_ATTR_IFPHY_INDEX,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_MACADDRESS,
|
||||
NLSMARTCAPWAP_ATTR_BSSID,
|
||||
|
||||
NLSMARTCAPWAP_ATTR_VLAN,
|
||||
|
||||
/* Last attribute */
|
||||
__NLSMARTCAPWAP_ATTR_AFTER_LAST,
|
||||
NLSMARTCAPWAP_ATTR_MAX = __NLSMARTCAPWAP_ATTR_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/* */
|
||||
enum sc_netlink_commands {
|
||||
NLSMARTCAPWAP_CMD_UNSPEC,
|
||||
|
||||
NLSMARTCAPWAP_CMD_LINK,
|
||||
|
||||
NLSMARTCAPWAP_CMD_ADD_IFACE,
|
||||
NLSMARTCAPWAP_CMD_DELETE_IFACE,
|
||||
|
||||
NLSMARTCAPWAP_CMD_BIND,
|
||||
|
||||
NLSMARTCAPWAP_CMD_SEND_KEEPALIVE,
|
||||
NLSMARTCAPWAP_CMD_RECV_KEEPALIVE,
|
||||
|
||||
NLSMARTCAPWAP_CMD_NEW_SESSION,
|
||||
NLSMARTCAPWAP_CMD_DELETE_SESSION,
|
||||
|
||||
NLSMARTCAPWAP_CMD_ADD_WLAN,
|
||||
NLSMARTCAPWAP_CMD_REMOVE_WLAN,
|
||||
|
||||
NLSMARTCAPWAP_CMD_SEND_DATA,
|
||||
NLSMARTCAPWAP_CMD_RECV_DATA,
|
||||
|
||||
NLSMARTCAPWAP_CMD_AUTH_STATION,
|
||||
NLSMARTCAPWAP_CMD_DEAUTH_STATION,
|
||||
|
||||
/* Last command */
|
||||
__NLSMARTCAPWAP_CMD_AFTER_LAST,
|
||||
NLSMARTCAPWAP_CMD_MAX = __NLSMARTCAPWAP_CMD_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
#endif /* __AC_NLSMARTCAPWAP_HEADER__ */
|
||||
|
@ -1,227 +1,227 @@
|
||||
#include "config.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/udp.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/udp.h>
|
||||
#include "socket.h"
|
||||
#include "capwap.h"
|
||||
|
||||
/* Socket */
|
||||
#define SOCKET_COUNT 2
|
||||
static struct socket* sc_sockets[SOCKET_COUNT];
|
||||
|
||||
/* */
|
||||
int sc_socket_recvpacket(struct sock* sk, struct sk_buff* skb) {
|
||||
TRACEKMOD("### sc_socket_recvpacket\n");
|
||||
|
||||
/* */
|
||||
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL;
|
||||
|
||||
/* */
|
||||
sc_capwap_recvpacket(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_socket_create(int type, union capwap_addr* sockaddr, uint16_t protocol) {
|
||||
int ret;
|
||||
|
||||
TRACEKMOD("### sc_socket_create\n");
|
||||
|
||||
/* Create socket */
|
||||
ret = sock_create_kern(sockaddr->ss.ss_family, SOCK_DGRAM, protocol, &sc_sockets[type]);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Bind to interface */
|
||||
ret = kernel_bind(sc_sockets[type], &sockaddr->sa, sizeof(union capwap_addr));
|
||||
if (ret) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Set callback */
|
||||
udp_sk(sc_sockets[type]->sk)->encap_type = 1;
|
||||
udp_sk(sc_sockets[type]->sk)->encap_rcv = sc_socket_recvpacket;
|
||||
|
||||
/* */
|
||||
if (!((sockaddr->ss.ss_family == AF_INET) ? sockaddr->sin.sin_port : sockaddr->sin6.sin6_port)) {
|
||||
union capwap_addr localaddr;
|
||||
int localaddrsize = sizeof(union capwap_addr);
|
||||
|
||||
/* Retrieve port */
|
||||
ret = kernel_getsockname(sc_sockets[type], &localaddr.sa, &localaddrsize);
|
||||
if (ret) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* */
|
||||
if ((sockaddr->ss.ss_family == AF_INET) && (localaddr.ss.ss_family == AF_INET)) {
|
||||
sockaddr->sin.sin_port = localaddr.sin.sin_port;
|
||||
} else if ((sockaddr->ss.ss_family == AF_INET6) && (localaddr.ss.ss_family == AF_INET6)) {
|
||||
sockaddr->sin6.sin6_port = localaddr.sin6.sin6_port;
|
||||
} else {
|
||||
ret = -EFAULT;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
sock_release(sc_sockets[type]);
|
||||
sc_sockets[type] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr) {
|
||||
unsigned char* nethdr;
|
||||
|
||||
TRACEKMOD("### sc_socket_getpeeraddr\n");
|
||||
|
||||
/* */
|
||||
nethdr = skb_network_header(skb);
|
||||
if (!nethdr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* */
|
||||
switch (ntohs(skb->protocol)) {
|
||||
case ETH_P_IP: {
|
||||
/* Validate IPv4 header */
|
||||
if ((nethdr[0] & 0xf0) != 0x40) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Retrieve address */
|
||||
peeraddr->sin.sin_family = AF_INET;
|
||||
peeraddr->sin.sin_addr.s_addr = ((struct iphdr*)nethdr)->saddr;
|
||||
peeraddr->sin.sin_port = udp_hdr(skb)->source;
|
||||
break;
|
||||
}
|
||||
|
||||
case ETH_P_IPV6: {
|
||||
/* Validate IPv6 header */
|
||||
if ((nethdr[0] & 0xf0) != 0x60) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Retrieve address */
|
||||
peeraddr->sin6.sin6_family = AF_INET6;
|
||||
memcpy(&peeraddr->sin6.sin6_addr, &((struct ipv6hdr*)nethdr)->saddr, sizeof(struct in6_addr));
|
||||
peeraddr->sin6.sin6_port = udp_hdr(skb)->source;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr) {
|
||||
struct kvec vec;
|
||||
struct msghdr msg;
|
||||
|
||||
TRACEKMOD("### sc_socket_send\n");
|
||||
|
||||
/* */
|
||||
vec.iov_base = buffer;
|
||||
vec.iov_len = length;
|
||||
|
||||
/* */
|
||||
memset(&msg, 0, sizeof(struct msghdr));
|
||||
msg.msg_name = sockaddr;
|
||||
msg.msg_namelen = sizeof(union capwap_addr);
|
||||
msg.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT;
|
||||
|
||||
/* */
|
||||
return kernel_sendmsg(sc_sockets[type], &msg, &vec, 1, length);
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_socket_init(void) {
|
||||
TRACEKMOD("### sc_socket_init\n");
|
||||
|
||||
memset(sc_sockets, 0, sizeof(sc_sockets));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_socket_bind(union capwap_addr* sockaddr) {
|
||||
int ret;
|
||||
|
||||
TRACEKMOD("### sc_socket_bind\n");
|
||||
|
||||
/* */
|
||||
if (sc_sockets[SOCKET_UDP] || sc_sockets[SOCKET_UDPLITE]) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* UDP socket */
|
||||
ret = sc_socket_create(SOCKET_UDP, sockaddr, IPPROTO_UDP);
|
||||
if (ret) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* UDPLite socket */
|
||||
ret = sc_socket_create(SOCKET_UDPLITE, sockaddr, IPPROTO_UDPLITE);
|
||||
if (ret) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* */
|
||||
udp_encap_enable();
|
||||
if (sockaddr->ss.ss_family == AF_INET6) {
|
||||
udpv6_encap_enable();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
sc_socket_close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_socket_close(void) {
|
||||
TRACEKMOD("### sc_socket_close\n");
|
||||
|
||||
/* Close sockets */
|
||||
if (sc_sockets[SOCKET_UDP]) {
|
||||
kernel_sock_shutdown(sc_sockets[SOCKET_UDP], SHUT_RDWR);
|
||||
sock_release(sc_sockets[SOCKET_UDP]);
|
||||
}
|
||||
|
||||
if (sc_sockets[SOCKET_UDPLITE]) {
|
||||
kernel_sock_shutdown(sc_sockets[SOCKET_UDPLITE], SHUT_RDWR);
|
||||
sock_release(sc_sockets[SOCKET_UDPLITE]);
|
||||
}
|
||||
|
||||
memset(sc_sockets, 0, sizeof(sc_sockets));
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2) {
|
||||
TRACEKMOD("### sc_addr_compare\n");
|
||||
|
||||
if (addr1->ss.ss_family == addr2->ss.ss_family) {
|
||||
if (addr1->ss.ss_family == AF_INET) {
|
||||
return (((addr1->sin.sin_addr.s_addr == addr2->sin.sin_addr.s_addr) && (addr1->sin.sin_port == addr2->sin.sin_port)) ? 0 : -1);
|
||||
} else if (addr1->ss.ss_family == AF_INET6) {
|
||||
return ((!memcmp(&addr1->sin6.sin6_addr, &addr2->sin6.sin6_addr, sizeof(struct in6_addr)) && (addr1->sin6.sin6_port == addr2->sin6.sin6_port)) ? 0 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#include "config.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/udp.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/udp.h>
|
||||
#include "socket.h"
|
||||
#include "capwap.h"
|
||||
|
||||
/* Socket */
|
||||
#define SOCKET_COUNT 2
|
||||
static struct socket* sc_sockets[SOCKET_COUNT];
|
||||
|
||||
/* */
|
||||
int sc_socket_recvpacket(struct sock* sk, struct sk_buff* skb) {
|
||||
TRACEKMOD("### sc_socket_recvpacket\n");
|
||||
|
||||
/* */
|
||||
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_DATA_CHANNEL;
|
||||
|
||||
/* */
|
||||
sc_capwap_recvpacket(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int sc_socket_create(int type, union capwap_addr* sockaddr, uint16_t protocol) {
|
||||
int ret;
|
||||
|
||||
TRACEKMOD("### sc_socket_create\n");
|
||||
|
||||
/* Create socket */
|
||||
ret = sock_create_kern(sockaddr->ss.ss_family, SOCK_DGRAM, protocol, &sc_sockets[type]);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Bind to interface */
|
||||
ret = kernel_bind(sc_sockets[type], &sockaddr->sa, sizeof(union capwap_addr));
|
||||
if (ret) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Set callback */
|
||||
udp_sk(sc_sockets[type]->sk)->encap_type = 1;
|
||||
udp_sk(sc_sockets[type]->sk)->encap_rcv = sc_socket_recvpacket;
|
||||
|
||||
/* */
|
||||
if (!((sockaddr->ss.ss_family == AF_INET) ? sockaddr->sin.sin_port : sockaddr->sin6.sin6_port)) {
|
||||
union capwap_addr localaddr;
|
||||
int localaddrsize = sizeof(union capwap_addr);
|
||||
|
||||
/* Retrieve port */
|
||||
ret = kernel_getsockname(sc_sockets[type], &localaddr.sa, &localaddrsize);
|
||||
if (ret) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* */
|
||||
if ((sockaddr->ss.ss_family == AF_INET) && (localaddr.ss.ss_family == AF_INET)) {
|
||||
sockaddr->sin.sin_port = localaddr.sin.sin_port;
|
||||
} else if ((sockaddr->ss.ss_family == AF_INET6) && (localaddr.ss.ss_family == AF_INET6)) {
|
||||
sockaddr->sin6.sin6_port = localaddr.sin6.sin6_port;
|
||||
} else {
|
||||
ret = -EFAULT;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
sock_release(sc_sockets[type]);
|
||||
sc_sockets[type] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr) {
|
||||
unsigned char* nethdr;
|
||||
|
||||
TRACEKMOD("### sc_socket_getpeeraddr\n");
|
||||
|
||||
/* */
|
||||
nethdr = skb_network_header(skb);
|
||||
if (!nethdr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* */
|
||||
switch (ntohs(skb->protocol)) {
|
||||
case ETH_P_IP: {
|
||||
/* Validate IPv4 header */
|
||||
if ((nethdr[0] & 0xf0) != 0x40) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Retrieve address */
|
||||
peeraddr->sin.sin_family = AF_INET;
|
||||
peeraddr->sin.sin_addr.s_addr = ((struct iphdr*)nethdr)->saddr;
|
||||
peeraddr->sin.sin_port = udp_hdr(skb)->source;
|
||||
break;
|
||||
}
|
||||
|
||||
case ETH_P_IPV6: {
|
||||
/* Validate IPv6 header */
|
||||
if ((nethdr[0] & 0xf0) != 0x60) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Retrieve address */
|
||||
peeraddr->sin6.sin6_family = AF_INET6;
|
||||
memcpy(&peeraddr->sin6.sin6_addr, &((struct ipv6hdr*)nethdr)->saddr, sizeof(struct in6_addr));
|
||||
peeraddr->sin6.sin6_port = udp_hdr(skb)->source;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr) {
|
||||
struct kvec vec;
|
||||
struct msghdr msg;
|
||||
|
||||
TRACEKMOD("### sc_socket_send\n");
|
||||
|
||||
/* */
|
||||
vec.iov_base = buffer;
|
||||
vec.iov_len = length;
|
||||
|
||||
/* */
|
||||
memset(&msg, 0, sizeof(struct msghdr));
|
||||
msg.msg_name = sockaddr;
|
||||
msg.msg_namelen = sizeof(union capwap_addr);
|
||||
msg.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT;
|
||||
|
||||
/* */
|
||||
return kernel_sendmsg(sc_sockets[type], &msg, &vec, 1, length);
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_socket_init(void) {
|
||||
TRACEKMOD("### sc_socket_init\n");
|
||||
|
||||
memset(sc_sockets, 0, sizeof(sc_sockets));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_socket_bind(union capwap_addr* sockaddr) {
|
||||
int ret;
|
||||
|
||||
TRACEKMOD("### sc_socket_bind\n");
|
||||
|
||||
/* */
|
||||
if (sc_sockets[SOCKET_UDP] || sc_sockets[SOCKET_UDPLITE]) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* UDP socket */
|
||||
ret = sc_socket_create(SOCKET_UDP, sockaddr, IPPROTO_UDP);
|
||||
if (ret) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* UDPLite socket */
|
||||
ret = sc_socket_create(SOCKET_UDPLITE, sockaddr, IPPROTO_UDPLITE);
|
||||
if (ret) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* */
|
||||
udp_encap_enable();
|
||||
if (sockaddr->ss.ss_family == AF_INET6) {
|
||||
udpv6_encap_enable();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
sc_socket_close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_socket_close(void) {
|
||||
TRACEKMOD("### sc_socket_close\n");
|
||||
|
||||
/* Close sockets */
|
||||
if (sc_sockets[SOCKET_UDP]) {
|
||||
kernel_sock_shutdown(sc_sockets[SOCKET_UDP], SHUT_RDWR);
|
||||
sock_release(sc_sockets[SOCKET_UDP]);
|
||||
}
|
||||
|
||||
if (sc_sockets[SOCKET_UDPLITE]) {
|
||||
kernel_sock_shutdown(sc_sockets[SOCKET_UDPLITE], SHUT_RDWR);
|
||||
sock_release(sc_sockets[SOCKET_UDPLITE]);
|
||||
}
|
||||
|
||||
memset(sc_sockets, 0, sizeof(sc_sockets));
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2) {
|
||||
TRACEKMOD("### sc_addr_compare\n");
|
||||
|
||||
if (addr1->ss.ss_family == addr2->ss.ss_family) {
|
||||
if (addr1->ss.ss_family == AF_INET) {
|
||||
return (((addr1->sin.sin_addr.s_addr == addr2->sin.sin_addr.s_addr) && (addr1->sin.sin_port == addr2->sin.sin_port)) ? 0 : -1);
|
||||
} else if (addr1->ss.ss_family == AF_INET6) {
|
||||
return ((!memcmp(&addr1->sin6.sin6_addr, &addr2->sin6.sin6_addr, sizeof(struct in6_addr)) && (addr1->sin6.sin6_port == addr2->sin6.sin6_port)) ? 0 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -1,35 +1,35 @@
|
||||
#ifndef __KMOD_SOCKET_HEADER__
|
||||
#define __KMOD_SOCKET_HEADER__
|
||||
|
||||
#include <linux/socket.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
/* */
|
||||
#define SOCKET_UDP 0
|
||||
#define SOCKET_UDPLITE 1
|
||||
|
||||
/* Universal socket address */
|
||||
union capwap_addr {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
struct sockaddr_storage ss;
|
||||
};
|
||||
|
||||
/* */
|
||||
int sc_socket_init(void);
|
||||
void sc_socket_close(void);
|
||||
|
||||
/* */
|
||||
int sc_socket_bind(union capwap_addr* sockaddr);
|
||||
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr);
|
||||
|
||||
/* */
|
||||
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr);
|
||||
|
||||
/* */
|
||||
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2);
|
||||
|
||||
#endif /* __KMOD_SOCKET_HEADER__ */
|
||||
#ifndef __KMOD_SOCKET_HEADER__
|
||||
#define __KMOD_SOCKET_HEADER__
|
||||
|
||||
#include <linux/socket.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
/* */
|
||||
#define SOCKET_UDP 0
|
||||
#define SOCKET_UDPLITE 1
|
||||
|
||||
/* Universal socket address */
|
||||
union capwap_addr {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
struct sockaddr_storage ss;
|
||||
};
|
||||
|
||||
/* */
|
||||
int sc_socket_init(void);
|
||||
void sc_socket_close(void);
|
||||
|
||||
/* */
|
||||
int sc_socket_bind(union capwap_addr* sockaddr);
|
||||
int sc_socket_send(int type, uint8_t* buffer, int length, union capwap_addr* sockaddr);
|
||||
|
||||
/* */
|
||||
int sc_socket_getpeeraddr(struct sk_buff* skb, union capwap_addr* peeraddr);
|
||||
|
||||
/* */
|
||||
int sc_addr_compare(const union capwap_addr* addr1, const union capwap_addr* addr2);
|
||||
|
||||
#endif /* __KMOD_SOCKET_HEADER__ */
|
||||
|
@ -1,157 +1,157 @@
|
||||
#include "config.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include "station.h"
|
||||
#include "capwap.h"
|
||||
#include "iface.h"
|
||||
|
||||
/* */
|
||||
#define STATION_HASH_SIZE 65536
|
||||
|
||||
/* */
|
||||
static LIST_HEAD(sc_station_list);
|
||||
static struct sc_capwap_station* __rcu sc_station_hash_addr[STATION_HASH_SIZE];
|
||||
|
||||
/* */
|
||||
static uint32_t sc_stations_hash_addr(const uint8_t* macaddress) {
|
||||
TRACEKMOD("### sc_stations_hash_addr\n");
|
||||
|
||||
return (((((uint32_t)macaddress[4] << 8) | (uint32_t)macaddress[5]) ^ ((uint32_t)macaddress[3] << 4)) % STATION_HASH_SIZE);
|
||||
}
|
||||
|
||||
/* */
|
||||
static struct sc_capwap_connection* sc_stations_searchconnection(struct sc_capwap_station* station) {
|
||||
struct sc_capwap_connection* connection;
|
||||
struct sc_capwap_session_priv* sessionpriv = rcu_access_pointer(station->sessionpriv);
|
||||
struct sc_netdev_priv* devpriv = rcu_access_pointer(station->devpriv);
|
||||
|
||||
TRACEKMOD("### sc_stations_searchconnection\n");
|
||||
|
||||
list_for_each_entry(connection, &sessionpriv->list_connections, list_session) {
|
||||
if ((connection->devpriv == devpriv) && (connection->radioid == station->radioid) && (connection->vlan == station->vlan)) {
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_stations_add(struct sc_capwap_station* station) {
|
||||
uint32_t hash;
|
||||
|
||||
TRACEKMOD("### sc_stations_add\n");
|
||||
|
||||
/* */
|
||||
list_add_rcu(&station->list, &sc_station_list);
|
||||
|
||||
hash = sc_stations_hash_addr(station->address);
|
||||
station->next_addr = rcu_dereference_protected(sc_station_hash_addr[hash], sc_capwap_update_lock_is_locked());
|
||||
rcu_assign_pointer(sc_station_hash_addr[hash], station);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct sc_capwap_station* sc_stations_search(const uint8_t* macaddress) {
|
||||
struct sc_capwap_station* station;
|
||||
|
||||
TRACEKMOD("### sc_stations_search\n");
|
||||
|
||||
/* */
|
||||
station = rcu_dereference_check(sc_station_hash_addr[sc_stations_hash_addr(macaddress)], sc_capwap_update_lock_is_locked());
|
||||
while (station) {
|
||||
if (!memcmp(&station->address, macaddress, MACADDRESS_EUI48_LENGTH)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* */
|
||||
station = rcu_dereference_check(station->next_addr, sc_capwap_update_lock_is_locked());
|
||||
}
|
||||
|
||||
return station;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_stations_free(struct sc_capwap_station* station) {
|
||||
uint32_t hash;
|
||||
struct sc_capwap_station* search;
|
||||
|
||||
TRACEKMOD("### sc_stations_free\n");
|
||||
|
||||
/* */
|
||||
hash = sc_stations_hash_addr(station->address);
|
||||
search = rcu_dereference_protected(sc_station_hash_addr[hash], sc_capwap_update_lock_is_locked());
|
||||
|
||||
if (search) {
|
||||
if (search == station) {
|
||||
rcu_assign_pointer(sc_station_hash_addr[hash], station->next_addr);
|
||||
} else {
|
||||
while (rcu_access_pointer(search->next_addr) && (rcu_access_pointer(search->next_addr) != station)) {
|
||||
search = rcu_dereference_protected(search->next_addr, sc_capwap_update_lock_is_locked());
|
||||
}
|
||||
|
||||
if (rcu_access_pointer(search->next_addr)) {
|
||||
rcu_assign_pointer(search->next_addr, station->next_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
list_del_rcu(&station->list_dev);
|
||||
list_del_rcu(&station->list_session);
|
||||
synchronize_net();
|
||||
|
||||
kfree(station);
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_stations_setconnection(struct sc_capwap_station* station) {
|
||||
struct sc_capwap_connection* connection;
|
||||
|
||||
TRACEKMOD("### sc_stations_setconnection\n");
|
||||
|
||||
/* */
|
||||
connection = sc_stations_searchconnection(station);
|
||||
if (!connection) {
|
||||
connection = (struct sc_capwap_connection*)kzalloc(sizeof(struct sc_capwap_connection), GFP_KERNEL);
|
||||
if (!connection) {
|
||||
TRACEKMOD("*** Unable to create connection\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* */
|
||||
connection->sessionpriv = rcu_access_pointer(station->sessionpriv);
|
||||
list_add_rcu(&connection->list_session, &connection->sessionpriv->list_connections);
|
||||
connection->devpriv = rcu_access_pointer(station->devpriv);
|
||||
list_add_rcu(&connection->list_dev, &connection->devpriv->list_connections);
|
||||
connection->radioid = station->radioid;
|
||||
connection->vlan = station->vlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
connection->count++;
|
||||
connection->wlanidmask |= 1 << (station->wlanid - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_stations_releaseconnection(struct sc_capwap_station* station) {
|
||||
struct sc_capwap_connection* connection;
|
||||
|
||||
TRACEKMOD("### sc_stations_releaseconnection\n");
|
||||
|
||||
connection = sc_stations_searchconnection(station);
|
||||
if (connection) {
|
||||
TRACEKMOD("*** Release connection reference %d\n", connection->count);
|
||||
|
||||
connection->count--;
|
||||
if (!connection->count) {
|
||||
list_del_rcu(&connection->list_session);
|
||||
list_del_rcu(&connection->list_dev);
|
||||
synchronize_net();
|
||||
|
||||
kfree(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "config.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include "station.h"
|
||||
#include "capwap.h"
|
||||
#include "iface.h"
|
||||
|
||||
/* */
|
||||
#define STATION_HASH_SIZE 65536
|
||||
|
||||
/* */
|
||||
static LIST_HEAD(sc_station_list);
|
||||
static struct sc_capwap_station* __rcu sc_station_hash_addr[STATION_HASH_SIZE];
|
||||
|
||||
/* */
|
||||
static uint32_t sc_stations_hash_addr(const uint8_t* macaddress) {
|
||||
TRACEKMOD("### sc_stations_hash_addr\n");
|
||||
|
||||
return (((((uint32_t)macaddress[4] << 8) | (uint32_t)macaddress[5]) ^ ((uint32_t)macaddress[3] << 4)) % STATION_HASH_SIZE);
|
||||
}
|
||||
|
||||
/* */
|
||||
static struct sc_capwap_connection* sc_stations_searchconnection(struct sc_capwap_station* station) {
|
||||
struct sc_capwap_connection* connection;
|
||||
struct sc_capwap_session_priv* sessionpriv = rcu_access_pointer(station->sessionpriv);
|
||||
struct sc_netdev_priv* devpriv = rcu_access_pointer(station->devpriv);
|
||||
|
||||
TRACEKMOD("### sc_stations_searchconnection\n");
|
||||
|
||||
list_for_each_entry(connection, &sessionpriv->list_connections, list_session) {
|
||||
if ((connection->devpriv == devpriv) && (connection->radioid == station->radioid) && (connection->vlan == station->vlan)) {
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_stations_add(struct sc_capwap_station* station) {
|
||||
uint32_t hash;
|
||||
|
||||
TRACEKMOD("### sc_stations_add\n");
|
||||
|
||||
/* */
|
||||
list_add_rcu(&station->list, &sc_station_list);
|
||||
|
||||
hash = sc_stations_hash_addr(station->address);
|
||||
station->next_addr = rcu_dereference_protected(sc_station_hash_addr[hash], sc_capwap_update_lock_is_locked());
|
||||
rcu_assign_pointer(sc_station_hash_addr[hash], station);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct sc_capwap_station* sc_stations_search(const uint8_t* macaddress) {
|
||||
struct sc_capwap_station* station;
|
||||
|
||||
TRACEKMOD("### sc_stations_search\n");
|
||||
|
||||
/* */
|
||||
station = rcu_dereference_check(sc_station_hash_addr[sc_stations_hash_addr(macaddress)], sc_capwap_update_lock_is_locked());
|
||||
while (station) {
|
||||
if (!memcmp(&station->address, macaddress, MACADDRESS_EUI48_LENGTH)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* */
|
||||
station = rcu_dereference_check(station->next_addr, sc_capwap_update_lock_is_locked());
|
||||
}
|
||||
|
||||
return station;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_stations_free(struct sc_capwap_station* station) {
|
||||
uint32_t hash;
|
||||
struct sc_capwap_station* search;
|
||||
|
||||
TRACEKMOD("### sc_stations_free\n");
|
||||
|
||||
/* */
|
||||
hash = sc_stations_hash_addr(station->address);
|
||||
search = rcu_dereference_protected(sc_station_hash_addr[hash], sc_capwap_update_lock_is_locked());
|
||||
|
||||
if (search) {
|
||||
if (search == station) {
|
||||
rcu_assign_pointer(sc_station_hash_addr[hash], station->next_addr);
|
||||
} else {
|
||||
while (rcu_access_pointer(search->next_addr) && (rcu_access_pointer(search->next_addr) != station)) {
|
||||
search = rcu_dereference_protected(search->next_addr, sc_capwap_update_lock_is_locked());
|
||||
}
|
||||
|
||||
if (rcu_access_pointer(search->next_addr)) {
|
||||
rcu_assign_pointer(search->next_addr, station->next_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
list_del_rcu(&station->list_dev);
|
||||
list_del_rcu(&station->list_session);
|
||||
synchronize_net();
|
||||
|
||||
kfree(station);
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_stations_setconnection(struct sc_capwap_station* station) {
|
||||
struct sc_capwap_connection* connection;
|
||||
|
||||
TRACEKMOD("### sc_stations_setconnection\n");
|
||||
|
||||
/* */
|
||||
connection = sc_stations_searchconnection(station);
|
||||
if (!connection) {
|
||||
connection = (struct sc_capwap_connection*)kzalloc(sizeof(struct sc_capwap_connection), GFP_KERNEL);
|
||||
if (!connection) {
|
||||
TRACEKMOD("*** Unable to create connection\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* */
|
||||
connection->sessionpriv = rcu_access_pointer(station->sessionpriv);
|
||||
list_add_rcu(&connection->list_session, &connection->sessionpriv->list_connections);
|
||||
connection->devpriv = rcu_access_pointer(station->devpriv);
|
||||
list_add_rcu(&connection->list_dev, &connection->devpriv->list_connections);
|
||||
connection->radioid = station->radioid;
|
||||
connection->vlan = station->vlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
connection->count++;
|
||||
connection->wlanidmask |= 1 << (station->wlanid - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_stations_releaseconnection(struct sc_capwap_station* station) {
|
||||
struct sc_capwap_connection* connection;
|
||||
|
||||
TRACEKMOD("### sc_stations_releaseconnection\n");
|
||||
|
||||
connection = sc_stations_searchconnection(station);
|
||||
if (connection) {
|
||||
TRACEKMOD("*** Release connection reference %d\n", connection->count);
|
||||
|
||||
connection->count--;
|
||||
if (!connection->count) {
|
||||
list_del_rcu(&connection->list_session);
|
||||
list_del_rcu(&connection->list_dev);
|
||||
synchronize_net();
|
||||
|
||||
kfree(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,58 +1,58 @@
|
||||
#ifndef __KMOD_AC_STATION_HEADER__
|
||||
#define __KMOD_AC_STATION_HEADER__
|
||||
|
||||
#include "capwap_rfc.h"
|
||||
|
||||
/* */
|
||||
struct sc_capwap_connection {
|
||||
int count;
|
||||
|
||||
/* Session */
|
||||
struct sc_capwap_session_priv* sessionpriv;
|
||||
struct list_head list_session;
|
||||
|
||||
/* Interface */
|
||||
struct sc_netdev_priv* devpriv;
|
||||
struct list_head list_dev;
|
||||
|
||||
/* */
|
||||
uint16_t vlan;
|
||||
uint8_t radioid;
|
||||
uint8_t wlanidmask;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_station {
|
||||
struct list_head list;
|
||||
|
||||
/* */
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
struct sc_capwap_station* __rcu next_addr;
|
||||
|
||||
/* Session */
|
||||
struct sc_capwap_session_priv* __rcu sessionpriv;
|
||||
struct list_head list_session;
|
||||
|
||||
/* Interface */
|
||||
struct sc_netdev_priv* __rcu devpriv;
|
||||
struct list_head list_dev;
|
||||
|
||||
/* */
|
||||
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
|
||||
uint16_t vlan;
|
||||
uint8_t radioid;
|
||||
uint8_t wlanid;
|
||||
};
|
||||
|
||||
/* */
|
||||
void sc_stations_add(struct sc_capwap_station* station);
|
||||
void sc_stations_free(struct sc_capwap_station* station);
|
||||
|
||||
/* */
|
||||
struct sc_capwap_station* sc_stations_search(const uint8_t* macaddress);
|
||||
|
||||
/* */
|
||||
int sc_stations_setconnection(struct sc_capwap_station* station);
|
||||
void sc_stations_releaseconnection(struct sc_capwap_station* station);
|
||||
|
||||
#endif /* __KMOD_AC_STATION_HEADER__ */
|
||||
#ifndef __KMOD_AC_STATION_HEADER__
|
||||
#define __KMOD_AC_STATION_HEADER__
|
||||
|
||||
#include "capwap_rfc.h"
|
||||
|
||||
/* */
|
||||
struct sc_capwap_connection {
|
||||
int count;
|
||||
|
||||
/* Session */
|
||||
struct sc_capwap_session_priv* sessionpriv;
|
||||
struct list_head list_session;
|
||||
|
||||
/* Interface */
|
||||
struct sc_netdev_priv* devpriv;
|
||||
struct list_head list_dev;
|
||||
|
||||
/* */
|
||||
uint16_t vlan;
|
||||
uint8_t radioid;
|
||||
uint8_t wlanidmask;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct sc_capwap_station {
|
||||
struct list_head list;
|
||||
|
||||
/* */
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
struct sc_capwap_station* __rcu next_addr;
|
||||
|
||||
/* Session */
|
||||
struct sc_capwap_session_priv* __rcu sessionpriv;
|
||||
struct list_head list_session;
|
||||
|
||||
/* Interface */
|
||||
struct sc_netdev_priv* __rcu devpriv;
|
||||
struct list_head list_dev;
|
||||
|
||||
/* */
|
||||
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
|
||||
uint16_t vlan;
|
||||
uint8_t radioid;
|
||||
uint8_t wlanid;
|
||||
};
|
||||
|
||||
/* */
|
||||
void sc_stations_add(struct sc_capwap_station* station);
|
||||
void sc_stations_free(struct sc_capwap_station* station);
|
||||
|
||||
/* */
|
||||
struct sc_capwap_station* sc_stations_search(const uint8_t* macaddress);
|
||||
|
||||
/* */
|
||||
int sc_stations_setconnection(struct sc_capwap_station* station);
|
||||
void sc_stations_releaseconnection(struct sc_capwap_station* station);
|
||||
|
||||
#endif /* __KMOD_AC_STATION_HEADER__ */
|
||||
|
Reference in New Issue
Block a user