#include <sys/un.h>

#include "utils/includes.h"
#include "utils/common.h"
#include "utils/ucode.h"
#include "hostapd.h"
#include "beacon.h"
#include "hw_features.h"
#include "ap_drv_ops.h"
#include "dfs.h"
#include "acs.h"
#include <libubox/uloop.h>

static uc_resource_type_t *global_type, *bss_type, *iface_type;
static struct hapd_interfaces *interfaces;
static uc_value_t *global, *bss_registry, *iface_registry;
static uc_vm_t *vm;

static uc_value_t *
hostapd_ucode_bss_get_uval(struct hostapd_data *hapd)
{
	uc_value_t *val;

	if (hapd->ucode.idx)
		return wpa_ucode_registry_get(bss_registry, hapd->ucode.idx);

	val = uc_resource_new(bss_type, hapd);
	hapd->ucode.idx = wpa_ucode_registry_add(bss_registry, val);

	return val;
}

static uc_value_t *
hostapd_ucode_iface_get_uval(struct hostapd_iface *hapd)
{
	uc_value_t *val;

	if (hapd->ucode.idx)
		return wpa_ucode_registry_get(iface_registry, hapd->ucode.idx);

	val = uc_resource_new(iface_type, hapd);
	hapd->ucode.idx = wpa_ucode_registry_add(iface_registry, val);

	return val;
}

static void
hostapd_ucode_update_bss_list(struct hostapd_iface *iface, uc_value_t *if_bss, uc_value_t *bss)
{
	uc_value_t *list;
	int i;

	list = ucv_array_new(vm);
	for (i = 0; iface->bss && i < iface->num_bss; i++) {
		struct hostapd_data *hapd = iface->bss[i];
		uc_value_t *val = hostapd_ucode_bss_get_uval(hapd);

		ucv_array_set(list, i, ucv_get(ucv_string_new(hapd->conf->iface)));
		ucv_object_add(bss, hapd->conf->iface, ucv_get(val));
	}
	ucv_object_add(if_bss, iface->phy, ucv_get(list));
}

static void
hostapd_ucode_update_interfaces(void)
{
	uc_value_t *ifs = ucv_object_new(vm);
	uc_value_t *if_bss = ucv_array_new(vm);
	uc_value_t *bss = ucv_object_new(vm);
	int i;

	for (i = 0; i < interfaces->count; i++) {
		struct hostapd_iface *iface = interfaces->iface[i];

		ucv_object_add(ifs, iface->phy, ucv_get(hostapd_ucode_iface_get_uval(iface)));
		hostapd_ucode_update_bss_list(iface, if_bss, bss);
	}

	ucv_object_add(ucv_prototype_get(global), "interfaces", ucv_get(ifs));
	ucv_object_add(ucv_prototype_get(global), "interface_bss", ucv_get(if_bss));
	ucv_object_add(ucv_prototype_get(global), "bss", ucv_get(bss));
	ucv_gc(vm);
}

static uc_value_t *
uc_hostapd_add_iface(uc_vm_t *vm, size_t nargs)
{
	uc_value_t *iface = uc_fn_arg(0);
	int ret;

	if (ucv_type(iface) != UC_STRING)
		return ucv_int64_new(-1);

	ret = hostapd_add_iface(interfaces, ucv_string_get(iface));
	hostapd_ucode_update_interfaces();

	return ucv_int64_new(ret);
}

static uc_value_t *
uc_hostapd_remove_iface(uc_vm_t *vm, size_t nargs)
{
	uc_value_t *iface = uc_fn_arg(0);

	if (ucv_type(iface) != UC_STRING)
		return NULL;

	hostapd_remove_iface(interfaces, ucv_string_get(iface));
	hostapd_ucode_update_interfaces();

	return NULL;
}

static struct hostapd_vlan *
bss_conf_find_vlan(struct hostapd_bss_config *bss, int id)
{
	struct hostapd_vlan *vlan;

	for (vlan = bss->vlan; vlan; vlan = vlan->next)
		if (vlan->vlan_id == id)
			return vlan;

	return NULL;
}

static int
bss_conf_rename_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
		     const char *ifname)
{
	if (!strcmp(ifname, vlan->ifname))
		return 0;

	hostapd_drv_if_rename(hapd, WPA_IF_AP_VLAN, vlan->ifname, ifname);
	os_strlcpy(vlan->ifname, ifname, sizeof(vlan->ifname));

	return 0;
}

