/*
 * File Name: wlu_server_shared.c
 * Common server specific functions for linux and win32
 *
 * Copyright (C) 2016, Broadcom Corporation
 * All Rights Reserved.
 * 
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
 * 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 Corporation.
 *
 * $Id: wlu_server_shared.c 428561 2013-10-09 09:32:29Z $
 */

/*
 * Description: Main Server specific wrappers
 * This module implements all the server specific functions
 * for Win32 and Linux
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef TARGETOS_symbian
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>

#else
#include <malloc.h>
#endif /* TARGETOS_symbian */
#include <assert.h>

#include <errno.h>
#ifndef WIN32
#include <sys/types.h>
#include <sys/socket.h>
#if  !defined(TARGETOS_symbian)
#include <arpa/inet.h>
#include <net/if.h>
#endif
#include <unistd.h>
#include <netdb.h>
#include <signal.h>
#endif /* WIN32 */

#ifdef WIN32
#include <windows.h>
#include <winioctl.h>
#include <ntddndis.h>
#include <typedefs.h>
#include <epictrl.h>
#include <irelay.h>
#include <proto/ethernet.h>
#include <nuiouser.h>
#include <bcmendian.h>
#include <oidencap.h>
#include <bcmutils.h>
#include <proto/802.11.h>
#endif /* WIN32 */

#include <bcmcdc.h>
#include <wlioctl.h>
#include <typedefs.h>
#include <bcmendian.h>
#include <bcmutils.h>
#if defined(RWL_WIFI) || defined(WIFI_REFLECTOR)
#include <rwl_wifi.h>
#endif /* defined(RWL_WIFI) || defined(WIFI_REFLECTOR) */
#include "wlu.h"
#include "wlu_remote.h"
#include "wlu_pipe.h"
#include "wlu_server_shared.h"
#ifdef RWLASD
extern int g_serv_sock_desc;
#endif
int g_rwl_hndle;
int set_ctrlc = 0;

#ifdef RWL_DONGLE
static rem_ioctl_t loc_cdc;
static const char* cmdname = "remote";
static const char* dongleset = "dongleset";
#endif

extern void store_old_interface(void *wl, char *old_intf_name);
extern int wl_check(void *wl);

extern void handle_ctrlc(int unused);
/* Function: rwl_transport_setup
 * This will do the initialization for
 * for all the transports
 */
static int
rwl_transport_setup(int argc, char** argv)
{
	int transport_descriptor = -1;

	UNUSED_PARAMETER(argc);
	UNUSED_PARAMETER(argv);

#ifdef RWL_SOCKET
	/* This function will parse the socket command line arguments
	 * & open the socket in listen mode
	 */
	remote_type = REMOTE_SOCKET;
	transport_descriptor = rwl_init_server_socket_setup(argc, argv, remote_type);

	if (transport_descriptor < 0) {
		DPRINT_ERR(ERR, "wl_socket_server:Transport setup failed \n");
	}
#endif /* RWL_SOCKET */
#if defined(RWL_DONGLE) || defined(RWL_WIFI) || defined(RWL_SERIAL)
	g_rem_pkt_ptr = &g_rem_pkt;
	transport_descriptor = 0;

#ifdef RWL_WIFI
	remote_type = REMOTE_WIFI;
#endif

#ifdef RWL_DONGLE
	remote_type = REMOTE_DONGLE;
#endif /* RWL_DONGLE */
#ifdef RWL_SERIAL
	remote_type = REMOTE_SERIAL;
	if (argc < 2) {
		DPRINT_ERR(ERR, "Port name is required from the command line\n");
	} else {
		(void)*argv++;
		DPRINT_DBG(OUTPUT, "Port name is %s\n", *argv);
		transport_descriptor = *(int*) rwl_open_transport(remote_type, *argv, 0, 0);
	}
#endif  /* RWL_SERIAL */
#endif /* RWL_DONGLE ||RWL_SERIAL ||RWL_WIFI */
#ifdef RWLASD
	g_serv_sock_desc = transport_descriptor;
#endif
	return transport_descriptor;

}

/* Function: remote_rx_header
 * This function will receive the CDC header from client
 * for socket transport
 * It will receive the command or ioctl from dongle driver for
 * dongle UART serial transport and wifi transport.
 * Arguments: wl - handle to driver
 *          : Des - Socket Descriptor to pass in AcceptConnection
 *          : g_rwl_hndle - Return socket handle that is used for transmission
 *          :           and reception of data in case of socket
 *                        In case of serial, it is just a return value
 */
