Add first draft of calls to backend web service
This commit is contained in:
		| @ -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 \ | ||||
|  | ||||
| @ -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"; | ||||
|  | ||||
							
								
								
									
										62
									
								
								src/ac/ac.c
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/ac/ac.c
									
									
									
									
									
								
							| @ -1,4 +1,6 @@ | ||||
| #include "ac.h" | ||||
| #include "ac_soap.h" | ||||
| #include "ac_backend.h" | ||||
| #include "capwap_dtls.h" | ||||
|  | ||||
| #include <libconfig.h> | ||||
| @ -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(); | ||||
|  | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
							
								
								
									
										166
									
								
								src/ac/ac_backend.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								src/ac/ac_backend.c
									
									
									
									
									
										Normal file
									
								
							| @ -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); | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/ac/ac_backend.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/ac/ac_backend.h
									
									
									
									
									
										Normal file
									
								
							| @ -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__ */ | ||||
							
								
								
									
										45
									
								
								webservice/smartcapwap.wsdl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								webservice/smartcapwap.wsdl
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
|  | ||||
| <wsdl:definitions  | ||||
| 	name="SmartCAPWAP WebService" | ||||
| 	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"  | ||||
| 	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"  | ||||
| 	xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"  | ||||
| 	xmlns:xs="http://www.w3.org/2001/XMLSchema"  | ||||
| 	xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"  | ||||
| 	xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"  | ||||
| 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  | ||||
| 	xmlns:tns="http://smartcapwap/namespace"  | ||||
| 	targetNamespace="http://smartcapwap/namespace" | ||||
| > | ||||
| 	<wsdl:types> | ||||
| 		<xs:schema targetNamespace="http://smartcapwap/namespace" elementFormDefault="qualified"/> | ||||
| 	</wsdl:types> | ||||
| 	<wsdl:message name="joinBackend"/> | ||||
| 	<wsdl:message name="joinBackendResponse"> | ||||
| 		<wsdl:part name="return" type="xsd:int"/> | ||||
| 	</wsdl:message> | ||||
| 	<wsdl:portType name="Presence"> | ||||
| 		<wsdl:operation name="joinBackend"> | ||||
| 			<wsdl:input message="tns:joinBackend"/> | ||||
| 			<wsdl:output message="tns:joinBackendResponse"/> | ||||
| 		</wsdl:operation> | ||||
| 	</wsdl:portType> | ||||
| 	<wsdl:binding name="Presence" type="tns:Presence"> | ||||
| 		<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> | ||||
| 		<wsdl:operation name="joinBackend"> | ||||
| 			<soap:operation soapAction="presence::joinBackend"/> | ||||
| 			<wsdl:input> | ||||
| 				<soap:body use="literal"/> | ||||
| 			</wsdl:input> | ||||
| 			<wsdl:output> | ||||
| 				<soap:body use="literal"/> | ||||
| 			</wsdl:output> | ||||
| 		</wsdl:operation> | ||||
| 	</wsdl:binding> | ||||
| 	<wsdl:service name="SmartCAPWAP"> | ||||
| 		<wsdl:port name="presence" binding="tns:Presence"> | ||||
| 			<soap:address location=""/> | ||||
| 		</wsdl:port> | ||||
| 	</wsdl:service> | ||||
| </wsdl:definitions> | ||||
		Reference in New Issue
	
	Block a user