static int
bss_reload_vlans(struct hostapd_data *hapd, struct hostapd_bss_config *bss)
{
	struct hostapd_bss_config *old_bss = hapd->conf;
	struct hostapd_vlan *vlan, *vlan_new, *wildcard;
	char ifname[IFNAMSIZ + 1], vlan_ifname[IFNAMSIZ + 1], *pos;
	int ret;

	vlan = bss_conf_find_vlan(old_bss, VLAN_ID_WILDCARD);
	wildcard = bss_conf_find_vlan(bss, VLAN_ID_WILDCARD);
	if (!!vlan != !!wildcard)
		return -1;

	if (vlan && wildcard && strcmp(vlan->ifname, wildcard->ifname) != 0)
		strcpy(vlan->ifname, wildcard->ifname);
	else
		wildcard = NULL;

	for (vlan = bss->vlan; vlan; vlan = vlan->next) {
		if (vlan->vlan_id == VLAN_ID_WILDCARD ||
		    vlan->dynamic_vlan > 0)
			continue;

		if (!bss_conf_find_vlan(old_bss, vlan->vlan_id))
			return -1;
	}

	for (vlan = old_bss->vlan; vlan; vlan = vlan->next) {
		if (vlan->vlan_id == VLAN_ID_WILDCARD)
			continue;

		if (vlan->dynamic_vlan == 0) {
			vlan_new = bss_conf_find_vlan(bss, vlan->vlan_id);
			if (!vlan_new)
				return -1;

			if (bss_conf_rename_vlan(hapd, vlan, vlan_new->ifname))
				return -1;

			continue;
		}

		if (!wildcard)
			continue;

		os_strlcpy(ifname, wildcard->ifname, sizeof(ifname));
		pos = os_strchr(ifname, '#');
		if (!pos)
			return -1;

		*pos++ = '\0';
		ret = os_snprintf(vlan_ifname, sizeof(vlan_ifname), "%s%d%s",
				  ifname, vlan->vlan_id, pos);
	        if (os_snprintf_error(sizeof(vlan_ifname), ret))
			return -1;

		if (bss_conf_rename_vlan(hapd, vlan, vlan_ifname))
			return -1;
	}

	return 0;
}

static uc_value_t *
uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
{
	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
	struct hostapd_bss_config *old_bss;
	struct hostapd_iface *iface;
	struct hostapd_config *conf;
	uc_value_t *file = uc_fn_arg(0);
	uc_value_t *index = uc_fn_arg(1);
	uc_value_t *files_only = uc_fn_arg(2);
	unsigned int i, idx = 0;
	int ret = -1;

	if (!hapd || ucv_type(file) != UC_STRING)
		goto out;

	if (ucv_type(index) == UC_INTEGER)
		idx = ucv_int64_get(index);

	iface = hapd->iface;
	conf = interfaces->config_read_cb(ucv_string_get(file));
	if (!conf)
		goto out;

	if (idx > conf->num_bss || !conf->bss[idx])
		goto free;

	if (ucv_boolean_get(files_only)) {
		struct hostapd_bss_config *bss = conf->bss[idx];
		struct hostapd_bss_config *old_bss = hapd->conf;

#define swap_field(name)				\
	do {								\
		void *ptr = old_bss->name;		\
		old_bss->name = bss->name;		\
		bss->name = ptr;				\
	} while (0)

		swap_field(ssid.wpa_psk_file);
		ret = bss_reload_vlans(hapd, bss);
		goto done;
	}

	hostapd_bss_deinit_no_free(hapd);
	hostapd_drv_stop_ap(hapd);
	hostapd_free_hapd_data(hapd);

	old_bss = hapd->conf;
	for (i = 0; i < iface->conf->num_bss; i++)
		if (iface->conf->bss[i] == hapd->conf)
			iface->conf->bss[i] = conf->bss[idx];
	hapd->conf = conf->bss[idx];
	conf->bss[idx] = old_bss;

	hostapd_setup_bss(hapd, hapd == iface->bss[0], true);
	hostapd_ucode_update_interfaces();

done:
	ret = 0;
free:
	hostapd_config_free(conf);
out:
	return ucv_int64_new(ret);
}

static void
hostapd_remove_iface_bss_conf(struct hostapd_config *iconf,
			      struct hostapd_bss_config *conf)
{
	int i;

	for (i = 0; i < iconf->num_bss; i++)
		if (iconf->bss[i] == conf)
			break;