static int
remote_rx_header(void *wl, int trans_Des)
{
	UNUSED_PARAMETER(wl);
	UNUSED_PARAMETER(trans_Des);

#ifdef RWL_SOCKET
	{
		struct sockaddr_in ClientAddress;
		int SizeOfCliAdd = sizeof(ClientAddress);

		/* Get the socket handle g_rwl_hndle for transmission & reception */
		if ((g_rwl_hndle = rwl_acceptconnection(trans_Des,
		                                        (struct sockaddr *)&ClientAddress,
		                                        &SizeOfCliAdd)) == BCME_ERROR) {
			return BCME_ERROR;
		}

		/* Get CDC header in order to determine buffer requirements */
		if ((g_rem_ptr = remote_CDC_rx_hdr((void *)&g_rwl_hndle, 0)) == NULL) {
			DPRINT_DBG(OUTPUT, "\n Waiting for client to transmit command\n");
			return BCME_ERROR;
		}
	}
#endif /* RWL_SOCKET */

#ifdef RWL_DONGLE
	{
		void *pkt_ptr = NULL;
		int error;

		/* wl driver is polled after every 200 ms (POLLING_TIME) */
		rwl_sleep(POLLING_TIME);

		if ((error = rwl_var_getbuf(wl, cmdname, NULL, 0, &pkt_ptr)) < 0) {
			DPRINT_ERR(ERR, "No packet in wl driver\r\n");
			return BCME_ERROR;
		}

		DPRINT_DBG(OUTPUT, "Polling the wl driver, error status=%d\n", error);

		if ((*(int *)pkt_ptr) == 0) {
			DPRINT_DBG(ERR, "packet not received\n");
			return BCME_ERROR;
		}

		DPRINT_DBG(OUTPUT, "packet received\n");

		/* Extract CDC header in order to determine buffer requirements */
		memcpy(g_rem_pkt_ptr, pkt_ptr, sizeof(rem_packet_t));
		g_rem_ptr = &g_rem_pkt_ptr->rem_cdc;
	}
#endif /* RWL_DONGLE */

#ifdef RWL_SERIAL
	{
		if (g_rwl_hndle == -1) {
			DPRINT_ERR(ERR, "failed to open com port.\r\n");
			return BCME_ERROR;
		}

		if ((g_rem_ptr = remote_CDC_rx_hdr((void *)&g_rwl_hndle, 1)) == NULL) {
			DPRINT_DBG(OUTPUT, "\n Waiting for client to transmit command\n");
			return BCME_ERROR;
		}
	}
#endif  /* RWL_SERIAL */

#ifdef RWL_WIFI
	{
		/* Poll the driver for the valid action frame and update the CDC + data  */
		dot11_action_wifi_vendor_specific_t *list;

		if ((list = rwl_wifi_allocate_actionframe()) == NULL) {
			DPRINT_DBG(OUTPUT, "remote_rx_header: Failed to allocate frame \n");
			return BCME_ERROR;
		}

		if (remote_CDC_DATA_wifi_rx((void *)wl, list) < 0) {
			free(list);
			return BCME_ERROR;
		}

		/* copy the valid length of the data to the g_rem_pkt_ptr */
		memcpy(g_rem_pkt_ptr, &list->data[0], sizeof(rem_packet_t));
		g_rem_ptr = &g_rem_pkt_ptr->rem_cdc;
		free(list);
	}
#endif /* RWL_WIFI */

	rwl_swap_header(g_rem_ptr, NETWORK_TO_HOST);

	DPRINT_INFO(OUTPUT, "%d %d %d %d\r\n", g_rem_ptr->msg.cmd,
	g_rem_ptr->msg.len, g_rem_ptr->msg.flags, g_rem_ptr->data_len);

	return SUCCESS;

}

/* Function: remote_rx_data
 * This function will receive the data from client
 * for different transports
 * In case of socket the data comes from a open TCP socket
 * However in case of dongle UART or wi-fi the data is accessed
 * from the driver buffers.
 */
int
remote_rx_data(void* buf_ptr)
{
#if defined(RWL_SOCKET) || defined(RWL_SERIAL)

	if ((remote_CDC_rx((void *)&g_rwl_hndle, g_rem_ptr, buf_ptr,
	                             g_rem_ptr->msg.len, 0)) == BCME_ERROR) {
		DPRINT_ERR(ERR, "Reading CDC %d data bytes failed\n", g_rem_ptr->msg.len);
		return BCME_ERROR;
	}
#elif defined(RWL_DONGLE) || defined(RWL_WIFI)
	if (g_rem_ptr->data_len != 0) {
		int length = g_rem_ptr->data_len;
		if (g_rem_ptr->data_len > g_rem_ptr->msg.len) {
			length = g_rem_ptr->msg.len;
		}
		memcpy(buf_ptr, g_rem_pkt_ptr->message, length);
	}
	else
		buf_ptr = NULL;
#else
	UNUSED_PARAMETER(buf_ptr);
#endif /* RWL_SOCKET || RWL_SERIAL */
	return SUCCESS;
}

#ifdef RWL_DONGLE
/*
 * Function to send the serial response to wl driver
 * The function calculates the no of frames based on the DATA_FRAME_LEN
 * adds cdc header to every frame, copies the header and fragmented frame
 * into rem_buf_ptr and sends the packet down to wl driver
 */

