Example #1
0
void wtp_radio_close(void)
{
	int i;

	ASSERT(g_wtp.radios != NULL);

	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 (radio->antenna.selections) {
			capwap_array_free(radio->antenna.selections);
		}

		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);

			/* Destroy BSS interface */
			if (wlan->wlanhandle)
				wifi_wlan_destroy(wlan->wlanhandle);

		}
		capwap_array_free(radio->wlan);
	}

	capwap_array_resize(g_wtp.radios, 0);
}
Example #2
0
static void capwap_acipv6list_element_free(void* data) {
	struct capwap_acipv6list_element* element = (struct capwap_acipv6list_element*)data;

	ASSERT(data != NULL);
	
	capwap_array_free(element->addresses);
	capwap_free(data);
}
static void capwap_80211_antenna_element_free(void* data) {
	struct capwap_80211_antenna_element* element = (struct capwap_80211_antenna_element*)data;

	ASSERT(data != NULL);
	ASSERT(element->selections != NULL);

	capwap_array_free(element->selections);
	capwap_free(data);
}
Example #4
0
void wtp_radio_free(void) {
	ASSERT(g_wtp.radios != NULL);

	if (g_wtp.radios->count > 0) {
		wtp_radio_close();
	}

	capwap_array_free(g_wtp.radios);
	capwap_hash_free(g_wtp.aclstations);
}
Example #5
0
static void capwap_acdescriptor_element_free(void* data) {
	int i;
	struct capwap_acdescriptor_element* element = (struct capwap_acdescriptor_element*)data;

	ASSERT(element != NULL);
	ASSERT(element->descsubelement != NULL);

	/* */
	for (i = 0; i < element->descsubelement->count; i++) {
		struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i);

		if (desc->data) {
			capwap_free(desc->data);
		}
	}

	capwap_array_free(element->descsubelement);
	capwap_free(data);
}
Example #6
0
void capwap_free_parsed_packet(struct capwap_parsed_packet* packet) {
	int i;
	struct capwap_list_item* itemlist;
	struct capwap_message_element_itemlist* messageelement;
	const struct capwap_message_elements_ops* msgops;

	ASSERT(packet != NULL);

	if (packet->rxmngpacket && packet->messages) {
		itemlist = packet->messages->first;
		while (itemlist) {
			messageelement = (struct capwap_message_element_itemlist*)itemlist->item;
			if (messageelement->data) {
				msgops = capwap_get_message_element_ops(messageelement->id);

				if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_SINGLE) {
					msgops->free(messageelement->data);
				} else if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_ARRAY) {
					struct capwap_array* arraymessageelement = (struct capwap_array*)messageelement->data;

					for (i = 0; i < arraymessageelement->count; i++) {
						msgops->free(*(void**)capwap_array_get_item_pointer(arraymessageelement, i));
					}

					/* */
					capwap_array_free(arraymessageelement);
				}
			}

			/* */
			itemlist = itemlist->next;
		}

		/* */
		packet->rxmngpacket = NULL;
		capwap_list_free(packet->messages);
		packet->messages = NULL;
	}
}
Example #7
0
/* Release reference of session */
static void ac_session_destroy(struct ac_session_t* session) {
#ifdef DEBUG
	char sessionname[33];
#endif

	ASSERT(session != NULL);

#ifdef DEBUG
	capwap_sessionid_printf(&session->sessionid, sessionname);
	capwap_logging_debug("Release Session AC %s", sessionname);
#endif

	/* Release last reference */
	capwap_lock_enter(&session->sessionlock);
	session->count--;

	/* Terminate SOAP request pending */
	if (session->soaprequest) {
		ac_soapclient_shutdown_request(session->soaprequest);
	}

	/* Check if all reference is release */
	while (session->count > 0) {
#ifdef DEBUG
		capwap_logging_debug("Wait for release Session AC %s (count=%d)", sessionname, session->count);
#endif
		/* */
		capwap_event_reset(&session->changereference);
		capwap_lock_exit(&session->sessionlock);

		/* Wait */
		capwap_event_wait(&session->changereference);

		capwap_lock_enter(&session->sessionlock);
	}

	capwap_lock_exit(&session->sessionlock);

	/* Close data channel */
	ac_kmod_delete_datasession(&session->sessionid);

	/* Free DTSL Control */
	capwap_crypt_freesession(&session->dtls);

	/* Free resource */
	while (session->packets->count > 0) {
		capwap_itemlist_free(capwap_itemlist_remove_head(session->packets));
	}

	/* Free WLANS */
	ac_wlans_destroy(session);

	/* */
	capwap_event_destroy(&session->changereference);
	capwap_event_destroy(&session->waitpacket);
	capwap_lock_destroy(&session->sessionlock);
	capwap_list_free(session->action);
	capwap_list_free(session->packets);

	/* Free fragments packet */
	if (session->rxmngpacket) {
		capwap_packet_rxmng_free(session->rxmngpacket);
	}

	capwap_list_free(session->requestfragmentpacket);
	capwap_list_free(session->responsefragmentpacket);
	capwap_list_free(session->notifyevent);
	capwap_timeout_free(session->timeout);

	/* Free DFA resource */
	capwap_array_free(session->dfa.acipv4list.addresses);
	capwap_array_free(session->dfa.acipv6list.addresses);

	if (session->wtpid) {
		capwap_free(session->wtpid);
	}

	/* Free item */
	capwap_itemlist_free(session->itemlist);
}
Example #8
0
int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet)
{
	int i;
	int result = 0;
	struct capwap_array* updateitems;

	ASSERT(packet != NULL);

	/* */
	updateitems = capwap_array_create(sizeof(struct wtp_update_configuration_item), 0, 1);

	/* */
	switch (GET_WBID_HEADER(packet->rxmngpacket->header)) {
	case CAPWAP_WIRELESS_BINDING_IEEE80211:
		wtp_radio_setconfiguration_80211(packet, updateitems);
		break;
	}

	log_printf(LOG_DEBUG, "wtp_radio_setconfiguration result #1: %d", result);

	/* Update radio frequency */
	for (i = 0; (i < updateitems->count) && !result; i++) {
		struct wtp_update_configuration_item* item =
			(struct wtp_update_configuration_item*)capwap_array_get_item_pointer(updateitems, i);

		switch (item->type) {
		case WTP_UPDATE_FREQUENCY_DSSS:
			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->devicehandle, WIFI_BAND_5GHZ,
							  item->radio->radioinformation.radiotype,
							  item->radio->ofdmcontrol.currentchannel);
			break;
		}
	}

	log_printf(LOG_DEBUG, "wtp_radio_setconfiguration result #2: %d", result);

	/* Update radio configuration */
	for (i = 0; (i < updateitems->count) && !result; i++) {
		struct wtp_update_configuration_item* item =
			(struct wtp_update_configuration_item*)capwap_array_get_item_pointer(updateitems, i);

		switch (item->type) {
		case WTP_UPDATE_RATES:
			result = wifi_device_updaterates(item->radio->devicehandle,
							 item->radio->rateset.rateset,
							 item->radio->rateset.ratesetcount);
			break;

		case WTP_UPDATE_CONFIGURATION: {
			struct device_setconfiguration_params params;

			memset(&params, 0, sizeof(struct device_setconfiguration_params));
			params.shortpreamble = ((item->radio->radioconfig.shortpreamble == CAPWAP_WTP_RADIO_CONF_SHORTPREAMBLE_ENABLE) ? 1 : 0);
			params.maxbssid = item->radio->radioconfig.maxbssid;
			params.dtimperiod = item->radio->radioconfig.dtimperiod;
			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->devicehandle, &params);
			break;
		}

		case WTP_UPDATE_TX_QUEUE:
			result = wifi_device_settxqueue(item->radio->devicehandle, &item->radio->qos);
			break;
		}
	}

	log_printf(LOG_DEBUG, "wtp_radio_setconfiguration result #3: %d", result);

	/* */
	capwap_array_free(updateitems);
	return result;
}
Example #9
0
static uint32_t ac_dfa_state_join_create_response(struct ac_session_t* session, struct capwap_parsed_packet* packet, struct ac_soap_response* response, struct capwap_packet_txmng* txmngpacket) {
	int i;
	int j;
	int length;
	struct json_object* jsonroot;
	struct json_object* jsonelement;
	struct capwap_list* controllist;
	struct capwap_list_item* item;
	unsigned short binding = GET_WBID_HEADER(packet->rxmngpacket->header);

	/* Receive SOAP response with JSON result
		{
			WTPRadioInformation: [
				<IEEE 802.11 BINDING>
				IEEE80211WTPRadioInformation: {
					RadioID: [int],
					Mode: [int]
				}
			]
			ACIPv4List: [
				{
					ACIPAddress: [string]
				}
			],
			ACIPv6List: [
				{
					ACIPAddress: [string]
				}
			]
			<IEEE 802.11 BINDING>
			WTPRadio: [
				{
					RadioID: [int],
					IEEE80211WTPRadioInformation: {
						Mode: [int]
					}
				}
			]
		}
	*/

	/* Add message elements response, every local value can be overwrite from backend server */
	jsonroot = ac_soapclient_parse_json_response(response);
	if (!jsonroot) {
		return CAPWAP_RESULTCODE_FAILURE;
	}

	/* AC Descriptor */
	ac_update_statistics();
	capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACDESCRIPTION, &g_ac.descriptor);

	/* AC Name */
	capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACNAME, &g_ac.acname);

	/* WTP Radio Information */
	if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
		struct ac_json_ieee80211_wtpradio wtpradio;
		struct capwap_array* wtpradioinformation = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);

		/* */
		ac_json_ieee80211_init(&wtpradio);

		/* */
		jsonelement = compat_json_object_object_get(jsonroot, IEEE80211_BINDING_JSON_ROOT);
		if (jsonelement) {
			ac_json_ieee80211_parsingjson(&wtpradio, jsonelement);
		}

		/* Copy WTP Radio Information if not present into SOAP response */
		for (i = 0; i < wtpradioinformation->count; i++) {
			ac_json_ieee80211_addmessageelement(&wtpradio, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(wtpradioinformation, i), 0);
		}

		/* */
		ac_json_ieee80211_buildpacket(&wtpradio, txmngpacket);

		/* Free resource */
		ac_json_ieee80211_free(&wtpradio);
	}

	/* ECN Support */
	capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ECNSUPPORT, &session->dfa.ecn);

	/* Get information from any local address */
	controllist = capwap_list_create();
	ac_get_control_information(controllist);

	/* CAPWAP Control IP Address */
	for (item = controllist->first; item != NULL; item = item->next) {
		struct ac_session_control* sessioncontrol = (struct ac_session_control*)item->item;

		if (sessioncontrol->localaddress.ss.ss_family == AF_INET) {
			struct capwap_controlipv4_element element;

			memcpy(&element.address, &((struct sockaddr_in*)&sessioncontrol->localaddress)->sin_addr, sizeof(struct in_addr));
			element.wtpcount = sessioncontrol->count;
			capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV4, &element);
		} else if (sessioncontrol->localaddress.ss.ss_family == AF_INET6) {
			struct capwap_controlipv6_element element;

			memcpy(&element.address, &((struct sockaddr_in6*)&sessioncontrol->localaddress)->sin6_addr, sizeof(struct in6_addr));
			element.wtpcount = sessioncontrol->count;
			capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV6, &element);
		}
	}

	capwap_list_free(controllist);

	/* CAPWAP Local IP Address */
	if (session->dtls.localaddr.ss.ss_family == AF_INET) {
		struct capwap_localipv4_element addr;

		memcpy(&addr.address, &session->dtls.localaddr.sin.sin_addr, sizeof(struct in_addr));
		capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV4, &addr);
	} else if (session->dtls.localaddr.ss.ss_family == AF_INET6) {
		struct capwap_localipv6_element addr;

		memcpy(&addr.address, &session->dtls.localaddr.sin6.sin6_addr, sizeof(struct in6_addr));
		capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV6, &addr);
	}

	/* ACIPv4List */
	jsonelement = NULL;
	if (jsonroot) {
		jsonelement = compat_json_object_object_get(jsonroot, "ACIPv4List");
		if (jsonelement && (json_object_get_type(jsonelement) == json_type_array)) {
			length = json_object_array_length(jsonelement);
		} else {
			jsonelement = NULL;
		}
	}

	if (jsonelement) {
		struct capwap_acipv4list_element* responseacipv4list;

		responseacipv4list = (struct capwap_acipv4list_element*)capwap_alloc(sizeof(struct capwap_acipv4list_element));
		responseacipv4list->addresses = capwap_array_create(sizeof(struct in_addr), 0, 0);

		for (j = 0; j < length; j++) {
			struct json_object* jsonvalue = json_object_array_get_idx(jsonelement, j);
			if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) {
				struct json_object* jsonitem;

				/* ACIPAddress */
				jsonitem = compat_json_object_object_get(jsonvalue, "ACIPAddress");
				if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
					const char* value = json_object_get_string(jsonitem);
					if (value) {
						union sockaddr_capwap address;
						if (capwap_address_from_string(value, &address)) {
							/* Accept only IPv4 address */
							if (address.ss.ss_family == AF_INET) {
								struct in_addr* responseaddress_in = (struct in_addr*)capwap_array_get_item_pointer(responseacipv4list->addresses, responseacipv4list->addresses->count);
								memcpy(responseaddress_in, &address.sin.sin_addr, sizeof(struct in_addr));
							}
						}
					}
				}
			}
		}

		if (responseacipv4list->addresses->count > 0) {
			capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV4LIST, responseacipv4list);
		}

		capwap_array_free(responseacipv4list->addresses);
		capwap_free(responseacipv4list);
	} else if (session->dfa.acipv4list.addresses->count > 0) {
		capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV4LIST, &session->dfa.acipv4list);
	}

	/* ACIPv6List */
	jsonelement = NULL;
	if (jsonroot) {
		jsonelement = compat_json_object_object_get(jsonroot, "ACIPv6List");
		if (jsonelement && (json_object_get_type(jsonelement) == json_type_array)) {
			length = json_object_array_length(jsonelement);
		} else {
			jsonelement = NULL;
		}
	}

	if (jsonelement) {
		int j;
		struct capwap_acipv6list_element* responseacipv6list;

		responseacipv6list = (struct capwap_acipv6list_element*)capwap_alloc(sizeof(struct capwap_acipv6list_element));
		responseacipv6list->addresses = capwap_array_create(sizeof(struct in6_addr), 0, 0);

		for (j = 0; j < length; j++) {
			struct json_object* jsonvalue = json_object_array_get_idx(jsonelement, j);
			if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) {
				struct json_object* jsonitem;

				/* ACIPAddress */
				jsonitem = compat_json_object_object_get(jsonvalue, "ACIPAddress");
				if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
					const char* value = json_object_get_string(jsonitem);
					if (value) {
						union sockaddr_capwap address;
						if (capwap_address_from_string(value, &address)) {
							/* Accept only IPv6 address */
							if (address.ss.ss_family == AF_INET6) {
								struct in6_addr* responseaddress_in6 = (struct in6_addr*)capwap_array_get_item_pointer(responseacipv6list->addresses, responseacipv6list->addresses->count);
								memcpy(responseaddress_in6, &address.sin6.sin6_addr, sizeof(struct in6_addr));
							}
						}
					}
				}
			}
		}

		if (responseacipv6list->addresses->count > 0) {
			capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV6LIST, responseacipv6list);
		}

		capwap_array_free(responseacipv6list->addresses);
		capwap_free(responseacipv6list);
	} else if (session->dfa.acipv6list.addresses->count > 0) {
		capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV6LIST, &session->dfa.acipv6list);
	}

	/* CAPWAP Transport Protocol */
	capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TRANSPORT, &session->dfa.transport);

	/* CAPWAP_ELEMENT_IMAGEIDENTIFIER */				/* TODO */
	/* CAPWAP_ELEMENT_MAXIMUMLENGTH */					/* TODO */
	/* CAPWAP_ELEMENT_VENDORPAYLOAD */					/* TODO */

	if (jsonroot) {
		json_object_put(jsonroot);
	}

	return CAPWAP_RESULTCODE_SUCCESS;
}