	if (i == iconf->num_bss)
		return;

	for (i++; i < iconf->num_bss; i++)
		iconf->bss[i - 1] = iconf->bss[i];
	iconf->num_bss--;
}


static uc_value_t *
uc_hostapd_bss_delete(uc_vm_t *vm, size_t nargs)
{
	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
	struct hostapd_iface *iface;
	int i, idx;

	if (!hapd)
		return NULL;

	iface = hapd->iface;
	if (iface->num_bss == 1) {
		wpa_printf(MSG_ERROR, "trying to delete last bss of an iface: %s\n", hapd->conf->iface);
		return NULL;
	}

	for (idx = 0; idx < iface->num_bss; idx++)
		if (iface->bss[idx] == hapd)
			break;

	if (idx == iface->num_bss)
		return NULL;

	for (i = idx + 1; i < iface->num_bss; i++)
		iface->bss[i - 1] = iface->bss[i];

	iface->num_bss--;

	iface->bss[0]->interface_added = 0;
	hostapd_drv_set_first_bss(iface->bss[0]);
	hapd->interface_added = 1;

	hostapd_drv_stop_ap(hapd);
	hostapd_bss_deinit(hapd);
	hostapd_remove_iface_bss_conf(iface->conf, hapd->conf);
	hostapd_config_free_bss(hapd->conf);
	os_free(hapd);

	hostapd_ucode_update_interfaces();
	ucv_gc(vm);

	return NULL;
}

static uc_value_t *
uc_hostapd_iface_add_bss(uc_vm_t *vm, size_t nargs)
{
	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
	struct hostapd_bss_config *bss;
	struct hostapd_config *conf;
	struct hostapd_data *hapd;
	uc_value_t *file = uc_fn_arg(0);
	uc_value_t *index = uc_fn_arg(1);
	unsigned int idx = 0;
	uc_value_t *ret = NULL;

	if (!iface || ucv_type(file) != UC_STRING)
		goto out;

	if (ucv_type(index) == UC_INTEGER)
		idx = ucv_int64_get(index);

	conf = interfaces->config_read_cb(ucv_string_get(file));
	if (!conf || idx > conf->num_bss || !conf->bss[idx])
		goto out;

	bss = conf->bss[idx];
	hapd = hostapd_alloc_bss_data(iface, iface->conf, bss);
	if (!hapd)
		goto out;

	hapd->driver = iface->bss[0]->driver;
	hapd->drv_priv = iface->bss[0]->drv_priv;
	if (interfaces->ctrl_iface_init &&
	    interfaces->ctrl_iface_init(hapd) < 0)
		goto free_hapd;

	if (iface->state == HAPD_IFACE_ENABLED &&
	    hostapd_setup_bss(hapd, -1, true))
		goto deinit_ctrl;

	iface->bss = os_realloc_array(iface->bss, iface->num_bss + 1,
				      sizeof(*iface->bss));
	iface->bss[iface->num_bss++] = hapd;

	iface->conf->bss = os_realloc_array(iface->conf->bss,
					    iface->conf->num_bss + 1,
					    sizeof(*iface->conf->bss));
	iface->conf->bss[iface->conf->num_bss] = bss;
	conf->bss[idx] = NULL;
	ret = hostapd_ucode_bss_get_uval(hapd);
	hostapd_ucode_update_interfaces();
	goto out;

deinit_ctrl:
	if (interfaces->ctrl_iface_deinit)
		interfaces->ctrl_iface_deinit(hapd);
free_hapd:
	hostapd_free_hapd_data(hapd);
	os_free(hapd);
out:
	hostapd_config_free(conf);
	return ret;
}

