/*
 * wl anqpo command module
 *
 * Broadcom Proprietary and Confidential. Copyright (C) 2017,
 * All Rights Reserved.
 * 
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
 * the contents of this file may not be disclosed to third parties, copied
 * or duplicated in any form, in whole or in part, without the prior
 * written permission of Broadcom.
 *
 *
 * <<Broadcom-WL-IPTag/Proprietary:>>
 *
 * $Id: wluc_anqpo.c 458728 2014-02-27 18:15:25Z $
 */

#ifdef WIN32
#include <windows.h>
#endif

#include <wlioctl.h>

#if	defined(DONGLEBUILD)
#include <typedefs.h>
#include <osl.h>
#endif

/* Because IL_BIGENDIAN was removed there are few warnings that need
 * to be fixed. Windows was not compiled earlier with IL_BIGENDIAN.
 * Hence these warnings were not seen earlier.
 * For now ignore the following warnings
 */
#ifdef WIN32
#pragma warning(push)
#pragma warning(disable : 4244)
#pragma warning(disable : 4761)
#endif

#include <bcmutils.h>
#include <bcmendian.h>
#include "wlu_common.h"
#include "wlu.h"

#ifdef LINUX
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <linux/if_packet.h>
#endif /* LINUX */

static cmd_func_t wl_anqpo_set;
static cmd_func_t wl_anqpo_stop_query;
static cmd_func_t wl_anqpo_start_query;
static cmd_func_t wl_anqpo_ignore_ssid_list;
static cmd_func_t wl_anqpo_ignore_bssid_list;
#if defined(linux)
static cmd_func_t wl_anqpo_results;
#endif	/* linux */

static cmd_t wl_anqpo_cmds[] = {
	{ "anqpo_set", wl_anqpo_set, -1, -1,
	"set ANQP offload parameters\n"
	"\tusage: anqpo_set [max_retransmit <number>]\n"
	"\t\t[response_timeout <msec>] [max_comeback_delay <msec>]\n"
	"\t\t[max_retries <number>] [query \"encoded ANQP query\"]"
	},
	{ "anqpo_stop_query", wl_anqpo_stop_query, -1, WLC_SET_VAR,
	"stop ANQP query\n"
	"\tusage: anqpo_stop_query"
	},
	{ "anqpo_start_query", wl_anqpo_start_query, -1, WLC_SET_VAR,
	"start ANQP query to peer(s)\n"
	"\tusage: anqpo_start_query <channel> <xx:xx:xx:xx:xx:xx>\n"
	"\t\t[<channel> <xx:xx:xx:xx:xx:xx>]>"
	},
	{ "anqpo_auto_hotspot", wl_varint, WLC_GET_VAR, WLC_SET_VAR,
	"automatic ANQP query to maximum number of hotspot APs, default 0 (disabled)\n"
	"\tusage: anqpo_auto_hotspot [max]"
	},
	{ "anqpo_ignore_mode", wl_varint, WLC_GET_VAR, WLC_SET_VAR,
	"ignore duplicate SSIDs or BSSIDs, default 0 (SSID)\n"
	"\tusage: anqpo_ignore_mode [0 (SSID) | 1 (BSSID)]"
	},
	{ "anqpo_ignore_ssid_list", wl_anqpo_ignore_ssid_list, WLC_GET_VAR, WLC_SET_VAR,
	"get, clear, set, or append to ANQP offload ignore SSID list\n"
	"\tusage: wl anqpo_ignore_ssid_list [clear |\n"
	"\t\tset <ssid1> [ssid2] |\n"
	"\t\tappend <ssid3> [ssid4]>"
	},
	{ "anqpo_ignore_bssid_list", wl_anqpo_ignore_bssid_list, WLC_GET_VAR, WLC_SET_VAR,
	"get, clear, set, or append to ANQP offload ignore BSSID list\n"
	"\tusage: wl anqpo_ignore_bssid_list [clear |\n"
	"\t\tset <xx:xx:xx:xx:xx:xx> [xx:xx:xx:xx:xx:xx] |\n"
	"\t\tappend <xx:xx:xx:xx:xx:xx> [xx:xx:xx:xx:xx:xx]]>"
	},
#if defined(linux)
	{ "anqpo_results", wl_anqpo_results, -1, WLC_SET_VAR,
	"Listens and displays ANQP results."
	},
#endif	/* linux */
	{ NULL, NULL, 0, 0, NULL }
};

