diff --git a/src/ac/ac.h b/src/ac/ac.h index 4a586bc..101972f 100644 --- a/src/ac/ac.h +++ b/src/ac/ac.h @@ -119,7 +119,8 @@ int ac_valid_binding(unsigned short binding); void ac_update_statistics(void); int ac_has_sessionid(struct capwap_sessionid_element* sessionid); -int ac_has_wtpid(unsigned char* id, unsigned short length); +int ac_has_wtpid(char* wtpid); +char* ac_get_printable_wtpid(struct capwap_wtpboarddata_element* wtpboarddata); #endif /* __CAPWAP_AC_HEADER__ */ diff --git a/src/ac/ac_dfa_join.c b/src/ac/ac_dfa_join.c index 7d61397..7273a79 100644 --- a/src/ac/ac_dfa_join.c +++ b/src/ac/ac_dfa_join.c @@ -16,7 +16,6 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* struct capwap_packet_txmng* txmngpacket; struct capwap_sessionid_element* sessionid; struct capwap_wtpboarddata_element* wtpboarddata; - struct capwap_wtpboarddata_board_subelement* wtpboarddatamacaddress; int status = AC_DFA_ACCEPT_PACKET; struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_FAILURE }; @@ -32,14 +31,18 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* /* Get sessionid and verify unique id */ sessionid = (struct capwap_sessionid_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID); if (!ac_has_sessionid(sessionid)) { + char* wtpid; + /* Checking macaddress for detect if WTP already connected */ wtpboarddata = (struct capwap_wtpboarddata_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPBOARDDATA); - wtpboarddatamacaddress = capwap_wtpboarddata_get_subelement(wtpboarddata, CAPWAP_BOARD_SUBELEMENT_MACADDRESS); - if (wtpboarddatamacaddress && !ac_has_wtpid((unsigned char*)wtpboarddatamacaddress->data, (unsigned short)wtpboarddatamacaddress->length)) { + + /* Get printable WTPID */ + wtpid = ac_get_printable_wtpid(wtpboarddata); + if (wtpid && !ac_has_wtpid(wtpid)) { struct ac_soap_response* response; /* Request authorization of Backend for complete join */ - response = ac_session_send_soap_request(session, "authorizeJoin"); + response = ac_soap_authorizejoin(session, wtpid); if (response) { /* Validate Join */ resultcode.code = ac_dfa_state_join_check_authorizejoin(session, response); @@ -47,8 +50,8 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* /* Valid WTP */ if (resultcode.code == CAPWAP_RESULTCODE_SUCCESS) { - session->wtpid = capwap_clone(wtpboarddatamacaddress->data, wtpboarddatamacaddress->length); - session->wtpidlength = wtpboarddatamacaddress->length; + session->wtpid = wtpid; + wtpid = NULL; /* Session id */ memcpy(&session->sessionid, sessionid, sizeof(struct capwap_sessionid_element)); @@ -62,6 +65,11 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* } else { resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_UNKNOWN_SOURCE; } + + /* */ + if (wtpid) { + capwap_free(wtpid); + } } else { resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_ID_ALREADY_IN_USE; } diff --git a/src/ac/ac_execute.c b/src/ac/ac_execute.c index 8066063..d6a6939 100644 --- a/src/ac/ac_execute.c +++ b/src/ac/ac_execute.c @@ -112,11 +112,11 @@ int ac_has_sessionid(struct capwap_sessionid_element* sessionid) { } /* */ -int ac_has_wtpid(unsigned char* wtpid, unsigned short length) { +int ac_has_wtpid(char* wtpid) { int result = 0; struct capwap_list_item* search; - if (!wtpid || !length) { + if (!wtpid || !wtpid[0]) { return -1; } @@ -128,11 +128,9 @@ int ac_has_wtpid(unsigned char* wtpid, unsigned short length) { ASSERT(session != NULL); - if (session->wtpidlength == length) { - if (!memcmp(wtpid, session->wtpid, length)) { - result = 1; - break; - } + if (session->wtpid && !strcmp(session->wtpid, wtpid)) { + result = 1; + break; } search = search->next; @@ -143,6 +141,54 @@ int ac_has_wtpid(unsigned char* wtpid, unsigned short length) { return result; } +/* */ +char* ac_get_printable_wtpid(struct capwap_wtpboarddata_element* wtpboarddata) { + char* wtpid = NULL; + struct capwap_wtpboarddata_board_subelement* wtpboarddatamacaddress; + + ASSERT(wtpboarddata != NULL); + + /* TODO: build printable wtpid depending on the model device */ + + /* Get macaddress */ + wtpboarddatamacaddress = capwap_wtpboarddata_get_subelement(wtpboarddata, CAPWAP_BOARD_SUBELEMENT_MACADDRESS); + if (wtpboarddatamacaddress != NULL) { + if (wtpboarddatamacaddress->length == MACADDRESS_EUI48_LENGTH) { + wtpid = capwap_alloc(18); + if (!wtpid) { + capwap_outofmemory(); + } + + /* */ + sprintf(wtpid, "%02x:%02x:%02x:%02x:%02x:%02x", + (unsigned char)wtpboarddatamacaddress->data[0], + (unsigned char)wtpboarddatamacaddress->data[1], + (unsigned char)wtpboarddatamacaddress->data[2], + (unsigned char)wtpboarddatamacaddress->data[3], + (unsigned char)wtpboarddatamacaddress->data[4], + (unsigned char)wtpboarddatamacaddress->data[5]); + } else if (wtpboarddatamacaddress->length == MACADDRESS_EUI64_LENGTH) { + wtpid = capwap_alloc(24); + if (!wtpid) { + capwap_outofmemory(); + } + + /* */ + sprintf(wtpid, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + (unsigned char)wtpboarddatamacaddress->data[0], + (unsigned char)wtpboarddatamacaddress->data[1], + (unsigned char)wtpboarddatamacaddress->data[2], + (unsigned char)wtpboarddatamacaddress->data[3], + (unsigned char)wtpboarddatamacaddress->data[4], + (unsigned char)wtpboarddatamacaddress->data[5], + (unsigned char)wtpboarddatamacaddress->data[6], + (unsigned char)wtpboarddatamacaddress->data[7]); + } + } + + return wtpid; +} + /* */ static struct ac_session_t* ac_get_session_from_keepalive(void* buffer, int buffersize) { struct capwap_parsed_packet packet; diff --git a/src/ac/ac_session.c b/src/ac/ac_session.c index be0f024..0dc51dc 100644 --- a/src/ac/ac_session.c +++ b/src/ac/ac_session.c @@ -1,3 +1,4 @@ +#include #include "ac.h" #include "capwap_dfa.h" #include "ac_session.h" @@ -727,7 +728,9 @@ void ac_free_reference_last_response(struct ac_session_t* session) { } /* */ -struct ac_soap_response* ac_session_send_soap_request(struct ac_session_t* session, char* method) { +struct ac_soap_response* ac_session_send_soap_request(struct ac_session_t* session, char* method, int numparam, ...) { + int i; + va_list listparam; struct ac_soap_request* request; struct ac_http_soap_server* server; struct ac_soap_response* response = NULL; @@ -762,19 +765,36 @@ struct ac_soap_response* ac_session_send_soap_request(struct ac_session_t* sessi return NULL; } - /* Send Request & Recv Response */ - if (ac_soapclient_send_request(session->soaprequest, "")) { - response = ac_soapclient_recv_response(session->soaprequest); + /* Add params */ + va_start(listparam, numparam); + for (i = 0; i < numparam; i++) { + char* type = va_arg(listparam, char*); + char* name = va_arg(listparam, char*); + char* value = va_arg(listparam, char*); + + if (!ac_soapclient_add_param(request, type, name, value)) { + ac_soapclient_close_request(session->soaprequest, 1); + session->soaprequest = NULL; + break; + } } + va_end(listparam); - /* Critical section */ - capwap_lock_enter(&session->sessionlock); + /* Send Request & Recv Response */ + if (session->soaprequest) { + if (ac_soapclient_send_request(session->soaprequest, "")) { + response = ac_soapclient_recv_response(session->soaprequest); + } - /* Free resource */ - ac_soapclient_close_request(session->soaprequest, 1); - session->soaprequest = NULL; + /* Critical section */ + capwap_lock_enter(&session->sessionlock); - capwap_lock_exit(&session->sessionlock); + /* Free resource */ + ac_soapclient_close_request(session->soaprequest, 1); + session->soaprequest = NULL; + + capwap_lock_exit(&session->sessionlock); + } return response; } diff --git a/src/ac/ac_session.h b/src/ac/ac_session.h index 16cb277..35cc59e 100644 --- a/src/ac/ac_session.h +++ b/src/ac/ac_session.h @@ -40,8 +40,7 @@ struct ac_session_t { struct ac_http_soap_request* soaprequest; /* */ - unsigned char* wtpid; - unsigned short wtpidlength; + char* wtpid; unsigned long count; struct sockaddr_storage acctrladdress; @@ -88,7 +87,6 @@ int ac_session_release_reference(struct ac_session_t* session); /* */ void ac_session_send_action(struct ac_session_t* session, long action, long param, void* data, long length); -struct ac_soap_response* ac_session_send_soap_request(struct ac_session_t* session, char* method); /* */ void ac_dfa_change_state(struct ac_session_t* session, int state); @@ -137,4 +135,9 @@ int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capw int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_parsed_packet* packet); int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_parsed_packet* packet); +/* Soap function */ +struct ac_soap_response* ac_session_send_soap_request(struct ac_session_t* session, char* method, int numparam, ...); +#define ac_soap_authorizejoin(s, id) ac_session_send_soap_request((s), "authorizeJoin", 1, "xs:string", "idwtp", id) + + #endif /* __AC_SESSION_HEADER__ */ diff --git a/webservice/smartcapwap.wsdl b/webservice/smartcapwap.wsdl index cc12626..69ea86c 100644 --- a/webservice/smartcapwap.wsdl +++ b/webservice/smartcapwap.wsdl @@ -12,7 +12,9 @@ - + + +