static uc_value_t *
uc_hostapd_iface_set_bss_order(uc_vm_t *vm, size_t nargs)
{
	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
	uc_value_t *bss_list = uc_fn_arg(0);
	struct hostapd_data **new_bss;
	struct hostapd_bss_config **new_conf;

	if (!iface)
		return NULL;

	if (ucv_type(bss_list) != UC_ARRAY ||
	    ucv_array_length(bss_list) != iface->num_bss)
		return NULL;

	new_bss = calloc(iface->num_bss, sizeof(*new_bss));
	new_conf = calloc(iface->num_bss, sizeof(*new_conf));
	for (size_t i = 0; i < iface->num_bss; i++) {
		struct hostapd_data *bss;

		bss = ucv_resource_data(ucv_array_get(bss_list, i), "hostapd.bss");
		if (bss->iface != iface)
			goto free;

		for (size_t k = 0; k < i; k++)
			if (new_bss[k] == bss)
				goto free;

		new_bss[i] = bss;
		new_conf[i] = bss->conf;
	}

	new_bss[0]->interface_added = 0;
	for (size_t i = 1; i < iface->num_bss; i++)
		new_bss[i]->interface_added = 1;

	free(iface->bss);
	iface->bss = new_bss;

	free(iface->conf->bss);
	iface->conf->bss = new_conf;
	iface->conf->num_bss = iface->num_bss;
	hostapd_drv_set_first_bss(iface->bss[0]);

	return ucv_boolean_new(true);

free:
	free(new_bss);
	free(new_conf);
	return NULL;
}

static uc_value_t *
uc_hostapd_bss_ctrl(uc_vm_t *vm, size_t nargs)
{
	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
	uc_value_t *arg = uc_fn_arg(0);
	struct sockaddr_storage from = {};
	static char reply[4096];
	int reply_len;

	if (!hapd || !interfaces->ctrl_iface_recv ||
	    ucv_type(arg) != UC_STRING)
		return NULL;

	reply_len = interfaces->ctrl_iface_recv(hapd, ucv_string_get(arg),
						reply, sizeof(reply),
						&from, sizeof(from));
	if (reply_len < 0)
		return NULL;

	if (reply_len && reply[reply_len - 1] == '\n')
		reply_len--;

	return ucv_string_new_length(reply, reply_len);
}

static void
uc_hostapd_disable_iface(struct hostapd_iface *iface)
{
	switch (iface->state) {
	case HAPD_IFACE_DISABLED:
		break;
#ifdef CONFIG_ACS
	case HAPD_IFACE_ACS:
		acs_cleanup(iface);
		iface->scan_cb = NULL;
		/* fallthrough */
#endif
	default:
		hostapd_disable_iface(iface);
		break;
	}
}

static uc_value_t *
uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs)
{
	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
	int i;

	if (!iface)
		return NULL;

	if (iface->state != HAPD_IFACE_ENABLED)
		uc_hostapd_disable_iface(iface);

	for (i = 0; i < iface->num_bss; i++) {
		struct hostapd_data *hapd = iface->bss[i];

		hostapd_drv_stop_ap(hapd);
		hapd->beacon_set_done = 0;
	}

	return NULL;
}

static uc_value_t *
uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs)
{
	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
	uc_value_t *info = uc_fn_arg(0);
	struct hostapd_config *conf;
	bool changed = false;
	uint64_t intval;
	int i;

	if (!iface)
		return NULL;

	if (!info) {
		iface->freq = 0;
		goto out;
	}

	if (ucv_type(info) != UC_OBJECT)
		return NULL;

#define UPDATE_VAL(field, name)							\
	if ((intval = ucv_int64_get(ucv_object_get(info, name, NULL))) &&	\
		!errno && intval != conf->field) do {				\
		conf->field = intval;						\
		changed = true;							\
	} while(0)

	conf = iface->conf;
	UPDATE_VAL(op_class, "op_class");
	UPDATE_VAL(hw_mode, "hw_mode");
	UPDATE_VAL(channel, "channel");
	UPDATE_VAL(secondary_channel, "sec_channel");
	if (!changed &&
	    (iface->bss[0]->beacon_set_done ||
	     iface->state == HAPD_IFACE_DFS))
		return ucv_boolean_new(true);

	intval = ucv_int64_get(ucv_object_get(info, "center_seg0_idx", NULL));
	if (!errno)
		hostapd_set_oper_centr_freq_seg0_idx(conf, intval);

	intval = ucv_int64_get(ucv_object_get(info, "center_seg1_idx", NULL));
	if (!errno)
		hostapd_set_oper_centr_freq_seg1_idx(conf, intval);

	intval = ucv_int64_get(ucv_object_get(info, "oper_chwidth", NULL));
	if (!errno)
		hostapd_set_oper_chwidth(conf, intval);

	intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL));
	if (!errno)
		iface->freq = intval;
	else
		iface->freq = 0;
	conf->acs = 0;