static int
rwl_serial_fragmented_tx(void* wl, rem_ioctl_t *rem_ptr, uchar *buf_ptr, int error)
{
	rem_ioctl_t *loc_ptr = &loc_cdc;
	uchar* rem_buf_ptr;
	uint noframes = 1;    /* Default noframes = 1 */
	uint count;
	uint frame_count;
	uint rem_bytes;

	loc_ptr->msg.cmd = error;
	loc_ptr->msg.flags = REMOTE_REPLY;
	loc_ptr->msg.len = rem_ptr->msg.len;
	loc_ptr->data_len = rem_ptr->data_len;

	/* Fragment the result if it is more than DATA_FRAME_LEN (960) */
	if (loc_ptr->msg.len > DATA_FRAME_LEN) {
		/* Calculate no of frames */
		noframes = (loc_ptr->msg.len)/DATA_FRAME_LEN;
		if ((loc_ptr->msg.len) % DATA_FRAME_LEN > 0) {
			noframes += 1;
			rem_bytes = (loc_ptr->msg.len) % DATA_FRAME_LEN;
		} else {
			rem_bytes = DATA_FRAME_LEN;
		}
	} else {
		rem_bytes = loc_ptr->msg.len;
	}
	DPRINT_INFO(OUTPUT, "No of frames = %d, rem_bytes:%d\n", noframes, rem_bytes);
	count = 0;
	frame_count = noframes;
	rem_buf_ptr = (uchar*)malloc(DONGLE_TX_FRAME_SIZE + REMOTE_SIZE);

	while (count < noframes) {
		memset(rem_buf_ptr, 0, DONGLE_TX_FRAME_SIZE + REMOTE_SIZE);
		/* Send reply to client */
		rem_ptr->msg.cmd = loc_ptr->msg.cmd;
		rem_ptr->msg.flags = loc_ptr->msg.flags;
		rem_ptr->msg.len = loc_ptr->msg.len;

		if (frame_count == 1)
			rem_ptr->data_len = rem_bytes;
		else
			rem_ptr->data_len = DATA_FRAME_LEN;

		DPRINT_DBG(OUTPUT, "GET--rem_ptr->data_len=%d\n", rem_ptr->data_len);

		/* Copy CDC Header */
		memcpy(rem_buf_ptr, (uchar*)rem_ptr, REMOTE_SIZE);

		/* Copy Data now */
		memcpy(&rem_buf_ptr[REMOTE_SIZE], &buf_ptr[count*DATA_FRAME_LEN],
		                                              rem_ptr->data_len);
		count++;
		frame_count--;

		DPRINT_INFO(OUTPUT, "FRAME %d\n", count);
		DPRINT_INFO(OUTPUT, "%d %d  %d  %d\n", rem_ptr->msg.cmd, rem_ptr->msg.len,
			rem_ptr->msg.flags, rem_ptr->data_len);

		rwl_sync_delay(noframes);

		if ((error = rwl_var_setbuf(wl, cmdname, rem_buf_ptr,
		            DONGLE_TX_FRAME_SIZE+REMOTE_SIZE)) < 0) {
			DPRINT_INFO(OUTPUT, "Unable to send to wl driver,error=%d\n", error);
			if (rem_buf_ptr)
				free(rem_buf_ptr);
			return BCME_ERROR;
		}
		else
			DPRINT_INFO(OUTPUT, "Packet sent to wl driver,error=%d\n", error);
	}

	if (rem_buf_ptr)
		free(rem_buf_ptr);

	return error;
}

/* This function transmits the response to the dongle driver in the case
 * of serial dongle transport.
 * In the case of big response, it calls the rwl_serial_fragmented_response
 * function to fragment the response and sends down to the driver.
 */

static int
remote_CDC_dongle_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags)
{
	int error;
	rem_ioctl_t resp_rem_cdc;

	if (flags & REMOTE_SET_IOCTL) {
		uchar* rem_buf_ptr;
		/* for set commands message length and data length should be set to zero
		 * unlike Get Ioctl which will have valid data and message length
		 */
		resp_rem_cdc.msg.len = 0;
		resp_rem_cdc.data_len = 0;
		resp_rem_cdc.msg.cmd = cmd;
		resp_rem_cdc.msg.flags = REMOTE_REPLY;

		DPRINT_INFO(OUTPUT, "Set:Resp packet:%d %d %d %d\n", resp_rem_cdc.msg.cmd,
		resp_rem_cdc.msg.len, resp_rem_cdc.msg.flags, resp_rem_cdc.data_len);

		if ((rem_buf_ptr = (uchar*)malloc(DONGLE_TX_FRAME_SIZE + REMOTE_SIZE)) == NULL) {
			DPRINT_ERR(ERR, "malloc failed for remote_CDC_dongle_tx\n");
			return BCME_ERROR;
		}

		/* Send reply to client here */
		memcpy(rem_buf_ptr, (char*)(&resp_rem_cdc), REMOTE_SIZE);
		if ((error = rwl_var_setbuf((void*)wl, cmdname, rem_buf_ptr,
		                 DONGLE_TX_FRAME_SIZE + REMOTE_SIZE)) < 0) {
			DPRINT_ERR(ERR, "unable to send SET results to driver=%d\n", error);
		} else
			DPRINT_INFO(OUTPUT, "Packet sent to wl driver, error=%d\n", error);

		if (rem_buf_ptr)
			free(rem_buf_ptr);

	} else { /* GET_IOCTL */
		resp_rem_cdc.msg.cmd = cmd;
		resp_rem_cdc.msg.len = buf_len;
		resp_rem_cdc.msg.flags = flags;
		resp_rem_cdc.data_len = data_len;
		if ((error = rwl_serial_fragmented_tx(wl, &resp_rem_cdc, buf, cmd)) < 0)
			DPRINT_ERR(ERR, "wl_server_serial: Return error code failed\n");
	}
	return error;
}
#endif /* RWL_DONGLE */

