static void* ac_json_80211_wtpradiofailalarm_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
	struct json_object* jsonitem;
	struct capwap_80211_wtpradiofailalarm_element* wtpradiofailalarm;

	wtpradiofailalarm = (struct capwap_80211_wtpradiofailalarm_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradiofailalarm_element));
	memset(wtpradiofailalarm, 0, sizeof(struct capwap_80211_wtpradiofailalarm_element));
	wtpradiofailalarm->radioid = radioid;

	/* */
	jsonitem = compat_json_object_object_get(jsonparent, "Type");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		wtpradiofailalarm->type = (uint8_t)json_object_get_int(jsonitem);
	} else {
		capwap_free(wtpradiofailalarm);
		return NULL;
	}

	/* */
	jsonitem = compat_json_object_object_get(jsonparent, "Status");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		wtpradiofailalarm->status = (uint8_t)json_object_get_int(jsonitem);
	} else {
		capwap_free(wtpradiofailalarm);
		return NULL;
	}

	return wtpradiofailalarm;
}
static void* ac_json_80211_ofdmcontrol_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
	struct json_object* jsonitem;
	struct capwap_80211_ofdmcontrol_element* ofdmcontrol;

	ofdmcontrol = (struct capwap_80211_ofdmcontrol_element*)capwap_alloc(sizeof(struct capwap_80211_ofdmcontrol_element));
	memset(ofdmcontrol, 0, sizeof(struct capwap_80211_ofdmcontrol_element));
	ofdmcontrol->radioid = radioid;

	/* */
	jsonitem = compat_json_object_object_get(jsonparent, "CurrentChan");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		ofdmcontrol->currentchannel = (uint8_t)json_object_get_int(jsonitem);
	} else {
		capwap_free(ofdmcontrol);
		return NULL;
	}

	jsonitem = compat_json_object_object_get(jsonparent, "BandSupport");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		ofdmcontrol->bandsupport = (uint8_t)json_object_get_int(jsonitem) & CAPWAP_OFDMCONTROL_BAND_MASK;
	} else {
		capwap_free(ofdmcontrol);
		return NULL;
	}

	jsonitem = compat_json_object_object_get(jsonparent, "TIThreshold");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		ofdmcontrol->tithreshold = (uint32_t)json_object_get_int(jsonitem);
	} else {
		capwap_free(ofdmcontrol);
		return NULL;
	}

	return ofdmcontrol;
}
Exemplo n.º 3
0
static int ac_backend_parsing_event(struct json_object* jsonitem) {
	int result = -1;
	struct json_object* jsonvalue;

	ASSERT(jsonitem != NULL);

	/* Receive event into JSON result
		{
			EventID: [int],
			Action: [string],
			Params: {
				<Depends on the Action>
			}
		}
	*/

	/* Get EventID */
	jsonvalue = compat_json_object_object_get(jsonitem, "EventID");
	if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_string)) {
		const char* idevent = json_object_get_string(jsonvalue);

		/* Get Action */
		jsonvalue = compat_json_object_object_get(jsonitem, "Action");
		if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_string)) {
			const char* action = json_object_get_string(jsonvalue);
			if (action) {
				jsonvalue = compat_json_object_object_get(jsonitem, "Params");
				if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) {
					/* Parsing params according to the action */
					if (!strcmp(action, "CloseWTPSession")) {
						result = ac_backend_parsing_closewtpsession_event(idevent, jsonvalue);
					} else if (!strcmp(action, "ResetWTP")) {
						result = ac_backend_parsing_resetwtp_event(idevent, jsonvalue);
					} else if (!strcmp(action, "AddWLAN")) {
						result = ac_backend_parsing_addwlan_event(idevent, jsonvalue);
					} else if (!strcmp(action, "UpdateWLAN")) {
						result = ac_backend_parsing_updatewlan_event(idevent, jsonvalue);
					} else if (!strcmp(action, "DeleteWLAN")) {
						result = ac_backend_parsing_deletewlan_event(idevent, jsonvalue);
					}

					/* Notify result action */
					ac_backend_soap_update_event(idevent, (!result ? SOAP_EVENT_STATUS_RUNNING : SOAP_EVENT_STATUS_GENERIC_ERROR));
				}
			}
		}
	}

	return result;
}
Exemplo n.º 4
0
static int ac_update_configuration_datachannelinterfaces(void* data, void* param) {
	int i;
	int mtu;
	int length;
	const char* bridge;
	struct ac_if_datachannel* iface = (struct ac_if_datachannel*)data;
	struct array_list* interfaces = (struct array_list*)param;

	/* Search interface */
	length = array_list_length(interfaces);
	for (i = 0; i < length; i++) {
		struct json_object* jsonvalue = array_list_get_idx(interfaces, i);
		if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) {
			struct json_object* jsonindex = compat_json_object_object_get(jsonvalue, "Index");
			if (jsonindex && (json_object_get_type(jsonindex) == json_type_int)) {
				if (iface->index == (unsigned long)json_object_get_int(jsonindex)) {
					if (!ac_update_configuration_getdatachannel_params(jsonvalue, &mtu, &bridge)) {
						/* TODO update interface */
					}

					/* Interface found */
					array_list_put_idx(interfaces, i, NULL);
					break;
				}
			}
		}
	}

	return ((i == length) ? HASH_DELETE_AND_CONTINUE : HASH_CONTINUE);
}
Exemplo n.º 5
0
static int ac_update_configuration_getdatachannel_params(struct json_object* jsonvalue, int* mtu, const char** bridge) {
	int result = -1;
	struct json_object* jsonmtu;

	/* */
	jsonmtu = compat_json_object_object_get(jsonvalue, "MTU");
	if (jsonmtu && (json_object_get_type(jsonmtu) == json_type_int)) {
		*mtu = json_object_get_int(jsonmtu);
		if ((*mtu >= MIN_MTU) && (*mtu <= MAX_MTU)) {
			struct json_object* jsonbridge = compat_json_object_object_get(jsonvalue, "Bridge");

			*bridge = ((jsonbridge && (json_object_get_type(jsonmtu) == json_type_string)) ? json_object_get_string(jsonbridge) : NULL);
			result = 0;
		}
	}

	return result;
}
static void* ac_json_80211_wtpradioinformation_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
	struct json_object* jsonitem;
	struct capwap_80211_wtpradioinformation_element* wtpradioinformation;

	wtpradioinformation = (struct capwap_80211_wtpradioinformation_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioinformation_element));
	memset(wtpradioinformation, 0, sizeof(struct capwap_80211_wtpradioinformation_element));
	wtpradioinformation->radioid = radioid;

	/* */
	jsonitem = compat_json_object_object_get(jsonparent, "Mode");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		wtpradioinformation->radiotype = (uint32_t)json_object_get_int(jsonitem) & CAPWAP_RADIO_TYPE_MASK;
	} else {
		capwap_free(wtpradioinformation);
		return NULL;
	}

	return wtpradioinformation;
}
Exemplo n.º 7
0
static int ac_backend_parsing_closewtpsession_event(const char* idevent, struct json_object* jsonparams) {
	int result = -1;
	struct ac_session_t* session;
	struct json_object* jsonwtpid;

	/* Params CloseWTPSession Action
		{
			WTPId: [string]
		}
	*/

	/* WTPId */
	jsonwtpid = compat_json_object_object_get(jsonparams, "WTPId");
	if (!jsonwtpid || (json_object_get_type(jsonwtpid) != json_type_string)) {
		return -1;
	}

	/* Get session */
	session = ac_search_session_from_wtpid(json_object_get_string(jsonwtpid));
	if (session) {
		struct ac_session_notify_event_t notify;

		/* Notify Request to Complete Event */
		strcpy(notify.idevent, idevent);
		notify.action = NOTIFY_ACTION_CHANGE_STATE;
		notify.session_state = CAPWAP_DEAD_STATE;
		ac_session_send_action(session, AC_SESSION_ACTION_NOTIFY_EVENT, 0, (void*)&notify, sizeof(struct ac_session_notify_event_t));

		/* Async close session */
		capwap_logging_debug("Receive close wtp session for WTP %s", session->wtpid);
		ac_session_send_action(session, AC_SESSION_ACTION_CLOSE, 0, NULL, 0);

		/* */
		ac_session_release_reference(session);
		result = 0;
	}

	return result;
}
Exemplo n.º 8
0
static int ac_session_action_authorizestation_response(struct ac_session_t* session, struct ac_soap_response* response, struct ac_notify_station_configuration_ieee8011_add_station* notify) {
	int result = -1;
	int ifindex = -1;
	uint16_t vlan = 0;
	struct ac_if_datachannel* datachannel;
	struct ac_wlan* wlan;
	struct json_object* jsonroot;
	struct json_object* jsonsection;
	struct json_object* jsonelement;
	struct capwap_header_data capwapheader;
	struct capwap_packet_txmng* txmngpacket;
	struct capwap_addstation_element addstation;
	struct capwap_80211_station_element station;

	/* Receive SOAP response with JSON result
		{
			DataChannelInterface: {
				Index: [int],
				VLAN: [int/string]
			},
		}
	*/

	/* */
	jsonroot = ac_soapclient_parse_json_response(response);
	if (!jsonroot) {
		return -1;
	}

	/* */
	jsonsection = compat_json_object_object_get(jsonroot, "DataChannelInterface");
	if (jsonsection && (json_object_get_type(jsonsection) == json_type_object)) {
		jsonelement = compat_json_object_object_get(jsonsection, "Index");
		if (jsonelement && (json_object_get_type(jsonelement) == json_type_int)) {
			unsigned long index = (unsigned long)json_object_get_int(jsonelement);

			/* Retrieve interface index */
			capwap_rwlock_rdlock(&g_ac.ifdatachannellock);

			datachannel = (struct ac_if_datachannel*)capwap_hash_search(g_ac.ifdatachannel, &index);
			if (datachannel) {
				ifindex = datachannel->ifindex;
			}

			capwap_rwlock_unlock(&g_ac.ifdatachannellock);

			/* Prepare request */
			if (ifindex >= 0) {
				wlan = ac_wlans_get_bssid_with_wlanid(session, notify->radioid, notify->wlanid);
				if (wlan) {
					memset(&addstation, 0, sizeof(struct capwap_addstation_element));
					addstation.radioid = notify->radioid;
					addstation.length = MACADDRESS_EUI48_LENGTH;
					addstation.address = notify->address;
					if (wlan->tunnelmode == CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL) {
						jsonelement = compat_json_object_object_get(jsonsection, "VLAN");
						if (jsonelement && (json_object_get_type(jsonelement) == json_type_string)) {
							const char* wtpvlan = json_object_get_string(jsonelement);
							if (wtpvlan && (strlen(wtpvlan) < CAPWAP_ADDSTATION_VLAN_MAX_LENGTH)) {
								addstation.vlan = (uint8_t*)wtpvlan;		/* Free with jsonroot */
							}
						}
					}

					/* */
					memset(&station, 0, sizeof(struct capwap_80211_station_element));
					station.radioid = notify->radioid;
					station.associationid = notify->associationid;
					memcpy(station.address, notify->address, MACADDRESS_EUI48_LENGTH);
					station.capabilities = notify->capabilities;
					station.wlanid = notify->wlanid;
					station.supportedratescount = notify->supportedratescount;
					memcpy(station.supportedrates, notify->supportedrates, station.supportedratescount);

					/* Build packet */
					capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, session->binding);
					txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_STATION_CONFIGURATION_REQUEST, session->localseqnumber, session->mtu);

					/* Add message element */
					capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ADDSTATION, &addstation);
					capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_STATION, &station);

					/* CAPWAP_ELEMENT_VENDORPAYLOAD */				/* TODO */

					/* Station Configuration Request complete, get fragment packets */
					capwap_packet_txmng_get_fragment_packets(txmngpacket, session->requestfragmentpacket, session->fragmentid);
					if (session->requestfragmentpacket->count > 1) {
						session->fragmentid++;
					}

					/* Free packets manager */
					capwap_packet_txmng_free(txmngpacket);

					/* Send Station Configuration Request to WTP */
					if (capwap_crypt_sendto_fragmentpacket(&session->dtls, session->requestfragmentpacket)) {
						/* Retrive VLAN */
						if (wlan->tunnelmode != CAPWAP_ADD_WLAN_TUNNELMODE_LOCAL) {
							jsonelement = compat_json_object_object_get(jsonroot, "DataChannelInterface.VLAN");
							if (jsonelement && (json_object_get_type(jsonelement) == json_type_int)) {
								int acvlan = json_object_get_int(jsonelement);
								if ((acvlan > 0) && (acvlan < VLAN_MAX)) {
									vlan = (uint16_t)acvlan;
								}
							}
						}

						/* Authorize station also into kernel module */
						if (!ac_kmod_authorize_station(&session->sessionid, addstation.address, ifindex, notify->radioid, notify->wlanid, vlan)) {
							result = 0;
							session->retransmitcount = 0;
							capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
						} else {
							capwap_logging_warning("Unable to authorize station into kernel module data channel");
							ac_free_reference_last_request(session);
							ac_session_teardown(session);
						}
					} else {
						capwap_logging_debug("Warning: error to send Station Configuration Request packet");
						ac_free_reference_last_request(session);
						ac_session_teardown(session);
					}
				}
			}
		}
	}

	/* */
	json_object_put(jsonroot);
	return result;
}
Exemplo n.º 9
0
static int ac_backend_parsing_resetwtp_event(const char* idevent, struct json_object* jsonparams) {
	int result = -1;
	struct ac_session_t* session;
	struct json_object* jsonwtpid;
	struct json_object* jsonimage;
	struct json_object* jsonvendor;
	struct json_object* jsondata;

	/* Params ResetWTP Action
		{
			WTPId: [string],
			ImageIdentifier: {
				Vendor: [int],
				Data: [string]
			}
		}
	*/

	/* WTPId */
	jsonwtpid = compat_json_object_object_get(jsonparams, "WTPId");
	if (!jsonwtpid || (json_object_get_type(jsonwtpid) != json_type_string)) {
		return -1;
	}

	/* ImageIdentifier */
	jsonimage = compat_json_object_object_get(jsonparams, "ImageIdentifier");
	if (!jsonimage || (json_object_get_type(jsonimage) != json_type_object)) {
		return -1;
	}

	jsonvendor = compat_json_object_object_get(jsonimage, "Vendor");
	jsondata = compat_json_object_object_get(jsonimage, "Data");
	if (!jsonvendor || !jsondata || (json_object_get_type(jsonvendor) != json_type_int) || (json_object_get_type(jsondata) != json_type_string)) {
		return -1;
	}

	/* Get session */
	session = ac_search_session_from_wtpid(json_object_get_string(jsonwtpid));
	if (session) {
		const char* name = json_object_get_string(jsondata);
		if (name && *name) {
			int length;
			struct ac_notify_reset_t* reset;
			struct ac_session_notify_event_t notify;

			/* Notification data */
			length = sizeof(struct ac_notify_reset_t) + strlen(name) + 1;
			reset = (struct ac_notify_reset_t*)capwap_alloc(length);

			/* */
			reset->vendor = (uint32_t)json_object_get_int(jsonvendor);
			strcpy((char*)reset->name, name);

			/* Notify Request to Complete Event */
			strcpy(notify.idevent, idevent);
			notify.action = NOTIFY_ACTION_CHANGE_STATE;
			notify.session_state = CAPWAP_DEAD_STATE;
			ac_session_send_action(session, AC_SESSION_ACTION_NOTIFY_EVENT, 0, (void*)&notify, sizeof(struct ac_session_notify_event_t));

			/* Notify Action */
			capwap_logging_debug("Receive reset request for WTP %s", session->wtpid);
			ac_session_send_action(session, AC_SESSION_ACTION_RESET_WTP, 0, (void*)reset, length);
			result = 0;

			/* */
			capwap_free(reset);
		}

		ac_session_release_reference(session);
	}

	return result;
}
Exemplo n.º 10
0
static int ac_backend_parsing_addwlan_event(const char* idevent, struct json_object* jsonparams) {
	int result = -1;
	struct ac_session_t* session;
	struct json_object* jsonwtpid;
	struct json_object* jsonradioid;
	struct json_object* jsonwlanid;
	struct json_object* jsoncapability;
	struct json_object* jsonqos;
	struct json_object* jsonauthtype;
	struct json_object* jsonmacmode;
	struct json_object* jsontunnelmode;
	struct json_object* jsonhidessid;
	struct json_object* jsonssid;
	const char* ssid;

	/* Params AddWLAN Action
		{
			WTPID: [string],
			RadioID: [int],
			WLANID: [int],
			Capability: [int],
			Key: {
				TODO
			},
			DefaultQoS: [int],
			AuthType: [int],
			MACMode: [int],
			TunnelMode: [int],
			SuppressSSID: [bool],
			SSID: [string],
			IE: {
				TODO
			}
		}
	*/

	/* WTPID */
	jsonwtpid = compat_json_object_object_get(jsonparams, "WTPID");
	if (!jsonwtpid || (json_object_get_type(jsonwtpid) != json_type_string)) {
		return -1;
	}

	/* RadioID */
	jsonradioid = compat_json_object_object_get(jsonparams, "RadioID");
	if (!jsonradioid || (json_object_get_type(jsonradioid) != json_type_int)) {
		return -1;
	}

	/* WLANID */
	jsonwlanid = compat_json_object_object_get(jsonparams, "WLANID");
	if (!jsonwlanid || (json_object_get_type(jsonwlanid) != json_type_int)) {
		return -1;
	}

	/* Capability */
	jsoncapability = compat_json_object_object_get(jsonparams, "Capability");
	if (!jsoncapability || (json_object_get_type(jsoncapability) != json_type_int)) {
		return -1;
	}

	/* Key */
	/* TODO */

	/* DefaultQoS */
	jsonqos = compat_json_object_object_get(jsonparams, "DefaultQoS");
	if (!jsonqos || (json_object_get_type(jsonqos) != json_type_int)) {
		return -1;
	}

	/* AuthType */
	jsonauthtype = compat_json_object_object_get(jsonparams, "AuthType");
	if (!jsonauthtype || (json_object_get_type(jsonauthtype) != json_type_int)) {
		return -1;
	}

	/* MACMode */
	jsonmacmode = compat_json_object_object_get(jsonparams, "MACMode");
	if (!jsonmacmode || (json_object_get_type(jsonmacmode) != json_type_int)) {
		return -1;
	}

	/* TunnelMode */
	jsontunnelmode = compat_json_object_object_get(jsonparams, "TunnelMode");
	if (!jsontunnelmode || (json_object_get_type(jsontunnelmode) != json_type_int)) {
		return -1;
	}

	/* SuppressSSID */
	jsonhidessid = compat_json_object_object_get(jsonparams, "SuppressSSID");
	if (!jsonhidessid || (json_object_get_type(jsonhidessid) != json_type_boolean)) {
		return -1;
	}

	/* SSID */
	jsonssid = compat_json_object_object_get(jsonparams, "SSID");
	if (jsonssid && (json_object_get_type(jsonssid) == json_type_string)) {
		ssid = json_object_get_string(jsonssid);
		if (strlen(ssid) > CAPWAP_ADD_WLAN_SSID_LENGTH) {
			return -1;
		}
	} else {
		return -1;
	}

	/* IE */
	/* TODO */

	/* Get session */
	session = ac_search_session_from_wtpid(json_object_get_string(jsonwtpid));
	if (session) {
		int length;
		struct ac_notify_addwlan_t* addwlan;
		struct ac_session_notify_event_t notify;

		/* Notification data */
		length = sizeof(struct ac_notify_addwlan_t);
		addwlan = (struct ac_notify_addwlan_t*)capwap_alloc(length);

		/* */
		addwlan->radioid = (uint8_t)json_object_get_int(jsonradioid);
		addwlan->wlanid = (uint8_t)json_object_get_int(jsonwlanid);
		addwlan->capability = (uint16_t)json_object_get_int(jsoncapability);
		addwlan->qos = (uint8_t)json_object_get_int(jsonqos);
		addwlan->authmode = (uint8_t)json_object_get_int(jsonauthtype);
		addwlan->macmode = (uint8_t)json_object_get_int(jsonmacmode);
		addwlan->tunnelmode = (uint8_t)json_object_get_int(jsontunnelmode);
		addwlan->suppressssid = (uint8_t)(json_object_get_boolean(jsonhidessid) ? 1 : 0);
		strcpy(addwlan->ssid, ssid);

		/* Notify Request to Complete Event */
		strcpy(notify.idevent, idevent);
		notify.action = NOTIFY_ACTION_RECEIVE_RESPONSE_CONTROLMESSAGE;
		notify.ctrlmsg_type = CAPWAP_IEEE80211_WLAN_CONFIGURATION_RESPONSE;
		ac_session_send_action(session, AC_SESSION_ACTION_NOTIFY_EVENT, 0, (void*)&notify, sizeof(struct ac_session_notify_event_t));

		/* Notify Action */
		capwap_logging_debug("Receive AddWLAN request for WTP %s with SSID: %s", session->wtpid, addwlan->ssid);
		ac_session_send_action(session, AC_SESSION_ACTION_ADDWLAN, 0, (void*)addwlan, length);

		/* */
		ac_session_release_reference(session);
		capwap_free(addwlan);
		result = 0;
	}

	return result;
}
Exemplo n.º 11
0
static void* ac_json_80211_wtpradioconf_createmessageelement(struct json_object* jsonparent, uint16_t radioid) {
	struct json_object* jsonitem;
	struct capwap_80211_wtpradioconf_element* wtpradioconf;

	wtpradioconf = (struct capwap_80211_wtpradioconf_element*)capwap_alloc(sizeof(struct capwap_80211_wtpradioconf_element));
	memset(wtpradioconf, 0, sizeof(struct capwap_80211_wtpradioconf_element));
	wtpradioconf->radioid = radioid;

	/* */
	jsonitem = compat_json_object_object_get(jsonparent, "ShortPreamble");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		wtpradioconf->shortpreamble = (uint8_t)json_object_get_int(jsonitem);
	} else {
		capwap_free(wtpradioconf);
		return NULL;
	}

	jsonitem = compat_json_object_object_get(jsonparent, "NumBSSIDs");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		wtpradioconf->maxbssid = (uint8_t)json_object_get_int(jsonitem);
	} else {
		capwap_free(wtpradioconf);
		return NULL;
	}

	jsonitem = compat_json_object_object_get(jsonparent, "DTIMPeriod");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		wtpradioconf->dtimperiod = (uint8_t)json_object_get_int(jsonitem);
	} else {
		capwap_free(wtpradioconf);
		return NULL;
	}

	jsonitem = compat_json_object_object_get(jsonparent, "BSSID");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
		if (!capwap_scanf_macaddress((unsigned char*)wtpradioconf->bssid, json_object_get_string(jsonitem), MACADDRESS_EUI48_LENGTH)) {
			capwap_free(wtpradioconf);
			return NULL;
		}
	} else {
		capwap_free(wtpradioconf);
		return NULL;
	}

	jsonitem = compat_json_object_object_get(jsonparent, "BeaconPeriod");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_int)) {
		wtpradioconf->beaconperiod = (uint16_t)json_object_get_int(jsonitem);
	} else {
		capwap_free(wtpradioconf);
		return NULL;
	}

	jsonitem = compat_json_object_object_get(jsonparent, "CountryString");
	if (jsonitem && (json_object_get_type(jsonitem) == json_type_string)) {
		const char* country = json_object_get_string(jsonitem);
		if (strlen(country) == (CAPWAP_WTP_RADIO_CONF_COUNTRY_LENGTH - 1)) {
			strcpy((char*)wtpradioconf->country, country);
		} else {
			capwap_free(wtpradioconf);
			return NULL;
		}
	} else {
		capwap_free(wtpradioconf);
		return NULL;
	}

	return wtpradioconf;
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
static void ac_update_configuration(struct json_object* jsonroot) {
	int i;
	int mtu;
	int length;
	const char* bridge;
	struct json_object* jsonelement;
	struct ac_if_datachannel* datachannel;

	ASSERT(jsonroot != NULL);

	/* Params
		{
			DataChannelInterfaces: [
				{
					Index: [int],
					MTU: [int],
					Bridge: [string]
				}
			]
		}
	*/

	/* DataChannelInterfaces */
	jsonelement = compat_json_object_object_get(jsonroot, "DataChannelInterfaces");
	if (jsonelement && (json_object_get_type(jsonelement) == json_type_array)) {
		struct array_list* interfaces = json_object_get_array(jsonelement);

		capwap_rwlock_wrlock(&g_ac.ifdatachannellock);

		/* Update and Remove active interfaces*/
		capwap_hash_foreach(g_ac.ifdatachannel, ac_update_configuration_datachannelinterfaces, interfaces);

		/* Add new interfaces*/
		length = array_list_length(interfaces);
		for (i = 0; i < length; i++) {
			struct json_object* jsonvalue = array_list_get_idx(interfaces, i);
			if (jsonvalue && (json_object_get_type(jsonvalue) == json_type_object)) {
				struct json_object* jsonindex = compat_json_object_object_get(jsonvalue, "Index");
				if (jsonindex && (json_object_get_type(jsonindex) == json_type_int)) {
					int index = json_object_get_int(jsonindex);
					if ((index >= 0) && (index < AC_IFACE_MAX_INDEX) && !ac_update_configuration_getdatachannel_params(jsonvalue, &mtu, &bridge)) {
						datachannel = (struct ac_if_datachannel*)capwap_alloc(sizeof(struct ac_if_datachannel));
						memset(datachannel, 0, sizeof(struct ac_if_datachannel));

						/* */
						datachannel->index = (unsigned long)index;
						datachannel->mtu = mtu;
						if (bridge && (strlen(bridge) < IFNAMSIZ)) {
							strcpy(datachannel->bridge, bridge);
						}

						/* */
						if (!ac_update_configuration_create_datachannelinterfaces(datachannel)) {
							capwap_hash_add(g_ac.ifdatachannel, (void*)datachannel);
						} else {
							capwap_free(datachannel);
						}
					}
				}
			}
		}

		capwap_rwlock_unlock(&g_ac.ifdatachannellock);
	}
}