out:
	switch (iface->state) {
	case HAPD_IFACE_ENABLED:
		if (!hostapd_is_dfs_required(iface) ||
			hostapd_is_dfs_chan_available(iface))
			break;
		wpa_printf(MSG_INFO, "DFS CAC required on new channel, restart interface");
		/* fallthrough */
	default:
		uc_hostapd_disable_iface(iface);
		break;
	}

	if (conf->channel && !iface->freq)
		iface->freq = hostapd_hw_get_freq(iface->bss[0], conf->channel);

	if (iface->state != HAPD_IFACE_ENABLED) {
		hostapd_enable_iface(iface);
		return ucv_boolean_new(true);
	}

	for (i = 0; i < iface->num_bss; i++) {
		struct hostapd_data *hapd = iface->bss[i];
		int ret;

		hapd->conf->start_disabled = 0;
		hostapd_set_freq(hapd, conf->hw_mode, iface->freq,
				 conf->channel,
				 conf->enable_edmg,
				 conf->edmg_channel,
				 conf->ieee80211n,
				 conf->ieee80211ac,
				 conf->ieee80211ax,
				 conf->ieee80211be,
				 conf->secondary_channel,
				 hostapd_get_oper_chwidth(conf),
				 hostapd_get_oper_centr_freq_seg0_idx(conf),
				 hostapd_get_oper_centr_freq_seg1_idx(conf));

		ieee802_11_set_beacon(hapd);
	}

	return ucv_boolean_new(true);
}

static uc_value_t *
uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs)
{
	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
	uc_value_t *info = uc_fn_arg(0);
	struct hostapd_config *conf;
	struct csa_settings csa = {};
	uint64_t intval;
	int i, ret = 0;

	if (!iface || ucv_type(info) != UC_OBJECT)
		return NULL;

	conf = iface->conf;
	if ((intval = ucv_int64_get(ucv_object_get(info, "csa_count", NULL))) && !errno)
		csa.cs_count = intval;
	if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno)
		csa.freq_params.sec_channel_offset = intval;

	csa.freq_params.ht_enabled = conf->ieee80211n;
	csa.freq_params.vht_enabled = conf->ieee80211ac;
	csa.freq_params.he_enabled = conf->ieee80211ax;
#ifdef CONFIG_IEEE80211BE
	csa.freq_params.eht_enabled = conf->ieee80211be;
#endif
	intval = ucv_int64_get(ucv_object_get(info, "oper_chwidth", NULL));
	if (errno)
		intval = hostapd_get_oper_chwidth(conf);
	if (intval)
		csa.freq_params.bandwidth = 40 << intval;
	else
		csa.freq_params.bandwidth = csa.freq_params.sec_channel_offset ? 40 : 20;

	if ((intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL))) && !errno)
		csa.freq_params.freq = intval;
	if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq1", NULL))) && !errno)
		csa.freq_params.center_freq1 = intval;
	if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq2", NULL))) && !errno)
		csa.freq_params.center_freq2 = intval;

	for (i = 0; i < iface->num_bss; i++)
		ret = hostapd_switch_channel(iface->bss[i], &csa);

	return ucv_boolean_new(!ret);
}

static uc_value_t *
uc_hostapd_bss_rename(uc_vm_t *vm, size_t nargs)
{
	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
	uc_value_t *ifname_arg = uc_fn_arg(0);
	char prev_ifname[IFNAMSIZ + 1];
	struct sta_info *sta;
	const char *ifname;
	int ret;

	if (!hapd || ucv_type(ifname_arg) != UC_STRING)
		return NULL;

	os_strlcpy(prev_ifname, hapd->conf->iface, sizeof(prev_ifname));
	ifname = ucv_string_get(ifname_arg);

	hostapd_ubus_free_bss(hapd);
	if (interfaces->ctrl_iface_deinit)
		interfaces->ctrl_iface_deinit(hapd);

	ret = hostapd_drv_if_rename(hapd, WPA_IF_AP_BSS, NULL, ifname);
	if (ret)
		goto out;

	for (sta = hapd->sta_list; sta; sta = sta->next) {
		char cur_name[IFNAMSIZ + 1], new_name[IFNAMSIZ + 1];

		if (!(sta->flags & WLAN_STA_WDS) || sta->pending_wds_enable)
			continue;

		snprintf(cur_name, sizeof(cur_name), "%s.sta%d", prev_ifname, sta->aid);
		snprintf(new_name, sizeof(new_name), "%s.sta%d", ifname, sta->aid);
		hostapd_drv_if_rename(hapd, WPA_IF_AP_VLAN, cur_name, new_name);
	}

	if (!strncmp(hapd->conf->ssid.vlan, hapd->conf->iface, sizeof(hapd->conf->ssid.vlan)))
		os_strlcpy(hapd->conf->ssid.vlan, ifname, sizeof(hapd->conf->ssid.vlan));
	os_strlcpy(hapd->conf->iface, ifname, sizeof(hapd->conf->iface));
	hostapd_ubus_add_bss(hapd);

	hostapd_ucode_update_interfaces();
out:
	if (interfaces->ctrl_iface_init)
		interfaces->ctrl_iface_init(hapd);

	return ret ? NULL : ucv_boolean_new(true);
}


