/*
 * FST module - Control Interface implementation
 * Copyright (c) 2014, Qualcomm Atheros, Inc.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "utils/includes.h"
#include "utils/common.h"
#include "common/defs.h"
#include "list.h"
#include "fst/fst.h"
#include "fst/fst_internal.h"
#include "fst_ctrl_defs.h"
#include "fst_ctrl_iface.h"


static struct fst_group * get_fst_group_by_id(const char *id)
{
	struct fst_group *g;

	foreach_fst_group(g) {
		const char *group_id = fst_group_get_id(g);

		if (os_strncmp(group_id, id, os_strlen(group_id)) == 0)
			return g;
	}

	return NULL;
}


/* notifications */
static bool format_session_state_extra(const union fst_event_extra *extra,
				       char *buffer, size_t size)
{
	int len;
	char reject_str[32] = FST_CTRL_PVAL_NONE;
	const char *initiator = FST_CTRL_PVAL_NONE;
	const struct fst_event_extra_session_state *ss;

	ss = &extra->session_state;
	if (ss->new_state != FST_SESSION_STATE_INITIAL)
		return true;

	switch (ss->extra.to_initial.reason) {
	case REASON_REJECT:
		if (ss->extra.to_initial.reject_code != WLAN_STATUS_SUCCESS)
			os_snprintf(reject_str, sizeof(reject_str), "%u",
				    ss->extra.to_initial.reject_code);
		/* fall through */
	case REASON_TEARDOWN:
	case REASON_SWITCH:
		switch (ss->extra.to_initial.initiator) {
		case FST_INITIATOR_LOCAL:
			initiator = FST_CS_PVAL_INITIATOR_LOCAL;
			break;
		case FST_INITIATOR_REMOTE:
			initiator = FST_CS_PVAL_INITIATOR_REMOTE;
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}

	len = os_snprintf(buffer, size,
			  FST_CES_PNAME_REASON "=%s "
			  FST_CES_PNAME_REJECT_CODE "=%s "
			  FST_CES_PNAME_INITIATOR "=%s",
			  fst_reason_name(ss->extra.to_initial.reason),
			  reject_str, initiator);

	return !os_snprintf_error(size, len);
}


static void fst_ctrl_iface_notify(struct fst_iface *f, u32 session_id,
				  enum fst_event_type event_type,
				  const union fst_event_extra *extra)
{
	struct fst_group *g;
	char extra_str[128] = "";
	const struct fst_event_extra_session_state *ss;
	const struct fst_event_extra_iface_state *is;
	const struct fst_event_extra_peer_state *ps;

	/*
	 * FST can use any of interface objects as it only sends messages
	 * on global Control Interface, so we just pick the 1st one.
	 */

	if (!f) {
		foreach_fst_group(g) {
			f = fst_group_first_iface(g);
			if (f)
				break;
		}
		if (!f)
			return;
	}

	WPA_ASSERT(f->iface_obj.ctx);

	switch (event_type) {
	case EVENT_FST_IFACE_STATE_CHANGED:
		if (!extra)
			return;
		is = &extra->iface_state;
		wpa_msg_global_only(f->iface_obj.ctx, MSG_INFO,
				    FST_CTRL_EVENT_IFACE " %s "
				    FST_CEI_PNAME_IFNAME "=%s "
				    FST_CEI_PNAME_GROUP "=%s",
				    is->attached ? FST_CEI_PNAME_ATTACHED :
				    FST_CEI_PNAME_DETACHED,
				    is->ifname, is->group_id);
		break;
	case EVENT_PEER_STATE_CHANGED:
		if (!extra)
			return;
		ps = &extra->peer_state;
		wpa_msg_global_only(fst_iface_get_wpa_obj_ctx(f), MSG_INFO,
				    FST_CTRL_EVENT_PEER " %s "
				    FST_CEP_PNAME_IFNAME "=%s "
				    FST_CEP_PNAME_ADDR "=" MACSTR,
				    ps->connected ? FST_CEP_PNAME_CONNECTED :
				    FST_CEP_PNAME_DISCONNECTED,
				    ps->ifname, MAC2STR(ps->addr));
		break;
	case EVENT_FST_SESSION_STATE_CHANGED:
		if (!extra)
			return;
		if (!format_session_state_extra(extra, extra_str,
						sizeof(extra_str))) {
			fst_printf(MSG_ERROR,
				   "CTRL: Cannot format STATE_CHANGE extra");
			extra_str[0] = 0;
		}
		ss = &extra->session_state;
		wpa_msg_global_only(fst_iface_get_wpa_obj_ctx(f), MSG_INFO,
				    FST_CTRL_EVENT_SESSION " "
				    FST_CES_PNAME_SESSION_ID "=%u "
				    FST_CES_PNAME_EVT_TYPE "=%s "
				    FST_CES_PNAME_OLD_STATE "=%s "
				    FST_CES_PNAME_NEW_STATE "=%s %s",
				    session_id,
				    fst_session_event_type_name(event_type),
				    fst_session_state_name(ss->old_state),
				    fst_session_state_name(ss->new_state),
				    extra_str);
		break;
	case EVENT_FST_ESTABLISHED:
	case EVENT_FST_SETUP:
		wpa_msg_global_only(fst_iface_get_wpa_obj_ctx(f), MSG_INFO,
				    FST_CTRL_EVENT_SESSION " "
				    FST_CES_PNAME_SESSION_ID "=%u "
				    FST_CES_PNAME_EVT_TYPE "=%s",
				    session_id,
				    fst_session_event_type_name(event_type));
		break;
	}
}


/* command processors */

/* fst session_get */
static int session_get(const char *session_id, char *buf, size_t buflen)
{
	struct fst_session *s;
	struct fst_iface *new_iface, *old_iface;
	const u8 *old_peer_addr, *new_peer_addr;
	u32 id;

	id = strtoul(session_id, NULL, 0);

	s = fst_session_get_by_id(id);
	if (!s) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	old_peer_addr = fst_session_get_peer_addr(s, true);
	new_peer_addr = fst_session_get_peer_addr(s, false);
	new_iface = fst_session_get_iface(s, false);
	old_iface = fst_session_get_iface(s, true);

	return os_snprintf(buf, buflen,
			   FST_CSG_PNAME_OLD_PEER_ADDR "=" MACSTR "\n"
			   FST_CSG_PNAME_NEW_PEER_ADDR "=" MACSTR "\n"
			   FST_CSG_PNAME_NEW_IFNAME "=%s\n"
			   FST_CSG_PNAME_OLD_IFNAME "=%s\n"
			   FST_CSG_PNAME_LLT "=%u\n"
			   FST_CSG_PNAME_STATE "=%s\n",
			   MAC2STR(old_peer_addr),
			   MAC2STR(new_peer_addr),
			   new_iface ? fst_iface_get_name(new_iface) :
			   FST_CTRL_PVAL_NONE,
			   old_iface ? fst_iface_get_name(old_iface) :
			   FST_CTRL_PVAL_NONE,
			   fst_session_get_llt(s),
			   fst_session_state_name(fst_session_get_state(s)));
}


/* fst session_set */
static int session_set(const char *session_id, char *buf, size_t buflen)
{
	struct fst_session *s;
	char *p, *q;
	u32 id;
	int ret;

	id = strtoul(session_id, &p, 0);

	s = fst_session_get_by_id(id);
	if (!s) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	if (*p != ' ' || !(q = os_strchr(p + 1, '=')))
		return os_snprintf(buf, buflen, "FAIL\n");
	p++;

	if (os_strncasecmp(p, FST_CSS_PNAME_OLD_IFNAME, q - p) == 0) {
		ret = fst_session_set_str_ifname(s, q + 1, true);
	} else if (os_strncasecmp(p, FST_CSS_PNAME_NEW_IFNAME, q - p) == 0) {
		ret = fst_session_set_str_ifname(s, q + 1, false);
	} else if (os_strncasecmp(p, FST_CSS_PNAME_OLD_PEER_ADDR, q - p) == 0) {
		ret = fst_session_set_str_peer_addr(s, q + 1, true);
	} else if (os_strncasecmp(p, FST_CSS_PNAME_NEW_PEER_ADDR, q - p) == 0) {
		ret = fst_session_set_str_peer_addr(s, q + 1, false);
	} else if (os_strncasecmp(p, FST_CSS_PNAME_LLT, q - p) == 0) {
		ret = fst_session_set_str_llt(s, q + 1);
	} else {
		fst_printf(MSG_ERROR, "CTRL: Unknown parameter: %s", p);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	return os_snprintf(buf, buflen, "%s\n", ret ? "FAIL" : "OK");
}


/* fst session_add/remove */
static int session_add(const char *group_id, char *buf, size_t buflen)
{
	struct fst_group *g;
	struct fst_session *s;

	g = get_fst_group_by_id(group_id);
	if (!g) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find group '%s'",
			   group_id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	s = fst_session_create(g);
	if (!s) {
		fst_printf(MSG_ERROR,
			   "CTRL: Cannot create session for group '%s'",
			   group_id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	return os_snprintf(buf, buflen, "%u\n", fst_session_get_id(s));
}


static int session_remove(const char *session_id, char *buf, size_t buflen)
{
	struct fst_session *s;
	struct fst_group *g;
	u32 id;

	id = strtoul(session_id, NULL, 0);

	s = fst_session_get_by_id(id);
	if (!s) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	g = fst_session_get_group(s);
	fst_session_reset(s);
	fst_session_delete(s);
	fst_group_delete_if_empty(g);

	return os_snprintf(buf, buflen, "OK\n");
}


/* fst session_initiate */
static int session_initiate(const char *session_id, char *buf, size_t buflen)
{
	struct fst_session *s;
	u32 id;

	id = strtoul(session_id, NULL, 0);

	s = fst_session_get_by_id(id);
	if (!s) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	if (fst_session_initiate_setup(s)) {
		fst_printf(MSG_WARNING, "CTRL: Cannot initiate session %u", id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	return os_snprintf(buf, buflen, "OK\n");
}


/* fst session_respond */
static int session_respond(const char *session_id, char *buf, size_t buflen)
{
	struct fst_session *s;
	char *p;
	u32 id;
	u8 status_code;

	id = strtoul(session_id, &p, 0);

	s = fst_session_get_by_id(id);
	if (!s) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	if (*p != ' ')
		return os_snprintf(buf, buflen, "FAIL\n");
	p++;

	if (!os_strcasecmp(p, FST_CS_PVAL_RESPONSE_ACCEPT)) {
		status_code = WLAN_STATUS_SUCCESS;
	} else if (!os_strcasecmp(p, FST_CS_PVAL_RESPONSE_REJECT)) {
		status_code = WLAN_STATUS_PENDING_ADMITTING_FST_SESSION;
	} else {
		fst_printf(MSG_WARNING,
			   "CTRL: session %u: unknown response status: %s",
			   id, p);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	if (fst_session_respond(s, status_code)) {
		fst_printf(MSG_WARNING, "CTRL: Cannot respond to session %u",
			   id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	fst_printf(MSG_INFO, "CTRL: session %u responded", id);

	return os_snprintf(buf, buflen, "OK\n");
}


/* fst session_transfer */
static int session_transfer(const char *session_id, char *buf, size_t buflen)
{
	struct fst_session *s;
	u32 id;

	id = strtoul(session_id, NULL, 0);

	s = fst_session_get_by_id(id);
	if (!s) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	if (fst_session_initiate_switch(s)) {
		fst_printf(MSG_WARNING,
			   "CTRL: Cannot initiate ST for session %u", id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	return os_snprintf(buf, buflen, "OK\n");
}


/* fst session_teardown */
static int session_teardown(const char *session_id, char *buf, size_t buflen)
{
	struct fst_session *s;
	u32 id;

	id = strtoul(session_id, NULL, 0);

	s = fst_session_get_by_id(id);
	if (!s) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find session %u", id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	if (fst_session_tear_down_setup(s)) {
		fst_printf(MSG_WARNING, "CTRL: Cannot tear down session %u",
			   id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	return os_snprintf(buf, buflen, "OK\n");
}


#ifdef CONFIG_FST_TEST
/* fst test_request */
static int test_request(const char *request, char *buf, size_t buflen)
{
	const char *p = request;
	int ret;

	if (!os_strncasecmp(p, FST_CTR_SEND_SETUP_REQUEST,
			    os_strlen(FST_CTR_SEND_SETUP_REQUEST))) {
		ret = fst_test_req_send_fst_request(
			p + os_strlen(FST_CTR_SEND_SETUP_REQUEST));
	} else if (!os_strncasecmp(p, FST_CTR_SEND_SETUP_RESPONSE,
				   os_strlen(FST_CTR_SEND_SETUP_RESPONSE))) {
		ret = fst_test_req_send_fst_response(
			p + os_strlen(FST_CTR_SEND_SETUP_RESPONSE));
	} else if (!os_strncasecmp(p, FST_CTR_SEND_ACK_REQUEST,
				   os_strlen(FST_CTR_SEND_ACK_REQUEST))) {
		ret = fst_test_req_send_ack_request(
			p + os_strlen(FST_CTR_SEND_ACK_REQUEST));
	} else if (!os_strncasecmp(p, FST_CTR_SEND_ACK_RESPONSE,
				   os_strlen(FST_CTR_SEND_ACK_RESPONSE))) {
		ret = fst_test_req_send_ack_response(
			p + os_strlen(FST_CTR_SEND_ACK_RESPONSE));
	} else if (!os_strncasecmp(p, FST_CTR_SEND_TEAR_DOWN,
				   os_strlen(FST_CTR_SEND_TEAR_DOWN))) {
		ret = fst_test_req_send_tear_down(
			p + os_strlen(FST_CTR_SEND_TEAR_DOWN));
	} else if (!os_strncasecmp(p, FST_CTR_GET_FSTS_ID,
				   os_strlen(FST_CTR_GET_FSTS_ID))) {
		u32 fsts_id = fst_test_req_get_fsts_id(
			p + os_strlen(FST_CTR_GET_FSTS_ID));
		if (fsts_id != FST_FSTS_ID_NOT_FOUND)
			return os_snprintf(buf, buflen, "%u\n", fsts_id);
		return os_snprintf(buf, buflen, "FAIL\n");
	} else if (!os_strncasecmp(p, FST_CTR_GET_LOCAL_MBIES,
				   os_strlen(FST_CTR_GET_LOCAL_MBIES))) {
		return fst_test_req_get_local_mbies(
			p + os_strlen(FST_CTR_GET_LOCAL_MBIES), buf, buflen);
	} else if (!os_strncasecmp(p, FST_CTR_IS_SUPPORTED,
				   os_strlen(FST_CTR_IS_SUPPORTED))) {
		ret = 0;
	} else {
		fst_printf(MSG_ERROR, "CTRL: Unknown parameter: %s", p);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	return os_snprintf(buf, buflen, "%s\n", ret ? "FAIL" : "OK");
}
#endif /* CONFIG_FST_TEST */


/* fst list_sessions */
struct list_sessions_cb_ctx {
	char *buf;
	size_t buflen;
	size_t reply_len;
};


static void list_session_enum_cb(struct fst_group *g, struct fst_session *s,
				 void *ctx)
{
	struct list_sessions_cb_ctx *c = ctx;
	int ret;

	ret = os_snprintf(c->buf, c->buflen, " %u", fst_session_get_id(s));

	c->buf += ret;
	c->buflen -= ret;
	c->reply_len += ret;
}


static int list_sessions(const char *group_id, char *buf, size_t buflen)
{
	struct list_sessions_cb_ctx ctx;
	struct fst_group *g;

	g = get_fst_group_by_id(group_id);
	if (!g) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find group '%s'",
			   group_id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	ctx.buf = buf;
	ctx.buflen = buflen;
	ctx.reply_len = 0;

	fst_session_enum(g, list_session_enum_cb, &ctx);

	ctx.reply_len += os_snprintf(buf + ctx.reply_len, ctx.buflen, "\n");

	return ctx.reply_len;
}


/* fst iface_peers */
static int iface_peers(const char *group_id, char *buf, size_t buflen)
{
	const char *ifname;
	struct fst_group *g;
	struct fst_iface *f;
	struct fst_get_peer_ctx *ctx;
	const u8 *addr;
	unsigned found = 0;
	int ret = 0;

	g = get_fst_group_by_id(group_id);
	if (!g) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find group '%s'",
			   group_id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	ifname = os_strchr(group_id, ' ');
	if (!ifname)
		return os_snprintf(buf, buflen, "FAIL\n");
	ifname++;

	foreach_fst_group_iface(g, f) {
		const char *in = fst_iface_get_name(f);

		if (os_strncmp(ifname, in, os_strlen(in)) == 0) {
			found = 1;
			break;
		}
	}

	if (!found)
		return os_snprintf(buf, buflen, "FAIL\n");

	addr = fst_iface_get_peer_first(f, &ctx, false);
	for (; addr != NULL; addr = fst_iface_get_peer_next(f, &ctx, false)) {
		int res;

		res = os_snprintf(buf + ret, buflen - ret, MACSTR "\n",
				  MAC2STR(addr));
		if (os_snprintf_error(buflen - ret, res))
			break;
		ret += res;
	}

	return ret;
}


static int get_peer_mbies(const char *params, char *buf, size_t buflen)
{
	char *endp;
	char ifname[FST_MAX_INTERFACE_SIZE];
	u8 peer_addr[ETH_ALEN];
	struct fst_group *g;
	struct fst_iface *iface = NULL;
	const struct wpabuf *mbies;

	if (fst_read_next_text_param(params, ifname, sizeof(ifname), &endp) ||
	    !*ifname)
		goto problem;

	while (isspace(*endp))
		endp++;
	if (fst_read_peer_addr(endp, peer_addr))
		goto problem;

	foreach_fst_group(g) {
		iface = fst_group_get_iface_by_name(g, ifname);
		if (iface)
			break;
	}
	if (!iface)
		goto problem;

	mbies = fst_iface_get_peer_mb_ie(iface, peer_addr);
	if (!mbies)
		goto problem;

	return wpa_snprintf_hex(buf, buflen, wpabuf_head(mbies),
				wpabuf_len(mbies));

problem:
	return os_snprintf(buf, buflen, "FAIL\n");
}


/* fst list_ifaces */
static int list_ifaces(const char *group_id, char *buf, size_t buflen)
{
	struct fst_group *g;
	struct fst_iface *f;
	int ret = 0;

	g = get_fst_group_by_id(group_id);
	if (!g) {
		fst_printf(MSG_WARNING, "CTRL: Cannot find group '%s'",
			   group_id);
		return os_snprintf(buf, buflen, "FAIL\n");
	}

	foreach_fst_group_iface(g, f) {
		int res;
		const u8 *iface_addr = fst_iface_get_addr(f);

		res = os_snprintf(buf + ret, buflen - ret,
				  "%s|" MACSTR "|%u|%u\n",
				  fst_iface_get_name(f),
				  MAC2STR(iface_addr),
				  fst_iface_get_priority(f),
				  fst_iface_get_llt(f));
		if (os_snprintf_error(buflen - ret, res))
			break;
		ret += res;
	}

	return ret;
}


/* fst list_groups */
static int list_groups(const char *cmd, char *buf, size_t buflen)
{
	struct fst_group *g;
	int ret = 0;

	foreach_fst_group(g) {
		int res;

		res = os_snprintf(buf + ret, buflen - ret, "%s\n",
				  fst_group_get_id(g));
		if (os_snprintf_error(buflen - ret, res))
			break;
		ret += res;
	}

	return ret;
}


static const char * band_freq(enum mb_band_id band)
{
	static const char *band_names[] = {
		[MB_BAND_ID_WIFI_2_4GHZ] = "2.4GHZ",
		[MB_BAND_ID_WIFI_5GHZ] = "5GHZ",
		[MB_BAND_ID_WIFI_60GHZ] = "60GHZ",
	};

	return fst_get_str_name(band, band_names, ARRAY_SIZE(band_names));
}


static int print_band(unsigned num, struct fst_iface *iface, const u8 *addr,
		      char *buf, size_t buflen)
{
	const struct wpabuf *wpabuf;
	enum hostapd_hw_mode hw_mode;
	u8 channel;
	int ret = 0;

	fst_iface_get_channel_info(iface, &hw_mode, &channel);

	ret += os_snprintf(buf + ret, buflen - ret, "band%u_frequency=%s\n",
			   num, band_freq(fst_hw_mode_to_band(hw_mode)));
	ret += os_snprintf(buf + ret, buflen - ret, "band%u_iface=%s\n",
			   num, fst_iface_get_name(iface));
	wpabuf = fst_iface_get_peer_mb_ie(iface, addr);
	if (wpabuf) {
		ret += os_snprintf(buf + ret, buflen - ret, "band%u_mb_ies=",
				   num);
		ret += wpa_snprintf_hex(buf + ret, buflen - ret,
					wpabuf_head(wpabuf),
					wpabuf_len(wpabuf));
		ret += os_snprintf(buf + ret, buflen - ret, "\n");
	}
	ret += os_snprintf(buf + ret, buflen - ret, "band%u_fst_group_id=%s\n",
			   num, fst_iface_get_group_id(iface));
	ret += os_snprintf(buf + ret, buflen - ret, "band%u_fst_priority=%u\n",
			   num, fst_iface_get_priority(iface));
	ret += os_snprintf(buf + ret, buflen - ret, "band%u_fst_llt=%u\n",
			   num, fst_iface_get_llt(iface));

	return ret;
}


static void fst_ctrl_iface_on_iface_state_changed(struct fst_iface *i,
						  bool attached)
{
	union fst_event_extra extra;

	os_memset(&extra, 0, sizeof(extra));
	extra.iface_state.attached = attached;
	os_strlcpy(extra.iface_state.ifname, fst_iface_get_name(i),
		   sizeof(extra.iface_state.ifname));
	os_strlcpy(extra.iface_state.group_id, fst_iface_get_group_id(i),
		   sizeof(extra.iface_state.group_id));

	fst_ctrl_iface_notify(i, FST_INVALID_SESSION_ID,
			      EVENT_FST_IFACE_STATE_CHANGED, &extra);
}


static int fst_ctrl_iface_on_iface_added(struct fst_iface *i)
{
	fst_ctrl_iface_on_iface_state_changed(i, true);
	return 0;
}


static void fst_ctrl_iface_on_iface_removed(struct fst_iface *i)
{
	fst_ctrl_iface_on_iface_state_changed(i, false);
}


static void fst_ctrl_iface_on_event(enum fst_event_type event_type,
				    struct fst_iface *i, struct fst_session *s,
				    const union fst_event_extra *extra)
{
	u32 session_id = s ? fst_session_get_id(s) : FST_INVALID_SESSION_ID;

	fst_ctrl_iface_notify(i, session_id, event_type, extra);
}


static const struct fst_ctrl ctrl_cli = {
	.on_iface_added = fst_ctrl_iface_on_iface_added,
	.on_iface_removed =  fst_ctrl_iface_on_iface_removed,
	.on_event = fst_ctrl_iface_on_event,
};

const struct fst_ctrl *fst_ctrl_cli = &ctrl_cli;


int fst_ctrl_iface_mb_info(const u8 *addr, char *buf, size_t buflen)
{
	struct fst_group *g;
	struct fst_iface *f;
	unsigned num = 0;
	int ret = 0;

	foreach_fst_group(g) {
		foreach_fst_group_iface(g, f) {
			if (fst_iface_is_connected(f, addr, true)) {
				ret += print_band(num++, f, addr,
						  buf + ret, buflen - ret);
			}
		}
	}

	return ret;
}


/* fst ctrl processor */
int fst_ctrl_iface_receive(const char *cmd, char *reply, size_t reply_size)
{
	static const struct fst_command {
		const char *name;
		unsigned has_param;
		int (*process)(const char *group_id, char *buf, size_t buflen);
	} commands[] = {
		{ FST_CMD_LIST_GROUPS, 0, list_groups},
		{ FST_CMD_LIST_IFACES, 1, list_ifaces},
		{ FST_CMD_IFACE_PEERS, 1, iface_peers},
		{ FST_CMD_GET_PEER_MBIES, 1, get_peer_mbies},
		{ FST_CMD_LIST_SESSIONS, 1, list_sessions},
		{ FST_CMD_SESSION_ADD, 1, session_add},
		{ FST_CMD_SESSION_REMOVE, 1, session_remove},
		{ FST_CMD_SESSION_GET, 1, session_get},
		{ FST_CMD_SESSION_SET, 1, session_set},
		{ FST_CMD_SESSION_INITIATE, 1, session_initiate},
		{ FST_CMD_SESSION_RESPOND, 1, session_respond},
		{ FST_CMD_SESSION_TRANSFER, 1, session_transfer},
		{ FST_CMD_SESSION_TEARDOWN, 1, session_teardown},
#ifdef CONFIG_FST_TEST
		{ FST_CMD_TEST_REQUEST, 1, test_request },
#endif /* CONFIG_FST_TEST */
		{ NULL, 0, NULL }
	};
	const struct fst_command *c;
	const char *p;
	const char *temp;
	bool non_spaces_found;

	for (c = commands; c->name; c++) {
		if (os_strncasecmp(cmd, c->name, os_strlen(c->name)) != 0)
			continue;
		p = cmd + os_strlen(c->name);
		if (c->has_param) {
			if (!isspace(p[0]))
				return os_snprintf(reply, reply_size, "FAIL\n");
			p++;
			temp = p;
			non_spaces_found = false;
			while (*temp) {
				if (!isspace(*temp)) {
					non_spaces_found = true;
					break;
				}
				temp++;
			}
			if (!non_spaces_found)
				return os_snprintf(reply, reply_size, "FAIL\n");
		}
		return c->process(p, reply, reply_size);
	}

	return os_snprintf(reply, reply_size, "UNKNOWN FST COMMAND\n");
}


int fst_read_next_int_param(const char *params, bool *valid, char **endp)
{
	int ret = -1;
	const char *curp;

	*valid = false;
	*endp = (char *) params;
	curp = params;
	if (*curp) {
		ret = (int) strtol(curp, endp, 0);
		if (!**endp || isspace(**endp))
			*valid = true;
	}

	return ret;
}


int fst_read_next_text_param(const char *params, char *buf, size_t buflen,
			     char **endp)
{
	size_t max_chars_to_copy;
	char *cur_dest;

	*endp = (char *) params;
	while (isspace(**endp))
		(*endp)++;
	if (!**endp || buflen <= 1)
		return -EINVAL;

	max_chars_to_copy = buflen - 1;
	/* We need 1 byte for the terminating zero */
	cur_dest = buf;
	while (**endp && !isspace(**endp) && max_chars_to_copy > 0) {
		*cur_dest = **endp;
		(*endp)++;
		cur_dest++;
		max_chars_to_copy--;
	}
	*cur_dest = 0;

	return 0;
}


int fst_read_peer_addr(const char *mac, u8 *peer_addr)
{
	if (hwaddr_aton(mac, peer_addr)) {
		fst_printf(MSG_WARNING, "Bad peer_mac %s: invalid addr string",
			   mac);
		return -1;
	}

	if (is_zero_ether_addr(peer_addr) ||
	    is_multicast_ether_addr(peer_addr)) {
		fst_printf(MSG_WARNING, "Bad peer_mac %s: not a unicast addr",
			   mac);
		return -1;
	}

	return 0;
}


int fst_parse_attach_command(const char *cmd, char *ifname, size_t ifname_size,
			     struct fst_iface_cfg *cfg)
{
	char *pos;
	char *endp;
	bool is_valid;
	int val;

	if (fst_read_next_text_param(cmd, ifname, ifname_size, &endp) ||
	    fst_read_next_text_param(endp, cfg->group_id, sizeof(cfg->group_id),
				     &endp))
		return -EINVAL;

	cfg->llt = FST_DEFAULT_LLT_CFG_VALUE;
	cfg->priority = 0;
	pos = os_strstr(endp, FST_ATTACH_CMD_PNAME_LLT);
	if (pos) {
		pos += os_strlen(FST_ATTACH_CMD_PNAME_LLT);
		if (*pos == '=') {
			val = fst_read_next_int_param(pos + 1, &is_valid,
						      &endp);
			if (is_valid)
				cfg->llt = val;
		}
	}
	pos = os_strstr(endp, FST_ATTACH_CMD_PNAME_PRIORITY);
	if (pos) {
		pos += os_strlen(FST_ATTACH_CMD_PNAME_PRIORITY);
		if (*pos == '=') {
			val = fst_read_next_int_param(pos + 1, &is_valid,
						      &endp);
			if (is_valid)
				cfg->priority = (u8) val;
		}
	}

	return 0;
}


int fst_parse_detach_command(const char *cmd, char *ifname, size_t ifname_size)
{
	char *endp;

	return fst_read_next_text_param(cmd, ifname, ifname_size, &endp);
}


int fst_iface_detach(const char *ifname)
{
	struct fst_group *g;

	foreach_fst_group(g) {
		struct fst_iface *f;

		f = fst_group_get_iface_by_name(g, ifname);
		if (f) {
			fst_detach(f);
			return 0;
		}
	}

	return -EINVAL;
}
