Changed the management of the wireless interfaces, from creation to usage.
The virtual interfaces are created at the startup of the wtp to reduce the time required to configure a wireless interface. Applied some patches to build the WTP on OpenWRT trunk
This commit is contained in:
		| @ -55,6 +55,7 @@ wtp_SOURCES = \ | ||||
| 	$(top_srcdir)/src/wtp/wtp_dfa_imagedata.c \ | ||||
| 	$(top_srcdir)/src/wtp/wtp_radio.c \ | ||||
| 	$(top_srcdir)/src/binding/ieee80211/ieee80211.c \ | ||||
| 	$(top_srcdir)/src/binding/ieee80211/netlink_link.c \ | ||||
| 	$(top_srcdir)/src/binding/ieee80211/wifi_drivers.c | ||||
|  | ||||
| wtp_LDADD = \ | ||||
|  | ||||
| @ -80,7 +80,7 @@ application: { | ||||
|  | ||||
| 	radio = ( | ||||
| 		{  | ||||
| 			device = "phy0";  | ||||
| 			device = "phy0"; | ||||
| 			enabled = true; | ||||
| 			driver = "nl80211"; | ||||
| 			mode = "g"; | ||||
| @ -93,7 +93,8 @@ application: { | ||||
| 			fragmentationthreshold = 2346; | ||||
| 			txmsdulifetime = 512; | ||||
| 			rxmsdulifetime = 512; | ||||
| 			maxbssid = 4; | ||||
| 			maxbssid = 1; | ||||
| 			bssprefixname = "ap"; | ||||
| 			dtimperiod = 1; | ||||
| 			beaconperiod = 100; | ||||
| 			antenna = { | ||||
|  | ||||
							
								
								
									
										41
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								configure.ac
									
									
									
									
									
								
							| @ -24,6 +24,7 @@ AC_INIT([PRODUCT_NAME], [PRODUCT_VERSION], [PRODUCT_BUGREPORT], [PRODUCT_TARNAME | ||||
| AC_CONFIG_AUX_DIR([.]) | ||||
| AC_CONFIG_MACRO_DIR([m4]) | ||||
| AM_INIT_AUTOMAKE | ||||
| AC_USE_SYSTEM_EXTENSIONS | ||||
|  | ||||
| # cross-compile macros | ||||
| AC_CANONICAL_BUILD | ||||
| @ -113,6 +114,11 @@ CFLAGS="${old_CFLAGS}" | ||||
| AM_CONDITIONAL([DEBUG_BUILD], [test "$enable_debug" = yes])  | ||||
| if test "${enable_debug}" = "yes"; then | ||||
| 	CFLAGS="${CFLAGS} -DDEBUG -Wall -Werror -g -O0" | ||||
|  | ||||
| 	AC_CHECK_HEADERS([execinfo.h], [have_backtrace="yes"],[]) | ||||
| 	if test "x${have_backtrace}" = "xyes"; then | ||||
| 		AC_DEFINE([USE_DEBUG_BACKTRACE], [1], [Use debug backtrace]) | ||||
| 	fi | ||||
| else | ||||
| 	CFLAGS="${CFLAGS} -O2" | ||||
| 	AC_DEFINE([DISABLE_LOGGING_DEBUG], [1], [Disable logging debug]) | ||||
| @ -120,7 +126,6 @@ fi | ||||
|  | ||||
| # | ||||
| AC_PROG_INSTALL | ||||
| AC_USE_SYSTEM_EXTENSIONS | ||||
|  | ||||
| AC_LANG(C) | ||||
|  | ||||
| @ -211,25 +216,19 @@ if test "${enable_ac}" = "yes"; then | ||||
| fi | ||||
|  | ||||
| # Check nl80211 | ||||
| has_libnl_ver=0 | ||||
| PKG_CHECK_MODULES( | ||||
| 	[LIBNL], | ||||
| 	[libnl-3.0 >= 3.0 libnl-genl-3.0 >= 3.0],  | ||||
| 	[AC_DEFINE([HAVE_LIBNL30], [1], [Use libnl-3.0 library])], | ||||
| 	[PKG_CHECK_MODULES( | ||||
| if test "${enable_wifi_drivers_nl80211}" = "yes"; then | ||||
| 	PKG_CHECK_MODULES( | ||||
| 		[LIBNL], | ||||
| 		[libnl-2.0 >= 2.0], | ||||
| 		[AC_DEFINE([HAVE_LIBNL20], [1], [Use libnl-2.0 library])], | ||||
| 		[libnl-1],  | ||||
| 		[AC_DEFINE([HAVE_LIBNL_10], [1], [Use libnl-1.0 library])], | ||||
| 		[PKG_CHECK_MODULES( | ||||
| 			[LIBNL], | ||||
| 			[libnl-1], | ||||
| 			[AC_DEFINE([HAVE_LIBNL10], [1], [Use libnl-1.0 library])], | ||||
| 			[AC_MSG_ERROR(You need the libnl and libnl-genl)] | ||||
| 			[libnl-tiny], | ||||
| 			[AC_DEFINE([HAVE_LIBNL_TINY], [1], [Use libnl-tiny library])], | ||||
| 			[AC_MSG_ERROR(You need the libnl or libnl-tiny)] | ||||
| 		)] | ||||
| 	)] | ||||
| ) | ||||
| 	) | ||||
|  | ||||
| if test "${enable_wifi_drivers_nl80211}" = "yes"; then | ||||
| 	AC_CHECK_HEADERS([netlink/genl/genl.h netlink/genl/family.h netlink/genl/ctrl.h], [], [AC_MSG_ERROR(You need the netlink header)]) | ||||
| 	AC_CHECK_HEADER([linux/nl80211.h], [], [AC_MSG_ERROR(You need the nl80211 header)]) | ||||
| 	AC_DEFINE([ENABLE_WIFI_DRIVERS_NL80211], [1], [Enable WTP support for nl80211 wifi binding]) | ||||
| @ -266,7 +265,7 @@ if test "${with_ssl_library}" = "openssl"; then | ||||
| 		)] | ||||
| 	) | ||||
| 	 | ||||
| 	if test "${have_openssl_ssl}" = "yes"; then | ||||
| 	if test "x${have_openssl_ssl}" = "xyes"; then | ||||
| 		have_openssl_engine="yes" | ||||
| 		OPENSSL_SSL_LIBS="${OPENSSL_SSL_LIBS} -ldl" | ||||
| 		#saved_CFLAGS="${CFLAGS}" | ||||
| @ -293,7 +292,7 @@ case "${with_ssl_library}" in | ||||
| 		have_crypto_ssl="${have_openssl_ssl}" | ||||
| 		SSL_CFLAGS="${OPENSSL_CRYPTO_CFLAGS} ${OPENSSL_SSL_CFLAGS}" | ||||
| 		SSL_LIBS="${OPENSSL_SSL_LIBS}" | ||||
| 		test "${have_crypto_engine}" = "yes" && AC_DEFINE([HAVE_OPENSSL_ENGINE], [1], [Use ssl library]) | ||||
| 		test "x${have_crypto_engine}" = "xyes" && AC_DEFINE([HAVE_OPENSSL_ENGINE], [1], [Use ssl library]) | ||||
| 		;; | ||||
| 	cyassl) | ||||
| 		have_crypto_engine="${have_cyassl_engine}" | ||||
| @ -301,14 +300,14 @@ case "${with_ssl_library}" in | ||||
| 		have_crypto_ssl="${have_cyassl_ssl}" | ||||
| 		SSL_CFLAGS="" | ||||
| 		SSL_LIBS="-lcyassl" | ||||
| 		test "${have_crypto_engine}" = "yes" && AC_DEFINE([HAVE_CYASSL_ENGINE], [1], [Use ssl library]) | ||||
| 		test "x${have_crypto_engine}" = "xyes" && AC_DEFINE([HAVE_CYASSL_ENGINE], [1], [Use ssl library]) | ||||
| 		;; | ||||
| esac | ||||
|  | ||||
| if test "${enable_dtls}" = "yes"; then | ||||
| 	test "${have_crypto_engine}" != "yes" && AC_MSG_ERROR([${with_ssl_library} engine is required but missing]) | ||||
| 	test "${have_crypto_ssl}" != "yes" && AC_MSG_ERROR([${with_ssl_library} ssl is required but missing]) | ||||
| 	test "${have_crypto_crypto}" != "yes" && AC_MSG_ERROR([${with_ssl_library} crypto is required but missing]) | ||||
| 	test "x${have_crypto_engine}" != "xyes" && AC_MSG_ERROR([${with_ssl_library} engine is required but missing]) | ||||
| 	test "x${have_crypto_ssl}" != "xyes" && AC_MSG_ERROR([${with_ssl_library} ssl is required but missing]) | ||||
| 	test "x${have_crypto_crypto}" != "xyes" && AC_MSG_ERROR([${with_ssl_library} crypto is required but missing]) | ||||
| 	AC_DEFINE([ENABLE_DTLS], [1], [Enable DTLS]) | ||||
| fi | ||||
|  | ||||
|  | ||||
| @ -12,6 +12,7 @@ | ||||
| /* Global values */ | ||||
| #define IEEE80211_MTU									2304 | ||||
| #define IEEE80211_SUPPORTEDRATE_MAX_COUNT				16 | ||||
| #define IEEE80211_MAX_STATIONS							2007 | ||||
|  | ||||
| /* Radio type with value same of IEEE802.11 Radio Information Message Element */ | ||||
| #define IEEE80211_RADIO_TYPE_80211B			0x00000001 | ||||
|  | ||||
							
								
								
									
										156
									
								
								src/binding/ieee80211/netlink_link.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								src/binding/ieee80211/netlink_link.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | ||||
| #include "capwap.h" | ||||
| #include <linux/socket.h> | ||||
| #include "wifi_drivers.h" | ||||
| #include "netlink_link.h" | ||||
|  | ||||
| /* */ | ||||
| struct netlink_request { | ||||
| 	struct nlmsghdr hdr; | ||||
| 	struct ifinfomsg ifinfo; | ||||
| 	char opts[16]; | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| struct netlink* netlink_init(void) { | ||||
| 	int sock; | ||||
| 	struct sockaddr_nl local; | ||||
| 	struct netlink* netlinkhandle; | ||||
|  | ||||
| 	/* Create netlink socket */ | ||||
| 	sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); | ||||
| 	if (sock < 0) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Bind to kernel */ | ||||
| 	memset(&local, 0, sizeof(struct sockaddr_nl)); | ||||
| 	local.nl_family = AF_NETLINK; | ||||
| 	local.nl_groups = RTMGRP_LINK; | ||||
| 	if (bind(sock, (struct sockaddr*)&local, sizeof(struct sockaddr_nl)) < 0) { | ||||
| 		close(sock); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Netlink reference */ | ||||
| 	netlinkhandle = (struct netlink*)capwap_alloc(sizeof(struct netlink)); | ||||
| 	netlinkhandle->sock = sock; | ||||
| 	netlinkhandle->nl_sequence = 1; | ||||
|  | ||||
| 	return netlinkhandle; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| void netlink_free(struct netlink* netlinkhandle) { | ||||
| 	ASSERT(netlinkhandle != NULL); | ||||
| 	ASSERT(netlinkhandle->sock  >= 0); | ||||
|  | ||||
| 	/* */ | ||||
| 	close(netlinkhandle->sock); | ||||
| 	capwap_free(netlinkhandle); | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| void netlink_event_receive(int fd, void** params, int paramscount) { | ||||
| 	int result; | ||||
| 	struct netlink* netlinkhandle; | ||||
| 	struct sockaddr_nl from; | ||||
| 	socklen_t fromlen; | ||||
| 	char buffer[8192]; | ||||
| 	struct nlmsghdr* message; | ||||
|  | ||||
| 	ASSERT(fd >= 0); | ||||
| 	ASSERT(params != NULL); | ||||
| 	ASSERT(paramscount == 2);  | ||||
|  | ||||
| 	/* */ | ||||
| 	netlinkhandle = (struct netlink*)params[0]; | ||||
|  | ||||
| 	/* Retrieve all netlink message */ | ||||
| 	for (;;) { | ||||
| 		/* Get message */ | ||||
| 		fromlen = sizeof(struct sockaddr_nl); | ||||
| 		result = recvfrom(netlinkhandle->sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&from, &fromlen); | ||||
| 		if (result <= 0) { | ||||
| 			if (errno == EINTR) { | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			/* */ | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		/* Parsing message */ | ||||
| 		message = (struct nlmsghdr*)buffer; | ||||
| 		while (NLMSG_OK(message, result)) { | ||||
| 			switch (message->nlmsg_type) { | ||||
| 				case RTM_NEWLINK: { | ||||
| 					if (netlinkhandle->newlink_event && NLMSG_PAYLOAD(message, 0) >= sizeof(struct ifinfomsg)) { | ||||
| 						netlinkhandle->newlink_event((wifi_global_handle)params[1], NLMSG_DATA(message), (uint8_t*)(NLMSG_DATA(message) + NLMSG_ALIGN(sizeof(struct ifinfomsg))), NLMSG_PAYLOAD(message, sizeof(struct ifinfomsg))); | ||||
| 					} | ||||
|  | ||||
| 					break; | ||||
| 				} | ||||
|  | ||||
| 				case RTM_DELLINK: { | ||||
| 					if (netlinkhandle->dellink_event && NLMSG_PAYLOAD(message, 0) >= sizeof(struct ifinfomsg)) { | ||||
| 						netlinkhandle->dellink_event((wifi_global_handle)params[1], NLMSG_DATA(message), (uint8_t*)(NLMSG_DATA(message) + NLMSG_ALIGN(sizeof(struct ifinfomsg))), NLMSG_PAYLOAD(message, sizeof(struct ifinfomsg))); | ||||
| 					} | ||||
|  | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			/* */ | ||||
| 			message = NLMSG_NEXT(message, result); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int netlink_set_link_status(struct netlink* netlinkhandle, int ifindex, int linkmode, int operstate) { | ||||
| 	char* data; | ||||
| 	struct rtattr* rta; | ||||
| 	struct netlink_request request; | ||||
|  | ||||
| 	ASSERT(netlinkhandle != NULL); | ||||
| 	ASSERT(ifindex >= 0); | ||||
|  | ||||
| 	/* */ | ||||
| 	memset(&request, 0, sizeof(struct netlink_request)); | ||||
| 	request.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); | ||||
| 	request.hdr.nlmsg_type = RTM_SETLINK; | ||||
| 	request.hdr.nlmsg_flags = NLM_F_REQUEST; | ||||
| 	request.hdr.nlmsg_seq = netlinkhandle->nl_sequence++; | ||||
| 	request.hdr.nlmsg_pid = 0; | ||||
| 	request.ifinfo.ifi_family = AF_UNSPEC; | ||||
| 	request.ifinfo.ifi_type = 0; | ||||
| 	request.ifinfo.ifi_index = ifindex; | ||||
| 	request.ifinfo.ifi_flags = 0; | ||||
| 	request.ifinfo.ifi_change = 0; | ||||
|  | ||||
| 	if (linkmode != -1) { | ||||
| 		rta = (struct rtattr*)((char*)&request + NLMSG_ALIGN(request.hdr.nlmsg_len)); | ||||
| 		rta->rta_type = IFLA_LINKMODE; | ||||
| 		rta->rta_len = RTA_LENGTH(sizeof(char)); | ||||
| 		data = (char*)RTA_DATA(rta); | ||||
| 		*data = (char)linkmode; | ||||
| 		request.hdr.nlmsg_len = NLMSG_ALIGN(request.hdr.nlmsg_len) + RTA_LENGTH(sizeof(char)); | ||||
| 	} | ||||
|  | ||||
| 	if (operstate != -1) { | ||||
| 		rta = (struct rtattr*)((char*)&request + NLMSG_ALIGN(request.hdr.nlmsg_len)); | ||||
| 		rta->rta_type = IFLA_OPERSTATE; | ||||
| 		rta->rta_len = RTA_LENGTH(sizeof(char)); | ||||
| 		data = (char*)RTA_DATA(rta); | ||||
| 		*data = (char)operstate; | ||||
| 		request.hdr.nlmsg_len = NLMSG_ALIGN(request.hdr.nlmsg_len) + RTA_LENGTH(sizeof(char)); | ||||
| 	} | ||||
|  | ||||
| 	/* Send new interface operation state */ | ||||
| 	if (send(netlinkhandle->sock, &request, request.hdr.nlmsg_len, 0) < 0) { | ||||
| 		capwap_logging_debug("*** netlink_set_link_status error"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	capwap_logging_debug("*** netlink_set_link_status complete"); | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										59
									
								
								src/binding/ieee80211/netlink_link.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/binding/ieee80211/netlink_link.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| #ifndef __NETLINK_LINK_HEADER__ | ||||
| #define __NETLINK_LINK_HEADER__ | ||||
|  | ||||
| #include <linux/rtnetlink.h> | ||||
| #include <linux/netlink.h> | ||||
|  | ||||
| /* */ | ||||
| #ifndef IFLA_IFNAME | ||||
| #define IFLA_IFNAME					3 | ||||
| #endif | ||||
|  | ||||
| #ifndef IFLA_WIRELESS | ||||
| #define IFLA_WIRELESS				11 | ||||
| #endif | ||||
|  | ||||
| #ifndef IFLA_OPERSTATE | ||||
| #define IFLA_OPERSTATE				16 | ||||
| #endif | ||||
|  | ||||
| #ifndef IFLA_LINKMODE | ||||
| #define IFLA_LINKMODE				17 | ||||
| #endif | ||||
|  | ||||
| #ifndef IF_OPER_DORMANT | ||||
| #define IF_OPER_DORMANT				5 | ||||
| #endif | ||||
|  | ||||
| #ifndef IF_OPER_UP | ||||
| #define IF_OPER_UP					6 | ||||
| #endif | ||||
|  | ||||
| #ifndef IFF_LOWER_UP | ||||
| #define IFF_LOWER_UP				0x10000 | ||||
| #endif | ||||
|  | ||||
| #ifndef IFF_DORMANT | ||||
| #define IFF_DORMANT					0x20000 | ||||
| #endif | ||||
|  | ||||
| /* */ | ||||
| struct netlink { | ||||
| 	int sock; | ||||
| 	void (*newlink_event)(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length); | ||||
| 	void (*dellink_event)(wifi_global_handle handle, struct ifinfomsg* infomsg, uint8_t* data, int length); | ||||
|  | ||||
| 	int nl_sequence; | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| struct netlink* netlink_init(void); | ||||
| void netlink_free(struct netlink* netlinkhandle); | ||||
|  | ||||
| /* */ | ||||
| int netlink_set_link_status(struct netlink* netlinkhandle, int ifindex, int linkmode, int operstate); | ||||
|  | ||||
| /* */ | ||||
| void netlink_event_receive(int fd, void** params, int paramscount); | ||||
|  | ||||
| #endif /* __NETLINK_LINK_HEADER__ */ | ||||
| @ -1,7 +1,6 @@ | ||||
| #include "capwap.h" | ||||
| #include "capwap_array.h" | ||||
| #include "capwap_list.h" | ||||
| #include "capwap_element.h" | ||||
| #include "wtp_radio.h" | ||||
| #include "wifi_drivers.h" | ||||
|  | ||||
| /* Declare enable wifi driver */ | ||||
| @ -17,276 +16,25 @@ static struct wifi_driver_instance wifi_driver[] = { | ||||
| }; | ||||
|  | ||||
| /* Radio instance */ | ||||
| static struct capwap_array* g_wifidevice = NULL; | ||||
| static struct capwap_list* g_wifidevice = NULL; | ||||
|  | ||||
| /* */ | ||||
| int wifi_driver_init(void) { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0; wifi_driver[i].ops != NULL; i++) { | ||||
| 		/* Initialize driver */ | ||||
| 		ASSERT(wifi_driver[i].ops->global_init != NULL); | ||||
| 		wifi_driver[i].handle = wifi_driver[i].ops->global_init(); | ||||
| 		if (!wifi_driver[i].handle) { | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Device handler */ | ||||
| 	g_wifidevice = capwap_array_create(sizeof(struct wifi_device), 0, 1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| void wifi_driver_free(void) { | ||||
| 	unsigned long i; | ||||
| 	unsigned long j; | ||||
|  | ||||
| 	/* Free device */ | ||||
| 	if (g_wifidevice) { | ||||
| 		for (i = 0; i < g_wifidevice->count; i++) { | ||||
| 			struct wifi_device* device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, i); | ||||
|  | ||||
| 			if (device->wlan) { | ||||
| 				if (device->instance->ops->wlan_delete != NULL) { | ||||
| 					for (j = 0; j < device->wlan->count; j++) { | ||||
| 						struct wifi_wlan* wlan = (struct wifi_wlan*)capwap_array_get_item_pointer(device->wlan, j); | ||||
|  | ||||
| 						if (wlan->handle) { | ||||
| 							device->instance->ops->wlan_delete(wlan->handle); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				capwap_array_free(device->wlan); | ||||
| 			} | ||||
|  | ||||
| 			if (device->handle && device->instance->ops->device_deinit) { | ||||
| 				device->instance->ops->device_deinit(device->handle); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		capwap_array_free(g_wifidevice); | ||||
| 	} | ||||
|  | ||||
| 	/* Free driver */ | ||||
| 	for (i = 0; wifi_driver[i].ops != NULL; i++) { | ||||
| 		if (wifi_driver[i].ops->global_deinit) { | ||||
| 			wifi_driver[i].ops->global_deinit(wifi_driver[i].handle); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_event_getfd(struct pollfd* fds, struct wifi_event* events, int count) { | ||||
| 	int i, j; | ||||
| 	int result = 0; | ||||
|  | ||||
| 	if ((count > 0) && (!fds || !events)) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* Get from driver */ | ||||
| 	for (i = 0; wifi_driver[i].ops != NULL; i++) { | ||||
| 		if (wifi_driver[i].ops->global_getfdevent) { | ||||
| 			result += wifi_driver[i].ops->global_getfdevent(wifi_driver[i].handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Get from device */ | ||||
| 	for (i = 0; i < g_wifidevice->count; i++) { | ||||
| 		struct wifi_device* device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, i); | ||||
| 		if (device->handle) { | ||||
| 			if (device->instance->ops->device_getfdevent) { | ||||
| 				result += device->instance->ops->device_getfdevent(device->handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL)); | ||||
| 			} | ||||
|  | ||||
| 			/* Get from wlan */ | ||||
| 			if (device->instance->ops->wlan_getfdevent) { | ||||
| 				for (j = 0; j < device->wlan->count; j++) { | ||||
| 					struct wifi_wlan* wlan = (struct wifi_wlan*)capwap_array_get_item_pointer(device->wlan, j); | ||||
|  | ||||
| 					if (wlan->handle) { | ||||
| 						result += device->instance->ops->wlan_getfdevent(wlan->handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL)); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_device_connect(int radioid, const char* ifname, const char* driver) { | ||||
| 	int i; | ||||
| 	int length; | ||||
| 	int result = -1; | ||||
|  | ||||
| 	ASSERT(radioid > 0); | ||||
| 	ASSERT(ifname != NULL); | ||||
| 	ASSERT(driver != NULL); | ||||
|  | ||||
| 	/* Check */ | ||||
| 	length = strlen(ifname); | ||||
| 	if ((length <= 0) || (length >= IFNAMSIZ)) { | ||||
| 		capwap_logging_warning("Wifi device name error: %s", ifname); | ||||
| 		return -1; | ||||
| 	} else if (g_wifidevice->count >= radioid) { | ||||
| 		struct wifi_device* device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, radioid); | ||||
|  | ||||
| 		if (device->handle) { | ||||
| 			capwap_logging_warning("Wifi device RadioID already used: %d", radioid); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Search driver */ | ||||
| 	for (i = 0; wifi_driver[i].ops != NULL; i++) { | ||||
| 		if (!strcmp(driver, wifi_driver[i].ops->name)) { | ||||
| 			wifi_device_handle devicehandle; | ||||
| 			struct device_init_params params = { | ||||
| 				.ifname = ifname | ||||
| 			}; | ||||
|  | ||||
| 			/* Device init */ | ||||
| 			ASSERT(wifi_driver[i].ops->device_init); | ||||
| 			devicehandle = wifi_driver[i].ops->device_init(wifi_driver[i].handle, ¶ms); | ||||
| 			if (devicehandle) { | ||||
| 				/* Register new device */ | ||||
| 				struct wifi_device* device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, radioid); | ||||
| 				device->handle = devicehandle; | ||||
| 				device->instance = &wifi_driver[i]; | ||||
| 				device->wlan = capwap_array_create(sizeof(struct wifi_wlan), 0, 1); | ||||
|  | ||||
| 				result = 0; | ||||
| 			} | ||||
|  | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| static struct wifi_device* wifi_device_getdevice(int radioid) { | ||||
| 	struct wifi_device* device; | ||||
|  | ||||
| 	ASSERT(radioid > 0); | ||||
|  | ||||
| 	if (g_wifidevice->count < radioid) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Get radio connection */ | ||||
| 	device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, radioid); | ||||
| 	if (!device->handle) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	return device; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| static struct wifi_wlan* wifi_wlan_getdevice(int radioid, int wlanid) { | ||||
| 	struct wifi_device* device; | ||||
|  | ||||
| 	ASSERT(radioid > 0); | ||||
| 	ASSERT(wlanid > 0); | ||||
|  | ||||
| 	if (g_wifidevice->count < radioid) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Get radio connection */ | ||||
| 	device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, radioid); | ||||
| 	if (!device->handle || (device->wlan->count < wlanid)) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* */ | ||||
| 	if (device->wlan->count < wlanid) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Return wlan connection */ | ||||
| 	return (struct wifi_wlan*)capwap_array_get_item_pointer(device->wlan, wlanid); | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_wlan_create(int radioid, int wlanid, const char* ifname, uint8_t* bssid) { | ||||
| 	int length; | ||||
| 	struct wifi_device* device; | ||||
| 	struct wifi_wlan* wlan; | ||||
| 	wifi_wlan_handle wlanhandle; | ||||
| 	struct wlan_init_params params; | ||||
|  | ||||
| 	ASSERT(radioid > 0); | ||||
| 	ASSERT(wlanid > 0); | ||||
| 	ASSERT(ifname != NULL); | ||||
| 	//ASSERT(bssid != NULL); | ||||
|  | ||||
| 	/* Check */ | ||||
| 	length = strlen(ifname); | ||||
| 	if ((length <= 0) || (length >= IFNAMSIZ)) { | ||||
| 		capwap_logging_warning("Wifi device name error: %s", ifname); | ||||
| 		return -1; | ||||
| 	} else if (g_wifidevice->count < radioid) { | ||||
| 		capwap_logging_warning("Wifi device RadioID %d is not connected", radioid); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* Get radio connection */ | ||||
| 	device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, radioid); | ||||
| 	if (!device->handle) { | ||||
| 		capwap_logging_warning("Wifi device RadioID %d is not connected", radioid); | ||||
| 		return -1; | ||||
| 	} else if (device->wlan->count >= wlanid) { | ||||
| 		wlan = (struct wifi_wlan*)capwap_array_get_item_pointer(device->wlan, wlanid); | ||||
| 		if (wlan->handle) { | ||||
| 			capwap_logging_warning("WLAN interface already used: %d", wlanid); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} else if (!device->instance->ops->wlan_create) { | ||||
| 		capwap_logging_warning("%s library don't support wlan_create", device->instance->ops->name); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* Create interface */ | ||||
| 	params.ifname = ifname; | ||||
| 	params.type = WLAN_INTERFACE_AP; | ||||
| 	wlanhandle = device->instance->ops->wlan_create(device->handle, ¶ms); | ||||
| 	if (!wlanhandle) { | ||||
| 		capwap_logging_warning("Unable to create virtual interface: %s", ifname); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* */ | ||||
| 	wlan = (struct wifi_wlan*)capwap_array_get_item_pointer(device->wlan, wlanid); | ||||
| 	wlan->handle = wlanhandle; | ||||
| 	wlan->device = device; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| static void wifi_wlan_getrates(struct wifi_device* device, struct wtp_radio* radio, struct device_setrates_params* device_params) { | ||||
| static void wifi_wlan_getrates(struct wifi_device* device, uint8_t* rates, int ratescount, struct device_setrates_params* device_params) { | ||||
| 	int i, j, w; | ||||
| 	int radiotype; | ||||
| 	uint32_t mode = 0; | ||||
| 	const struct wifi_capability* capability;  | ||||
|  | ||||
| 	ASSERT(device != NULL); | ||||
| 	ASSERT(radio != NULL); | ||||
| 	ASSERT(radio->rateset.ratesetcount > 0); | ||||
| 	ASSERT(rates != NULL); | ||||
| 	ASSERT(ratescount > 0); | ||||
| 	ASSERT(device_params != NULL); | ||||
|  | ||||
| 	/* */ | ||||
| 	memset(device_params, 0, sizeof(struct device_setrates_params)); | ||||
|  | ||||
| 	/* Retrieve capability */ | ||||
| 	capability = wifi_device_getcapability(radio->radioid); | ||||
| 	capability = wifi_device_getcapability(device); | ||||
| 	if (!capability) { | ||||
| 		return; | ||||
| 	} | ||||
| @ -298,19 +46,19 @@ static void wifi_wlan_getrates(struct wifi_device* device, struct wtp_radio* rad | ||||
| 	} | ||||
|  | ||||
| 	/* Check type of rate mode */ | ||||
| 	for (i = 0; i < radio->rateset.ratesetcount; i++) { | ||||
| 	for (i = 0; i < ratescount; i++) { | ||||
| 		if (device->currentfreq.band == WIFI_BAND_2GHZ) { | ||||
| 			if (IS_IEEE80211_RATE_B(radio->rateset.rateset[i])) { | ||||
| 			if (IS_IEEE80211_RATE_B(rates[i])) { | ||||
| 				mode |= CAPWAP_RADIO_TYPE_80211B; | ||||
| 			} else if (IS_IEEE80211_RATE_G(radio->rateset.rateset[i])) { | ||||
| 			} else if (IS_IEEE80211_RATE_G(rates[i])) { | ||||
| 				mode |= CAPWAP_RADIO_TYPE_80211G; | ||||
| 			} else if (IS_IEEE80211_RATE_N(radio->rateset.rateset[i])) { | ||||
| 			} else if (IS_IEEE80211_RATE_N(rates[i])) { | ||||
| 				mode |= CAPWAP_RADIO_TYPE_80211N; | ||||
| 			} | ||||
| 		} else if (device->currentfreq.band == WIFI_BAND_5GHZ) { | ||||
| 			if (IS_IEEE80211_RATE_A(radio->rateset.rateset[i])) { | ||||
| 			if (IS_IEEE80211_RATE_A(rates[i])) { | ||||
| 				mode |= CAPWAP_RADIO_TYPE_80211A; | ||||
| 			} else if (IS_IEEE80211_RATE_N(radio->rateset.rateset[i])) { | ||||
| 			} else if (IS_IEEE80211_RATE_N(rates[i])) { | ||||
| 				mode |= CAPWAP_RADIO_TYPE_80211N; | ||||
| 			} | ||||
| 		} | ||||
| @ -330,12 +78,12 @@ static void wifi_wlan_getrates(struct wifi_device* device, struct wtp_radio* rad | ||||
|  | ||||
| 		if (bandcap->band == device->currentfreq.band) { | ||||
| 			for (j = 0; j < bandcap->rate->count; j++) { | ||||
| 				struct wifi_rate_capability* rate = (struct wifi_rate_capability*)capwap_array_get_item_pointer(bandcap->rate, j); | ||||
| 				struct wifi_rate_capability* ratecapability = (struct wifi_rate_capability*)capwap_array_get_item_pointer(bandcap->rate, j); | ||||
|  | ||||
| 				/* Validate rate */ | ||||
| 				for (w = 0; w < radio->rateset.ratesetcount; w++) { | ||||
| 					if (radio->rateset.rateset[w] == rate->bitrate) { | ||||
| 						device_params->supportedrates[device_params->supportedratescount++] = rate->bitrate; | ||||
| 				for (w = 0; w < ratescount; w++) { | ||||
| 					if (rates[w] == ratecapability->bitrate) { | ||||
| 						device_params->supportedrates[device_params->supportedratescount++] = ratecapability->bitrate; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| @ -372,85 +120,162 @@ static void wifi_wlan_getrates(struct wifi_device* device, struct wtp_radio* rad | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_wlan_startap(int radioid, int wlanid, struct wifi_wlan_startap_params* params) { | ||||
| 	struct wifi_wlan* wlan; | ||||
| 	struct wlan_startap_params wlan_params; | ||||
| int wifi_driver_init(void) { | ||||
| 	int i; | ||||
|  | ||||
| 	ASSERT(radioid > 0); | ||||
| 	ASSERT(wlanid > 0); | ||||
|  | ||||
| 	/* */ | ||||
| 	wlan = wifi_wlan_getdevice(radioid, wlanid); | ||||
| 	if (!wlan || !wlan->device->instance->ops->wlan_startap) { | ||||
| 		return -1; | ||||
| 	for (i = 0; wifi_driver[i].ops != NULL; i++) { | ||||
| 		/* Initialize driver */ | ||||
| 		ASSERT(wifi_driver[i].ops->global_init != NULL); | ||||
| 		wifi_driver[i].handle = wifi_driver[i].ops->global_init(); | ||||
| 		if (!wifi_driver[i].handle) { | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Start AP */ | ||||
| 	memset(&wlan_params, 0, sizeof(struct wlan_startap_params)); | ||||
| 	wlan_params.ssid = params->ssid; | ||||
| 	wlan_params.ssid_hidden = params->ssid_hidden; | ||||
| 	wlan_params.capability = params->capability; | ||||
| 	wlan_params.authenticationtype = params->authmode; | ||||
| 	/* Device handler */ | ||||
| 	g_wifidevice = capwap_list_create(); | ||||
|  | ||||
| 	return wlan->device->instance->ops->wlan_startap(wlan->handle, &wlan_params); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_wlan_stopap(int radioid, int wlanid) { | ||||
| 	struct wifi_wlan* wlan; | ||||
| void wifi_driver_free(void) { | ||||
| 	unsigned long i; | ||||
| 	struct capwap_list_item* itemdevice; | ||||
| 	struct capwap_list_item* itemwlan; | ||||
|  | ||||
| 	/* */ | ||||
| 	wlan = wifi_wlan_getdevice(radioid, wlanid); | ||||
| 	if (!wlan->device->instance->ops->wlan_stopap) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 	/* Free device */ | ||||
| 	if (g_wifidevice) { | ||||
| 		for (itemdevice = g_wifidevice->first; itemdevice != NULL; itemdevice = itemdevice->next) { | ||||
| 			struct wifi_device* device = (struct wifi_device*)itemdevice->item; | ||||
|  | ||||
| 	return wlan->device->instance->ops->wlan_stopap(wlan->handle); | ||||
| } | ||||
| 			if (device->wlan) { | ||||
| 				if (device->instance->ops->wlan_delete != NULL) { | ||||
| 					for (itemwlan = device->wlan->first; itemwlan != NULL; itemwlan = itemwlan->next) { | ||||
| 						struct wifi_wlan* wlan = (struct wifi_wlan*)itemwlan->item; | ||||
|  | ||||
| /* */ | ||||
| int wifi_wlan_getbssid(int radioid, int wlanid, uint8_t* bssid) { | ||||
| 	struct wifi_wlan* wlan; | ||||
| 						if (wlan->handle) { | ||||
| 							device->instance->ops->wlan_delete(wlan->handle); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 	/* */ | ||||
| 	wlan = wifi_wlan_getdevice(radioid, wlanid); | ||||
| 	if (!wlan->device->instance->ops->wlan_getmacaddress) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 				capwap_list_free(device->wlan); | ||||
| 			} | ||||
|  | ||||
| 	return wlan->device->instance->ops->wlan_getmacaddress(wlan->handle, bssid); | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| void wifi_wlan_destroy(int radioid, int wlanid) { | ||||
| 	struct wifi_wlan* wlan; | ||||
|  | ||||
| 	ASSERT(radioid > 0); | ||||
| 	ASSERT(wlanid > 0); | ||||
|  | ||||
| 	wlan = wifi_wlan_getdevice(radioid, wlanid); | ||||
| 	if (wlan && wlan->handle) { | ||||
| 		if (wlan->device->instance->ops->wlan_delete) { | ||||
| 			wlan->device->instance->ops->wlan_delete(wlan->handle); | ||||
| 			if (device->handle && device->instance->ops->device_deinit) { | ||||
| 				device->instance->ops->device_deinit(device->handle); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		memset(wlan, 0, sizeof(struct wifi_wlan)); | ||||
| 		capwap_list_free(g_wifidevice); | ||||
| 	} | ||||
|  | ||||
| 	/* Free driver */ | ||||
| 	for (i = 0; wifi_driver[i].ops != NULL; i++) { | ||||
| 		if (wifi_driver[i].ops->global_deinit) { | ||||
| 			wifi_driver[i].ops->global_deinit(wifi_driver[i].handle); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| const struct wifi_capability* wifi_device_getcapability(int radioid) { | ||||
| 	struct wifi_device* device; | ||||
| int wifi_event_getfd(struct pollfd* fds, struct wifi_event* events, int count) { | ||||
| 	int i; | ||||
| 	int result = 0; | ||||
| 	struct capwap_list_item* itemdevice; | ||||
| 	struct capwap_list_item* itemwlan; | ||||
|  | ||||
| 	ASSERT(radioid > 0); | ||||
| 	if ((count > 0) && (!fds || !events)) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (g_wifidevice->count <= radioid) { | ||||
| 	/* Get from driver */ | ||||
| 	for (i = 0; wifi_driver[i].ops != NULL; i++) { | ||||
| 		if (wifi_driver[i].ops->global_getfdevent) { | ||||
| 			result += wifi_driver[i].ops->global_getfdevent(wifi_driver[i].handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Get from device */ | ||||
| 	for (itemdevice = g_wifidevice->first; itemdevice != NULL; itemdevice = itemdevice->next) { | ||||
| 		struct wifi_device* device = (struct wifi_device*)itemdevice->item; | ||||
| 		if (device->handle) { | ||||
| 			if (device->instance->ops->device_getfdevent) { | ||||
| 				result += device->instance->ops->device_getfdevent(device->handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL)); | ||||
| 			} | ||||
|  | ||||
| 			/* Get from wlan */ | ||||
| 			if (device->wlan && device->instance->ops->wlan_getfdevent) { | ||||
| 				for (itemwlan = device->wlan->first; itemwlan != NULL; itemwlan = itemwlan->next) { | ||||
| 					struct wifi_wlan* wlan = (struct wifi_wlan*)itemwlan->item; | ||||
|  | ||||
| 					if (wlan->handle) { | ||||
| 						result += device->instance->ops->wlan_getfdevent(wlan->handle, (count ? &fds[result] : NULL), (count ? &events[result] : NULL)); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| struct wifi_device* wifi_device_connect(const char* ifname, const char* driver) { | ||||
| 	int i; | ||||
| 	int length; | ||||
| 	struct wifi_device* device = NULL; | ||||
|  | ||||
| 	ASSERT(ifname != NULL); | ||||
| 	ASSERT(driver != NULL); | ||||
|  | ||||
| 	/* Check */ | ||||
| 	length = strlen(ifname); | ||||
| 	if ((length <= 0) || (length >= IFNAMSIZ)) { | ||||
| 		capwap_logging_warning("Wifi device name error: %s", ifname); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Search driver */ | ||||
| 	for (i = 0; wifi_driver[i].ops != NULL; i++) { | ||||
| 		if (!strcmp(driver, wifi_driver[i].ops->name)) { | ||||
| 			wifi_device_handle devicehandle; | ||||
| 			struct device_init_params params = { | ||||
| 				.ifname = ifname | ||||
| 			}; | ||||
|  | ||||
| 			/* Device init */ | ||||
| 			ASSERT(wifi_driver[i].ops->device_init); | ||||
| 			devicehandle = wifi_driver[i].ops->device_init(wifi_driver[i].handle, ¶ms); | ||||
| 			if (devicehandle) { | ||||
| 				struct capwap_list_item* itemdevice; | ||||
|  | ||||
| 				/* Register new device */ | ||||
| 				itemdevice = capwap_itemlist_create(sizeof(struct wifi_device)); | ||||
| 				device = (struct wifi_device*)itemdevice->item; | ||||
| 				device->handle = devicehandle; | ||||
| 				device->instance = &wifi_driver[i]; | ||||
| 				device->wlan = capwap_list_create(); | ||||
|  | ||||
| 				/* Appent to device list */ | ||||
| 				capwap_itemlist_insert_after(g_wifidevice, NULL, itemdevice); | ||||
| 			} | ||||
|  | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return device; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| const struct wifi_capability* wifi_device_getcapability(struct wifi_device* device) { | ||||
| 	ASSERT(device != NULL); | ||||
| 	ASSERT(device->handle != NULL); | ||||
|  | ||||
| 	/* Retrieve cached capability */ | ||||
| 	device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, radioid); | ||||
| 	if (!device->handle || !device->instance->ops->device_getcapability) { | ||||
| 	if (!device->instance->ops->device_getcapability) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| @ -458,12 +283,13 @@ const struct wifi_capability* wifi_device_getcapability(int radioid) { | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_device_setconfiguration(int radioid, struct device_setconfiguration_params* params) { | ||||
| 	struct wifi_device* device; | ||||
| int wifi_device_setconfiguration(struct wifi_device* device, struct device_setconfiguration_params* params) { | ||||
| 	ASSERT(device != NULL); | ||||
| 	ASSERT(device->handle != NULL); | ||||
| 	ASSERT(params != NULL); | ||||
|  | ||||
| 	/* Get radio device */ | ||||
| 	device = wifi_device_getdevice(radioid); | ||||
| 	if (!device || !device->handle || !device->instance->ops->device_setconfiguration) { | ||||
| 	if (!device->instance->ops->device_setconfiguration) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| @ -472,20 +298,22 @@ int wifi_device_setconfiguration(int radioid, struct device_setconfiguration_par | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_device_setfrequency(int radioid, uint32_t band, uint32_t mode, uint8_t channel) { | ||||
| int wifi_device_setfrequency(struct wifi_device* device, uint32_t band, uint32_t mode, uint8_t channel) { | ||||
| 	int i, j; | ||||
| 	int result = -1; | ||||
| 	const struct wifi_capability* capability; | ||||
| 	uint32_t frequency = 0; | ||||
|  | ||||
| 	ASSERT(radioid > 0); | ||||
| 	ASSERT(device != NULL); | ||||
| 	ASSERT(device->handle != NULL); | ||||
|  | ||||
| 	if (g_wifidevice->count <= radioid) { | ||||
| 	/* Check device */ | ||||
| 	if (!device->instance->ops->device_setfrequency) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* Capability device */ | ||||
| 	capability = wifi_device_getcapability(radioid); | ||||
| 	capability = wifi_device_getcapability(device); | ||||
| 	if (!capability || !(capability->flags & WIFI_CAPABILITY_RADIOTYPE) || !(capability->flags & WIFI_CAPABILITY_BANDS)) { | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -507,9 +335,6 @@ int wifi_device_setfrequency(int radioid, uint32_t band, uint32_t mode, uint8_t | ||||
|  | ||||
| 	/* Configure frequency */ | ||||
| 	if (frequency) { | ||||
| 		struct wifi_device* device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, radioid); | ||||
|  | ||||
| 		memset(&device->currentfreq, 0, sizeof(struct wifi_frequency)); | ||||
| 		device->currentfreq.band = band; | ||||
| 		device->currentfreq.mode = mode; | ||||
| 		device->currentfreq.channel = channel; | ||||
| @ -523,10 +348,7 @@ int wifi_device_setfrequency(int radioid, uint32_t band, uint32_t mode, uint8_t | ||||
| 		} | ||||
|  | ||||
| 		/* Set frequency */ | ||||
| 		device = (struct wifi_device*)capwap_array_get_item_pointer(g_wifidevice, radioid); | ||||
| 		if (device->handle && device->instance->ops->device_setfrequency) { | ||||
| 			result = device->instance->ops->device_setfrequency(device->handle, &device->currentfreq); | ||||
| 		} | ||||
| 		result = device->instance->ops->device_setfrequency(device->handle, &device->currentfreq); | ||||
| 	} | ||||
|  | ||||
| 	/* */ | ||||
| @ -534,23 +356,124 @@ int wifi_device_setfrequency(int radioid, uint32_t band, uint32_t mode, uint8_t | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_device_updaterates(int radioid) { | ||||
| 	struct wtp_radio* radio; | ||||
| 	struct wifi_device* device; | ||||
| int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int ratescount) { | ||||
| 	struct device_setrates_params params; | ||||
|  | ||||
| 	ASSERT(device != NULL); | ||||
| 	ASSERT(device->handle != NULL); | ||||
| 	ASSERT(rates != NULL); | ||||
| 	ASSERT(ratescount > 0); | ||||
|  | ||||
| 	/* Get radio device */ | ||||
| 	device = wifi_device_getdevice(radioid); | ||||
| 	radio = wtp_radio_get_phy(radioid); | ||||
| 	if (!device || !radio || !device->handle || !device->instance->ops->device_setrates) { | ||||
| 	if (!device->instance->ops->device_setrates) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* Set rates */ | ||||
| 	wifi_wlan_getrates(device, radio, ¶ms); | ||||
| 	wifi_wlan_getrates(device, rates, ratescount, ¶ms); | ||||
| 	return device->instance->ops->device_setrates(device->handle, ¶ms); | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| struct wifi_wlan* wifi_wlan_create(struct wifi_device* device, const char* ifname) { | ||||
| 	int length; | ||||
| 	struct wifi_wlan* wlan; | ||||
| 	wifi_wlan_handle wlanhandle; | ||||
| 	struct capwap_list_item* itemwlan; | ||||
|  | ||||
| 	ASSERT(device != NULL); | ||||
| 	ASSERT(device->handle != NULL); | ||||
| 	ASSERT(ifname != NULL); | ||||
|  | ||||
| 	/* Check */ | ||||
| 	length = strlen(ifname); | ||||
| 	if ((length <= 0) || (length >= IFNAMSIZ)) { | ||||
| 		capwap_logging_warning("Wifi device name error: %s", ifname); | ||||
| 		return NULL; | ||||
| 	} else if (!device->instance->ops->wlan_create) { | ||||
| 		capwap_logging_warning("%s library don't support wlan_create", device->instance->ops->name); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Create interface */ | ||||
| 	wlanhandle = device->instance->ops->wlan_create(device->handle, ifname); | ||||
| 	if (!wlanhandle) { | ||||
| 		capwap_logging_warning("Unable to create BSS: %s", ifname); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Create new BSS */ | ||||
| 	itemwlan = capwap_itemlist_create(sizeof(struct wifi_wlan)); | ||||
| 	wlan = (struct wifi_wlan*)itemwlan->item; | ||||
| 	wlan->handle = wlanhandle; | ||||
| 	wlan->device = device; | ||||
|  | ||||
| 	/* Appent to wlan list */ | ||||
| 	capwap_itemlist_insert_after(device->wlan, NULL, itemwlan); | ||||
| 	return wlan; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params) { | ||||
| 	ASSERT(wlan != NULL); | ||||
| 	ASSERT(wlan->device != NULL); | ||||
| 	ASSERT(params != NULL); | ||||
|  | ||||
| 	/* Check */ | ||||
| 	if (!wlan->device->instance->ops->wlan_startap) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* Start AP */ | ||||
| 	return wlan->device->instance->ops->wlan_startap(wlan->handle, params); | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| void wifi_wlan_stopap(struct wifi_wlan* wlan) { | ||||
| 	ASSERT(wlan != NULL); | ||||
| 	ASSERT(wlan->device != NULL); | ||||
|  | ||||
| 	/* Stop AP */ | ||||
| 	if (wlan->device->instance->ops->wlan_stopap) { | ||||
| 		wlan->device->instance->ops->wlan_stopap(wlan->handle); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_wlan_getbssid(struct wifi_wlan* wlan, uint8_t* bssid) { | ||||
| 	ASSERT(wlan != NULL); | ||||
| 	ASSERT(wlan->handle != NULL); | ||||
| 	ASSERT(bssid != NULL); | ||||
|  | ||||
| 	/* */ | ||||
| 	if (!wlan->device->instance->ops->wlan_getmacaddress) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	return wlan->device->instance->ops->wlan_getmacaddress(wlan->handle, bssid); | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| void wifi_wlan_destroy(struct wifi_wlan* wlan) { | ||||
| 	struct capwap_list_item* itemwlan; | ||||
|  | ||||
| 	ASSERT(wlan != NULL); | ||||
| 	ASSERT(wlan->handle != NULL); | ||||
|  | ||||
| 	/* */ | ||||
| 	if (wlan->device->instance->ops->wlan_delete) { | ||||
| 		wlan->device->instance->ops->wlan_delete(wlan->handle); | ||||
| 	} | ||||
|  | ||||
| 	/* Remove from wlan list of device */ | ||||
| 	for (itemwlan = wlan->device->wlan->first; itemwlan != NULL; itemwlan = itemwlan->next) { | ||||
| 		if (wlan == (struct wifi_wlan*)itemwlan->item) { | ||||
| 			capwap_itemlist_free(capwap_itemlist_remove(wlan->device->wlan, itemwlan)); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| uint32_t wifi_iface_index(const char* ifname) { | ||||
| 	if (!ifname || !*ifname) { | ||||
| @ -560,6 +483,24 @@ uint32_t wifi_iface_index(const char* ifname) { | ||||
| 	return if_nametoindex(ifname); | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_iface_getstatus(int sock, const char* ifname) { | ||||
| 	struct ifreq ifreq; | ||||
|  | ||||
| 	ASSERT(sock > 0); | ||||
| 	ASSERT(ifname != NULL); | ||||
| 	ASSERT(*ifname != 0); | ||||
|  | ||||
| 	/* Change link state of interface */ | ||||
| 	memset(&ifreq, 0, sizeof(ifreq)); | ||||
| 	strcpy(ifreq.ifr_name, ifname); | ||||
| 	if (!ioctl(sock, SIOCGIFFLAGS, &ifreq)) { | ||||
| 		return ((ifreq.ifr_flags & IFF_UP) ? 1: 0); | ||||
| 	} | ||||
|  | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wifi_iface_updown(int sock, const char* ifname, int up) { | ||||
| 	struct ifreq ifreq; | ||||
| @ -572,9 +513,18 @@ int wifi_iface_updown(int sock, const char* ifname, int up) { | ||||
| 	memset(&ifreq, 0, sizeof(ifreq)); | ||||
| 	strcpy(ifreq.ifr_name, ifname); | ||||
| 	if (!ioctl(sock, SIOCGIFFLAGS, &ifreq)) { | ||||
| 		/* Set flag */ | ||||
| 		if (up) { | ||||
| 			if (ifreq.ifr_flags & IFF_UP) { | ||||
| 				return 0;	/* Flag is already set */ | ||||
| 			} | ||||
| 			 | ||||
| 			ifreq.ifr_flags |= IFF_UP; | ||||
| 		} else { | ||||
| 			if (!(ifreq.ifr_flags & IFF_UP)) { | ||||
| 				return 0;	/* Flag is already unset */ | ||||
| 			} | ||||
|  | ||||
| 			ifreq.ifr_flags &= ~IFF_UP; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| @ -94,22 +94,18 @@ struct device_setconfiguration_params { | ||||
| 	uint8_t country[WIFI_COUNTRY_LENGTH]; | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| struct wlan_init_params { | ||||
| 	const char* ifname; | ||||
| 	int type; | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| struct wlan_startap_params { | ||||
| 	const char* ssid; | ||||
| 	uint8_t ssid_hidden; | ||||
|  | ||||
| 	uint16_t capability; | ||||
|  | ||||
| 	uint8_t authenticationtype; | ||||
| 	uint8_t qos; | ||||
| 	uint8_t authmode; | ||||
| 	uint8_t macmode; | ||||
| 	uint8_t tunnelmode; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* */ | ||||
| struct wlan_send_frame_params { | ||||
| 	char* packet; | ||||
| @ -204,10 +200,11 @@ struct wifi_frequency { | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| #define WIFI_EVENT_MAX_ITEMS					2 | ||||
| struct wifi_event { | ||||
| 	void (*event_handler)(int fd, void* param1, void* param2); | ||||
| 	void* param1; | ||||
| 	void* param2; | ||||
| 	void (*event_handler)(int fd, void** params, int paramscount); | ||||
| 	int paramscount; | ||||
| 	void* params[WIFI_EVENT_MAX_ITEMS]; | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| @ -230,10 +227,10 @@ struct wifi_driver_ops { | ||||
| 	void (*device_deinit)(wifi_device_handle handle); | ||||
|  | ||||
| 	/* WLAN functions */ | ||||
| 	wifi_wlan_handle (*wlan_create)(wifi_device_handle handle, struct wlan_init_params* params); | ||||
| 	wifi_wlan_handle (*wlan_create)(wifi_device_handle handle, const char* ifname); | ||||
| 	int (*wlan_getfdevent)(wifi_wlan_handle handle, struct pollfd* fds, struct wifi_event* events); | ||||
| 	int (*wlan_startap)(wifi_wlan_handle handle, struct wlan_startap_params* params); | ||||
| 	int (*wlan_stopap)(wifi_wlan_handle handle); | ||||
| 	void (*wlan_stopap)(wifi_wlan_handle handle); | ||||
| 	int (*wlan_getmacaddress)(wifi_wlan_handle handle, uint8_t* address);  | ||||
| 	void (*wlan_delete)(wifi_wlan_handle handle); | ||||
| }; | ||||
| @ -249,7 +246,7 @@ struct wifi_device { | ||||
| 	wifi_device_handle handle;							/* Device handle */ | ||||
| 	struct wifi_driver_instance* instance;				/* Driver instance */ | ||||
|  | ||||
| 	struct capwap_array* wlan;							/* Virtual AP */ | ||||
| 	struct capwap_list* wlan;							/* BSS */ | ||||
|  | ||||
| 	/* Current frequency */ | ||||
| 	struct wifi_frequency currentfreq; | ||||
| @ -261,17 +258,6 @@ struct wifi_wlan { | ||||
| 	struct wifi_device* device; | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| struct wifi_wlan_startap_params { | ||||
| 	uint16_t capability; | ||||
| 	uint8_t qos; | ||||
| 	uint8_t authmode; | ||||
| 	uint8_t macmode; | ||||
| 	uint8_t tunnelmode; | ||||
| 	uint8_t ssid_hidden; | ||||
| 	char ssid[IEEE80211_IE_SSID_MAX_LENGTH + 1]; | ||||
| }; | ||||
|  | ||||
| /* Initialize wifi driver engine */ | ||||
| int wifi_driver_init(void); | ||||
| void wifi_driver_free(void); | ||||
| @ -280,18 +266,18 @@ void wifi_driver_free(void); | ||||
| int wifi_event_getfd(struct pollfd* fds, struct wifi_event* events, int count); | ||||
|  | ||||
| /* */ | ||||
| int wifi_device_connect(int radioid, const char* ifname, const char* driver); | ||||
| const struct wifi_capability* wifi_device_getcapability(int radioid); | ||||
| int wifi_device_setconfiguration(int radioid, struct device_setconfiguration_params* params); | ||||
| int wifi_device_setfrequency(int radioid, uint32_t band, uint32_t mode, uint8_t channel); | ||||
| int wifi_device_updaterates(int radioid); | ||||
| struct wifi_device* wifi_device_connect(const char* ifname, const char* driver); | ||||
| const struct wifi_capability* wifi_device_getcapability(struct wifi_device* device); | ||||
| int wifi_device_setconfiguration(struct wifi_device* device, struct device_setconfiguration_params* params); | ||||
| int wifi_device_setfrequency(struct wifi_device* device, uint32_t band, uint32_t mode, uint8_t channel); | ||||
| int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int ratescount); | ||||
|  | ||||
| /* */ | ||||
| int wifi_wlan_create(int radioid, int wlanid, const char* ifname, uint8_t* bssid); | ||||
| int wifi_wlan_startap(int radioid, int wlanid, struct wifi_wlan_startap_params* params); | ||||
| int wifi_wlan_stopap(int radioid, int wlanid); | ||||
| int wifi_wlan_getbssid(int radioid, int wlanid, uint8_t* bssid); | ||||
| void wifi_wlan_destroy(int radioid, int wlanid); | ||||
| struct wifi_wlan* wifi_wlan_create(struct wifi_device* device, const char* ifname); | ||||
| int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params); | ||||
| void wifi_wlan_stopap(struct wifi_wlan* wlan); | ||||
| int wifi_wlan_getbssid(struct wifi_wlan* wlan, uint8_t* bssid); | ||||
| void wifi_wlan_destroy(struct wifi_wlan* wlan); | ||||
|  | ||||
| /* Util functions */ | ||||
| uint32_t wifi_iface_index(const char* ifname); | ||||
| @ -314,6 +300,7 @@ void wifi_aid_free(uint32_t* aidbitfield, uint16_t aid); | ||||
| /* */ | ||||
| int wifi_retrieve_information_elements_position(struct ieee80211_ie_items* items, const uint8_t* data, int length); | ||||
|  | ||||
| int wifi_iface_getstatus(int sock, const char* ifname); | ||||
| int wifi_iface_updown(int sock, const char* ifname, int up); | ||||
| #define wifi_iface_up(sock, ifname)										wifi_iface_updown(sock, ifname, 1) | ||||
| #define wifi_iface_down(sock, ifname)									wifi_iface_updown(sock, ifname, 0) | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -2,9 +2,10 @@ | ||||
| #define __WIFI_NL80211_HEADER__ | ||||
|  | ||||
| #include "capwap_hash.h" | ||||
| #include "netlink_link.h" | ||||
|  | ||||
| /* Compatibility functions */ | ||||
| #if !defined(HAVE_LIBNL20) && !defined(HAVE_LIBNL30) | ||||
| #ifdef HAVE_LIBNL_10  | ||||
| #define nl_sock nl_handle | ||||
| #endif | ||||
|  | ||||
| @ -24,19 +25,31 @@ struct nl80211_global_handle { | ||||
| 	struct nl_sock* nl_event; | ||||
| 	int nl_event_fd; | ||||
|  | ||||
| 	struct netlink* netlinkhandle; | ||||
|  | ||||
| 	int sock_util; | ||||
|  | ||||
| 	struct capwap_list* devicelist; | ||||
| }; | ||||
|  | ||||
| /* Device handle */ | ||||
| #define NL80211_DEVICE_SET_FREQUENCY					0x00000001 | ||||
| #define NL80211_DEVICE_SET_RATES						0x00000002 | ||||
| #define NL80211_DEVICE_SET_CONFIGURATION				0x00000004 | ||||
|  | ||||
| #define NL80211_DEVICE_REQUIRED_FOR_BSS					(NL80211_DEVICE_SET_FREQUENCY | NL80211_DEVICE_SET_RATES | NL80211_DEVICE_SET_CONFIGURATION) | ||||
|  | ||||
| struct nl80211_device_handle { | ||||
| 	struct nl80211_global_handle* globalhandle; | ||||
|  | ||||
| 	uint32_t phyindex; | ||||
| 	char phyname[IFNAMSIZ]; | ||||
|  | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	/* */ | ||||
| 	struct capwap_list* wlanlist; | ||||
| 	unsigned long wlanactive; | ||||
|  | ||||
| 	/* */ | ||||
| 	uint16_t beaconperiod; | ||||
| @ -63,7 +76,9 @@ struct nl80211_device_handle { | ||||
| }; | ||||
|  | ||||
| /* WLAN handle */ | ||||
| #define NL80211_WLAN_SET_BEACON						0x00000001 | ||||
| #define NL80211_WLAN_RUNNING						0x00000001 | ||||
| #define NL80211_WLAN_SET_BEACON						0x00000002 | ||||
| #define NL80211_WLAN_OPERSTATE_RUNNING				0x00000004 | ||||
|  | ||||
| struct nl80211_wlan_handle { | ||||
| 	struct nl80211_device_handle* devicehandle; | ||||
| @ -91,9 +106,13 @@ struct nl80211_wlan_handle { | ||||
|  | ||||
| 	/* Station information */ | ||||
| 	unsigned long stationscount; | ||||
| 	unsigned long maxstationscount; | ||||
| 	struct capwap_hash* stations; | ||||
|  | ||||
| 	uint32_t aidbitfield[WIFI_AID_BITFIELD_SIZE]; | ||||
|  | ||||
| 	/* Scan */ | ||||
| 	unsigned long scancomplete; | ||||
| }; | ||||
|  | ||||
| /* Physical device info */ | ||||
|  | ||||
| @ -1,4 +1,3 @@ | ||||
| #include <execinfo.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| @ -7,6 +6,10 @@ | ||||
| #include "config.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_DEBUG_BACKTRACE | ||||
| #include <execinfo.h> | ||||
| #endif | ||||
|  | ||||
| #include "capwap_logging.h" | ||||
| #include "capwap_error.h" | ||||
|  | ||||
| @ -23,8 +26,10 @@ struct capwap_memory_block { | ||||
| 	size_t size; | ||||
| 	const char* file; | ||||
| 	int line; | ||||
| #ifdef USE_DEBUG_BACKTRACE | ||||
| 	void* backtrace[BACKTRACE_BUFFER]; | ||||
| 	int backtrace_count; | ||||
| #endif | ||||
| 	struct capwap_memory_block* next; | ||||
| }; | ||||
|  | ||||
| @ -54,7 +59,9 @@ void* capwap_alloc_debug(size_t size, const char* file, const int line) { | ||||
| 	block->size = size; | ||||
| 	block->file = file; | ||||
| 	block->line = line; | ||||
| #ifdef USE_DEBUG_BACKTRACE | ||||
| 	block->backtrace_count = backtrace(block->backtrace, BACKTRACE_BUFFER); | ||||
| #endif | ||||
| 	block->next = g_memoryblocks; | ||||
|  | ||||
| 	/* Canary */ | ||||
| @ -125,13 +132,16 @@ void capwap_free_debug(void* p, const char* file, const int line) { | ||||
|  | ||||
| /* Dump memory alloced */ | ||||
| void capwap_dump_memory(void) { | ||||
| #ifdef USE_DEBUG_BACKTRACE | ||||
| 	char** backtrace_functions; | ||||
| #endif | ||||
| 	struct capwap_memory_block* findblock; | ||||
|  | ||||
| 	findblock = g_memoryblocks; | ||||
| 	while (findblock != NULL) { | ||||
| 		capwap_logging_debug("%s(%d): block at %p, %d bytes long", findblock->file, findblock->line, findblock->item, findblock->size); | ||||
|  | ||||
| #ifdef USE_DEBUG_BACKTRACE | ||||
| 		backtrace_functions = backtrace_symbols(findblock->backtrace, findblock->backtrace_count); | ||||
| 		if (backtrace_functions) { | ||||
| 			int j; | ||||
| @ -143,7 +153,7 @@ void capwap_dump_memory(void) { | ||||
|  | ||||
| 			free(backtrace_functions); | ||||
| 		} | ||||
| 		 | ||||
| #endif | ||||
|  | ||||
| 		/* Next */ | ||||
| 		findblock = findblock->next; | ||||
| @ -162,6 +172,7 @@ int capwap_check_memory_leak(int verbose) { | ||||
| } | ||||
|  | ||||
| /* Backtrace call stack */ | ||||
| #ifdef USE_DEBUG_BACKTRACE | ||||
| void capwap_backtrace_callstack(void) { | ||||
| 	int i; | ||||
| 	int count; | ||||
| @ -183,3 +194,4 @@ void capwap_backtrace_callstack(void) { | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -19,7 +19,11 @@ void capwap_free_debug(void* p, const char* file, const int line); | ||||
| int capwap_check_memory_leak(int verbose); | ||||
| void capwap_dump_memory(void); | ||||
|  | ||||
| #ifdef USE_DEBUG_BACKTRACE | ||||
| void capwap_backtrace_callstack(void); | ||||
| #else | ||||
| #define capwap_backtrace_callstack()	(0) | ||||
| #endif | ||||
|  | ||||
| #else | ||||
|  | ||||
|  | ||||
							
								
								
									
										172
									
								
								src/wtp/wtp.c
									
									
									
									
									
								
							
							
						
						
									
										172
									
								
								src/wtp/wtp.c
									
									
									
									
									
								
							| @ -7,6 +7,7 @@ | ||||
| #include "capwap_element.h" | ||||
| #include "capwap_dtls.h" | ||||
| #include "wtp_dfa.h" | ||||
| #include "wtp_radio.h" | ||||
|  | ||||
| #include <arpa/inet.h> | ||||
| #include <libconfig.h> | ||||
| @ -14,8 +15,9 @@ | ||||
| struct wtp_t g_wtp; | ||||
|  | ||||
| /* Local param */ | ||||
| #define WTP_STANDARD_NAME				"Unknown WTP" | ||||
| #define WTP_STANDARD_LOCATION			"Unknown Location" | ||||
| #define WTP_STANDARD_NAME					"Unknown WTP" | ||||
| #define WTP_STANDARD_LOCATION				"Unknown Location" | ||||
| #define WTP_WAIT_RADIO_INITIALIZATION		1 | ||||
|  | ||||
| static char g_configurationfile[260] = WTP_STANDARD_CONFIGURATION_FILE; | ||||
|  | ||||
| @ -186,7 +188,7 @@ static void wtp_print_usage(void) { | ||||
| static int wtp_parsing_radio_configuration(config_setting_t* configElement, struct wtp_radio* radio) { | ||||
| 	int i; | ||||
| 	int configBool; | ||||
| 	long int configInt; | ||||
| 	LIBCONFIG_LOOKUP_INT_ARG configInt; | ||||
| 	const char* configString; | ||||
| 	config_setting_t* configItems; | ||||
| 	config_setting_t* configSection; | ||||
| @ -458,6 +460,16 @@ static int wtp_parsing_radio_configuration(config_setting_t* configElement, stru | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (config_setting_lookup_string(configElement, "bssprefixname", &configString) == CONFIG_TRUE) { | ||||
| 		if (strlen(configString) < IFNAMSIZ) { | ||||
| 			strcpy(radio->wlanprefix, configString); | ||||
| 		} else { | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} else { | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (config_setting_lookup_int(configElement, "dtimperiod", &configInt) == CONFIG_TRUE) { | ||||
| 		if ((configInt > 0) && (configInt < 256)) { | ||||
| 			radio->radioconfig.dtimperiod = (uint8_t)configInt; | ||||
| @ -501,17 +513,16 @@ static int wtp_parsing_radio_configuration(config_setting_t* configElement, stru | ||||
| /* Parsing configuration */ | ||||
| static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	int i; | ||||
| 	int result; | ||||
| 	int configInt; | ||||
| 	int configBool; | ||||
| 	int configIPv4; | ||||
| 	int configIPv6; | ||||
| 	long int configLongInt; | ||||
| 	LIBCONFIG_LOOKUP_INT_ARG configInt; | ||||
| 	const char* configString; | ||||
| 	config_setting_t* configSetting; | ||||
|  | ||||
| 	/* Logging configuration */ | ||||
| 	if (config_lookup_bool(config, "logging.enable", &configInt) == CONFIG_TRUE) { | ||||
| 		if (!configInt) { | ||||
| 	if (config_lookup_bool(config, "logging.enable", &configBool) == CONFIG_TRUE) { | ||||
| 		if (!configBool) { | ||||
| 			capwap_logging_verboselevel(CAPWAP_LOGGING_NONE); | ||||
| 			capwap_logging_disable_allinterface(); | ||||
| 		} else { | ||||
| @ -559,8 +570,8 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	} | ||||
|  | ||||
| 	/* Set running mode */ | ||||
| 	if (config_lookup_bool(config, "application.standalone", &configInt) == CONFIG_TRUE) { | ||||
| 		g_wtp.standalone = ((configInt != 0) ? 1 : 0); | ||||
| 	if (config_lookup_bool(config, "application.standalone", &configBool) == CONFIG_TRUE) { | ||||
| 		g_wtp.standalone = ((configBool != 0) ? 1 : 0); | ||||
| 	} | ||||
|  | ||||
| 	/* Set name of WTP */ | ||||
| @ -623,20 +634,20 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	/* Set tunnelmode of WTP */ | ||||
| 	if (config_lookup(config, "application.tunnelmode") != NULL) { | ||||
| 		g_wtp.mactunnel.mode = 0; | ||||
| 		if (config_lookup_bool(config, "application.tunnelmode.nativeframe", &configInt) == CONFIG_TRUE) { | ||||
| 			if (configInt != 0) { | ||||
| 		if (config_lookup_bool(config, "application.tunnelmode.nativeframe", &configBool) == CONFIG_TRUE) { | ||||
| 			if (configBool != 0) { | ||||
| 				g_wtp.mactunnel.mode |= CAPWAP_WTP_NATIVE_FRAME_TUNNEL; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (config_lookup_bool(config, "application.tunnelmode.ethframe", &configInt) == CONFIG_TRUE) { | ||||
| 			if (configInt != 0) { | ||||
| 		if (config_lookup_bool(config, "application.tunnelmode.ethframe", &configBool) == CONFIG_TRUE) { | ||||
| 			if (configBool != 0) { | ||||
| 				g_wtp.mactunnel.mode |=  CAPWAP_WTP_8023_FRAME_TUNNEL; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (config_lookup_bool(config, "application.tunnelmode.localbridging", &configInt) == CONFIG_TRUE) { | ||||
| 			if (configInt != 0) { | ||||
| 		if (config_lookup_bool(config, "application.tunnelmode.localbridging", &configBool) == CONFIG_TRUE) { | ||||
| 			if (configBool != 0) { | ||||
| 				g_wtp.mactunnel.mode |=  CAPWAP_WTP_LOCAL_BRIDGING; | ||||
| 			} | ||||
| 		} | ||||
| @ -655,8 +666,8 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	} | ||||
|  | ||||
| 	/* Set VendorID Boardinfo of WTP */ | ||||
| 	if (config_lookup_int(config, "application.boardinfo.idvendor", &configLongInt) == CONFIG_TRUE) { | ||||
| 		g_wtp.boarddata.vendor = (unsigned long)configLongInt; | ||||
| 	if (config_lookup_int(config, "application.boardinfo.idvendor", &configInt) == CONFIG_TRUE) { | ||||
| 		g_wtp.boarddata.vendor = (unsigned long)configInt; | ||||
| 	} | ||||
|  | ||||
| 	/* Set Element Boardinfo of WTP */ | ||||
| @ -769,22 +780,48 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 							radio = wtp_radio_create_phy(); | ||||
| 							strcpy(radio->device, configString); | ||||
|  | ||||
| 							if (config_setting_lookup_bool(configElement, "enabled", &configInt) == CONFIG_TRUE) { | ||||
| 								if (configInt) { | ||||
| 							if (config_setting_lookup_bool(configElement, "enabled", &configBool) == CONFIG_TRUE) { | ||||
| 								if (configBool) { | ||||
| 									/* Retrieve radio capability */ | ||||
| 									if (wtp_parsing_radio_configuration(configElement, radio)) { | ||||
| 										/* Initialize radio device */ | ||||
| 										if (config_setting_lookup_string(configElement, "driver", &configString) == CONFIG_TRUE) { | ||||
| 											if (*configString && (strlen(configString) < WIFI_DRIVER_NAME_SIZE)) { | ||||
| 												result = wifi_device_connect(radio->radioid, radio->device, configString); | ||||
| 												if (!result) { | ||||
| 												radio->devicehandle = wifi_device_connect(radio->device, configString); | ||||
| 												if (radio->devicehandle) { | ||||
| 													radio->status = WTP_RADIO_ENABLED; | ||||
| 													capwap_logging_info("Register radioid %d with radio device: %s - %s", radio->radioid, radio->device, configString); | ||||
|  | ||||
| 													/* Update radio capability with device query */ | ||||
| 													capability = wifi_device_getcapability(radio->radioid); | ||||
| 													capability = wifi_device_getcapability(radio->devicehandle); | ||||
| 													if (capability) { | ||||
| 														/* TODO */ | ||||
| 														uint8_t bssid; | ||||
| 														char wlanname[IFNAMSIZ]; | ||||
| 														struct capwap_list_item* itemwlan; | ||||
| 														struct wtp_radio_wlanpool* wlanpool; | ||||
|  | ||||
| 														/* Create interface */ | ||||
| 														for (bssid = 0; bssid < radio->radioconfig.maxbssid; bssid++) { | ||||
| 															sprintf(wlanname, "%s%02d.%02d", radio->wlanprefix, (int)radio->radioid, (int)bssid + 1); | ||||
| 															if (wifi_iface_index(wlanname)) { | ||||
| 																capwap_logging_error("interface %s already exists", wlanname); | ||||
| 																return 0; | ||||
| 															} | ||||
|  | ||||
| 															/* */ | ||||
| 															itemwlan = capwap_itemlist_create(sizeof(struct wtp_radio_wlanpool)); | ||||
| 															wlanpool = (struct wtp_radio_wlanpool*)itemwlan->item; | ||||
| 															wlanpool->radio = radio; | ||||
| 															wlanpool->wlanhandle = wifi_wlan_create(radio->devicehandle, wlanname); | ||||
| 															if (!wlanpool->wlanhandle) { | ||||
| 																capwap_logging_error("Unable to create interface: %s", wlanname); | ||||
| 																return 0; | ||||
| 															} | ||||
|  | ||||
| 															/* Appent to wlan pool */ | ||||
| 															capwap_logging_debug("Created wlan interface: %s", wlanname); | ||||
| 															capwap_itemlist_insert_after(radio->wlanpool, NULL, itemwlan); | ||||
| 														} | ||||
| 													} | ||||
| 												} else { | ||||
| 													radio->status = WTP_RADIO_HWFAILURE; | ||||
| @ -855,7 +892,7 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 		for (i = 0; i < count; i++) { | ||||
| 			config_setting_t* configElement = config_setting_get_elem(configSetting, i); | ||||
| 			if (configElement != NULL) { | ||||
| 				long int configVendor; | ||||
| 				LIBCONFIG_LOOKUP_INT_ARG configVendor; | ||||
| 				if (config_setting_lookup_int(configElement, "idvendor", &configVendor) == CONFIG_TRUE) { | ||||
| 					const char* configType; | ||||
| 					if (config_setting_lookup_string(configElement, "type", &configType) == CONFIG_TRUE) { | ||||
| @ -916,9 +953,9 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	} | ||||
|  | ||||
| 	/* Set Timer of WTP */ | ||||
| 	if (config_lookup_int(config, "application.timer.statistics", &configLongInt) == CONFIG_TRUE) { | ||||
| 		if ((configLongInt > 0) && (configLongInt < 65536)) { | ||||
| 			g_wtp.statisticstimer.timer = (unsigned short)configLongInt; | ||||
| 	if (config_lookup_int(config, "application.timer.statistics", &configInt) == CONFIG_TRUE) { | ||||
| 		if ((configInt > 0) && (configInt < 65536)) { | ||||
| 			g_wtp.statisticstimer.timer = (unsigned short)configInt; | ||||
| 		} else { | ||||
| 			capwap_logging_error("Invalid configuration file, invalid application.timer.statistics value"); | ||||
| 			return 0; | ||||
| @ -926,8 +963,8 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	} | ||||
|  | ||||
| 	/* Set DTLS of WTP */ | ||||
| 	if (config_lookup_bool(config, "application.dtls.enable", &configInt) == CONFIG_TRUE) { | ||||
| 		if (configInt != 0) { | ||||
| 	if (config_lookup_bool(config, "application.dtls.enable", &configBool) == CONFIG_TRUE) { | ||||
| 		if (configBool != 0) { | ||||
| 			struct capwap_dtls_param dtlsparam; | ||||
|  | ||||
| 			/* Init dtls param */ | ||||
| @ -937,14 +974,14 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 			/* Set DTLS Policy of WTP */ | ||||
| 			if (config_lookup(config, "application.dtls.dtlspolicy") != NULL) { | ||||
| 				g_wtp.validdtlsdatapolicy = 0; | ||||
| 				if (config_lookup_bool(config, "application.dtls.dtlspolicy.cleardatachannel", &configInt) == CONFIG_TRUE) { | ||||
| 					if (configInt != 0) { | ||||
| 				if (config_lookup_bool(config, "application.dtls.dtlspolicy.cleardatachannel", &configBool) == CONFIG_TRUE) { | ||||
| 					if (configBool != 0) { | ||||
| 						g_wtp.validdtlsdatapolicy |= CAPWAP_ACDESC_CLEAR_DATA_CHANNEL_ENABLED; | ||||
| 					} | ||||
| 				} | ||||
| 		 | ||||
| 				if (config_lookup_bool(config, "application.dtls.dtlspolicy.dtlsdatachannel", &configInt) == CONFIG_TRUE) { | ||||
| 					if (configInt != 0) { | ||||
| 				if (config_lookup_bool(config, "application.dtls.dtlspolicy.dtlsdatachannel", &configBool) == CONFIG_TRUE) { | ||||
| 					if (configBool != 0) { | ||||
| 						g_wtp.validdtlsdatapolicy |= CAPWAP_ACDESC_DTLS_DATA_CHANNEL_ENABLED; | ||||
| 					} | ||||
| 				} | ||||
| @ -1058,9 +1095,9 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	} | ||||
|  | ||||
| 	/* Set mtu of WTP */ | ||||
| 	if (config_lookup_int(config, "application.network.mtu", &configLongInt) == CONFIG_TRUE) { | ||||
| 		if ((configLongInt > 0) && (configLongInt < 65536)) { | ||||
| 			g_wtp.mtu = (unsigned short)configLongInt; | ||||
| 	if (config_lookup_int(config, "application.network.mtu", &configInt) == CONFIG_TRUE) { | ||||
| 		if ((configInt > 0) && (configInt < 65536)) { | ||||
| 			g_wtp.mtu = (unsigned short)configInt; | ||||
| 		} else { | ||||
| 			capwap_logging_error("Invalid configuration file, invalid application.network.mtu value"); | ||||
| 			return 0; | ||||
| @ -1068,9 +1105,9 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	} | ||||
|  | ||||
| 	/* Set network port of WTP */ | ||||
| 	if (config_lookup_int(config, "application.network.port", &configLongInt) == CONFIG_TRUE) { | ||||
| 		if ((configLongInt > 0) && (configLongInt < 65535)) { | ||||
| 			g_wtp.net.bind_sock_ctrl_port = (unsigned short)configLongInt; | ||||
| 	if (config_lookup_int(config, "application.network.port", &configInt) == CONFIG_TRUE) { | ||||
| 		if ((configInt > 0) && (configInt < 65535)) { | ||||
| 			g_wtp.net.bind_sock_ctrl_port = (unsigned short)configInt; | ||||
| 		} else { | ||||
| 			capwap_logging_error("Invalid configuration file, invalid application.network.port value"); | ||||
| 			return 0; | ||||
| @ -1108,8 +1145,8 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	} | ||||
|  | ||||
| 	/* Set ip dual stack of WTP */ | ||||
| 	if (config_lookup_bool(config, "application.network.ipdualstack", &configInt) == CONFIG_TRUE) { | ||||
| 		if (!configInt) { | ||||
| 	if (config_lookup_bool(config, "application.network.ipdualstack", &configBool) == CONFIG_TRUE) { | ||||
| 		if (!configBool) { | ||||
| 			g_wtp.net.bind_ctrl_flags |= CAPWAP_IPV6ONLY_FLAG; | ||||
| 			g_wtp.net.bind_data_flags |= CAPWAP_IPV6ONLY_FLAG; | ||||
| 		} else { | ||||
| @ -1119,8 +1156,8 @@ static int wtp_parsing_configuration_1_0(config_t* config) { | ||||
| 	} | ||||
|  | ||||
| 	/* Set search discovery of WTP */ | ||||
| 	if (config_lookup_bool(config, "application.acdiscovery.search", &configInt) == CONFIG_TRUE) { | ||||
| 		g_wtp.acdiscoveryrequest = (configInt ? 1 : 0); | ||||
| 	if (config_lookup_bool(config, "application.acdiscovery.search", &configBool) == CONFIG_TRUE) { | ||||
| 		g_wtp.acdiscoveryrequest = (configBool ? 1 : 0); | ||||
| 	} | ||||
|  | ||||
| 	/* Set discovery host of WTP */ | ||||
| @ -1271,12 +1308,54 @@ static int wtp_configure(void) { | ||||
| 	return CAPWAP_SUCCESSFUL; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| static void wtp_wait_radio_ready(void) { | ||||
| 	int index; | ||||
| 	struct wtp_fds fds; | ||||
| 	struct timeout_control timeout; | ||||
|  | ||||
| 	/* Get only radio file descriptor */ | ||||
| 	memset(&fds, 0, sizeof(struct wtp_fds)); | ||||
| 	wtp_radio_update_fdevent(&fds); | ||||
| 	capwap_init_timeout(&timeout); | ||||
|  | ||||
| 	for (;;) { | ||||
| 		capwap_set_timeout(WTP_WAIT_RADIO_INITIALIZATION, &timeout, CAPWAP_TIMER_CONTROL_CONNECTION); | ||||
|  | ||||
| 		/* Wait packet */ | ||||
| 		index = capwap_wait_recvready(fds.fdspoll, fds.fdstotalcount, &timeout); | ||||
| 		if (index < 0) { | ||||
| 			break; | ||||
| 		} else if (!fds.events[index].event_handler) { | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		fds.events[index].event_handler(fds.fdspoll[index].fd, fds.events[index].params, fds.events[index].paramscount); | ||||
| 	} | ||||
|  | ||||
| 	/* */ | ||||
| 	wtp_free_fds(&fds); | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| int wtp_update_radio_in_use() { | ||||
| 	/* TODO */ | ||||
| 	return g_wtp.radios->count; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| void wtp_free_fds(struct wtp_fds* fds) { | ||||
| 	ASSERT(fds != NULL); | ||||
|  | ||||
| 	if (fds->fdspoll) { | ||||
| 		capwap_free(fds->fdspoll); | ||||
| 	} | ||||
|  | ||||
| 	if (fds->events) { | ||||
| 		capwap_free(fds->events); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Main*/ | ||||
| int main(int argc, char** argv) { | ||||
| 	int value; | ||||
| @ -1319,6 +1398,11 @@ int main(int argc, char** argv) { | ||||
| 						capwap_logging_info("Running WTP in daemon mode"); | ||||
| 					} | ||||
|  | ||||
| 					/* Wait the initialization of radio interfaces */ | ||||
| 					capwap_logging_info("Wait the initialization of radio interfaces"); | ||||
| 					wtp_wait_radio_ready(); | ||||
|  | ||||
| 					/* */ | ||||
| 					capwap_logging_info("Startup WTP"); | ||||
|  | ||||
| 					/* Complete configuration WTP */ | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
| #include "capwap_network.h" | ||||
| #include "capwap_protocol.h" | ||||
| #include "wifi_drivers.h" | ||||
| #include "wtp_radio.h" | ||||
|  | ||||
| /* WTP Configuration */ | ||||
| #define WTP_STANDARD_CONFIGURATION_FILE					"/etc/capwap/wtp.conf" | ||||
| @ -74,6 +73,16 @@ struct wtp_state { | ||||
| 	int rfcDTLSSessionDelete; | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| struct wtp_fds { | ||||
| 	struct pollfd* fdspoll; | ||||
| 	int fdstotalcount; | ||||
| 	int fdsnetworkcount; | ||||
|  | ||||
| 	struct wifi_event* events; | ||||
| 	int eventscount; | ||||
| }; | ||||
|  | ||||
| /* WTP */ | ||||
| struct wtp_t { | ||||
| 	int standalone; | ||||
| @ -83,9 +92,7 @@ struct wtp_t { | ||||
|  | ||||
| 	/* */ | ||||
| 	struct capwap_network net; | ||||
| 	struct pollfd* fds; | ||||
| 	int fdstotalcount; | ||||
| 	int fdsnetworkcount; | ||||
| 	struct wtp_fds fds; | ||||
|  | ||||
| 	/* */ | ||||
| 	struct wtp_state dfa; | ||||
| @ -137,8 +144,6 @@ struct wtp_t { | ||||
|  | ||||
| 	/* */ | ||||
| 	struct capwap_array* radios; | ||||
| 	struct wifi_event* events; | ||||
| 	int eventscount; | ||||
|  | ||||
| 	/* Radio ACL  */ | ||||
| 	int defaultaclstations; | ||||
| @ -158,6 +163,7 @@ extern struct wtp_t g_wtp; | ||||
|  | ||||
| /* */ | ||||
| int wtp_update_radio_in_use(); | ||||
| void wtp_free_fds(struct wtp_fds* fds); | ||||
|  | ||||
| /* Build capwap element helper */ | ||||
| void wtp_create_radioadmstate_element(struct capwap_packet_txmng* txmngpacket); | ||||
|  | ||||
| @ -150,11 +150,12 @@ static void wtp_dfa_execute(struct capwap_parsed_packet* packet, struct timeout_ | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| static int wtp_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr, struct timeout_control* timeout) { | ||||
| static int wtp_recvfrom(struct wtp_fds* fds, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr, struct timeout_control* timeout) { | ||||
| 	int index; | ||||
|  | ||||
| 	ASSERT(fds); | ||||
| 	ASSERT(fdscount > 0); | ||||
| 	ASSERT(fds != NULL); | ||||
| 	ASSERT(fds->fdspoll != NULL); | ||||
| 	ASSERT(fds->fdstotalcount > 0); | ||||
| 	ASSERT(buffer != NULL); | ||||
| 	ASSERT(size != NULL); | ||||
| 	ASSERT(*size > 0); | ||||
| @ -162,31 +163,49 @@ static int wtp_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* siz | ||||
| 	ASSERT(recvtoaddr != NULL); | ||||
|  | ||||
| 	/* Wait packet */ | ||||
| 	index = capwap_wait_recvready(fds, fdscount, timeout); | ||||
| 	index = capwap_wait_recvready(fds->fdspoll, fds->fdstotalcount, timeout); | ||||
| 	if (index < 0) { | ||||
| 		return index; | ||||
| 	} else if (index >= g_wtp.fdsnetworkcount) { | ||||
| 		int pos = index - g_wtp.fdsnetworkcount; | ||||
| 	} else if (index >= fds->fdsnetworkcount) { | ||||
| 		int pos = index - fds->fdsnetworkcount; | ||||
|  | ||||
| 		if (pos < g_wtp.eventscount) { | ||||
| 			if (!g_wtp.events[pos].event_handler) { | ||||
| 		if (pos < fds->eventscount) { | ||||
| 			if (!fds->events[pos].event_handler) { | ||||
| 				return CAPWAP_RECV_ERROR_SOCKET; | ||||
| 			} | ||||
|  | ||||
| 			g_wtp.events[pos].event_handler(fds[index].fd, g_wtp.events[pos].param1, g_wtp.events[pos].param2); | ||||
| 			fds->events[pos].event_handler(fds->fdspoll[index].fd, fds->events[pos].params, fds->events[pos].paramscount); | ||||
| 		} | ||||
|  | ||||
| 		return WTP_RECV_NOERROR_RADIO; | ||||
| 	} | ||||
|  | ||||
| 	/* Receive packet */ | ||||
| 	if (!capwap_recvfrom_fd(fds[index].fd, buffer, size, recvfromaddr, recvtoaddr)) { | ||||
| 	if (!capwap_recvfrom_fd(fds->fdspoll[index].fd, buffer, size, recvfromaddr, recvtoaddr)) { | ||||
| 		return CAPWAP_RECV_ERROR_SOCKET; | ||||
| 	} | ||||
|  | ||||
| 	return index; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| static void wtp_dfa_init_fdspool(struct wtp_fds* fds, struct capwap_network* net) { | ||||
| 	ASSERT(fds != NULL); | ||||
| 	ASSERT(net != NULL); | ||||
|  | ||||
| 	/* */ | ||||
| 	memset(fds, 0, sizeof(struct wtp_fds)); | ||||
| 	fds->fdstotalcount = CAPWAP_MAX_SOCKETS * 2; | ||||
| 	fds->fdspoll = (struct pollfd*)capwap_alloc(sizeof(struct pollfd) * fds->fdstotalcount); | ||||
|  | ||||
| 	/* Retrive all socket for polling */ | ||||
| 	fds->fdsnetworkcount = capwap_network_set_pollfd(net, fds->fdspoll, fds->fdstotalcount); | ||||
| 	fds->fdstotalcount = fds->fdsnetworkcount; | ||||
|  | ||||
| 	/* Update Event File Descriptor */ | ||||
| 	wtp_radio_update_fdevent(fds); | ||||
| } | ||||
|  | ||||
| /* WTP state machine */ | ||||
| int wtp_dfa_running(void) { | ||||
| 	int res; | ||||
| @ -209,21 +228,13 @@ int wtp_dfa_running(void) { | ||||
|  | ||||
| 	/* Init */ | ||||
| 	capwap_init_timeout(&timeout); | ||||
| 	capwap_set_timeout(0, &timeout, CAPWAP_TIMER_CONTROL_CONNECTION);	/* Start DFA with timeout */ | ||||
|  | ||||
| 	memset(&packet, 0, sizeof(struct capwap_parsed_packet)); | ||||
|  | ||||
| 	/* Start DFA with timeout */ | ||||
| 	capwap_set_timeout(0, &timeout, CAPWAP_TIMER_CONTROL_CONNECTION); | ||||
|  | ||||
| 	/* Configure poll struct */ | ||||
| 	g_wtp.fdstotalcount = CAPWAP_MAX_SOCKETS * 2; | ||||
| 	g_wtp.fds = (struct pollfd*)capwap_alloc(sizeof(struct pollfd) * g_wtp.fdstotalcount); | ||||
|  | ||||
| 	/* Retrive all socket for polling */ | ||||
| 	g_wtp.fdsnetworkcount = capwap_network_set_pollfd(&g_wtp.net, g_wtp.fds, g_wtp.fdstotalcount); | ||||
| 	g_wtp.fdstotalcount = g_wtp.fdsnetworkcount; | ||||
| 	ASSERT(g_wtp.fdstotalcount > 0); | ||||
|  | ||||
| 	/* Update Event File Descriptor */ | ||||
| 	wtp_radio_update_fdevent(); | ||||
| 	wtp_dfa_init_fdspool(&g_wtp.fds, &g_wtp.net); | ||||
|  | ||||
| 	/* Handler signal */ | ||||
| 	g_wtp.running = 1; | ||||
| @ -241,7 +252,7 @@ int wtp_dfa_running(void) { | ||||
| 		isrecvpacket = 0; | ||||
| 		buffer = bufferencrypt; | ||||
| 		buffersize = CAPWAP_MAX_PACKET_SIZE; | ||||
| 		index = wtp_recvfrom(g_wtp.fds, g_wtp.fdstotalcount, buffer, &buffersize, &recvfromaddr, &recvtoaddr, &timeout); | ||||
| 		index = wtp_recvfrom(&g_wtp.fds, buffer, &buffersize, &recvfromaddr, &recvtoaddr, &timeout); | ||||
| 		if (!g_wtp.running) { | ||||
| 			capwap_logging_debug("Closing WTP, Teardown connection"); | ||||
|  | ||||
| @ -261,7 +272,7 @@ int wtp_dfa_running(void) { | ||||
| 				int check; | ||||
|  | ||||
| 				/* Retrieve network information */ | ||||
| 				capwap_get_network_socket(&g_wtp.net, &socket, g_wtp.fds[index].fd); | ||||
| 				capwap_get_network_socket(&g_wtp.net, &socket, g_wtp.fds.fdspoll[index].fd); | ||||
|  | ||||
| 				/* Check source */ | ||||
| 				if (socket.isctrlsocket && (g_wtp.acctrladdress.ss_family != AF_UNSPEC)) { | ||||
| @ -339,7 +350,7 @@ int wtp_dfa_running(void) { | ||||
| 							socklen_t sockinfolen = sizeof(struct sockaddr_storage); | ||||
|  | ||||
| 							memset(&sockinfo, 0, sizeof(struct sockaddr_storage)); | ||||
| 							if (getsockname(g_wtp.fds[index].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) { | ||||
| 							if (getsockname(g_wtp.fds.fdspoll[index].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) { | ||||
| 								break;  | ||||
| 							} | ||||
|  | ||||
| @ -447,7 +458,7 @@ int wtp_dfa_running(void) { | ||||
| 	} | ||||
|  | ||||
| 	/* Free memory */ | ||||
| 	capwap_free(g_wtp.fds); | ||||
| 	wtp_free_fds(&g_wtp.fds); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @ -4,6 +4,7 @@ | ||||
| #include "capwap_array.h" | ||||
| #include "capwap_list.h" | ||||
| #include "wtp_dfa.h" | ||||
| #include "wtp_radio.h" | ||||
|  | ||||
| /* */ | ||||
| void wtp_send_configure(struct timeout_control* timeout) { | ||||
|  | ||||
| @ -4,6 +4,7 @@ | ||||
| #include "capwap_array.h" | ||||
| #include "capwap_list.h" | ||||
| #include "wtp_dfa.h" | ||||
| #include "wtp_radio.h" | ||||
|  | ||||
| /* */ | ||||
| void wtp_send_join(struct timeout_control* timeout) { | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| #include "capwap_dfa.h" | ||||
| #include "capwap_element.h" | ||||
| #include "wtp_dfa.h" | ||||
| #include "wtp_radio.h" | ||||
|  | ||||
| /* */ | ||||
| static int send_echo_request() { | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| #include "wtp.h" | ||||
| #include "wtp_radio.h" | ||||
|  | ||||
| /* */ | ||||
| void wtp_create_radioopsstate_element(struct capwap_packet_txmng* txmngpacket) { | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| #include "wtp.h" | ||||
| #include "capwap_hash.h" | ||||
| #include "capwap_list.h" | ||||
| #include "wtp_radio.h" | ||||
|  | ||||
| /* */ | ||||
| @ -27,7 +28,7 @@ static int wtp_radio_configure_phy(struct wtp_radio* radio) { | ||||
| 		memcpy(radio->rateset.rateset, radio->supportedrates.supportedrates, CAPWAP_RATESET_MAXLENGTH); | ||||
|  | ||||
| 		/* Update rates */ | ||||
| 		if (wifi_device_updaterates(radio->radioid)) { | ||||
| 		if (wifi_device_updaterates(radio->devicehandle, radio->rateset.rateset, radio->rateset.ratesetcount)) { | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| @ -48,23 +49,6 @@ static int wtp_radio_configure_phy(struct wtp_radio* radio) { | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| static void wtp_radio_destroy_wlan(struct wtp_radio_wlan* wlan) { | ||||
| 	if (wlan->wlanid && wlan->radio) { | ||||
| 		if (wlan->state != WTP_RADIO_WLAN_STATE_IDLE) { | ||||
| 			if (wlan->state == WTP_RADIO_WLAN_STATE_AP) { | ||||
| 				wifi_wlan_stopap(wlan->radio->radioid, wlan->wlanid); | ||||
| 			} | ||||
|  | ||||
| 			/* Destroy interface */ | ||||
| 			wifi_wlan_destroy(wlan->radio->radioid, wlan->wlanid); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Release item */ | ||||
| 	memset(wlan, 0, sizeof(struct wtp_radio_wlan)); | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| unsigned long wtp_radio_acl_item_gethash(const void* key, unsigned long keysize, unsigned long hashsize) { | ||||
| 	uint8_t* macaddress = (uint8_t*)key; | ||||
| @ -84,7 +68,8 @@ void wtp_radio_init(void) { | ||||
|  | ||||
| /* */ | ||||
| void wtp_radio_close(void) { | ||||
| 	int i, j; | ||||
| 	int i; | ||||
| 	struct capwap_list_item* itemwlan; | ||||
|  | ||||
| 	ASSERT(g_wtp.radios != NULL); | ||||
|  | ||||
| @ -96,11 +81,29 @@ void wtp_radio_close(void) { | ||||
| 		} | ||||
|  | ||||
| 		if (radio->wlan) { | ||||
| 			for (j = 0; j < radio->wlan->count; j++) { | ||||
| 				wtp_radio_destroy_wlan((struct wtp_radio_wlan*)capwap_array_get_item_pointer(radio->wlan, j)); | ||||
| 			for (itemwlan = radio->wlan->first; itemwlan != NULL; itemwlan = itemwlan->next) { | ||||
| 				struct wtp_radio_wlan* wlan = (struct wtp_radio_wlan*)itemwlan->item; | ||||
|  | ||||
| 				/* Destroy BSS interface */ | ||||
| 				if (wlan->wlanhandle) { | ||||
| 					wifi_wlan_destroy(wlan->wlanhandle); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			capwap_array_free(radio->wlan); | ||||
| 			capwap_list_free(radio->wlan); | ||||
| 		} | ||||
|  | ||||
| 		if (radio->wlanpool) { | ||||
| 			for (itemwlan = radio->wlanpool->first; itemwlan != NULL; itemwlan = itemwlan->next) { | ||||
| 				struct wtp_radio_wlanpool* wlanpool = (struct wtp_radio_wlanpool*)itemwlan->item; | ||||
|  | ||||
| 				/* Destroy BSS interface */ | ||||
| 				if (wlanpool->wlanhandle) { | ||||
| 					wifi_wlan_destroy(wlanpool->wlanhandle); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			capwap_list_free(radio->wlanpool); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -110,10 +113,9 @@ void wtp_radio_close(void) { | ||||
| /* */ | ||||
| void wtp_radio_free(void) { | ||||
| 	ASSERT(g_wtp.radios != NULL); | ||||
| 	ASSERT(g_wtp.radios->count == 0); | ||||
|  | ||||
| 	if (g_wtp.events) { | ||||
| 		capwap_free(g_wtp.events); | ||||
| 	if (g_wtp.radios->count > 0) { | ||||
| 		wtp_radio_close(); | ||||
| 	} | ||||
|  | ||||
| 	capwap_array_free(g_wtp.radios); | ||||
| @ -125,7 +127,6 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet) { | ||||
| 	int i; | ||||
| 	int result = 0; | ||||
| 	unsigned short binding; | ||||
| 	struct wtp_radio* radio; | ||||
| 	struct capwap_array* messageelements; | ||||
| 	struct capwap_array* updateitems; | ||||
| 	struct wtp_update_configuration_item* item; | ||||
| @ -138,6 +139,7 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet) { | ||||
| 	/* */ | ||||
| 	binding = GET_WBID_HEADER(packet->rxmngpacket->header); | ||||
| 	if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) { | ||||
| 		struct wtp_radio* radio; | ||||
| 		struct capwap_list_item* search; | ||||
|  | ||||
| 		/* Set radio configuration and invalidate the old values */ | ||||
| @ -422,12 +424,12 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet) { | ||||
|  | ||||
| 		switch (item->type) { | ||||
| 			case WTP_UPDATE_FREQUENCY_DSSS: { | ||||
| 				result = wifi_device_setfrequency(item->radio->radioid, WIFI_BAND_2GHZ, item->radio->radioinformation.radiotype, item->radio->directsequencecontrol.currentchannel); | ||||
| 				result = wifi_device_setfrequency(item->radio->devicehandle, WIFI_BAND_2GHZ, item->radio->radioinformation.radiotype, item->radio->directsequencecontrol.currentchannel); | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			case WTP_UPDATE_FREQUENCY_OFDM: { | ||||
| 				result = wifi_device_setfrequency(item->radio->radioid, WIFI_BAND_5GHZ, item->radio->radioinformation.radiotype, item->radio->ofdmcontrol.currentchannel); | ||||
| 				result = wifi_device_setfrequency(item->radio->devicehandle, WIFI_BAND_5GHZ, item->radio->radioinformation.radiotype, item->radio->ofdmcontrol.currentchannel); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| @ -439,7 +441,7 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet) { | ||||
|  | ||||
| 		switch (item->type) { | ||||
| 			case WTP_UPDATE_RATES: { | ||||
| 				result = wifi_device_updaterates(radio->radioid); | ||||
| 				result = wifi_device_updaterates(item->radio->devicehandle, item->radio->rateset.rateset, item->radio->rateset.ratesetcount); | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| @ -453,7 +455,7 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet) { | ||||
| 				memcpy(params.bssid, item->radio->radioconfig.bssid, ETH_ALEN); | ||||
| 				params.beaconperiod = item->radio->radioconfig.beaconperiod; | ||||
| 				memcpy(params.country, item->radio->radioconfig.country, WIFI_COUNTRY_LENGTH); | ||||
| 				result = wifi_device_setconfiguration(item->radio->radioid, ¶ms); | ||||
| 				result = wifi_device_setconfiguration(item->radio->devicehandle, ¶ms); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| @ -474,7 +476,8 @@ struct wtp_radio* wtp_radio_create_phy(void) { | ||||
| 	radio->status = WTP_RADIO_DISABLED; | ||||
|  | ||||
| 	/* Init configuration radio */ | ||||
| 	radio->wlan = capwap_array_create(sizeof(struct wtp_radio_wlan), 0, 1); | ||||
| 	radio->wlan = capwap_list_create(); | ||||
| 	radio->wlanpool = capwap_list_create(); | ||||
| 	radio->antenna.selections = capwap_array_create(sizeof(uint8_t), 0, 1); | ||||
| 	return radio; | ||||
| } | ||||
| @ -483,8 +486,12 @@ struct wtp_radio* wtp_radio_create_phy(void) { | ||||
| struct wtp_radio* wtp_radio_get_phy(uint8_t radioid) { | ||||
| 	int i; | ||||
|  | ||||
| 	ASSERT(IS_VALID_RADIOID(radioid)); | ||||
| 	/* Check */ | ||||
| 	if (!IS_VALID_RADIOID(radioid)) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Retrieve radio */ | ||||
| 	for (i = 0; i < g_wtp.radios->count; i++) { | ||||
| 		struct wtp_radio* radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i); | ||||
| 		if (radioid == radio->radioid) { | ||||
| @ -497,13 +504,19 @@ struct wtp_radio* wtp_radio_get_phy(uint8_t radioid) { | ||||
|  | ||||
| /* */ | ||||
| struct wtp_radio_wlan* wtp_radio_get_wlan(struct wtp_radio* radio, uint8_t wlanid) { | ||||
| 	int i; | ||||
| 	struct capwap_list_item* itemwlan; | ||||
|  | ||||
| 	ASSERT(IS_VALID_WLANID(wlanid)); | ||||
| 	ASSERT(radio != NULL); | ||||
|  | ||||
| 	for (i = 0; i < radio->wlan->count; i++) { | ||||
| 		struct wtp_radio_wlan* wlan = (struct wtp_radio_wlan*)capwap_array_get_item_pointer(radio->wlan, i); | ||||
| 		if ((wlanid == wlan->wlanid) && (radio == wlan->radio)) { | ||||
| 	/* Check */ | ||||
| 	if (!IS_VALID_WLANID(wlanid)) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Retrieve BSS */ | ||||
| 	for (itemwlan = radio->wlan->first; itemwlan != NULL; itemwlan = itemwlan->next) { | ||||
| 		struct wtp_radio_wlan* wlan = (struct wtp_radio_wlan*)itemwlan->item; | ||||
| 		if (wlanid == wlan->wlanid) { | ||||
| 			return wlan; | ||||
| 		} | ||||
| 	} | ||||
| @ -512,8 +525,11 @@ struct wtp_radio_wlan* wtp_radio_get_wlan(struct wtp_radio* radio, uint8_t wlani | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| void wtp_radio_update_fdevent(void) { | ||||
| void wtp_radio_update_fdevent(struct wtp_fds* fds) { | ||||
| 	int count; | ||||
| 	struct pollfd* fdsbuffer; | ||||
|  | ||||
| 	ASSERT(fds != NULL); | ||||
|  | ||||
| 	/* Retrieve number of File Descriptor Event */ | ||||
| 	count = wifi_event_getfd(NULL, NULL, 0); | ||||
| @ -521,41 +537,43 @@ void wtp_radio_update_fdevent(void) { | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* */ | ||||
| 	if (g_wtp.eventscount != count) { | ||||
| 		struct pollfd* fds; | ||||
|  | ||||
| 		/* Resize poll */ | ||||
| 		fds = (struct pollfd*)capwap_alloc(sizeof(struct pollfd) * (g_wtp.fdsnetworkcount + count)); | ||||
| 		memcpy(fds, g_wtp.fds, sizeof(struct pollfd) * g_wtp.fdsnetworkcount); | ||||
| 		capwap_free(g_wtp.fds); | ||||
| 		g_wtp.fds = fds; | ||||
|  | ||||
| 		/* Events Callback */ | ||||
| 		if (g_wtp.events) { | ||||
| 			capwap_free(g_wtp.events); | ||||
| 	/* Resize poll */ | ||||
| 	if (fds->eventscount != count) { | ||||
| 		fdsbuffer = (struct pollfd*)capwap_alloc(sizeof(struct pollfd) * (fds->fdsnetworkcount + count)); | ||||
| 		if (fds->fdspoll && (fds->fdsnetworkcount > 0)) { | ||||
| 			memcpy(fdsbuffer, fds->fdspoll, sizeof(struct pollfd) * fds->fdsnetworkcount); | ||||
| 			capwap_free(fds->fdspoll); | ||||
| 		} | ||||
|  | ||||
| 		g_wtp.events = (struct wifi_event*)((count > 0) ? capwap_alloc(sizeof(struct wifi_event) * count) : NULL); | ||||
| 		fds->fdspoll = fdsbuffer; | ||||
|  | ||||
| 		/* Events Callback */ | ||||
| 		if (fds->events) { | ||||
| 			capwap_free(fds->events); | ||||
| 		} | ||||
|  | ||||
| 		fds->events = (struct wifi_event*)((count > 0) ? capwap_alloc(sizeof(struct wifi_event) * count) : NULL); | ||||
|  | ||||
| 		/* */ | ||||
| 		g_wtp.eventscount = count; | ||||
| 		g_wtp.fdstotalcount = g_wtp.fdsnetworkcount + g_wtp.eventscount; | ||||
| 		fds->eventscount = count; | ||||
| 		fds->fdstotalcount = fds->fdsnetworkcount + count; | ||||
| 	} | ||||
|  | ||||
| 	/* Retrieve File Descriptor Event */ | ||||
| 	if (count > 0) { | ||||
| 		count = wifi_event_getfd(&g_wtp.fds[g_wtp.fdsnetworkcount], g_wtp.events, g_wtp.eventscount); | ||||
| 		ASSERT(g_wtp.eventscount == count); | ||||
| 		ASSERT(fds->fdspoll != NULL); | ||||
| 		wifi_event_getfd(&fds->fdspoll[fds->fdsnetworkcount], fds->events, fds->eventscount); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* */ | ||||
| uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwap_80211_assignbssid_element* bssid) { | ||||
| 	char wlanname[IFNAMSIZ]; | ||||
| 	struct wtp_radio* radio; | ||||
| 	struct wtp_radio_wlan* wlan; | ||||
| 	struct wifi_wlan_startap_params params; | ||||
| 	struct wtp_radio_wlanpool* wlanpool; | ||||
| 	struct capwap_list_item* itemwlan; | ||||
| 	struct capwap_list_item* itemwlanpool; | ||||
| 	struct wlan_startap_params params; | ||||
| 	struct capwap_80211_addwlan_element* addwlan; | ||||
|  | ||||
| 	/* Get message elements */ | ||||
| @ -576,6 +594,11 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwa | ||||
| 		return CAPWAP_RESULTCODE_FAILURE; | ||||
| 	} | ||||
|  | ||||
| 	/* Verify exist interface into pool */ | ||||
| 	if (!radio->wlanpool->first) { | ||||
| 		return CAPWAP_RESULTCODE_FAILURE; | ||||
| 	} | ||||
|  | ||||
| 	/* Prepare physical interface for create wlan */ | ||||
| 	if (!radio->wlan->count) { | ||||
| 		if (wtp_radio_configure_phy(radio)) { | ||||
| @ -583,51 +606,45 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwa | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Set virtual interface information */ | ||||
| 	wlan = (struct wtp_radio_wlan*)capwap_array_get_item_pointer(radio->wlan, radio->wlan->count); | ||||
| 	wlan->radio = radio; | ||||
| 	wlan->wlanid = addwlan->wlanid; | ||||
| 	sprintf(wlanname, "%s%02d.%02d", g_wtp.wlanprefix, (int)addwlan->radioid, (int)addwlan->wlanid); | ||||
| 	if (wifi_iface_index(wlanname)) { | ||||
| 		memset(wlan, 0, sizeof(struct wtp_radio_wlan)); | ||||
| 		return CAPWAP_RESULTCODE_FAILURE; | ||||
| 	} | ||||
|  | ||||
| 	/* Create virtual interface */ | ||||
| 	if (!wifi_wlan_create(addwlan->radioid, addwlan->wlanid, wlanname, NULL)) { | ||||
| 		wlan->state = WTP_RADIO_WLAN_STATE_CREATED; | ||||
| 	} else { | ||||
| 		wtp_radio_destroy_wlan(wlan); | ||||
| 		return CAPWAP_RESULTCODE_FAILURE; | ||||
| 	} | ||||
| 	/* Get interface from pool */ | ||||
| 	itemwlanpool = capwap_itemlist_remove_head(radio->wlanpool); | ||||
| 	wlanpool = (struct wtp_radio_wlanpool*)itemwlanpool->item; | ||||
|  | ||||
| 	/* Wlan configuration */ | ||||
| 	memset(¶ms, 0, sizeof(struct wifi_wlan_startap_params)); | ||||
| 	memset(¶ms, 0, sizeof(struct wlan_startap_params)); | ||||
| 	params.ssid = (const char*)addwlan->ssid; | ||||
| 	params.ssid_hidden = addwlan->suppressssid; | ||||
| 	params.capability = addwlan->capability; | ||||
| 	params.qos = addwlan->qos; | ||||
| 	params.authmode = addwlan->authmode; | ||||
| 	params.macmode = addwlan->macmode; | ||||
| 	params.tunnelmode = addwlan->tunnelmode; | ||||
| 	params.ssid_hidden = addwlan->suppressssid; | ||||
| 	strcpy(params.ssid, (const char*)addwlan->ssid); | ||||
|  | ||||
| 	/* TODO (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE) */ | ||||
|  | ||||
| 	/* Start AP */ | ||||
| 	if (!wifi_wlan_startap(addwlan->radioid, addwlan->wlanid, ¶ms)) { | ||||
| 		wlan->state = WTP_RADIO_WLAN_STATE_AP; | ||||
| 	} else { | ||||
| 		wtp_radio_destroy_wlan(wlan); | ||||
| 	if (wifi_wlan_startap(wlanpool->wlanhandle, ¶ms)) { | ||||
| 		capwap_itemlist_insert_before(radio->wlanpool, NULL, itemwlanpool); | ||||
| 		return CAPWAP_RESULTCODE_FAILURE; | ||||
| 	} | ||||
|  | ||||
| 	/* Move interface from pool to used */ | ||||
| 	itemwlan = capwap_itemlist_create(sizeof(struct wtp_radio_wlan)); | ||||
| 	wlan = (struct wtp_radio_wlan*)itemwlan->item; | ||||
| 	wlan->wlanid = addwlan->wlanid; | ||||
| 	wlan->wlanhandle = wlanpool->wlanhandle; | ||||
| 	wlan->radio = wlanpool->radio; | ||||
|  | ||||
| 	/* */ | ||||
| 	capwap_itemlist_free(itemwlanpool); | ||||
| 	capwap_itemlist_insert_after(radio->wlan, NULL, itemwlan); | ||||
|  | ||||
| 	/* Update Event File Descriptor */ | ||||
| 	wtp_radio_update_fdevent(); | ||||
| 	wtp_radio_update_fdevent(&g_wtp.fds); | ||||
|  | ||||
| 	/* Retrieve macaddress of new device */ | ||||
| 	bssid->radioid = addwlan->radioid; | ||||
| 	bssid->wlanid = addwlan->wlanid; | ||||
| 	wifi_wlan_getbssid(addwlan->radioid, addwlan->wlanid, bssid->bssid); | ||||
| 	wifi_wlan_getbssid(wlan->wlanhandle, bssid->bssid); | ||||
|  | ||||
| 	return CAPWAP_RESULTCODE_SUCCESS; | ||||
| } | ||||
|  | ||||
| @ -20,22 +20,27 @@ | ||||
| #define WTP_PREFIX_NAME_MAX_LENGTH			(IFNAMSIZ - 6) | ||||
| #define WTP_PREFIX_DEFAULT_NAME				"ap" | ||||
|  | ||||
| #define WTP_RADIO_WLAN_STATE_IDLE			0 | ||||
| #define WTP_RADIO_WLAN_STATE_CREATED		1 | ||||
| #define WTP_RADIO_WLAN_STATE_AP				2 | ||||
|  | ||||
| struct wtp_radio_wlan { | ||||
| 	struct wtp_radio* radio; | ||||
| 	int state; | ||||
| 	uint8_t wlanid; | ||||
| 	struct wifi_wlan* wlanhandle; | ||||
| 	struct wtp_radio* radio; | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| struct wtp_radio_wlanpool { | ||||
| 	struct wifi_wlan* wlanhandle; | ||||
| 	struct wtp_radio* radio; | ||||
| }; | ||||
|  | ||||
| /* */ | ||||
| struct wtp_radio { | ||||
| 	uint8_t radioid; | ||||
| 	char device[IFNAMSIZ]; | ||||
| 	struct wifi_device* devicehandle; | ||||
|  | ||||
| 	struct capwap_array* wlan; | ||||
| 	char wlanprefix[IFNAMSIZ]; | ||||
| 	struct capwap_list* wlan; | ||||
| 	struct capwap_list* wlanpool; | ||||
|  | ||||
| 	int status; | ||||
| 	struct capwap_80211_antenna_element antenna; | ||||
| @ -64,7 +69,7 @@ struct wtp_radio_wlan* wtp_radio_get_wlan(struct wtp_radio* radio, uint8_t wlani | ||||
|  | ||||
| /* */ | ||||
| int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet); | ||||
| void wtp_radio_update_fdevent(void); | ||||
| void wtp_radio_update_fdevent(struct wtp_fds* fds); | ||||
|  | ||||
| /* */ | ||||
| uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwap_80211_assignbssid_element* bssid); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user