/* This function gets the command send by the client from the dongle driver */
int
rwl_var_getbuf(void* wl, const char* iovar, void* param, int param_len, void** buf_ptr)
{
	int len;

	memset(rwl_buf, 0, WLC_IOCTL_MAXLEN);
	strcpy((char*)rwl_buf, iovar);
	/* include the null */
	len = strlen(iovar) + 1;

	if (param_len)
		memcpy(&rwl_buf[len], param, param_len);

	*buf_ptr = rwl_buf;

	return wl_get(wl, WLC_GET_VAR, &rwl_buf[0], WLC_IOCTL_MAXLEN);
}

/* This function will send the buffer to the dongle driver */
int
rwl_var_setbuf(void* wl, const char* iovar, void* param, int param_len)
{
	int len;

	memset(rwl_buf, 0, WLC_IOCTL_MAXLEN);
	strcpy((char*)rwl_buf, iovar);

	/* include the null */
	len = strlen(iovar) + 1;

	if (param_len)
		memcpy(&rwl_buf[len], param, param_len);

	len  += param_len;

	DPRINT_DBG(OUTPUT, "setbuf:%s, len:%d\n", rwl_buf, len);

	return wl_set(wl, WLC_SET_VAR, &rwl_buf[0], len);
}

/* This function will send the buffer to the dongle driver */
int
rwl_var_send_vs_actionframe(void* wl, const char* iovar, void* param, int param_len)
{
	int len;

	memset(rwl_buf, 0, WLC_IOCTL_MAXLEN);
	strcpy((char*) rwl_buf, iovar);

	/* include the null */
	len = strlen(iovar) + 1;

	if (param_len)
		memcpy((void*)&rwl_buf[len+ OFFSETOF(wl_action_frame_t, data)], param, param_len);

	/* Set the PacketID (not used by remote WL */
	memset((void*)&rwl_buf[len + OFFSETOF(wl_action_frame_t, packetId)], 0, 4);

	/* Set the dest addr */
	memcpy((void*)&rwl_buf[len + OFFSETOF(wl_action_frame_t, da)],
	(void*)&rwlea,
	ETHER_ADDR_LEN);

	/*  set the length */
	memcpy((void*)&rwl_buf[len + OFFSETOF(wl_action_frame_t, len)], (void*) &param_len, 2);

	len  += param_len + ETHER_ADDR_LEN + 2 + 4;

	DPRINT_DBG(OUTPUT, "setbuf:%s, len:%d\n", rwl_buf, len);

	return wl_set(wl, WLC_SET_VAR, &rwl_buf[0], len);
}
/*
 * This function is used for transmitting the response over different
 * transports.
 * In case of socket the data is directly sent to the client which is waiting on a open socket.
 * In case of socket the data is sent in one big chunk unlike other transports
 *
 * In case of serial the data is sent to the driver using remote_CDC_dongle_tx function
 * which in turn may fragment the data and send it in chunks to the client.
 *
 * In case of wi-fi the data is sent to the driver using the remote_CDC_tx. However
 * in this case the data is converted into 802.11 Action frames and sent using wi-fi driver.
 * Arguments: wl - Driver handle
 *            hndle - Socket handle for socket transport.
 */
int
remote_tx_response(void *wl, void* buf_ptr, int cmd)
{
	int error = -1;

	UNUSED_PARAMETER(wl);
	UNUSED_PARAMETER(buf_ptr);
	UNUSED_PARAMETER(cmd);

#if defined(RWL_SOCKET) || defined(RWL_SERIAL)
	if ((error = remote_CDC_tx((void*)&g_rwl_hndle, cmd, buf_ptr, g_rem_ptr->msg.len,
	                                  g_rem_ptr->msg.len, REMOTE_REPLY, 0)) < 0)
		DPRINT_ERR(ERR, "wl_server: Return results failed\n");
#endif /* RWL_SOCKET || RWL_SERIAL */

#ifdef RWL_DONGLE
	if ((error = remote_CDC_dongle_tx(wl, cmd, buf_ptr, g_rem_ptr->msg.len,
	                          g_rem_ptr->data_len, g_rem_ptr->msg.flags)) < 0)
		DPRINT_ERR(ERR, "wl_server: Return results failed\n");
#endif /* RWL_DONGLE */

#ifdef RWL_WIFI
	/* Purge all the queued cmd's , this to ensure late response time out at */
	/* client side and client might issue the next cmd if server is slow */
	rwl_wifi_purge_actionframes(wl);
	if ((g_rem_ptr->msg.flags & REMOTE_SHELL_CMD) ||
		(g_rem_ptr->msg.flags & REMOTE_GET_IOCTL)||
		(g_rem_ptr->msg.flags & REMOTE_ASD_CMD) ||
		(g_rem_ptr->msg.flags & REMOTE_VISTA_CMD)) {
		if ((error = remote_CDC_tx(wl, cmd, buf_ptr, g_rem_ptr->msg.len,
			g_rem_ptr->msg.len, REMOTE_REPLY, 0)) < 0)
			DPRINT_ERR(ERR, "Wifi_server: Return results failed\n");
	} else {
		if ((error = remote_CDC_tx(wl, cmd, buf_ptr, 0, 0, REMOTE_REPLY, 0)) < 0)
			DPRINT_ERR(ERR, "Failed due to bad flag %d\n", g_rem_ptr->msg.flags);
	}
#endif /* RWL_WIFI */
	return error;
}