int hostapd_ucode_init(struct hapd_interfaces *ifaces)
{
	static const uc_function_list_t global_fns[] = {
		{ "printf",	uc_wpa_printf },
		{ "getpid", uc_wpa_getpid },
		{ "sha1", uc_wpa_sha1 },
		{ "freq_info", uc_wpa_freq_info },
		{ "add_iface", uc_hostapd_add_iface },
		{ "remove_iface", uc_hostapd_remove_iface },
		{ "udebug_set", uc_wpa_udebug_set },
	};
	static const uc_function_list_t bss_fns[] = {
		{ "ctrl", uc_hostapd_bss_ctrl },
		{ "set_config", uc_hostapd_bss_set_config },
		{ "rename", uc_hostapd_bss_rename },
		{ "delete", uc_hostapd_bss_delete },
	};
	static const uc_function_list_t iface_fns[] = {
		{ "set_bss_order", uc_hostapd_iface_set_bss_order },
		{ "add_bss", uc_hostapd_iface_add_bss },
		{ "stop", uc_hostapd_iface_stop },
		{ "start", uc_hostapd_iface_start },
		{ "switch_channel", uc_hostapd_iface_switch_channel },
	};
	uc_value_t *data, *proto;

	interfaces = ifaces;
	vm = wpa_ucode_create_vm();

	global_type = uc_type_declare(vm, "hostapd.global", global_fns, NULL);
	bss_type = uc_type_declare(vm, "hostapd.bss", bss_fns, NULL);
	iface_type = uc_type_declare(vm, "hostapd.iface", iface_fns, NULL);

	bss_registry = ucv_array_new(vm);
	uc_vm_registry_set(vm, "hostap.bss_registry", bss_registry);

	iface_registry = ucv_array_new(vm);
	uc_vm_registry_set(vm, "hostap.iface_registry", iface_registry);

	global = wpa_ucode_global_init("hostapd", global_type);

	if (wpa_ucode_run(HOSTAPD_UC_PATH "hostapd.uc"))
		goto free_vm;
	ucv_gc(vm);

	return 0;

free_vm:
	wpa_ucode_free_vm();
	return -1;
}

void hostapd_ucode_free(void)
{
	if (wpa_ucode_call_prepare("shutdown") == 0)
		ucv_put(wpa_ucode_call(0));
	wpa_ucode_free_vm();
}

void hostapd_ucode_free_iface(struct hostapd_iface *iface)
{
	wpa_ucode_registry_remove(iface_registry, iface->ucode.idx);
}

void hostapd_ucode_add_bss(struct hostapd_data *hapd)
{
	uc_value_t *val;

	if (wpa_ucode_call_prepare("bss_add"))
		return;

	val = hostapd_ucode_bss_get_uval(hapd);
	uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
	uc_value_push(ucv_get(val));
	ucv_put(wpa_ucode_call(2));
	ucv_gc(vm);
}

void hostapd_ucode_reload_bss(struct hostapd_data *hapd)
{
	uc_value_t *val;

	if (wpa_ucode_call_prepare("bss_reload"))
		return;

	val = hostapd_ucode_bss_get_uval(hapd);
	uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
	uc_value_push(ucv_get(val));
	ucv_put(wpa_ucode_call(2));
	ucv_gc(vm);
}

void hostapd_ucode_free_bss(struct hostapd_data *hapd)
{
	uc_value_t *val;

	val = wpa_ucode_registry_remove(bss_registry, hapd->ucode.idx);
	if (!val)
		return;

	hapd->ucode.idx = 0;
	if (wpa_ucode_call_prepare("bss_remove"))
		return;

	uc_value_push(ucv_string_new(hapd->conf->iface));
	uc_value_push(ucv_get(val));
	ucv_put(wpa_ucode_call(2));
	ucv_gc(vm);
}