static char *buf;

/* module initialization */
void
wluc_anqpo_module_init(void)
{
	/* get the global buf */
	buf = wl_get_buf();

	/* register anqpo commands */
	wl_module_cmds_register(wl_anqpo_cmds);
}

#define ANQPO_EVENTS_BUFFER_SIZE	2048

static int
wl_anqpo_set(void *wl, cmd_t *cmd, char **argv)
{
	int err = BCME_USAGE_ERROR, malloc_size;
	char *buffer;
	wl_anqpo_set_t *set;
	int length;

	UNUSED_PARAMETER(cmd);

	malloc_size = OFFSETOF(wl_anqpo_set_t, query_data) +
		(ANQPO_MAX_QUERY_SIZE * sizeof(uint8));
	buffer = malloc(malloc_size);
	if (buffer == NULL) {
		fprintf(stderr, "Not enough memory\n");
		return BCME_NOMEM;
	}
	memset(buffer, 0, malloc_size);
	set = (wl_anqpo_set_t *)buffer;
	/* parameters not configured by default */
	set->max_retransmit = -1;
	set->response_timeout = -1;
	set->max_comeback_delay = -1;
	set->max_retries = -1;

	while (*++argv) {
		if (!stricmp(*argv, "max_retransmit")) {
			if (*++argv)
				set->max_retransmit = atoi(*argv);
			else {
				fprintf(stderr, "Missing max retransmit\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
		}
		else if (!stricmp(*argv, "response_timeout")) {
			if (*++argv)
				set->response_timeout = atoi(*argv);
			else {
				fprintf(stderr, "Missing response timeout\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
		}
		else if (!stricmp(*argv, "max_comeback_delay")) {
			if (*++argv)
				set->max_comeback_delay = atoi(*argv);
			else {
				fprintf(stderr, "Missing max comeback delay\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
		}
		else if (!stricmp(*argv, "max_retries")) {
			if (*++argv)
				set->max_retries = atoi(*argv);
			else {
				fprintf(stderr, "Missing retries\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
		}
		else if (!stricmp(*argv, "query")) {
			if (*++argv) {
				if ((set->query_len = hexstr2hex(*argv)) == 0) {
					fprintf(stderr, "Invalid ANQP query\n");
					err = BCME_USAGE_ERROR;
					goto done;
				}
				if (set->query_len > ANQPO_MAX_QUERY_SIZE) {
					fprintf(stderr, "ANQP query size %d exceeds %d\n",
						set->query_len, ANQPO_MAX_QUERY_SIZE);
					err = BCME_USAGE_ERROR;
					goto done;
				}
				memcpy(set->query_data, *argv, set->query_len);
			}
			else {
				fprintf(stderr, "Missing ANQP query\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
		}
		else {
			fprintf(stderr, "Invalid parameter %s\n", *argv);
			err = BCME_USAGE_ERROR;
			goto done;
		}

	}

	length = OFFSETOF(wl_anqpo_set_t, query_data) + set->query_len;
	set->max_retransmit = htod16(set->max_retransmit);
	set->response_timeout = htod16(set->response_timeout);
	set->max_comeback_delay = htod16(set->max_comeback_delay);
	set->max_retries = htod16(set->max_retries);
	set->query_len = htod16(set->query_len);

	err = wlu_iovar_set(wl, cmd->name, set, length);

done:
	free(buffer);
	return err;
}

static int
wl_anqpo_stop_query(void *wl, cmd_t *cmd, char **argv)
{
	UNUSED_PARAMETER(cmd);
	UNUSED_PARAMETER(argv);
	return wlu_iovar_set(wl, cmd->name, 0, 0);
}

static int
wl_anqpo_start_query(void *wl, cmd_t *cmd, char **argv)
{
	int err = BCME_USAGE_ERROR, malloc_size;
	char *buffer;
	wl_anqpo_peer_list_t *list;
	wl_anqpo_peer_t *peer;
	int c;
	int length;

	UNUSED_PARAMETER(cmd);

	malloc_size = OFFSETOF(wl_anqpo_peer_list_t, peer) +
		(ANQPO_MAX_PEER_LIST * sizeof(wl_anqpo_peer_t));
	buffer = malloc(malloc_size);
	if (buffer == NULL) {
		fprintf(stderr, "Not enough memory\n");
		return BCME_NOMEM;
	}
	memset(buffer, 0, malloc_size);
	list = (wl_anqpo_peer_list_t *)buffer;
	peer = &list->peer[0];

	c = 1;
	while (argv[c] && argv[c + 1]) {
		if ((peer->channel = htod16(atoi(argv[c]))) == 0) {
			fprintf(stderr, "Invalid channel\n");
			err = BCME_USAGE_ERROR;
			goto done;
		}
		if (!wl_ether_atoe(argv[c + 1], &peer->addr)) {
			fprintf(stderr, "Invalid address\n");
			err = BCME_USAGE_ERROR;
			goto done;
		}
		list->count++;
		c += 2;
		peer++;
	}

	length = OFFSETOF(wl_anqpo_peer_list_t, peer) +
		(list->count * sizeof(wl_anqpo_peer_t));
	list->count = htod16(list->count);

	err = wlu_iovar_set(wl, cmd->name, list, length);

done:
	free(buffer);
	return err;
}

static int
wl_anqpo_ignore_ssid_list(void *wl, cmd_t *cmd, char **argv)
{
	int err = BCME_USAGE_ERROR, malloc_size;
	char *buffer;
	wl_anqpo_ignore_ssid_list_t *list;
	int length;

	UNUSED_PARAMETER(cmd);

	malloc_size = OFFSETOF(wl_anqpo_ignore_ssid_list_t, ssid) +
		(ANQPO_MAX_IGNORE_SSID * (sizeof(wl_anqpo_ignore_ssid_list_t) -
		OFFSETOF(wl_anqpo_ignore_ssid_list_t, ssid)));
	buffer = malloc(malloc_size);
	if (buffer == NULL) {
		fprintf(stderr, "Not enough memory\n");
		return BCME_NOMEM;
	}
	memset(buffer, 0, malloc_size);
	list = (wl_anqpo_ignore_ssid_list_t *)buffer;

	/* get */
	if (!argv[1]) {
		int i;

		if ((err = wlu_iovar_get(wl, cmd->name, list, malloc_size)) < 0)
			goto done;
		list->count = dtoh16(list->count);
		for (i = 0; i < list->count; i++) {
			char ssidbuf[SSID_FMT_BUF_LEN];

			wl_format_ssid(ssidbuf, list->ssid[i].SSID, list->ssid[i].SSID_len);
			printf("%s\n", ssidbuf);
		}
		goto done;
	}

	/* set */
	argv++;
	if (!stricmp(*argv, "clear")) {
		list->is_clear = TRUE;
	}
	else if (!stricmp(*argv, "set")) {
		list->is_clear = TRUE;
		while (*++argv) {
			int len = strlen(*argv);
			if (list->count > ANQPO_MAX_IGNORE_SSID) {
				fprintf(stderr, "Too many BSSID\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
			if (len > 32) {
				fprintf(stderr, "SSID too long\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
			list->ssid[list->count].SSID_len = len;
			memcpy(list->ssid[list->count].SSID, *argv, len);
			list->count++;
		}
	}
	else if (!stricmp(*argv, "append")) {
		while (*++argv) {
			int len = strlen(*argv);
			if (list->count > ANQPO_MAX_IGNORE_SSID) {
				fprintf(stderr, "Too many BSSID\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
			if (len > 32) {
				fprintf(stderr, "SSID too long\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
			list->ssid[list->count].SSID_len = len;
			memcpy(list->ssid[list->count].SSID, *argv, len);
			list->count++;
		}
	}
	else {
		fprintf(stderr, "Invalid parameter %s\n", *argv);
		err = BCME_USAGE_ERROR;
		goto done;
	}

	length = OFFSETOF(wl_anqpo_ignore_ssid_list_t, ssid) +
		(list->count * (sizeof(wl_anqpo_ignore_ssid_list_t) -
		OFFSETOF(wl_anqpo_ignore_ssid_list_t, ssid)));
	list->count = htod16(list->count);

	err = wlu_iovar_set(wl, cmd->name, list, length);

done:
	free(buffer);
	return err;
}

static int
wl_anqpo_ignore_bssid_list(void *wl, cmd_t *cmd, char **argv)
{
	int err = BCME_USAGE_ERROR, malloc_size;
	char *buffer;
	wl_anqpo_ignore_bssid_list_t *list;
	int length;

	UNUSED_PARAMETER(cmd);

	malloc_size = OFFSETOF(wl_anqpo_ignore_bssid_list_t, bssid) +
		(ANQPO_MAX_IGNORE_BSSID * (sizeof(wl_anqpo_ignore_bssid_list_t) -
		OFFSETOF(wl_anqpo_ignore_bssid_list_t, bssid)));
	buffer = malloc(malloc_size);
	if (buffer == NULL) {
		fprintf(stderr, "Not enough memory\n");
		return BCME_NOMEM;
	}
	memset(buffer, 0, malloc_size);
	list = (wl_anqpo_ignore_bssid_list_t *)buffer;

	/* get */
	if (!argv[1]) {
		int i;

		if ((err = wlu_iovar_get(wl, cmd->name, list, malloc_size)) < 0)
			goto done;
		list->count = dtoh16(list->count);
		for (i = 0; i < list->count; i++) {
			printf("%s\n", wl_ether_etoa(&list->bssid[i]));
		}
		goto done;
	}

	/* set */
	argv++;
	if (!stricmp(*argv, "clear")) {
		list->is_clear = TRUE;
	}
	else if (!stricmp(*argv, "set")) {
		list->is_clear = TRUE;
		while (*++argv) {
			if (list->count > ANQPO_MAX_IGNORE_BSSID) {
				fprintf(stderr, "Too many BSSID\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
			if (!wl_ether_atoe(*argv, &list->bssid[list->count])) {
				fprintf(stderr, "Invalid BSSID\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
			list->count++;
		}
	}
	else if (!stricmp(*argv, "append")) {
		while (*++argv) {
			if (list->count > ANQPO_MAX_IGNORE_BSSID) {
				fprintf(stderr, "Too many BSSID\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
			if (!wl_ether_atoe(*argv, &list->bssid[list->count])) {
				fprintf(stderr, "Invalid BSSID\n");
				err = BCME_USAGE_ERROR;
				goto done;
			}
			list->count++;
		}
	}
	else {
		fprintf(stderr, "Invalid parameter %s\n", *argv);
		err = BCME_USAGE_ERROR;
		goto done;
	}

	length = OFFSETOF(wl_anqpo_ignore_bssid_list_t, bssid) +
		(list->count * (sizeof(wl_anqpo_ignore_bssid_list_t) -
		OFFSETOF(wl_anqpo_ignore_bssid_list_t, bssid)));
	list->count = htod16(list->count);

	err = wlu_iovar_set(wl, cmd->name, list, length);

done:
	free(buffer);
	return err;
}

#if defined(linux)
static int
wl_anqpo_results(void *wl, cmd_t *cmd, char **argv)
{
	int fd, err, octets;
	struct sockaddr_ll sll;
	struct ifreq ifr;
	char *data;
	uint8 event_inds_mask[WL_EVENTING_MASK_LEN];	/* event bit mask */

	UNUSED_PARAMETER(cmd);
	UNUSED_PARAMETER(argv);

	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, ((struct ifreq *)wl)->ifr_name, (IFNAMSIZ - 1));

	memset(event_inds_mask, '\0', WL_EVENTING_MASK_LEN);
	event_inds_mask[WLC_E_GAS_FRAGMENT_RX / 8] |= 1 << (WLC_E_GAS_FRAGMENT_RX % 8);
	event_inds_mask[WLC_E_GAS_COMPLETE / 8] |= 1 << (WLC_E_GAS_COMPLETE % 8);
	if ((err = wlu_iovar_set(wl, "event_msgs", &event_inds_mask, WL_EVENTING_MASK_LEN)))
		goto exit2;

	fd = socket(PF_PACKET, SOCK_RAW, hton16(ETHER_TYPE_BRCM));
	if (fd < 0) {
		printf("Cannot create socket %d\n", fd);
		err = -1;
		goto exit2;
	}

	err = ioctl(fd, SIOCGIFINDEX, &ifr);
	if (err < 0) {
		printf("Cannot get index %d\n", err);
		goto exit1;
	}

	/* bind the socket first before starting so we won't miss any event */
	memset(&sll, 0, sizeof(sll));
	sll.sll_family = AF_PACKET;
	sll.sll_protocol = hton16(ETHER_TYPE_BRCM);
	sll.sll_ifindex = ifr.ifr_ifindex;
	err = bind(fd, (struct sockaddr *)&sll, sizeof(sll));
	if (err < 0) {
		printf("Cannot bind %d\n", err);
		goto exit1;
	}

	data = (char*)malloc(ANQPO_EVENTS_BUFFER_SIZE);

	if (data == NULL) {
		printf("Cannot not allocate %d bytes for events receive buffer\n",
			ANQPO_EVENTS_BUFFER_SIZE);
		err = BCME_NOMEM;
		goto exit1;
	}

	/* receive result */
	while (1) {
		bcm_event_t *bcm_event;
		int event_type;

		octets = recv(fd, data, ANQPO_EVENTS_BUFFER_SIZE, 0);
		bcm_event = (bcm_event_t *)data;
		event_type = ntoh32(bcm_event->event.event_type);

		if (octets >= (int)sizeof(bcm_event_t)) {
			uint32 status = ntoh32(bcm_event->event.status);

			if (event_type == WLC_E_GAS_FRAGMENT_RX) {
				wl_event_gas_t *gas_data =
					(wl_event_gas_t *)&data[sizeof(bcm_event_t)];

				gas_data->channel = dtoh16(gas_data->channel);
				gas_data->status_code = dtoh16(gas_data->status_code);
				gas_data->data_len = dtoh16(gas_data->data_len);

				printf("WLC_E_GAS_FRAGMENT_RX: %s\n",
					status == WLC_E_STATUS_PARTIAL ? "WLC_E_STATUS_PARTIAL" :
					status == WLC_E_STATUS_SUCCESS ? "WLC_E_STATUS_SUCCESS" :
					status == WLC_E_STATUS_FAIL ? "WLC_E_STATUS_FAIL" :
					"unknown");
				printf("   channel         = %d\n", gas_data->channel);
				printf("   peer            = %s\n",
					wl_ether_etoa(&bcm_event->event.addr));
				printf("   dialog token    = 0x%02x (%d)\n",
					gas_data->dialog_token, gas_data->dialog_token);
				printf("   fragment id     = 0x%02x\n", gas_data->fragment_id);
				printf("   GAS status      = %s\n",
					gas_data->status_code == DOT11_SC_SUCCESS ? "SUCCESS" :
					gas_data->status_code == DOT11_SC_FAILURE ? "UNSPECIFIED" :
					gas_data->status_code == DOT11_SC_ADV_PROTO_NOT_SUPPORTED ?
						"ADVERTISEMENT_PROTOCOL_NOT_SUPPORTED" :
					gas_data->status_code == DOT11_SC_NO_OUTSTAND_REQ ?
						"NO_OUTSTANDING_REQUEST" :
					gas_data->status_code == DOT11_SC_RSP_NOT_RX_FROM_SERVER ?
						"RESPONSE_NOT_RECEIVED_FROM_SERVER" :
					gas_data->status_code == DOT11_SC_TIMEOUT ?
						"TIMEOUT" :
					gas_data->status_code == DOT11_SC_QUERY_RSP_TOO_LARGE ?
						"QUERY_RESPONSE_TOO_LARGE" :
					gas_data->status_code == DOT11_SC_SERVER_UNREACHABLE ?
						"SERVER_UNREACHABLE" :
					gas_data->status_code == DOT11_SC_TRANSMIT_FAILURE ?
						"TRANSMISSION_FAILURE" : "unknown");
				printf("   GAS data length = %d\n", gas_data->data_len);
				if (gas_data->data_len) {
					wl_hexdump(gas_data->data, gas_data->data_len);
				}
			}
			else if (event_type == WLC_E_GAS_COMPLETE) {
				printf("WLC_E_GAS_COMPLETE: %s\n",
					status == WLC_E_STATUS_SUCCESS ? "WLC_E_STATUS_SUCCESS" :
					"unknown");
			}
		}
	}

	free(data);
exit1:
	close(fd);
exit2:
	return err;
}
#endif	/* linux */
