From 4953ff684d3dcb0702e79464653269c642e233e0 Mon Sep 17 00:00:00 2001 From: vemax78 Date: Tue, 23 Jul 2013 22:10:26 +0200 Subject: [PATCH] Add first draft of calls to backend web service --- build/ac/Makefile.am | 1 + conf/ac.conf | 8 +- src/ac/ac.c | 62 +++++++++++++- src/ac/ac.h | 3 + src/ac/ac_backend.c | 166 ++++++++++++++++++++++++++++++++++++ src/ac/ac_backend.h | 12 +++ webservice/smartcapwap.wsdl | 45 ++++++++++ 7 files changed, 293 insertions(+), 4 deletions(-) create mode 100644 src/ac/ac_backend.c create mode 100644 src/ac/ac_backend.h create mode 100644 webservice/smartcapwap.wsdl diff --git a/build/ac/Makefile.am b/build/ac/Makefile.am index 43b9eb9..e4a7072 100755 --- a/build/ac/Makefile.am +++ b/build/ac/Makefile.am @@ -46,6 +46,7 @@ ac_SOURCES = \ $(top_srcdir)/src/common/capwap_lock.c \ $(top_srcdir)/src/common/capwap_socket.c \ $(top_srcdir)/src/ac/ac.c \ + $(top_srcdir)/src/ac/ac_backend.c \ $(top_srcdir)/src/ac/ac_execute.c \ $(top_srcdir)/src/ac/ac_session.c \ $(top_srcdir)/src/ac/ac_discovery.c \ diff --git a/conf/ac.conf b/conf/ac.conf index 6b32013..23df6f5 100755 --- a/conf/ac.conf +++ b/conf/ac.conf @@ -3,7 +3,7 @@ version = "1.0"; application: { - standalone = false; + standalone = true; name = "ac 1"; @@ -76,6 +76,12 @@ application: { }; }; +backend: { + server: ( + { url = "http://localhost/csoap.php"; } + ); +}; + logging: { enable = true; level = "debug"; diff --git a/src/ac/ac.c b/src/ac/ac.c index 8ccb5bd..2b43e3f 100644 --- a/src/ac/ac.c +++ b/src/ac/ac.c @@ -1,4 +1,6 @@ #include "ac.h" +#include "ac_soap.h" +#include "ac_backend.h" #include "capwap_dtls.h" #include @@ -63,6 +65,9 @@ static int ac_init(void) { capwap_lock_init(&g_ac.sessionslock); g_ac.datasessionshandshake = capwap_list_create(); + /* Backend */ + g_ac.availablebackends = capwap_array_create(sizeof(struct ac_http_soap_server*), 0, 0); + return 1; } @@ -96,6 +101,13 @@ static void ac_destroy(void) { capwap_lock_destroy(&g_ac.sessionslock); capwap_event_destroy(&g_ac.changesessionlist); capwap_list_free(g_ac.datasessionshandshake); + + /* Backend */ + for (i = 0; i < g_ac.availablebackends->count; i++) { + ac_soapclient_free_server(*(struct ac_http_soap_server**)capwap_array_get_item_pointer(g_ac.availablebackends, i)); + } + + capwap_array_free(g_ac.availablebackends); } /* Help */ @@ -288,7 +300,12 @@ static int ac_parsing_configuration_1_0(config_t* config) { desc->vendor = (unsigned long)configVendor; desc->type = type; desc->length = lengthValue; + desc->data = (uint8_t*)capwap_alloc(desc->length + 1); + if (!desc->data) { + capwap_outofmemory(); + } + strcpy((char*)desc->data, configValue); desc->data[desc->length] = 0; } else { @@ -552,6 +569,29 @@ static int ac_parsing_configuration_1_0(config_t* config) { } } + /* Backend */ + configSetting = config_lookup(config, "backend.server"); + if (configSetting != NULL) { + int count = config_setting_length(configSetting); + + /* Retrieve server */ + for (i = 0; i < count; i++) { + config_setting_t* configServer = config_setting_get_elem(configSetting, i); + if (configServer != NULL) { + if (config_setting_lookup_string(configServer, "url", &configString) == CONFIG_TRUE) { + struct ac_http_soap_server** server = (struct ac_http_soap_server**)capwap_array_get_item_pointer(g_ac.availablebackends, g_ac.availablebackends->count); + + /* */ + *server = ac_soapclient_create_server(configString); + if (!*server) { + capwap_logging_error("Invalid configuration file, invalid backend.server value"); + return 0; + } + } + } + } + } + return 1; } @@ -688,6 +728,9 @@ int main(int argc, char** argv) { return CAPWAP_CRYPT_ERROR; } + /* Init soap module */ + ac_soapclient_init(); + /* Alloc AC */ if (!ac_init()) { return AC_ERROR_SYSTEM_FAILER; @@ -709,15 +752,28 @@ int main(int argc, char** argv) { /* Complete configuration AC */ result = ac_configure(); if (result == CAPWAP_SUCCESSFUL) { - /* Running AC */ - result = ac_execute(); - ac_close(); + /* Enable Backend Management */ + if (ac_backend_start()) { + /* Running AC */ + result = ac_execute(); + + /* Disable Backend Management */ + ac_backend_stop(); + + /* Close connection */ + ac_close(); + } else { + capwap_logging_error("Unable start backend management"); + } } } /* Free memory */ ac_destroy(); + /* Free soap */ + ac_soapclient_free(); + /* Free crypt */ capwap_crypt_free(); diff --git a/src/ac/ac.h b/src/ac/ac.h index 228f39f..4a586bc 100644 --- a/src/ac/ac.h +++ b/src/ac/ac.h @@ -105,6 +105,9 @@ struct ac_t { /* Dtls */ int enabledtls; struct capwap_dtls_context dtlscontext; + + /* Backend Management */ + struct capwap_array* availablebackends; }; extern struct ac_t g_ac; diff --git a/src/ac/ac_backend.c b/src/ac/ac_backend.c new file mode 100644 index 0000000..6637a8e --- /dev/null +++ b/src/ac/ac_backend.c @@ -0,0 +1,166 @@ +#include "ac.h" +#include "ac_backend.h" +#include "ac_soap.h" + +/* */ +#define SOAP_NAMESPACE_URI "http://smartcapwap/namespace" + +/* */ +#define AC_BACKEND_WAIT_TIMEOUT 60000 + +/* */ +struct ac_backend_t { + pthread_t threadid; + int endthread; + + capwap_event_t wait; + + /* Backend Soap */ + int activebackend; + int backendstatus; + int errorjoinbackend; + + /* Soap Request */ + struct ac_http_soap_request* soaprequest; +}; + +static struct ac_backend_t g_ac_backend; + +/* */ +static int ac_backend_soap_join(void) { + int result = 0; + struct ac_soap_request* request; + struct ac_http_soap_server* server; + + /* Get HTTP Soap Server */ + server = *(struct ac_http_soap_server**)capwap_array_get_item_pointer(g_ac.availablebackends, g_ac_backend.activebackend); + + /* Build Soap Request */ + request = ac_soapclient_create_request("joinBackend", SOAP_NAMESPACE_URI); + if (!request) { + return 0; + } + + /* Prepare to Send Request */ + g_ac_backend.soaprequest = ac_soapclient_prepare_request(request, server); + if (!g_ac_backend.soaprequest) { + ac_soapclient_free_request(request); + return 0; + } + + /* Send Request & Recv Response */ + if (ac_soapclient_send_request(g_ac_backend.soaprequest, "presence::joinBackend")) { + struct ac_soap_response* response = ac_soapclient_recv_response(g_ac_backend.soaprequest); + if (response) { + + /* */ + ac_soapclient_free_response(response); + } + } + + /* */ + ac_soapclient_close_request(g_ac_backend.soaprequest, 1); + g_ac_backend.soaprequest = NULL; + + return result; +} + +/* */ +static void ac_backend_soap_leave(void) { + if (!g_ac_backend.backendstatus) { + return; + } + +} + +/* */ +static void ac_backend_run(void) { + while (!g_ac_backend.endthread) { + if (g_ac_backend.backendstatus) { + } else { + /* Join with a Backend Server */ + if (ac_backend_soap_join()) { + /* Join Complete */ + g_ac_backend.backendstatus = 1; + g_ac_backend.errorjoinbackend = 0; + } else { + /* Change Backend Server */ + g_ac_backend.activebackend = (g_ac_backend.activebackend + 1) % g_ac.availablebackends->count; + g_ac_backend.errorjoinbackend++; + + /* Wait timeout before continue */ + if (g_ac_backend.errorjoinbackend >= g_ac.availablebackends->count) { + capwap_event_wait_timeout(&g_ac_backend.wait, AC_BACKEND_WAIT_TIMEOUT); + + /* */ + g_ac_backend.errorjoinbackend = 0; + } + } + } + } + + /* Leave backend */ + ac_backend_soap_leave(); +} + +/* */ +static void* ac_backend_thread(void* param) { + capwap_logging_debug("Backend start"); + ac_backend_run(); + capwap_logging_debug("Backend stop"); + + /* Thread exit */ + pthread_exit(NULL); + return NULL; +} + +/* */ +int ac_backend_isconnect(void) { + return (g_ac_backend.backendstatus ? 1 : 0); +} + +/* */ +struct ac_http_soap_server* ac_backend_gethttpsoapserver(void) { + if (!ac_backend_isconnect()) { + return NULL; + } + + return *(struct ac_http_soap_server**)capwap_array_get_item_pointer(g_ac.availablebackends, g_ac_backend.activebackend); +} + +/* */ +int ac_backend_start(void) { + int result; + + memset(&g_ac_backend, 0, sizeof(struct ac_backend_t)); + + /* */ + if (!g_ac.availablebackends->count) { + capwap_logging_error("List of available backends is empty"); + return 0; + } + + /* Init */ + capwap_event_init(&g_ac_backend.wait); + + /* Create thread */ + result = pthread_create(&g_ac_backend.threadid, NULL, ac_backend_thread, NULL); + if (result) { + capwap_logging_debug("Unable create backend thread"); + return 0; + } + + return 1; +} + +/* */ +void ac_backend_stop(void) { + void* dummy; + + g_ac_backend.endthread = 1; + capwap_event_signal(&g_ac_backend.wait); + pthread_join(g_ac_backend.threadid, &dummy); + + /* */ + capwap_event_destroy(&g_ac_backend.wait); +} diff --git a/src/ac/ac_backend.h b/src/ac/ac_backend.h new file mode 100644 index 0000000..c24119d --- /dev/null +++ b/src/ac/ac_backend.h @@ -0,0 +1,12 @@ +#ifndef __AC_BACKEND_HEADER__ +#define __AC_BACKEND_HEADER__ + +/* */ +int ac_backend_start(void); +void ac_backend_stop(void); + +/* */ +int ac_backend_isconnect(void); +struct ac_http_soap_server* ac_backend_gethttpsoapserver(void); + +#endif /* __AC_BACKEND_HEADER__ */ diff --git a/webservice/smartcapwap.wsdl b/webservice/smartcapwap.wsdl new file mode 100644 index 0000000..97c576c --- /dev/null +++ b/webservice/smartcapwap.wsdl @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +