/*
 * wl tdls 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_tdls.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"

static cmd_func_t wl_tdls_endpoint;
static cmd_func_t wl_tdls_wfd_ie;

static cmd_t wl_tdls_cmds[] = {
	{ "tdls_endpoint", wl_tdls_endpoint, WLC_GET_VAR, WLC_SET_VAR,
	"Available TDLS operations to each TDLS peer.\n"
	"\tusage: wl tdls_endpoint <disc, create, delete, PM, wake, cw> <ea> [chanspec]\n"
	"\t       [chanspec] only applies to 'cw' operaton.\n\n"
	"\t       addendum:\n"
	"\t       wl tdls_endpoint wfd_disc <ea> sends a WFD tunneled Probe Request"},
	{ "tdls_wfd_ie", wl_tdls_wfd_ie, WLC_GET_VAR, -1,
	"To set, get and clear additional WFD IE in setup_req and setup_resp\n"
	"\tTo set2, get2 and clear2 additional WFD IE in tunneled probe_req and probe_resp\n"
	"\tusage: wl tdls_wfd_ie get  <own|peer_eth_addr#> [ip] [port]\n"
	"\t       wl tdls_wfd_ie get2 <own|peer_eth_addr#> [alt_mac] [port] [PC_bit]\n"
	"\t\t       peer_eth_addr#: HH:HH:HH:HH:HH:HH\n"
	"\t\t       and peer must be TDLS connected (only in case of setup)\n\n"
	"\t       wl tdls_wfd_ie <clr|clr2> own\n\n"
	"\t       wl tdls_wfd_ie set  own wfd_ie_hexa_string [ip# [port# [type# [bssid#]]]]\n"
	"\t       wl tdls_wfd_ie set2 own wfd_ie_hexa_string [alt_mac# [port# [type#]]]\n"
	"\t\t       wfd_ie_hexa_string: should start with the full WFD IE header\n"
	"\t\t                           e.g. 0xDDXX506F9A0A...\n"
	"\t\t       ip#:      XXX.XXX.XXX.XXX\n"
	"\t\t       alt_mac#: HH:HH:HH:HH:HH:HH\n"
	"\t\t       port#:    0-65535\n"
	"\t\t       type#:    0 for source, 1 for primary sink\n"
	"\t\t       bssid#:   HH:HH:HH:HH:HH:HH"},
	{ "tdls_sta_info", wl_sta_info, WLC_GET_VAR, -1,
	"wl tdls_sta_info <xx:xx:xx:xx:xx:xx>"},
	{ NULL, NULL, 0, 0, NULL }
};

static char *buf;

/* module initialization */
void
wluc_tdls_module_init(void)
{
	(void)g_swap;

	/* get the global buf */
	buf = wl_get_buf();

	/* register tdls commands */
	wl_module_cmds_register(wl_tdls_cmds);
}

static int
wl_tdls_endpoint(void *wl, cmd_t *cmd, char **argv)
{
	const char *cmdname_tdls = "tdls_endpoint";
	tdls_iovar_t info;
	chanspec_t chanspec;

	if (strcmp(cmd->name, cmdname_tdls)) {
		printf("error: invalid command name.\n");
		return BCME_USAGE_ERROR;
	}

	if (!*++argv)
		return BCME_USAGE_ERROR;

	memset(&info, 0, sizeof(tdls_iovar_t));

	if (!strcmp("create", *argv))
		info.mode = TDLS_MANUAL_EP_CREATE;
	else if (!strcmp("modify", *argv))
		info.mode = TDLS_MANUAL_EP_MODIFY;
	else if (!strcmp("delete", *argv))
		info.mode = TDLS_MANUAL_EP_DELETE;
	else if (!strcmp("PM", *argv))
		info.mode = TDLS_MANUAL_EP_PM;
	else if (!strcmp("wake", *argv))
		info.mode = TDLS_MANUAL_EP_WAKE;
	else if (!strcmp("disc", *argv))
		info.mode = TDLS_MANUAL_EP_DISCOVERY;
	else if (!strcmp("cw", *argv)) {
		info.mode = TDLS_MANUAL_EP_CHSW;
	}
	else if (!strcmp("wfd_disc", *argv))
		info.mode = TDLS_MANUAL_EP_WFD_TPQ;
	else {
		printf("error: invalid mode string\n");
		return BCME_USAGE_ERROR;
	}

	argv++;
	if (!*argv) {
		printf("error: missing ea\n");
		return BCME_USAGE_ERROR;
	}

	if (!wl_ether_atoe(*argv, &info.ea)) {
		printf("error: could not parse MAC address %s\n", *argv);
		return BCME_USAGE_ERROR;
	}

	if (info.mode == TDLS_MANUAL_EP_CHSW) {
		argv++;
		if (!*argv) {
			printf("error: missing target channel number\n");
			return BCME_USAGE_ERROR;
		}
		if (atoi(*argv) != 0) {
			chanspec = wf_chspec_aton(*argv);
			if (chanspec == 0) {
				printf("error: bad chanspec \"%s\".\n", *argv);
				return BCME_USAGE_ERROR;
			}
			chanspec = wl_chspec_to_driver(chanspec);
			if (chanspec == INVCHANSPEC) {
				return BCME_USAGE_ERROR;
			}
			info.chanspec = chanspec;
		}
	}

	return wlu_var_setbuf(wl, cmd->name, &info, sizeof(info));
}