/* Close the Socket handle */
void close_sock_handle(int hndle)
{
#ifdef RWL_SOCKET
	rwl_close_pipe(remote_type, (void*)&hndle);
#else
	UNUSED_PARAMETER(hndle);
#endif
}


/*
 * Send the response to the remote if the channel of the server matches with the
 * server channel.
 */
void remote_wifi_response(void* wl)
{
#ifdef RWL_WIFI
	dot11_action_wifi_vendor_specific_t *list;

	if ((list = rwl_wifi_allocate_actionframe()) == NULL) {
		DPRINT_DBG(OUTPUT, "remote_wifi_response: Failed to allocate frame \n");
		return;
	}

	/* it's sync frame and received from client */
	memcpy((char*)&list->data[RWL_WIFI_CDC_HEADER_OFFSET],
	&g_rem_pkt_ptr[RWL_WIFI_CDC_HEADER_OFFSET], REMOTE_SIZE);
	memcpy((char*)&list->data[REMOTE_SIZE], g_rem_pkt_ptr->message,
	RWL_WIFI_FRAG_DATA_SIZE);
	list->type = RWL_WIFI_FIND_MY_PEER;
	/* Store the client mac addr */
	memcpy((void*)&rwlea, (void*)&list->data[RWL_DUT_MAC_ADDRESS_OFFSET], ETHER_ADDR_LEN);
	/* send the response to client if server is on the same channel */
	rwl_wifi_find_server_response(wl, list);

	free(list);
#else
	UNUSED_PARAMETER(wl);
#endif /* RWL_WIFI */
	return;
}

/* Function to check IN-dongle mode firmware */
int
rwl_iovar_check(void *wl)
{
	void *ptr;
#ifdef RWL_WIFI
	dot11_action_wifi_vendor_specific_t rec_frame;

	/* Check for indongle mode firmware */
	return rwl_var_getbuf(wl, RWL_WIFI_GET_ACTION_CMD, &rec_frame,
	RWL_WIFI_ACTION_FRAME_SIZE, &ptr);
#endif
	UNUSED_PARAMETER(ptr);
	UNUSED_PARAMETER(wl);
#ifdef RWL_DONGLE
	return rwl_var_getbuf(wl, "remote", NULL, 0, &ptr);
#else
	return 0;
#endif
}


#ifndef TARGETOS_symbian
/* Function to get a ctrl-c packet */
int
get_ctrlc_header(void *wl)
{
#if defined(RWL_SOCKET) || defined(RWL_SERIAL)
	fd_set fdset;
	struct timeval tv;
	UNUSED_PARAMETER(wl);
	FD_ZERO(&fdset);
	FD_SET((unsigned)g_rwl_hndle, &fdset);
	tv.tv_sec = 0;
	tv.tv_usec = 0;
	if ((select(g_rwl_hndle+1, &fdset, NULL, NULL, &tv)) > 0) {
		if (FD_ISSET(g_rwl_hndle, &fdset)) {
			remote_CDC_rx_hdr((void *)&g_rwl_hndle, 0);
			return BCME_OK;
		}
	}
	return BCME_ERROR;

#else
	return remote_rx_header(wl, 0);
#endif /* if defined(RWL_SOCKET) || defined(RWL_SERIAL) */
}
#endif /* TARGETOS_symbian */

/* Main server module common for all transports
 * This module will do the initial transport setups.
 * Then it receives the command from client in CDC format
 * and transmits the response back to the client.
 * In the case of socket, it receives the command from the client
 * and sends the response directly to the client via TCP socket.
 *
 * In the case of serial & wifi , it receives the command from the driver
 * and sends the response to the driver.
 */
