freewtp/src/ac/ac_dfa_configure.c

795 lines
26 KiB
C

#include "ac.h"
#include "capwap_dfa.h"
#include "capwap_array.h"
#include "ac_session.h"
#include "ac_json.h"
#include "ac_wlans.h"
#include <json/json.h>
#include <arpa/inet.h>
/* */
static void ac_dfa_state_configure_set_radio_configuration(struct ac_session_t* session, struct ac_json_ieee80211_wtpradio* wtpradio) {
int i;
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
struct ac_json_ieee80211_item* item = &wtpradio->items[i];
if (item->valid) {
struct ac_device* device = &session->wlans->devices[i];
/* Set rates */
if (item->rateset || item->supportedrates) {
if (item->rateset) {
memcpy(device->supportedrates, item->rateset->rateset, item->rateset->ratesetcount);
device->supportedratescount = item->rateset->ratesetcount;
} else if (item->supportedrates) {
memcpy(device->supportedrates, item->supportedrates->supportedrates, item->supportedrates->supportedratescount);
device->supportedratescount = item->supportedrates->supportedratescount;
}
}
}
}
}
/* */
static struct ac_soap_response* ac_dfa_state_configure_parsing_request(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
int i;
const char* jsonmessage;
char* base64confstatus;
struct json_object* jsonarray;
struct json_object* jsonparam;
struct json_object* jsonhash;
struct capwap_array* elemarray;
struct capwap_statisticstimer_element* statisticstimer;
struct capwap_wtprebootstat_element* wtprebootstat;
struct capwap_wtpstaticipaddress_element* wtpstaticipaddress;
struct ac_soap_response* response;
unsigned short binding = GET_WBID_HEADER(packet->rxmngpacket->header);
/* Create SOAP request with JSON param
{
RadioAdministrativeState: [
{
RadioID: [int],
AdminState: [int]
}
],
StatisticsTimer: {
StatisticsTimer: [int]
},
WTPRebootStatistics: {
RebootCount: [int],
ACInitiatedCount: [int],
LinkFailureCount: [int],
SWFailureCount: [int],
HWFailureCount: [int],
OtherFailureCount: [int],
UnknownFailureCount: [int],
LastFailureType: [int]
},
ACNamePriority: [
{
Priority: [int],
ACName: [string]
}
],
WTPStaticIPAddressInformation: {
IPAddress: [string],
Netmask: [string],
Gateway: [string],
Static: [int]
},
<IEEE 802.11 BINDING>
WTPRadio: [
{
RadioID: [int],
IEEE80211Antenna: {
Diversity: [bool],
Combiner: [int],
AntennaSelection: [
[int]
]
},
IEEE80211DirectSequenceControl: {
CurrentChan: [int],
CurrentCCA: [int],
EnergyDetectThreshold: [int]
},
IEEE80211MACOperation: {
RTSThreshold: [int],
ShortRetry: [int],
LongRetry: [int],
FragmentationThreshold: [int],
TxMSDULifetime: [int],
RxMSDULifetime: [int]
},
IEEE80211MultiDomainCapability: {
FirstChannel: [int],
NumberChannels: [int],
MaxTxPowerLevel: [int]
},
IEEE80211OFDMControl: {
CurrentChan: [int],
BandSupport: [int],
TIThreshold: [int]
},
IEEE80211SupportedRates: [
[int]
],
IEEE80211TxPower: {
CurrentTxPower: [int]
},
IEEE80211TXPowerLevel: [
[int]
],
IEEE80211WTPRadioConfiguration: {
ShortPreamble: [int],
NumBSSIDs: [int],
DTIMPeriod: [int],
BSSID: [string],
BeaconPeriod: [int],
CountryString: [string]
},
IEEE80211WTPRadioInformation: {
Mode: [int]
}
}
]
}
*/
/* */
jsonparam = json_object_new_object();
/* RadioAdministrativeState */
jsonarray = json_object_new_array();
elemarray = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RADIOADMSTATE);
for (i = 0; i < elemarray->count; i++) {
struct json_object* jsonradioadm;
struct capwap_radioadmstate_element* radioadm = *(struct capwap_radioadmstate_element**)capwap_array_get_item_pointer(elemarray, i);
/* */
jsonradioadm = json_object_new_object();
json_object_object_add(jsonradioadm, "RadioID", json_object_new_int((int)radioadm->radioid));
json_object_object_add(jsonradioadm, "AdminState", json_object_new_int((int)radioadm->state));
json_object_array_add(jsonarray, jsonradioadm);
}
json_object_object_add(jsonparam, "RadioAdministrativeState", jsonarray);
/* StatisticsTimer */
statisticstimer = (struct capwap_statisticstimer_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_STATISTICSTIMER);
jsonhash = json_object_new_object();
json_object_object_add(jsonhash, "StatisticsTimer", json_object_new_int((int)statisticstimer->timer));
json_object_object_add(jsonparam, "StatisticsTimer", jsonhash);
/* WTPRebootStatistics */
wtprebootstat = (struct capwap_wtprebootstat_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPREBOOTSTAT);
jsonhash = json_object_new_object();
json_object_object_add(jsonhash, "RebootCount", json_object_new_int((int)wtprebootstat->rebootcount));
json_object_object_add(jsonhash, "ACInitiatedCount", json_object_new_int((int)wtprebootstat->acinitiatedcount));
json_object_object_add(jsonhash, "LinkFailureCount", json_object_new_int((int)wtprebootstat->linkfailurecount));
json_object_object_add(jsonhash, "SWFailureCount", json_object_new_int((int)wtprebootstat->swfailurecount));
json_object_object_add(jsonhash, "HWFailureCount", json_object_new_int((int)wtprebootstat->hwfailurecount));
json_object_object_add(jsonhash, "OtherFailureCount", json_object_new_int((int)wtprebootstat->otherfailurecount));
json_object_object_add(jsonhash, "UnknownFailureCount", json_object_new_int((int)wtprebootstat->unknownfailurecount));
json_object_object_add(jsonhash, "LastFailureType", json_object_new_int((int)wtprebootstat->lastfailuretype));
json_object_object_add(jsonparam, "WTPRebootStatistics", jsonhash);
/* ACNamePriority */
elemarray = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_ACNAMEPRIORITY);
if (elemarray && elemarray->count) {
jsonarray = json_object_new_array();
for (i = 0; i < elemarray->count; i++) {
json_object* jacname;
struct capwap_acnamepriority_element* acname = *(struct capwap_acnamepriority_element**)capwap_array_get_item_pointer(elemarray, i);
/* */
jacname = json_object_new_object();
json_object_object_add(jacname, "Priority", json_object_new_int((int)acname->priority));
json_object_object_add(jacname, "ACName", json_object_new_string((char*)acname->name));
json_object_array_add(jsonarray, jacname);
}
json_object_object_add(jsonparam, "ACNamePriority", jsonarray);
}
/* WTPStaticIPAddressInformation */
wtpstaticipaddress = (struct capwap_wtpstaticipaddress_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPSTATICIPADDRESS);
if (wtpstaticipaddress) {
char ipbuffer[INET_ADDRSTRLEN];
/* */
jsonhash = json_object_new_object();
json_object_object_add(jsonhash, "IPAddress", json_object_new_string(inet_ntop(AF_INET, (void*)&wtpstaticipaddress->address, ipbuffer, INET_ADDRSTRLEN)));
json_object_object_add(jsonhash, "Netmask", json_object_new_string(inet_ntop(AF_INET, (void*)&wtpstaticipaddress->netmask, ipbuffer, INET_ADDRSTRLEN)));
json_object_object_add(jsonhash, "Gateway", json_object_new_string(inet_ntop(AF_INET, (void*)&wtpstaticipaddress->gateway, ipbuffer, INET_ADDRSTRLEN)));
json_object_object_add(jsonhash, "Static", json_object_new_int((int)wtpstaticipaddress->staticip));
json_object_object_add(jsonparam, "WTPStaticIPAddressInformation", jsonhash);
}
/* Binding message */
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
struct ac_json_ieee80211_wtpradio wtpradio;
struct capwap_list_item* search = packet->messages->first;
/* Reording message by radioid and management */
ac_json_ieee80211_init(&wtpradio);
while (search) {
struct capwap_message_element_itemlist* messageelement = (struct capwap_message_element_itemlist*)search->item;
/* Parsing only IEEE 802.11 message element */
if (IS_80211_MESSAGE_ELEMENTS(messageelement->type)) {
if (!ac_json_ieee80211_parsingmessageelement(&wtpradio, messageelement)) {
json_object_put(jsonparam);
return NULL;
}
}
/* Next */
search = search->next;
}
/* Generate JSON tree */
jsonarray = ac_json_ieee80211_getjson(&wtpradio);
json_object_object_add(jsonparam, IEEE80211_BINDING_JSON_ROOT, jsonarray);
/* Free resource */
ac_json_ieee80211_free(&wtpradio);
}
/* Get JSON param and convert base64 */
jsonmessage = json_object_to_json_string(jsonparam);
base64confstatus = capwap_alloc(AC_BASE64_ENCODE_LENGTH(strlen(jsonmessage)));
ac_base64_string_encode(jsonmessage, base64confstatus);
/* Send message */
response = ac_soap_configurestatuswtpsession(session, session->wtpid, base64confstatus);
/* Free JSON */
json_object_put(jsonparam);
capwap_free(base64confstatus);
return response;
}
/* */
static uint32_t ac_dfa_state_configure_create_response(struct ac_session_t* session, struct capwap_parsed_packet* packet, struct ac_soap_response* response, struct capwap_packet_txmng* txmngpacket) {
int length;
char* json;
unsigned long i;
xmlChar* xmlResult;
struct json_object* jsonroot;
struct json_object* jsonelement;
struct capwap_array* radioadmstate;
struct capwap_timers_element responsetimers;
struct capwap_idletimeout_element responseidletimeout;
struct capwap_wtpfallback_element responsewtpfallback;
unsigned short binding = GET_WBID_HEADER(packet->rxmngpacket->header);
if ((response->responsecode != HTTP_RESULT_OK) || !response->xmlResponseReturn) {
return CAPWAP_RESULTCODE_FAILURE;
}
/* Receive SOAP response with JSON result
{
CAPWAPTimers: {
Discovery: [int],
EchoRequest: [int]
},
DecryptionErrorReportPeriod: [
{
RadioID: [int],
ReportInterval: [int]
}
],
IdleTimeout: {
Timeout: [int]
},
WTPFallback: {
Mode: [int]
}
ACIPv4List: [
{
ACIPAddress: [string]
}
],
ACIPv6List: [
{
ACIPAddress: [string]
}
]
WTPStaticIPAddressInformation: {
IPAddress: [string],
Netmask: [string],
Gateway: [string],
Static: [int]
}
<IEEE 802.11 BINDING>
WTPRadio: [
{
RadioID: [int],
IEEE80211Antenna: {
Diversity: [bool],
Combiner: [int],
AntennaSelection: [
[int]
]
},
IEEE80211DirectSequenceControl: {
CurrentChan: [int],
CurrentCCA: [int],
EnergyDetectThreshold: [int]
},
IEEE80211MACOperation: {
RTSThreshold: [int],
ShortRetry: [int],
LongRetry: [int],
FragmentationThreshold: [int],
TxMSDULifetime: [int],
RxMSDULifetime: [int]
},
IEEE80211MultiDomainCapability: {
FirstChannel: [int],
NumberChannels: [int],
MaxTxPowerLevel: [int]
},
IEEE80211OFDMControl: {
CurrentChan: [int],
BandSupport: [int],
TIThreshold: [int]
},
IEEE80211Rateset: [
[int]
],
IEEE80211SupportedRates: [
[int]
],
IEEE80211TxPower: {
CurrentTxPower: [int]
},
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]
}
}
IEEE80211WTPRadioConfiguration: {
ShortPreamble: [int],
NumBSSIDs: [int],
DTIMPeriod: [int],
BSSID: [string],
BeaconPeriod: [int],
CountryString: [string]
}
}
]
}
*/
/* Decode base64 result */
xmlResult = xmlNodeGetContent(response->xmlResponseReturn);
if (!xmlResult) {
return CAPWAP_RESULTCODE_FAILURE;
}
length = xmlStrlen(xmlResult);
if (!length) {
return CAPWAP_RESULTCODE_FAILURE;
}
json = (char*)capwap_alloc(AC_BASE64_DECODE_LENGTH(length));
ac_base64_string_decode((const char*)xmlResult, json);
xmlFree(xmlResult);
/* Parsing JSON result */
jsonroot = json_tokener_parse(json);
capwap_free(json);
/* Add message elements response, every local value can be overwrite from backend server */
/* CAPWAP Timers */
memcpy(&responsetimers, &session->dfa.timers, sizeof(struct capwap_timers_element));
if (jsonroot) {
jsonelement = compat_json_object_object_get(jsonroot, "CAPWAPTimers");
if (jsonelement && (json_object_get_type(jsonelement) == json_type_object)) {
struct json_object* jsonitem;
/* Discovery */
jsonitem = compat_json_object_object_get(jsonelement, "Discovery");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
int value = json_object_get_int(jsonitem);
if ((value > 0) && (value < 256)) {
responsetimers.discovery = (uint8_t)value;
}
}
/* EchoRequest */
jsonitem = compat_json_object_object_get(jsonelement, "EchoRequest");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
int value = json_object_get_int(jsonitem);
if ((value > 0) && (value < 256)) {
responsetimers.echorequest = (uint8_t)value;
}
}
}
}
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TIMERS, &responsetimers);
/* Decryption Error Report Period */
jsonelement = NULL;
if (jsonroot) {
jsonelement = compat_json_object_object_get(jsonroot, "DecryptionErrorReportPeriod");
if (jsonelement && (json_object_get_type(jsonelement) == json_type_array)) {
length = json_object_array_length(jsonelement);
} else {
jsonelement = NULL;
}
}
/* Build Decryption Error Report Period List with elements of Radio Administration State */
radioadmstate = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RADIOADMSTATE);
for (i = 0; i < radioadmstate->count; i++) {
struct capwap_decrypterrorreportperiod_element report;
struct capwap_radioadmstate_element* radioadm = *(struct capwap_radioadmstate_element**)capwap_array_get_item_pointer(radioadmstate, i);
report.radioid = radioadm->radioid;
report.interval = session->dfa.decrypterrorreport_interval;
/* Search for JSON overwrite value */
if (jsonelement) {
int j;
for (j = 0; j < length; j++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonelement, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) {
struct json_object* jsonitem;
/* RadioID */
jsonitem = compat_json_object_object_get(jsonvalue, "RadioID");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
int value = json_object_get_int(jsonitem);
if ((value > 0) && (value < 256) && ((uint8_t)value == report.radioid)) {
/* Get ReportInterval value */
jsonitem = compat_json_object_object_get(jsonvalue, "ReportInterval");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
value = json_object_get_int(jsonitem);
if ((value > 0) && (value < 65536)) {
report.interval = (uint16_t)value;
break;
}
}
}
}
}
}
}
/* */
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD, &report);
}
/* IdleTimeout */
memcpy(&responseidletimeout, &session->dfa.idletimeout, sizeof(struct capwap_idletimeout_element));
if (jsonroot) {
jsonelement = compat_json_object_object_get(jsonroot, "IdleTimeout");
if (jsonelement && (json_object_get_type(jsonelement) == json_type_object)) {
struct json_object* jsonitem;
/* Timeout */
jsonitem = compat_json_object_object_get(jsonelement, "Timeout");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
int value = json_object_get_int(jsonitem);
if (value > 0) {
responseidletimeout.timeout = (uint32_t)value;
}
}
}
}
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_IDLETIMEOUT, &responseidletimeout);
/* WTPFallback */
memcpy(&responsewtpfallback, &session->dfa.wtpfallback, sizeof(struct capwap_wtpfallback_element));
if (jsonroot) {
jsonelement = compat_json_object_object_get(jsonroot, "WTPFallback");
if (jsonelement && (json_object_get_type(jsonelement) == json_type_object)) {
struct json_object* jsonitem;
/* Mode */
jsonitem = compat_json_object_object_get(jsonelement, "Mode");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
int value = json_object_get_int(jsonitem);
if ((value > 0) && (value < 256)) {
responsewtpfallback.mode = (uint8_t)value;
}
}
}
}
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPFALLBACK, &responsewtpfallback);
/* ACIPv4List */
jsonelement = NULL;
if (jsonroot) {
jsonelement = compat_json_object_object_get(jsonroot, "ACIPv4List");
if (jsonelement && (json_object_get_type(jsonelement) == json_type_array)) {
length = json_object_array_length(jsonelement);
} else {
jsonelement = NULL;
}
}
if (jsonelement) {
int j;
struct capwap_acipv4list_element* responseacipv4list;
responseacipv4list = (struct capwap_acipv4list_element*)capwap_alloc(sizeof(struct capwap_acipv4list_element));
responseacipv4list->addresses = capwap_array_create(sizeof(struct in_addr), 0, 0);
for (j = 0; j < length; j++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonelement, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) {
struct json_object* jsonitem;
/* ACIPAddress */
jsonitem = compat_json_object_object_get(jsonvalue, "ACIPAddress");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
const char* value = json_object_get_string(jsonitem);
if (value) {
union sockaddr_capwap address;
if (capwap_address_from_string(value, &address)) {
/* Accept only IPv4 address */
if (address.ss.ss_family == AF_INET) {
struct in_addr* responseaddress_in = (struct in_addr*)capwap_array_get_item_pointer(responseacipv4list->addresses, responseacipv4list->addresses->count);
memcpy(responseaddress_in, &address.sin.sin_addr, sizeof(struct in_addr));
}
}
}
}
}
}
if (responseacipv4list->addresses->count > 0) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV4LIST, responseacipv4list);
}
capwap_array_free(responseacipv4list->addresses);
capwap_free(responseacipv4list);
} else if (session->dfa.acipv4list.addresses->count > 0) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV4LIST, &session->dfa.acipv4list);
}
/* ACIPv6List */
jsonelement = NULL;
if (jsonroot) {
jsonelement = compat_json_object_object_get(jsonroot, "ACIPv6List");
if (jsonelement && (json_object_get_type(jsonelement) == json_type_array)) {
length = json_object_array_length(jsonelement);
} else {
jsonelement = NULL;
}
}
if (jsonelement) {
int j;
struct capwap_acipv6list_element* responseacipv6list;
responseacipv6list = (struct capwap_acipv6list_element*)capwap_alloc(sizeof(struct capwap_acipv6list_element));
responseacipv6list->addresses = capwap_array_create(sizeof(struct in6_addr), 0, 0);
for (j = 0; j < length; j++) {
struct json_object* jsonvalue = json_object_array_get_idx(jsonelement, i);
if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) {
struct json_object* jsonitem;
/* ACIPAddress */
jsonitem = compat_json_object_object_get(jsonvalue, "ACIPAddress");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
const char* value = json_object_get_string(jsonitem);
if (value) {
union sockaddr_capwap address;
if (capwap_address_from_string(value, &address)) {
/* Accept only IPv6 address */
if (address.ss.ss_family == AF_INET6) {
struct in6_addr* responseaddress_in6 = (struct in6_addr*)capwap_array_get_item_pointer(responseacipv6list->addresses, responseacipv6list->addresses->count);
memcpy(responseaddress_in6, &address.sin6.sin6_addr, sizeof(struct in6_addr));
}
}
}
}
}
}
if (responseacipv6list->addresses->count > 0) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV6LIST, responseacipv6list);
}
capwap_array_free(responseacipv6list->addresses);
capwap_free(responseacipv6list);
} else if (session->dfa.acipv6list.addresses->count > 0) {
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV6LIST, &session->dfa.acipv6list);
}
/* WTPStaticIPAddressInformation */
if (jsonroot) {
jsonelement = compat_json_object_object_get(jsonroot, "WTPStaticIPAddressInformation");
if (jsonelement && (json_object_get_type(jsonelement) == json_type_object)) {
struct json_object* jsonitem;
/* IPAddress */
jsonitem = compat_json_object_object_get(jsonelement, "IPAddress");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
union sockaddr_capwap address;
const char* addressvalue = json_object_get_string(jsonitem);
if (capwap_address_from_string(addressvalue, &address)) {
if (address.ss.ss_family == AF_INET) {
/* Netmask */
jsonitem = compat_json_object_object_get(jsonelement, "Netmask");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
union sockaddr_capwap netmask;
const char* netmaskvalue = json_object_get_string(jsonitem);
if (capwap_address_from_string(netmaskvalue, &netmask)) {
if (netmask.ss.ss_family == AF_INET) {
/* Gateway */
jsonitem = compat_json_object_object_get(jsonelement, "Gateway");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
union sockaddr_capwap gateway;
const char* gatewayvalue = json_object_get_string(jsonitem);
if (capwap_address_from_string(gatewayvalue, &gateway)) {
if (gateway.ss.ss_family == AF_INET) {
/* Static */
jsonitem = compat_json_object_object_get(jsonelement, "Static");
if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
int value = json_object_get_int(jsonitem);
struct capwap_wtpstaticipaddress_element responsewtpstaticipaddress;
memcpy(&responsewtpstaticipaddress.address, &address.sin.sin_addr, sizeof(struct in_addr));
memcpy(&responsewtpstaticipaddress.netmask, &netmask.sin.sin_addr, sizeof(struct in_addr));
memcpy(&responsewtpstaticipaddress.gateway, &gateway.sin.sin_addr, sizeof(struct in_addr));
responsewtpstaticipaddress.staticip = (uint8_t)value;
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPSTATICIPADDRESS, &responsewtpstaticipaddress);
}
}
}
}
}
}
}
}
}
}
}
}
/* WTP Radio Information */
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
struct ac_json_ieee80211_wtpradio wtpradio;
/* */
ac_json_ieee80211_init(&wtpradio);
/* Parsing SOAP response */
jsonelement = compat_json_object_object_get(jsonroot, IEEE80211_BINDING_JSON_ROOT);
if (jsonelement) {
if (ac_json_ieee80211_parsingjson(&wtpradio, jsonelement)) {
/* Add IEEE802.11 message elements to packet */
ac_json_ieee80211_buildpacket(&wtpradio, txmngpacket);
/* Retrieve frequency and rates configuration */
ac_dfa_state_configure_set_radio_configuration(session, &wtpradio);
}
}
/* Free resource */
ac_json_ieee80211_free(&wtpradio);
}
/* CAPWAP_ELEMENT_VENDORPAYLOAD */ /* TODO */
if (jsonroot) {
json_object_put(jsonroot);
}
return CAPWAP_RESULTCODE_SUCCESS;
}
/* */
void ac_dfa_state_configure(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
struct ac_soap_response* response;
struct capwap_header_data capwapheader;
struct capwap_packet_txmng* txmngpacket;
uint32_t result = CAPWAP_RESULTCODE_FAILURE;
ASSERT(session != NULL);
ASSERT(packet != NULL);
/* Create response */
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, GET_WBID_HEADER(packet->rxmngpacket->header));
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_CONFIGURATION_STATUS_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, session->mtu);
/* Parsing request and add message element for respone message */
response = ac_dfa_state_configure_parsing_request(session, packet);
if (response) {
result = ac_dfa_state_configure_create_response(session, packet, response, txmngpacket);
ac_soapclient_free_response(response);
}
/* With error add result code message element */
if (!CAPWAP_RESULTCODE_OK(result)) {
struct capwap_resultcode_element resultcode = { .code = result };
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RESULTCODE, &resultcode);
/* */
if (result == CAPWAP_RESULTCODE_FAILURE) {
/* TODO: Add AC List Message Elements */
}
}
/* Configure response complete, get fragment packets */
ac_free_reference_last_response(session);
capwap_packet_txmng_get_fragment_packets(txmngpacket, session->responsefragmentpacket, session->fragmentid);
if (session->responsefragmentpacket->count > 1) {
session->fragmentid++;
}
/* Free packets manager */
capwap_packet_txmng_free(txmngpacket);
/* Save remote sequence number */
session->remotetype = packet->rxmngpacket->ctrlmsg.type;
session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
/* Send Configure response to WTP */
if (!capwap_crypt_sendto_fragmentpacket(&session->dtls, session->responsefragmentpacket)) {
/* Response is already created and saved. When receive a re-request, DFA autoresponse */
capwap_logging_debug("Warning: error to send configuration status response packet");
}
/* Change state */
if (CAPWAP_RESULTCODE_OK(result)) {
ac_dfa_change_state(session, CAPWAP_DATA_CHECK_STATE);
capwap_timeout_set(session->timeout, session->idtimercontrol, AC_CHANGE_STATE_PENDING_INTERVAL, ac_dfa_teardown_timeout, session, NULL);
} else {
ac_session_teardown(session);
}
}