#define WFD_DEV			0
#define WFD_DEV_LEN		6
#define WFD_IP				8
#define WFD_IP_LEN		5
#define WFD_ALT_MAC		10
#define WFD_ALT_MAC_LEN	6

static int
wl_tdls_wfd_ie(void *wl, cmd_t *cmd, char **argv)
{
	const char *cmdname_tdls = "tdls_wfd_ie";
	tdls_wfd_ie_iovar_t info;
	tdls_wfd_ie_iovar_t* buf_info = (tdls_wfd_ie_iovar_t*) buf;
	int ret;
	uint8* ptr;
	uint8 element, subelement = 0;
	uint16 offset;
	uint8 buffer[TDLS_WFD_IE_SIZE - (WFA_OUI_LEN + 3)];
	uint16 length, element_length, current_length;
	bcm_tlv_t * ie;
	unsigned long value;
	struct ether_addr ea;
	struct ipv4_addr ipa_set;

	if (strcmp(cmd->name, cmdname_tdls)) {
		printf("error: invalid command name.\n");
		return BCME_USAGE_ERROR;
	}

	if (!*++argv)
		return BCME_USAGE_ERROR;

	if (!strcmp(*argv, "clr")) {
		memset(&info, 0, sizeof(tdls_wfd_ie_iovar_t));

		if (!*++argv)
			return BCME_USAGE_ERROR;

		if (!strcmp("own", *argv))
			info.mode = TDLS_WFD_IE_TX;
		else {
			printf("error: invalid mode string\n");
			return BCME_USAGE_ERROR;
		}

		return wlu_var_setbuf(wl, cmd->name, &info, sizeof(info));

	} else if (!strcmp(*argv, "get")) {
		memset(buf_info, 0, sizeof(*buf_info));

		if (!*++argv)
			return BCME_USAGE_ERROR;

		if (!strcmp("own", *argv))
			buf_info->mode = TDLS_WFD_IE_TX;
		else if (wl_ether_atoe(*argv, &buf_info->ea))
			buf_info->mode = TDLS_WFD_IE_RX;
		else {
			printf("error: invalid mode string\n");
			return BCME_USAGE_ERROR;
		}

		if ((ret = wlu_iovar_getbuf(wl, cmd->name, buf_info,
			sizeof(*buf_info), buf, WLC_IOCTL_MAXLEN)) < 0) {
			return ret;
		}

		/* empty */
		if (!buf_info->length)
			return ret;

		if (!*++argv)
			wl_hexdump((uchar *)buf_info->data, buf_info->length);
		else {
			if (!strcmp("ip", *argv)) {
				element = WFD_IP;
				element_length = WFD_IP_LEN;
			} else if (!strcmp("port", *argv)) {
				element = WFD_DEV;
				element_length = WFD_DEV_LEN;
			} else {
				printf("error: unknown element\n");
				return BCME_USAGE_ERROR;
			}

			/* Reassemble the WFD IE (without header) */

			ptr = buf_info->data;
			length = buf_info->length;
			offset = 0;
			current_length = 0;

			while (length - offset > WFA_OUI_LEN + 3) {
				if ((ie = bcm_parse_tlvs(ptr + offset,
					length - offset, DOT11_MNG_VS_ID)) != NULL) {
					if (ie->len > WFA_OUI_LEN + 1) {
						if ((!memcmp(ie->data, WFA_OUI, WFA_OUI_LEN)) &&
						    (*(ie->data + WFA_OUI_LEN) ==
						    WFA_OUI_TYPE_WFD)) {
							/* WFD */
							memcpy(buffer + current_length,
								ie->data + WFA_OUI_LEN + 1,
								ie->len - WFA_OUI_LEN - 1);
							current_length += ie->len - WFA_OUI_LEN - 1;
						}
					}
					offset = (uint16)((uint8*)ie - ptr + ie->len + 2);
				}
				else
					break;
			}

			/* Find the elements */

			ptr = buffer;
			length = current_length;

			while (length > 3) {
				current_length = (ptr[1] << 8) + ptr[2];
				if ((ptr[0] == element) && (current_length == element_length) &&
				(current_length <= length - 3)) {

					switch (element) {
						case WFD_IP:
	/* we do not care about the IP version i.e. ptr[3] */
	printf("%u.%u.%u.%u\n", ptr[4], ptr[5], ptr[6], ptr[7]);
						break;

						case WFD_DEV:
	/* just get the RTSP TCP valid port */
	printf("%u\n", (ptr[5] << 8) + ptr[6]);
						break;
					}
					break;

				} else {
					if (current_length + 3 < length) {
						length -= current_length + 3;
						ptr += current_length + 3;
					} else
						break;
				}
			}
		}

		return ret;

	} else if (!strcmp(*argv, "set")) {
		memset(&info, 0, sizeof(tdls_wfd_ie_iovar_t));

		if (!*++argv)
			return BCME_USAGE_ERROR;

		if (!strcmp("own", *argv))
			info.mode = TDLS_WFD_IE_TX;
		else {
			printf("error: invalid mode string\n");
			return BCME_USAGE_ERROR;
		}

		argv++;
		if (!*argv) {
			printf("error: missing IE string\n");
			return BCME_USAGE_ERROR;
		}

		if (strlen((char*)*argv) - 2 > sizeof(info.data) * 2) {
			printf("error: IE string too long; max is %u bytes\n",
			    (unsigned int)sizeof(info.data));
			return BCME_BADARG;
		}

		ret = wl_pattern_atoh(*argv, (char*)info.data);

		if (ret <= 0) {
			printf("error: could not parse IE string address %s\n", *argv);
			return BCME_USAGE_ERROR;
		}

		info.length = ret;

		if (*++argv) {
		/* IP specified */

			/* watchdog */
			if (info.length != 32) {
				printf(
				"if one or several set fields are used, "
				"the following the IE string must be\n"
				"exactly 32 bytes and must have the following order:\n"
				"\t6-byte header (0xDD1E506F9A0A)\n"
				"\t9-byte subelement 0 (WFD device information)\n"
				"\t9-byte subelement 1 (BSSID)\n"
				"\t8-byte subelement 8 (IP address)\n");
				return BCME_USAGE_ERROR;
			}

			if (!wl_atoip(*argv, &ipa_set))
			return BCME_USAGE_ERROR;

			memcpy(&info.data[28], (uint8*) &ipa_set, sizeof(ipa_set));

			if (*++argv) {
			/* port specified */

				value = strtoul(*argv, NULL, 0);
				info.data[11] = (uint8) (0xFF & (value >> 8));
				info.data[12] = (uint8) (0xFF & value);

				if (*++argv) {
					/* WFD type (Source or Primary Sink) specified */

					element = (uint8) (0x01 & strtoul(*argv, NULL, 0));
					if (element)
						info.data[10] |= 0x01;
					else
						info.data[10] &= ~0x01;

					if (*++argv) {
					/* BSSID specified */

						if (!wl_ether_atoe(*argv, &ea))
							return BCME_USAGE_ERROR;

						memcpy(&info.data[18], (uint8*) &ea, sizeof(ea));
					}
				}
			}
		}

		return wlu_var_setbuf(wl, cmd->name, &info, sizeof(info));

	} else if (!strcmp(*argv, "clr2")) {
		memset(&info, 0, sizeof(tdls_wfd_ie_iovar_t));

		if (!*++argv)
			return BCME_USAGE_ERROR;

		if (!strcmp("own", *argv))
			info.mode = TDLS_WFD_PROBE_IE_TX;
		else {
			printf("error: invalid mode string\n");
			return BCME_USAGE_ERROR;
		}

		return wlu_var_setbuf(wl, cmd->name, &info, sizeof(info));

	} else if (!strcmp(*argv, "get2")) {
		memset(buf_info, 0, sizeof(*buf_info));

		if (!*++argv)
			return BCME_USAGE_ERROR;

		if (!strcmp("own", *argv))
			buf_info->mode = TDLS_WFD_PROBE_IE_TX;
		else if (wl_ether_atoe(*argv, &buf_info->ea))
			buf_info->mode = TDLS_WFD_PROBE_IE_RX;
		else {
			printf("error: invalid mode string\n");
			return BCME_USAGE_ERROR;
		}

		if ((ret = wlu_iovar_getbuf(wl, cmd->name, buf_info,
			sizeof(*buf_info), buf, WLC_IOCTL_MAXLEN)) < 0) {
			return ret;
		}

		/* empty */
		if (!buf_info->length)
			return ret;

		if (!*++argv)
			wl_hexdump((uchar *)buf_info->data, buf_info->length);

		else {
			if (!strcmp("alt_mac", *argv)) {
				element = WFD_ALT_MAC;
				element_length = WFD_ALT_MAC_LEN;
			} else if (!strcmp("port", *argv)) {
				element = WFD_DEV;
				element_length = WFD_DEV_LEN;
				subelement = 1;
			} else if (!strcmp("PC_bit", *argv)) {
				element = WFD_DEV;
				element_length = WFD_DEV_LEN;
				subelement = 0;
			} else {
				printf("error: unknown element\n");
				return BCME_USAGE_ERROR;
			}

			/* Reassemble the WFD IE (without header) */

			ptr = buf_info->data;
			length = buf_info->length;
			offset = 0;
			current_length = 0;

			while (length - offset > WFA_OUI_LEN + 3) {
				if ((ie = bcm_parse_tlvs(ptr + offset,
					length - offset, DOT11_MNG_VS_ID)) != NULL) {
					if (ie->len > WFA_OUI_LEN + 1) {
						if ((!memcmp(ie->data, WFA_OUI, WFA_OUI_LEN)) &&
							(*(ie->data + WFA_OUI_LEN) ==
							WFA_OUI_TYPE_WFD)) {
							/* WFD */
							memcpy(buffer + current_length,
								ie->data + WFA_OUI_LEN + 1,
								ie->len - WFA_OUI_LEN - 1);
							current_length += ie->len - WFA_OUI_LEN - 1;
						}
					}
					offset = (uint16)((uint8*)ie - ptr + ie->len + 2);
				}
				else
					break;
			}

			/* Find the elements */

			ptr = buffer;
			length = current_length;

			while (length > 3) {
				current_length = (ptr[1] << 8) + ptr[2];
				if ((ptr[0] == element) && (current_length == element_length) &&
					(current_length <= length - 3)) {

					switch (element) {
	case WFD_ALT_MAC:
		printf("%02X:%02X:%02X:%02X:%02X:%02X\n",
			ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8]);
		break;
	case WFD_DEV:
			if (subelement)
				/* just get the RTSP TCP valid port */
				printf("%u\n", (ptr[5] << 8) + ptr[6]);
			else
				/* just get the Preferred Connection bit */
				printf("%u\n", ptr[4] >> 7);
		break;
					}
					break;

				} else {
					if (current_length + 3 < length) {
						length -= current_length + 3;
						ptr += current_length + 3;
					} else
						break;
				}
			}
		}

		return ret;

	} else if (!strcmp(*argv, "set2")) {
		memset(&info, 0, sizeof(tdls_wfd_ie_iovar_t));

		if (!*++argv)
			return BCME_USAGE_ERROR;

		if (!strcmp("own", *argv))
			info.mode = TDLS_WFD_PROBE_IE_TX;
		else {
			printf("error: invalid mode string\n");
			return BCME_USAGE_ERROR;
		}

		argv++;
		if (!*argv) {
			printf("error: missing IE string\n");
			return BCME_USAGE_ERROR;
		}

		if (strlen((char*)*argv) - 2 > sizeof(info.data) * 2) {
			printf("error: IE string too long; max is %u bytes\n",
				(unsigned int)sizeof(info.data));
			return BCME_USAGE_ERROR;
		}

		ret = wl_pattern_atoh(*argv, (char*)info.data);

		if (ret <= 0) {
			printf("error: could not parse IE string address %s\n", *argv);
			return BCME_USAGE_ERROR;
		}

		info.length = ret;

		if (*++argv) {
		/* alt MAC specified */

			/* watchdog */
			if (info.length != 24) {
				printf(
				"if one or several set2 fields are used, "
				"the following the IE string must be\n"
				"exactly 24 bytes and must have the following order:\n"
				"\t6-byte header (0xDD16506F9A0A)\n"
				"\t9-byte subelement 0  (WFD device information)\n"
				"\t9-byte subelement 10 (alternate MAC address)\n");
				return BCME_USAGE_ERROR;
			}

			if (!wl_ether_atoe(*argv, &ea))
				return BCME_USAGE_ERROR;
			memcpy(&info.data[18], (uint8*) &ea, sizeof(ea));

			if (*++argv) {
			/* port specified */

				value = strtoul(*argv, NULL, 0);
				info.data[11] = (uint8) (0xFF & (value >> 8));
				info.data[12] = (uint8) (0xFF & value);

				if (*++argv) {
					/* WFD type (Source or Primary Sink) specified */

					element = (uint8) (0x01 & strtoul(*argv, NULL, 0));
					if (element)
						info.data[10] |= 0x01;
					else
						info.data[10] &= ~0x01;
				}
			}
		}

		return wlu_var_setbuf(wl, cmd->name, &info, sizeof(info));

	} else {
		printf("error: unknown operation\n");
		return BCME_USAGE_ERROR;
	}
}