int
remote_server_exec(int argc, char **argv, void *wl)
{
	int err;
	int transport_descriptor;
	char *async_cmd_flag = NULL;
	int skip;
	int download_flag = 0;
	FILE *fp = NULL;
	char *fn = "dwnldfile.bin";
	char old_intf_name[IFNAMSIZ];
#ifdef WIN32
	char shell_fname[MAX_SHELL_FILE_LENGTH];
	DWORD dwlen;
#endif
#ifdef RWL_DONGLE
	int uart_enable = 1;
	/* To set dongle flag when dongle server starts */
	if ((err = rwl_var_setbuf(wl, dongleset, &uart_enable,
		sizeof(int))) < 0) {
			DPRINT_INFO(OUTPUT, "Unable to send to wl driver,error=%d\n", err);
	}
#endif
	if (rwl_iovar_check (wl) < 0) {
		DPRINT_ERR(ERR, "wl_server: RWL_WIFI/RWL_DONGLE not defined ");
		DPRINT_ERR(ERR, "Or In-Dongle mode enabled\n");
		exit(0);
	}
	/* Initialise for all the transports - socket, serial, and wifi
	 * In Socket transport, main socket handler will be returned.
	 */
	if ((transport_descriptor = rwl_transport_setup(argc, argv)) < 0)
		return BCME_ERROR;

#ifdef RWL_WIFI
	remote_wifi_ser_init_cmds(wl);
#endif
	/* Create a directory /tmp/RWL for the shell response files */
	if (rwl_create_dir() < 0)
		return BCME_ERROR;


#ifdef RWLASD
	/* DUT initialization function */
	wfa_dut_init(&trafficBuf, &respBuf, &parmsVal, &xcCmdBuf, &toutvalp);
#endif

	/* Copy old interface name to restore it */
	store_old_interface(wl, old_intf_name);

	while (1) {
		uchar *buf_ptr = NULL;
		char *errstr = NULL;
#ifdef VISTA_SERVER
		int index;
		char *vista_buf[MAX_VISTA_ARGC];
#endif
#ifdef RWL_SERIAL
		g_rwl_hndle = transport_descriptor;
#else
		g_rwl_hndle = -1;
#endif
#ifdef RWL_DONGLE
		if (set_ctrlc) {
			uart_enable = 0;
			if ((err = rwl_var_setbuf(wl, dongleset, &uart_enable,
				sizeof(int))) < 0) {
				DPRINT_INFO(OUTPUT, "Unable to send to wl driver,error=%d\n", err);
			}
			set_ctrlc = 0;
			exit(0);
		}
#endif /* RWL_DONGLE */

		/* Receive the CDC header */
		if ((remote_rx_header(wl, transport_descriptor)) == BCME_ERROR) {
			DPRINT_DBG(OUTPUT, "\n Waiting for client to transmit command\n");
			continue;
		}

		DPRINT_INFO(OUTPUT, "REC : cmd %d\t msg len %d  msg flag %d\t msg status %d\n",
		            g_rem_ptr->msg.cmd, g_rem_ptr->msg.len,
		            g_rem_ptr->msg.flags, g_rem_ptr->msg.status);

#ifdef RWL_WIFI
		/* send the response to remote if it is findserver cmd, this is specific to wifi */
		if (g_rem_ptr->msg.flags & REMOTE_FINDSERVER_IOCTL) {
			remote_wifi_response(wl);
			continue;
		}
#endif /* RWL_WIFI */

		/*
		 * Allocate buffer only if there is a response message expected.
		 * Some commands such as up/down do not output anything.
		 */
		if (g_rem_ptr->msg.len) {
			if ((buf_ptr = malloc(g_rem_ptr->msg.len)) == NULL) {
				DPRINT_ERR(ERR, "malloc of %d bytes failed\n", g_rem_ptr->msg.len);
				continue;
			}
		}

		/* Receive the data */
		if ((err = remote_rx_data(buf_ptr)) == BCME_ERROR) {
			if (buf_ptr)
				free(buf_ptr);
			continue;
		}

		/* Process RWL negotiate commands */
		if (g_rem_ptr->msg.flags & REMOTE_NEGOTIATE_CMD) {
			if (g_rem_ptr->msg.cmd == NEGOTIATE_GET_OS) {
				if (g_rem_ptr->msg.len >= sizeof(int)) {
					*(int*)buf_ptr = LINUX_OS;
					g_rem_ptr->msg.len = sizeof(int);

					DPRINT_INFO(OUTPUT, "RESP : os type %d\n", *(int*)buf_ptr);
					if (remote_tx_response(wl, buf_ptr, 0) < 0)
						DPRINT_ERR(ERR, "\nReturn results failed\n");
				}
			}
#ifdef RWL_SOCKET
			close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */
			if (buf_ptr)
				free(buf_ptr);
			continue;
		}

		/* Process command */
		if (g_rem_ptr->msg.flags & REMOTE_SHELL_CMD) {
			/* Get the response length first and get the response buffer in case of
			 * synchronous shell commands and the buf_ptr will have the response file
			 * name. In case of asynchronous shell commands, buf_ptr
			 * will be get updated by the remote_shell_execute function.
			 */
			need_speedy_response = 1;
#ifndef WIN32
			if (buf_ptr) {
				async_cmd_flag = strstr((char*)buf_ptr, "%");
			}
			if ((err = remote_shell_execute((char*)buf_ptr, wl)) > 0) {
				if (async_cmd_flag)
					g_rem_ptr->msg.len = err;
			}
			/* Sync shell command: No need to send response from here */
			else {
#ifdef RWL_SOCKET
				/* Transmitted to client. Then close the handle &
				 * get the new handle for next transmission & reception.
				 */
				close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */
				continue;
			}
#else
			if ((err = remote_shell_execute((char*)buf_ptr, wl)) != SUCCESS) {
				DPRINT_ERR(ERR, "Error in executing shell command\n");
				if (buf_ptr)
					free(buf_ptr);
#ifdef RWL_SOCKET
				/* Transmitted to client. Then close the handle &
				 * get the new handle for next transmission & reception.
				 */
				close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */
				continue;
			}
			/* Get the response from the temporary file */
			if ((err = remote_shell_get_resp(shell_fname, wl)) != SUCCESS) {
				DPRINT_ERR(ERR, "Error in executing shell command\n");
			}
			if (buf_ptr)
				free(buf_ptr);
#ifdef RWL_SOCKET
			/* Transmitted to client. Then close the handle &
			 * get the new handle for next transmission & reception.
			 */
			close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */
			continue;
#endif	/* WIN32 */
		} /* REMOTE_SHELL_CMD */

#ifdef RWLASD
		if (g_rem_ptr->msg.flags & REMOTE_ASD_CMD) {
			if ((err = remote_asd_exec(buf_ptr, (int *)&g_rem_ptr->msg.len)) < 0) {
				DPRINT_ERR(ERR, "Error in executing asd command\n");
			}
		} /* REMOTE_ASD_CMD */
#endif

/*
 * added to take care of OID base problem for cross OS RWL cleint server
 * In case of LX Server and WIN32 client OID base need to be removed
 * In case of WIN32 server and LX client OID base need to be added
 */
		if (!(g_rem_ptr->msg.flags & REMOTE_ASD_CMD)) {
		if (g_rem_ptr->msg.cmd > MAX_IOVAR)
			g_rem_ptr->msg.cmd -= WL_OID_BASE;
#if defined(WIN32)
		if (g_rem_ptr->msg.cmd < MAX_IOVAR)
			g_rem_ptr->msg.cmd += WL_OID_BASE;
#endif
		}
#ifdef VISTA_SERVER
		if (g_rem_ptr->msg.flags & REMOTE_VISTA_CMD) {
			vista_buf[0] = strtok(buf_ptr, " \t\n");
			for (index = 1; (vista_buf[index] = strtok(NULL, " \t\n")) != NULL;
				index++);
			if ((err = remote_vista_exec(wl, vista_buf)) < 0) {
				DPRINT_ERR(ERR, "Error in executing vista command\n");
			}
			memcpy(buf_ptr, vista_buf[0], strlen(vista_buf[0]));
			g_rem_ptr->msg.len = strlen(vista_buf[0]);
		} /* REMOTE_VISTA_CMD */
#endif /* VISTA_SERVER */

#ifndef RWL_DONGLE
		if (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL ||
			g_rem_ptr->msg.flags & REMOTE_SET_IOCTL) {
			if (strlen(g_rem_ptr->intf_name) != 0) {
				struct ifreq ifr;
				/* validate the interface */
				memset(&ifr, 0, sizeof(ifr));
				if (g_rem_ptr->intf_name)
					strncpy(ifr.ifr_name, g_rem_ptr->intf_name, IFNAMSIZ);

				if (wl_check((void *)&ifr)) {
					DPRINT_ERR(ERR, "%s: wl driver adapter not found\n",
						g_rem_ptr->intf_name);
					/* Signal end of command output */
					g_rem_ptr->msg.len = 0;
					remote_tx_response(wl, NULL, BCME_NODEVICE);
					if (buf_ptr)
						free(buf_ptr);
#ifdef RWL_SOCKET
					close_sock_handle(g_rwl_hndle);
#endif
					continue;
				}

				if (set_interface(wl, g_rem_ptr->intf_name) == BCME_OK)
					DPRINT_DBG(OUTPUT, "\n %s Interface will be used \n",
						(char *)wl);
			}
		}
#endif /* ifndef RWL_DONGLE */
		if (g_rem_ptr->msg.flags & REMOTE_SET_IOCTL ||
			g_rem_ptr->msg.flags & RDHD_SET_IOCTL) {
#ifdef WIN32
#if defined(RWL_DONGLE) || defined(RWL_WIFI)
			/* For commands with msg length as zero initialize the buffer to null */
			if (g_rem_ptr->msg.len == 0)
				buf_ptr = NULL;
#endif
#else
			if (g_rem_ptr->msg.len == 0)
				buf_ptr = NULL;
#endif /* WIN32 */

			if (g_rem_ptr->msg.flags & REMOTE_SET_IOCTL) {
				if (g_rem_ptr->msg.cmd == WLC_SET_VAR && buf_ptr &&
				    !strncmp((const char *)buf_ptr,
					     "init", g_rem_ptr->msg.len)) {
					DPRINT_INFO(OUTPUT, "REC : init command\n");
					err = 0;
				} else if (g_rem_ptr->msg.cmd == WLC_SET_VAR && buf_ptr &&
				   !strncmp((const char *)buf_ptr,
					    "download", g_rem_ptr->msg.len)) {
					DPRINT_INFO(OUTPUT, "REC : download command\n");
					download_flag =  download_flag? 0: 1;
					if (download_flag) {
						DPRINT_INFO(OUTPUT, "download started\n");
						if (!(fp = fopen(fn, "wb"))) {
							DPRINT_ERR(ERR, "Failed to open file\n");
							err = -2;
						}
					} else {
						DPRINT_INFO(OUTPUT, "download completed\n");
						if (fp != NULL)
							fclose(fp);
					}
					err = 0;
				} else if (g_rem_ptr->msg.cmd == WLC_SET_VAR && buf_ptr &&
				   !strncmp((const char *)buf_ptr,
					    "membytes", g_rem_ptr->msg.len)) {
					DPRINT_INFO(OUTPUT, "REC : membytes command\n");
					skip = strlen("membytes ") + 8;
					if (fp != NULL)
						fwrite(buf_ptr + skip, 1,
						       g_rem_ptr->msg.len - skip, fp);
					else
						DPRINT_ERR(ERR, "Download file has been closed.\n");
					err = 0;
				} else {
					err = wl_ioctl(wl, g_rem_ptr->msg.cmd,
					       (void *)buf_ptr, g_rem_ptr->msg.len, TRUE);
					DPRINT_INFO(OUTPUT, "SEND : cmd %d\t msg len %d\n",
					    g_rem_ptr->msg.cmd, g_rem_ptr->msg.len);
					DPRINT_INFO(OUTPUT, "error code: %d\n", err);
				}
			}
			if (err == BCME_IOCTL_ERROR) {
				if (rwl_var_getbuf(wl, "bcmerrorstr", NULL, 0, (void**)&errstr)) {
					DPRINT_ERR(ERR, "Error in executing wl_ioctl\r\n");
				} else {
					DPRINT_ERR(ERR, "%s\n", errstr);
				}
				DPRINT_ERR(ERR, "Setting Default Interface1 \n");
				set_interface(wl, old_intf_name);
			}

			if (g_rem_ptr->msg.flags & RDHD_SET_IOCTL) {
				err = dhd_ioctl(wl, g_rem_ptr->msg.cmd,
				(void *)buf_ptr, g_rem_ptr->msg.len, TRUE);
			}
			g_rem_ptr->msg.flags = REMOTE_SET_IOCTL;

		} /* RDHD/REMOTE_SET_IOCTL */

		if (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL ||
			g_rem_ptr->msg.flags & RDHD_GET_IOCTL) {
			if (g_rem_ptr->msg.cmd == WLC_GET_VAR && buf_ptr &&
				strncmp((const char *)buf_ptr, "exit", g_rem_ptr->msg.len) == 0) {
					/* exit command from remote client terminates server */
					free(buf_ptr);
					break;
			}
			if (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL)
				err = wl_ioctl(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr,
					g_rem_ptr->msg.len, FALSE);
			if (err == BCME_IOCTL_ERROR) {
				if (rwl_var_getbuf(wl, "bcmerrorstr", NULL, 0, (void**)&errstr)) {
					DPRINT_ERR(ERR,
						"REMOTE_GET_IOCTL::Error in executing wl_ioctl\n");
				} else {
					DPRINT_ERR(ERR, "%s\n", errstr);
				}
				DPRINT_ERR(ERR, "Setting Default Interface \n");
				set_interface(wl, old_intf_name);
			}

			if (g_rem_ptr->msg.flags & RDHD_GET_IOCTL)
				err = dhd_ioctl(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr,
					g_rem_ptr->msg.len, FALSE);
			g_rem_ptr->msg.flags = REMOTE_GET_IOCTL;
		} /* REMOTE_GET_IOCTL */
		DPRINT_INFO(OUTPUT, "RESP : cmd %d\t msg len %d\n",
		g_rem_ptr->msg.cmd, g_rem_ptr->msg.len);
		/* setting back default interface  */
		set_interface(wl, old_intf_name);
		/* Transmit the response results */
		if (remote_tx_response(wl, buf_ptr, err) < 0) {
			DPRINT_ERR(ERR, "\nReturn results failed\n");
		}

#ifdef RWL_SOCKET
		if (g_rem_ptr->msg.flags != REMOTE_SHELL_CMD)
		/* Transmitted to client. Then close the handle & get the new handle
		 * for next transmission & reception. In case of shell commands this
		 * should be closed in respective shellproc files.
		 */
		close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */

		if (buf_ptr) {
			free(buf_ptr);
		}
	} /* end of while */
#if defined(RWL_SOCKET)
	/* Close the main handle for socket */
	close_sock_handle(transport_descriptor);
#elif defined(RWL_SERIAL)
	/* Close the main handle for serial pipe  */
	rwl_close_pipe(remote_type, (void*)&transport_descriptor);
#endif

#ifdef RWLASD
	wfa_dut_deinit();
#endif

	return err;
}
