/*
 * wpa_supplicant ctrl_iface helpers
 * Copyright (c) 2010-2011, Atheros Communications, Inc.
 * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"
#include <time.h>

#include "common.h"
#include "wpa_ctrl.h"
#include "wpa_helpers.h"


char *wpas_ctrl_path = "/var/run/wpa_supplicant/";
static int default_timeout = 60;


static struct wpa_ctrl * wpa_open_ctrl(const char *ifname)
{
	char buf[128];
	struct wpa_ctrl *ctrl;

	os_snprintf(buf, sizeof(buf), "%s%s", wpas_ctrl_path, ifname);
	ctrl = wpa_ctrl_open(buf);
	if (ctrl == NULL)
		printf("wpa_command: wpa_ctrl_open(%s) failed\n", buf);
	return ctrl;
}


int wpa_command(const char *ifname, const char *cmd)
{
	struct wpa_ctrl *ctrl;
	char buf[128];
	size_t len;

	printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
	ctrl = wpa_open_ctrl(ifname);
	if (ctrl == NULL)
		return -1;
	len = sizeof(buf);
	if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
		printf("wpa_command: wpa_ctrl_request failed\n");
		wpa_ctrl_close(ctrl);
		return -1;
	}
	wpa_ctrl_close(ctrl);
	buf[len] = '\0';
	if (strncmp(buf, "FAIL", 4) == 0) {
		printf("wpa_command: Command failed (FAIL received)\n");
		return -1;
	}
	return 0;
}


int wpa_command_resp(const char *ifname, const char *cmd,
		     char *resp, size_t resp_size)
{
	struct wpa_ctrl *ctrl;
	size_t len;

	printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
	ctrl = wpa_open_ctrl(ifname);
	if (ctrl == NULL)
		return -1;
	len = resp_size;
	if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), resp, &len, NULL) < 0) {
		printf("wpa_command: wpa_ctrl_request failed\n");
		wpa_ctrl_close(ctrl);
		return -1;
	}
	wpa_ctrl_close(ctrl);
	resp[len] = '\0';
	return 0;
}


struct wpa_ctrl * open_wpa_mon(const char *ifname)
{
	struct wpa_ctrl *ctrl;

	ctrl = wpa_open_ctrl(ifname);
	if (ctrl == NULL)
		return NULL;
	if (wpa_ctrl_attach(ctrl) < 0) {
		wpa_ctrl_close(ctrl);
		return NULL;
	}

	return ctrl;
}


int get_wpa_cli_event2(struct wpa_ctrl *mon,
		       const char *event, const char *event2,
		       char *buf, size_t buf_size)
{
	int fd, ret;
	fd_set rfd;
	char *pos;
	struct timeval tv;
	time_t start, now;

	printf("Waiting for wpa_cli event %s\n", event);
	fd = wpa_ctrl_get_fd(mon);
	if (fd < 0)
		return -1;

	time(&start);
	while (1) {
		size_t len;

		FD_ZERO(&rfd);
		FD_SET(fd, &rfd);
		tv.tv_sec = default_timeout;
		tv.tv_usec = 0;
		ret = select(fd + 1, &rfd, NULL, NULL, &tv);
		if (ret == 0) {
			printf("Timeout on waiting for event %s\n", event);
			return -1;
		}
		if (ret < 0) {
			printf("select: %s\n", strerror(errno));
			return -1;
		}
		len = buf_size;
		if (wpa_ctrl_recv(mon, buf, &len) < 0) {
			printf("Failure while waiting for event %s\n", event);
			return -1;
		}
		if (len == buf_size)
			len--;
		buf[len] = '\0';

		pos = strchr(buf, '>');
		if (pos &&
		    (strncmp(pos + 1, event, strlen(event)) == 0 ||
		     (event2 &&
		      strncmp(pos + 1, event2, strlen(event2)) == 0)))
			return 0; /* Event found */

		time(&now);
		if ((int) (now - start) > default_timeout) {
			printf("Timeout on waiting for event %s\n", event);
			return -1;
		}
	}
}


int get_wpa_cli_event(struct wpa_ctrl *mon,
		      const char *event, char *buf, size_t buf_size)
{
	return get_wpa_cli_event2(mon, event, NULL, buf, buf_size);
}


int get_wpa_status(const char *ifname, const char *field, char *obuf,
		   size_t obuf_size)
{
	struct wpa_ctrl *ctrl;
	char buf[4096];
	char *pos, *end;
	size_t len, flen;

	ctrl = wpa_open_ctrl(ifname);
	if (ctrl == NULL)
		return -1;
	len = sizeof(buf);
	if (wpa_ctrl_request(ctrl, "STATUS", 6, buf, &len, NULL) < 0) {
		wpa_ctrl_close(ctrl);
		return -1;
	}
	wpa_ctrl_close(ctrl);
	buf[len] = '\0';

	flen = strlen(field);
	pos = buf;
	while (pos + flen < buf + len) {
		if (pos > buf) {
			if (*pos != '\n') {
				pos++;
				continue;
			}
			pos++;
		}
		if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
			pos++;
			continue;
		}
		pos += flen + 1;
		end = strchr(pos, '\n');
		if (end == NULL)
			return -1;
		*end++ = '\0';
		if (end - pos > (int) obuf_size)
			return -1;
		memcpy(obuf, pos, end - pos);
		return 0;
	}

	return -1;
}


int wait_ip_addr(const char *ifname, int timeout)
{
	char ip[30];
	int count = timeout;
	struct wpa_ctrl *ctrl;

	while (count > 0) {
		printf("%s: ifname='%s' - %d seconds remaining\n",
		       __func__, ifname, count);
		count--;
		if (get_wpa_status(ifname, "ip_address", ip, sizeof(ip)) == 0
		    && strlen(ip) > 0) {
			printf("IP address found: '%s'\n", ip);
			return 0;
		}
		ctrl = wpa_open_ctrl(ifname);
		if (ctrl == NULL)
			return -1;
		wpa_ctrl_close(ctrl);
		sleep(1);
	}
	printf("%s: Could not get IP address for ifname='%s'", __func__,
	       ifname);
	return -1;
}


int add_network(const char *ifname)
{
	char res[30];

	if (wpa_command_resp(ifname, "ADD_NETWORK", res, sizeof(res)) < 0)
		return -1;
	return atoi(res);
}


int set_network(const char *ifname, int id, const char *field,
		const char *value)
{
	char buf[200];
	snprintf(buf, sizeof(buf), "SET_NETWORK %d %s %s", id, field, value);
	return wpa_command(ifname, buf);
}


int set_network_quoted(const char *ifname, int id, const char *field,
		       const char *value)
{
	char buf[200];
	snprintf(buf, sizeof(buf), "SET_NETWORK %d %s \"%s\"",
		 id, field, value);
	return wpa_command(ifname, buf);
}


int add_cred(const char *ifname)
{
	char res[30];

	if (wpa_command_resp(ifname, "ADD_CRED", res, sizeof(res)) < 0)
		return -1;
	return atoi(res);
}


int set_cred(const char *ifname, int id, const char *field, const char *value)
{
	char buf[200];
	snprintf(buf, sizeof(buf), "SET_CRED %d %s %s", id, field, value);
	return wpa_command(ifname, buf);
}


int set_cred_quoted(const char *ifname, int id, const char *field,
		    const char *value)
{
	char buf[200];
	snprintf(buf, sizeof(buf), "SET_CRED %d %s \"%s\"",
		 id, field, value);
	return wpa_command(ifname, buf);
}
