/*
 * wl bssload 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_bssload.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 int wl_bssload_static(void *wl, cmd_t *cmd, char **argv);
#if defined(WLBSSLOAD_REPORT)
static int wl_bssload_report(void *wl, cmd_t *cmd, char **argv);
static int wl_bssload_report_event(void *wl, cmd_t *cmd, char **argv);
#if defined(linux)
static cmd_func_t wl_bssload_event_check;
#endif   /* linux */
#endif   /* WLBSSLOAD_REPORT */

static cmd_t wl_bssload_cmds[] = {
	{ "bssload_static", wl_bssload_static, WLC_GET_VAR, WLC_SET_VAR,
	"get or set static BSS load\n"
	"\tusage: wl bssload_static [off | <sta_count> <chan_util> <acc>]"},
#if defined(WLBSSLOAD_REPORT)
	{ "bssload_report", wl_bssload_report, WLC_GET_VAR, -1,
	"Get the latest BSS Load IE data from the associated AP's beacon\n"
	"\tUsage: bssload_report"
	},
	{ "bssload_report_event", wl_bssload_report_event, WLC_GET_VAR, WLC_SET_VAR,
	"Get/Set BSS load threshold for sending WLC_E_BSS_LOAD event\n"
	"\tUsage: wl bssload_report_event [rate_limit_msec] [level] [level] ...\n"
	"\t\t[level] is a 0...255 channel utilization value.\n"
	"\t\tUp to 8 levels in increasing order may be specified."
	},
#if defined(linux)
	{ "bssload_event_check", wl_bssload_event_check, -1, -1,
	"Listens forever for BSS Load events and prints them.\n"
	"\tUsage: wl bssload_event_check"
	},
#endif	/* linux */
#endif   /* WLBSSLOAD_REPORT */
	{ NULL, NULL, 0, 0, NULL }
};

static char *buf;

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

	/* register bssload commands */
	wl_module_cmds_register(wl_bssload_cmds);
}

static int
wl_bssload_static(void *wl, cmd_t *cmd, char **argv)
{
	int err = -1;
	wl_bssload_static_t bssload;

	UNUSED_PARAMETER(cmd);

	/* get */
	if (!argv[1]) {
		if ((err = wlu_iovar_get(wl, cmd->name, &bssload, sizeof(bssload))) < 0)
			return err;
		if (bssload.is_static) {
			printf("station count: %d\n", dtoh16(bssload.sta_count));
			printf("channel utilization: %d\n", bssload.chan_util);
			printf("avail admission capacity: %d\n", dtoh16(bssload.aac));
		}
	}
	else {
		/* set */
		argv++;
		memset(&bssload, 0, sizeof(bssload));
		if (!stricmp(*argv, "off")) {
			bssload.is_static = FALSE;
		}
		else {
			bssload.sta_count = htod16(strtoul(*argv, NULL, 0));

			if (*++argv == NULL) {
				printf("wl_bssload_static: "
					"channel utilization not provided\n");
				return -1;
			}
			bssload.chan_util = strtoul(*argv, NULL, 0);

			if (*++argv == NULL) {
				printf("wl_bssload_static: "
					"avail admission capacity not provided\n");
				return -1;
			}
			bssload.aac = htod16(strtoul(*argv, NULL, 0));

			bssload.is_static = TRUE;
		}

		err = wlu_iovar_set(wl, cmd->name, &bssload, sizeof(bssload));
	}

	return err;
}

#if defined(WLBSSLOAD_REPORT)
static int
wl_bssload_report(void *wl, cmd_t *cmd, char **argv)
{
	int ret = 0;
	wl_bssload_t *bssload = NULL;

	/* If any arguments are given, print help */
	if (ARGCNT(argv) > 1)
		goto usage;

	/* Get and print the current BSS Load values */
	if ((ret = wlu_var_getbuf_sm(wl, cmd->name, NULL, 0, (void*)&bssload)))
		return ret;
	if (bssload == NULL)
		return BCME_ERROR;
	printf("BSS Load from associated AP beacon:\n");
	printf("station count               : %u\n", dtoh16(bssload->sta_count));
	printf("channel utilization         : %u\n", bssload->chan_util);
	printf("available admission capacity: %u\n", dtoh16(bssload->aac));
	return 0;

usage:
	return -1;
}

static int
wl_bssload_report_event(void *wl, cmd_t *cmd, char **argv)
{
	int ret;
	wl_bssload_cfg_t blcfg;

	(void) wl;
	if (!*++argv) {
		/* get */
		void *ptr = NULL;
		uint i;

		if ((ret = wlu_var_getbuf(wl, cmd->name, NULL, 0, &ptr)) < 0)
			return ret;

		memcpy(&blcfg, ptr, sizeof(blcfg));
		blcfg.rate_limit_msec = dtoh32(blcfg.rate_limit_msec);

		printf("rate_limit_msec: %d\n", blcfg.rate_limit_msec);
		printf("%d channel utilization levels:", blcfg.num_util_levels);
		for (i = 0; i < blcfg.num_util_levels; i++) {
			printf(" %d", blcfg.util_levels[i]);
		}
		printf("\n");
	} else {
		/* set */
		memset(&blcfg, 0, sizeof(wl_bssload_cfg_t));
		blcfg.rate_limit_msec = atoi(*argv);

		while (*++argv && blcfg.num_util_levels < MAX_BSSLOAD_LEVELS) {
			blcfg.util_levels[blcfg.num_util_levels++] = atoi(*argv);
			if (blcfg.num_util_levels > 1 &&
				blcfg.util_levels[blcfg.num_util_levels - 1] <=
				blcfg.util_levels[blcfg.num_util_levels - 2]) {
				printf("Channel utilization level %u was <= level %u.\n",
					blcfg.util_levels[blcfg.num_util_levels - 1],
					blcfg.util_levels[blcfg.num_util_levels - 2]);
				goto usage;
			}
		}

		if (*argv) {
			printf("Too many parameters.\n");
			goto usage;
		}

		blcfg.rate_limit_msec = htod32(blcfg.rate_limit_msec);
		ret = wlu_var_setbuf(wl, cmd->name, &blcfg, sizeof(blcfg));
	}
	return ret;

usage:
	return -1;
}

#if defined(linux)
static void
wl_bssload_event_cb(int event_type, bcm_event_t *bcm_event)
{
	struct timeval tv;
	uint32 sec, msec;
	int ret;
	wl_bssload_t *data = (wl_bssload_t *) (bcm_event + 1);

	if (event_type == WLC_E_BSS_LOAD) {
		/* Print a timestamp */
		ret = gettimeofday(&tv, NULL);
		if (ret == 0) {
			sec = (uint32) (tv.tv_sec % 10000);
			msec = (uint32) tv.tv_usec / 1000;
			printf("%04d.%03d\n", sec, msec);
		}

		printf("WLC_E_BSS_LOAD: chan_util = %u\n", data->chan_util);
		printf("                sta_count = %u\n", dtoh16(data->sta_count));
		printf("                aac       = %u\n", dtoh16(data->aac));
	}
}

static int
wl_bssload_event_check(void *wl, cmd_t *cmd, char **argv)
{
	if (argv[1] && argv[1][0] == '-') {
		wl_cmd_usage(stderr, cmd);
		return -1;
	}
	return wl_wait_for_event(wl, argv, WLC_E_BSS_LOAD, 2048, wl_bssload_event_cb);
}
#endif	/* linux */
#endif   /* WLBSSLOAD_REPORT */
