/****************************************************************************
*  (c) Copyright 2007 Wi-Fi Alliance.  All Rights Reserved
*
*
*  LICENSE
*
*  License is granted only to Wi-Fi Alliance members and designated
*  contractors ($B!H(BAuthorized Licensees$B!I(B)..AN  Authorized Licensees are granted
*  the non-exclusive, worldwide, limited right to use, copy, import, export
*  and distribute this software:
*  (i) solely for noncommercial applications and solely for testing Wi-Fi
*  equipment; and
*  (ii) solely for the purpose of embedding the software into Authorized
*  Licensee$B!G(Bs proprietary equipment and software products for distribution to
*  its customers utipnder a license with at least the same restrictions as
*  contained in this License, including, without limitation, the disclaimer of
*  warranty and limitation of liability, below..AN  The distribution rights
*  granted in clause
*  (ii), above, include distribution to third party companies who will
*  redistribute the Authorized Licensee$B!G(Bs product to their customers with or
*  without such third party$B!G(Bs private label. Other than expressly granted
*  herein, this License is not transferable or sublicensable, and it does not
*  extend to and may not be used with non-Wi-Fi applications..AN  Wi-Fi Alliance
*  reserves all rights not expressly granted herein..AN
*.AN
*  Except as specifically set forth above, commercial derivative works of
*  this software or applications that use the Wi-Fi scripts generated by this
*  software are NOT AUTHORIZED without specific prior written permission from
*  Wi-Fi Alliance.
*.AN
*  Non-Commercial derivative works of this software for internal use are
*  authorized and are limited by the same restrictions; provided, however,
*  that the Authorized Licensee shall provide Wi-Fi Alliance with a copy of
*  such derivative works under a perpetual, payment-free license to use,
*  modify, and distribute such derivative works for purposes of testing Wi-Fi
*  equipment.
*.AN
*  Neither the name of the author nor "Wi-Fi Alliance" may be used to endorse
*  or promote products that are derived from or that use this software without
*  specific prior written permission from Wi-Fi Alliance.
*
*  THIS SOFTWARE IS PROVIDED BY WI-FI ALLIANCE "AS IS" AND ANY EXPRESS OR
*  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
*  OF MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A.AN PARTICULAR PURPOSE,
*  ARE DISCLAIMED. IN NO EVENT SHALL WI-FI ALLIANCE BE LIABLE FOR ANY DIRECT,
*  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
*  (INCLUDING, BUT NOT LIMITED TO, THE COST OF PROCUREMENT OF SUBSTITUTE
*  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
*  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
*  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE) ARISING IN ANY WAY OUT OF
*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
*   File: wfa_cs.c -- configuration and setup
*   This file contains all implementation for the dut setup and control
*   functions, such as network interfaces, ip address and wireless specific
*   setup with its supplicant.
*
*   The current implementation is to show how these functions
*   should be defined in order to support the Agent Control/Test Manager
*   control commands. To simplify the current work and avoid any GPL licenses,
*   the functions mostly invoke shell commands by calling linux system call,
*   system("<commands>").
*
*   It depends on the differnt device and platform, vendors can choice their
*   own ways to interact its systems, supplicants and process these commands
*   such as using the native APIs.
*
*   Revision History:
*        2006/03/10  -- initially created by qhu
*        2006/06/01  -- BETA Release by qhu
*        2006/06/13  -- 00.02 Release by qhu
*        2006/06/30  -- 00.10 Release by qhu
*        2006/07/10  -- 01.00 Release by qhu
*        2006/09/01  -- 01.05 Release by qhu
*        2006/10/26  -- 01.06 Released by qhu
*                       replace hardcoded buf size with macro
*        2006/12/02  -- bugs: 1. fixes incorrect order of getipconfig.sh
*                                input parameters reported by p.schwann
*                             2. will add a new network for wap_cli command
*                                in case the network id 0 not present,
*                                recommended by c.benson
*                                the solution is to reimplement with calling
*                                native C API
*        2007/01/11  -- 01.10 released by qhu
*        2007/02/15  -- WMM Extension Beta released by qhu, mkaroshi
*        2007/03/18  -- add file close statements
*        2007/03/21  -- rename the file to avoid the confusion.
*        2007/03/30  -- 01.40 WPA2 and Official WMM Beta Release by qhu
*        2007/04/20  -- 02.00 WPA2 and Official WMM Release by qhu
*        2007/08/15 --  02.10 WMM-Power Save release by qhu
*        2007/10/10 --  02.20 Voice SOHO beta -- qhu
*        2007/11/07 --  02.30 Voice HSO -- qhu
*
*/
#ifndef WIN32
#include <unistd.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <poll.h>
#include <bcmendian.h>
#else
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <iphlpapi.h>
#endif

#include "wfa_debug.h"
#include "wfa_ver.h"
#include "wfa_main.h"
#include "wfa_types.h"
#include "wfa_ca.h"
#include "wfa_tlv.h"
#include "wfa_sock.h"
#include "wfa_tg.h"
#include "wfa_cmds.h"
#include "wfa_rsp.h"
#include "wfa_miscs.h"
#ifdef WFA_WMM_EXT
#ifdef WFA_WMM_PS_EXT
#include "wfa_wmmps.h"
#endif
#endif

#define CERTIFICATES_PATH    "/etc/wpa_supplicant"
#define TSPEC_VER 2
#define TSPEC_BUF_SIZE 15
#define MAX_TOKENS 15
#define BYTE_0 0
#define BYTE_1 1
#define BYTE_2 2 
#define TID_INDEX 4 
#define NO_TSINFO 1 
#define TID_MISMATCH 2 

/* Some device may only support UDP ECHO, activate this line */
//#define WFA_PING_UDP_ECHO_ONLY 1


int g_serv_sock_desc;

/* Start --> Modified as per BRCM 1.3 ASD */

/* error code */
#define BCM_OK			0
#define BCM_BAD			1

#define BCM_SSID_LEN_MAX	32
#define BCM_SSID_MAX		32

/* defines for BSS types */
#define BCM_BSS_INVALID		0
#define	BCM_BSS_INDEPENDENT	1
#define BCM_BSS_INFRA		3
#define	BCM_BSS_AUTO		4

/* defines for WPA AITHENTICATION */
#define BCM_WPA_AUTH_DISABLED	0x0
#define BCM_WPA_AUTH_NONE	0x1
#define BCM_WPA_AUTH_8021X	0x2
#define BCM_WPA_AUTH_PSK	0x4
#define BCM_WPA2_AUTH_8021X	0x40
#define BCM_WPA2_AUTH_PSK	0x80

#define BCM_WEP_KEY_SIZE_MAX	32
#define BCM_8021X_ASSOC_TIMEOUT	3600
#define BCM_PRI_KEY_BAD		(-1)

typedef union bcmEapObj {
	caStaSetEapTLS_t setEapTLS;
	caStaSetEapTTLS_t setEapTTLS;
	caStaSetEapSIM_t setEapSIM;
	caStaSetEapPEAP_t setEapPEAP;
	caStaSetEapFAST_t setEapFAST;
	caStaSetEapAKA_t setEapAKA;
} bcmEapObj_t;

typedef struct bcmSsidObj
{
	char ssidStr[BCM_SSID_LEN_MAX + 1];
	int bssType;
	int channel;
	int wsec;
	int auth; /* 802.11 authentication : default 0 for open. */
	int wpa_auth; /* WPA authentication: default 1 for WPA-NONE */
	int uapsd;
	char keys[4][BCM_WEP_KEY_SIZE_MAX]; /* wl addwep */
	int primary_key;
	BYTE passphrase[64]; /* wl set_pmk */
	int powerSave;
	/* UAPSD */
	int maxSPLength;
	int acBE;
	int acBK;
	int acVI;
	int acVO;
	/* EAP Types*/
	bcmEapObj_t eapObj;  
	int eapType;
} bcmSsidObj_t;

typedef struct bcmSsidObjTbl
{
	bcmSsidObj_t ssidObj[BCM_SSID_MAX];
	uint addCnt;
	uint delCnt;
	uint entries;
} bcmSsidObjTbl_t;

bcmSsidObjTbl_t bsotbl;
int bcmSsidIsGood(char *ssidStr);
bcmSsidObj_t *bcmWfaSsidTblFreeEntry();
bcmSsidObj_t *bcmWfaSsidTblSsidFind(char *ssidStr);
bcmSsidObj_t *bcmWfaSsidObjTblAdd(char *ssidStr);
void bcmWfaSsidObjTblDel(char *ssidStr);
void bcmWfaSsidObjPrint(bcmSsidObj_t *bso);
void bcmWfaSsidObjTblPrint(void);

/* End --> Modified as per BRCM 1.3 ASD */

/* Since the two definitions are used all over the CA function */
char gCmdStr[WFA_CMD_STR_SZ];
dutCmdResponse_t gGenericResp;

/*
* agtCmdProcGetVersion(): response "ca_get_version" command to controller
*  input:  cmd --- not used
*          valLen -- not used
*  output: parms -- a buffer to store the version info response.
*/

int agtCmdProcGetVersion(int len, BYTE *parms, int *respLen, BYTE *respBuf)
{
	dutCmdResponse_t *getverResp = &gGenericResp;

	DPRINT_INFO(WFA_OUT, "entering agtCmdProcGetVersion ...\n");

	getverResp->status = STATUS_COMPLETE;
	strncpy(getverResp->cmdru.version, WFA_SYSTEM_VER, 8);

	wfaEncodeTLV(WFA_GET_VERSION_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)getverResp, respBuf);

	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);

	return TRUE;
}

/*
* wfaStaAssociate():
*    The function is to force the station wireless I/F to re/associate
*    with the AP.
*/
int wfaStaAssociate(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	int retVal = TRUE;
	dutCommand_t *assoc = (dutCommand_t *)caCmdBuf;
	dutCmdResponse_t *staAssocResp = &gGenericResp;
	/* Start: Modified as per BRCM 1.3 ASD */
	int imode; /* 0 for ibss, 1 for infrastructure */
	char ssidTarget[WFA_SSID_NAME_LEN];
	bcmSsidObj_t *bso;
	int idx;
	char identity[WFA_BUFF_128],dummy[WFA_BUFF_128];

	DPRINT_INFO(WFA_OUT, "entering wfaStaAssociate ...\n");
	/* use 'ifconfig' command to bring down the interface (linux specific) */

	memcpy(ssidTarget, assoc->cmdsu.ssid, WFA_SSID_NAME_LEN);
	bso = bcmWfaSsidTblSsidFind(ssidTarget);
	if (!bso) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidTarget))) {
			DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidTarget);
			retVal = FALSE;
			goto exit;
		}
		if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
			bcmWfaSsidObjPrint(bso);
		}

	}
	imode = (bso->bssType == BCM_BSS_INDEPENDENT) ? 0 : 1;
	sprintf(gCmdStr, "%s disassoc", rwl_client_path);
	exec_process(gCmdStr);

        asd_sleep(3); 
	/*Default case will be non-802.1x associations*/
	switch (bso->eapType) {
		case BCM_EAP_TYPE_TLS:
				strncpy(identity,bso->eapObj.setEapTLS.clientCertificate,sizeof(identity));
		        	/* For EAPTLS, identity is taken as the file name of the Client certificate
			         * since we do not have any username information in this mode
			 	 */
				printf("\n %s\n",identity);
				strtok_r(identity,".",(char **)&dummy);
				printf("\n %s\n",identity);
				S_N_PRINTF(gCmdStr,sizeof(gCmdStr),"%s sh cnClient -A %s -ssid %s -%s -%s -tls "
				"-usercert %s %s -identity %s -validate %s -timeout %d %s ", rwl_client_path,	
				bso->eapObj.setEapTLS.intf, bso->eapObj.setEapTLS.ssid, 
				bso->eapObj.setEapTLS.keyMgmtType, bso->eapObj.setEapTLS.encrptype, 
				bso->eapObj.setEapTLS.clientCertificate, KEY_FILE, identity, 
				bso->eapObj.setEapTLS.trustedRootCA, BCM_8021X_ASSOC_TIMEOUT, "%"); 
				retVal = exec_process_cnclient(gCmdStr, rwl_client_path, rwl_wifi_flag);
				break;
		case BCM_EAP_TYPE_TTLS:
				S_N_PRINTF(gCmdStr,sizeof(gCmdStr),"%s sh cnClient -A %s -ssid %s -%s -%s -ttls-%s "
				"-user %s -password %s -identity %s -validate %s -timeout %d %s  ", rwl_client_path, 
				bso->eapObj.setEapTTLS.intf, bso->eapObj.setEapTTLS.ssid, 
				bso->eapObj.setEapTTLS.keyMgmtType, bso->eapObj.setEapTTLS.encrptype, TTLS_innerEAP, 
				bso->eapObj.setEapTTLS.username, bso->eapObj.setEapTTLS.passwd, 
				bso->eapObj.setEapTTLS.username, bso->eapObj.setEapTTLS.trustedRootCA, 
				BCM_8021X_ASSOC_TIMEOUT, "%");
				retVal = exec_process_cnclient(gCmdStr, rwl_client_path, rwl_wifi_flag);
				break;
		case BCM_EAP_TYPE_SIM:
				S_N_PRINTF(gCmdStr,sizeof(gCmdStr),"%s sh cnClient -A %s -ssid %s -%s -%s -sim %s "
				"-scpin %s -timeout %d %s ", rwl_client_path, bso->eapObj.setEapSIM.intf,
				bso->eapObj.setEapSIM.ssid, bso->eapObj.setEapSIM.keyMgmtType, 
				bso->eapObj.setEapSIM.encrptype, bso->eapObj.setEapSIM.username, 
				bso->eapObj.setEapSIM.passwd, BCM_8021X_ASSOC_TIMEOUT, "%");
				retVal = exec_process_cnclient(gCmdStr, rwl_client_path, rwl_wifi_flag);
				break;
		case BCM_EAP_TYPE_PEAP:
				S_N_PRINTF(gCmdStr,sizeof(gCmdStr),"%s sh cnClient -A %s -ssid %s -%s -%s -peap-%s "
				"-user %s -password %s -identity %s -timeout %d %s ", rwl_client_path, 
				bso->eapObj.setEapPEAP.intf, bso->eapObj.setEapPEAP.ssid, 
				bso->eapObj.setEapPEAP.keyMgmtType, bso->eapObj.setEapPEAP.encrptype, 
				bso->eapObj.setEapPEAP.innerEAP, bso->eapObj.setEapPEAP.username,
				bso->eapObj.setEapPEAP.passwd, bso->eapObj.setEapPEAP.username, 
				BCM_8021X_ASSOC_TIMEOUT, "%");
				retVal = exec_process_cnclient(gCmdStr, rwl_client_path, rwl_wifi_flag);
				break;
		case BCM_EAP_TYPE_FAST:
				S_N_PRINTF(gCmdStr,sizeof(gCmdStr),"%s sh cnClient -A %s -ssid %s -%s -%s -fast-%s "
				"-user %s -password %s -identity %s -validate %s -timeout %d %s ", rwl_client_path, 
				bso->eapObj.setEapFAST.intf, bso->eapObj.setEapFAST.ssid, 
				bso->eapObj.setEapFAST.keyMgmtType, bso->eapObj.setEapFAST.encrptype, 
				bso->eapObj.setEapFAST.innerEAP, bso->eapObj.setEapFAST.username,
				bso->eapObj.setEapFAST.passwd, bso->eapObj.setEapFAST.username,
				bso->eapObj.setEapFAST.trustedRootCA, BCM_8021X_ASSOC_TIMEOUT, "%");
				retVal = exec_process_cnclient(gCmdStr, rwl_client_path, rwl_wifi_flag);
				break;
		case BCM_EAP_TYPE_AKA:
				S_N_PRINTF(gCmdStr,sizeof(gCmdStr),"%s sh cnClient -A %s -ssid %s -%s -%s -eap-aka "
				"-user %s -password %s -identity %s -timeout %d %s ", rwl_client_path, 
				bso->eapObj.setEapAKA.intf, bso->eapObj.setEapAKA.ssid, 
				bso->eapObj.setEapAKA.keyMgmtType, bso->eapObj.setEapAKA.encrptype, 
				bso->eapObj.setEapAKA.username,	bso->eapObj.setEapAKA.passwd, 
				bso->eapObj.setEapAKA.username,BCM_8021X_ASSOC_TIMEOUT, "%");
				retVal = exec_process_cnclient(gCmdStr, rwl_client_path, rwl_wifi_flag);
				break;
		default:	
			/* Run the commands in the batching mode in case of wifi transport*/
			if(rwl_wifi_flag) {
				asd_sleep(1);
				sprintf(gCmdStr, "%s seq_start", rwl_client_path);
				exec_process(gCmdStr);
			}
	

			asd_sleep(1);
			if ((!imode) && bso->channel){
				sprintf(gCmdStr, "%s channel %d", rwl_client_path, bso->channel);
				exec_process(gCmdStr);
			}

			sprintf(gCmdStr, "%s infra %d", rwl_client_path, imode);
			exec_process(gCmdStr);

			/*Execute the command wme_apsd_sta only if the driver is down*/
			sprintf(gCmdStr, "%s wme_apsd_sta %d %d %d %d %d", rwl_client_path, 
			bso->maxSPLength, bso->acBE, bso->acBK, bso->acVI, bso->acVO);
			exec_process(gCmdStr);

			asd_sleep(3);
			sprintf(gCmdStr, "%s up", rwl_client_path);
			exec_process(gCmdStr);
	
			if(rwl_wifi_flag) {
				sprintf(gCmdStr, "%s seq_stop", rwl_client_path);
				exec_process(gCmdStr);
			}

			asd_sleep(2);
			/* handle WEP keys */
			for(idx = 0; idx < 4; idx++) {
				if(bso->keys[idx][0] != '\0') {
					sprintf(gCmdStr, "%s addwep %d %s", rwl_client_path, idx, bso->keys[idx]);
				} else {
					sprintf(gCmdStr, "%s rmwep %d", rwl_client_path, idx);
				}
				exec_process(gCmdStr);
			}

			/* set primary key */
			if(bso->primary_key != BCM_PRI_KEY_BAD) {
				sprintf(gCmdStr, "%s primary_key %d", rwl_client_path, bso->primary_key);
				exec_process(gCmdStr);
			}

			/* security */
			sprintf(gCmdStr, "%s wsec %d", rwl_client_path, bso->wsec);
			exec_process(gCmdStr);

			if(bso->passphrase[0] != '\0') {
				sprintf(gCmdStr, "%s set_pmk %s", rwl_client_path, bso->passphrase);
				exec_process(gCmdStr);
			}
	
			if(bso->wpa_auth == BCM_WPA_AUTH_PSK) {
				sprintf(gCmdStr, "%s sup_wpa 1", rwl_client_path );
				exec_process(gCmdStr);	
			} else if(bso->wpa_auth == BCM_WPA2_AUTH_PSK) {
				sprintf(gCmdStr, "%s sup_wpa 2", rwl_client_path );
				exec_process(gCmdStr);	
			}

			sprintf(gCmdStr, "%s auth %d", rwl_client_path, bso->auth);
			exec_process(gCmdStr);

			sprintf(gCmdStr, "%s wpa_auth %d", rwl_client_path, bso->wpa_auth);
			exec_process(gCmdStr);

			sprintf(gCmdStr, "%s ssid %s", rwl_client_path, ssidTarget);
			exec_process(gCmdStr);
	}
/*
 * Then report back to control PC for completion.
 * This does not have failed/error status. The result only tells
 * a completion.
 */
exit:
	/* End: Modified as per BRCM 1.3 ASD   */

	/*
	* Then report back to control PC for completion.
	* This does not have failed/error status. The result only tells
	* a completion.
	*/
	if(retVal == TRUE)
		staAssocResp->status = STATUS_COMPLETE;
	else
		staAssocResp->status = STATUS_ERROR;	
	wfaEncodeTLV(WFA_STA_ASSOCIATE_RESP_TLV, 4, (BYTE *)staAssocResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
	return retVal;  /* Modified as per BRCM 1.3 ASD   */
}

/*
 * wfaStaReAssociate():
 *    The function is to force the station wireless I/F to re/associate 
 *    with the AP.
 */
int wfaStaReAssociate(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
   dutCommand_t *assoc = (dutCommand_t *)caCmdBuf;
   dutCmdResponse_t *staAssocResp = &gGenericResp;

   DPRINT_INFO(WFA_OUT, "entering wfaStaAssociate ...\n");
   sprintf(gCmdStr, "%s mpc 0", rwl_client_path);
   exec_process(gCmdStr);
   sprintf(gCmdStr, "%s up", rwl_client_path);
   exec_process(gCmdStr);
   /* "wl reassoc" command is not able to associate completly and receives an Auto IP */
   sprintf(gCmdStr, "%s reassoc %s", rwl_client_path, assoc->cmdsu.bssid);
   exec_process(gCmdStr);
   
   staAssocResp->status = STATUS_COMPLETE;
   wfaEncodeTLV(WFA_STA_ASSOCIATE_RESP_TLV, 4, (BYTE *)staAssocResp, respBuf);   
   *respLen = WFA_TLV_HDR_LEN + 4;

   return TRUE; 
}

/*
* wfaStaGetIpConfig():
* This function is to retriev the ip info including
*     1. dhcp enable
*     2. ip address
*     3. mask
*     4. primary-dns
*     5. secondary-dns
*
*     The current implementation is to use a script to find these information
*     and store them in a file.
*/

int wfaStaGetIpConfig(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	int   i = 0;
#ifdef WIN32
	int slen;
	DWORD dwStatus;
	IP_ADAPTER_INFO AdapterInfo[16];	// Allocate information for up to 16 NICs
	PIP_ADAPTER_INFO pAdapterInfo;
	DWORD dwBufLen = sizeof(AdapterInfo);	// Save the memory size of buffer
#endif

	dutCommand_t *getIpConf = (dutCommand_t *)caCmdBuf;
	dutCmdResponse_t *ipconfigResp = &gGenericResp;
	char *ifname = getIpConf->intf;
	caStaGetIpConfigResp_t *ifinfo = &ipconfigResp->cmdru.getIfconfig;
#ifndef WIN32 
	FILE *shell_fpt;
	DPRINT_INFO(WFA_OUT,"Entering staGetIpConfig...\n");
	/* Start: Modified as per BRCM 1.3 ASD */
	/* Dhcp */
	sprintf(gCmdStr,"ps ax | grep -v grep | grep dhcli | wc -l >%s 2>&1", TMP_FILE_PATH);

	system(gCmdStr);

	shell_fpt = fopen(TMP_FILE_PATH, "rb");
	fread(gCmdStr, sizeof(char), 20, shell_fpt);
	fclose(shell_fpt);

	remove(TMP_FILE_PATH);
	if (atoi(gCmdStr) >= 1)
		ifinfo->isDhcp = 1;
	else
		ifinfo->isDhcp = 0;
	/* ipaddr */
	sprintf(gCmdStr, "%s %s | grep 'inet addr' |  cut -d: -f2 | cut -d' ' -f1>%s 2>&1",
	IFCONFIG_PATH, ifname, TMP_FILE_PATH);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);

	system(gCmdStr);

	shell_fpt = fopen(TMP_FILE_PATH, "rb");
	ifinfo->ipaddr[0] = 0;
	fread(ifinfo->ipaddr, sizeof(char), 20, shell_fpt);
	ifinfo->ipaddr[strlen(ifinfo->ipaddr) - 1] = 0; /* Purge newline */
	if(ifinfo->ipaddr[0] == 0)
		strncpy(ifinfo->ipaddr, "none", 15);
	fclose(shell_fpt);

	remove(TMP_FILE_PATH);
	/* mask */
	sprintf(gCmdStr, "%s %s | grep 'inet addr' |  cut -d: -f4 >%s 2>&1",
	IFCONFIG_PATH, ifname, TMP_FILE_PATH);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);

	system(gCmdStr);

	shell_fpt = fopen(TMP_FILE_PATH, "rb");
	ifinfo->mask[0] = 0;
	fread(ifinfo->mask, sizeof(char), 20, shell_fpt);
	ifinfo->mask[strlen(ifinfo->mask) - 1] = 0; /* Purge newline */
	if(ifinfo->mask[0] == 0)
		strcpy(ifinfo->mask, "none");
	fclose(shell_fpt);

	remove(TMP_FILE_PATH);
	/* dns */
	sprintf(gCmdStr, "cat /etc/resolv.conf | grep nameserver | awk '{print $2}'>%s 2>&1", TMP_FILE_PATH);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);

	system(gCmdStr);

	shell_fpt = fopen(TMP_FILE_PATH, "rb");
	for (i = 0; i < WFA_MAX_DNS_NUM; i++){
		fgets(ifinfo->dns[i], WFA_IP_ADDR_STR_LEN, shell_fpt);
		if (ifinfo->dns[i][0])
			ifinfo->dns[i][strlen(ifinfo->dns[i]) - 1] = 0; /* Purge newline */
		else
			strcpy(ifinfo->dns[i], "NOTDEF");
	}

	fclose(shell_fpt);

	remove(TMP_FILE_PATH);
	/* End: Modified as per BRCM 1.3 ASD */

#else
	/* The eth1 interface name in WinCE is BCMSDDHD1 and 
	* the eth0 interface name is VMINI1. The command that comes in from Linux CA
	* will send the eth0 or eth1 interface, which is then translated to WinCE 
	* specific interface name to get the Adapters information*/
	if(!strcmp(getIpConf->intf, "eth1")) {
		strcpy(getIpConf->intf , "BCMSDDHD1");
	} else if(!strcmp(getIpConf->intf, "eth0"))	{
		strcpy(getIpConf->intf , "VMINI1");
	} 
	/* Get the network interface information */
	dwStatus = GetAdaptersInfo(// Call GetAdapterInfo
		AdapterInfo,// [out] buffer to receive data
		&dwBufLen);// [in] size of receive data buffer

	pAdapterInfo= AdapterInfo;// Contains pointer to current adapter info

	while(pAdapterInfo){
		if(strcmp(pAdapterInfo->AdapterName, getIpConf->intf)==0){
			/*Check if DHCP Enabled*/
			if(pAdapterInfo->DhcpEnabled)
				ifinfo->isDhcp = 1;
			else
				ifinfo->isDhcp = 0;

			/*IP Address */
			strcpy(ifinfo->ipaddr, pAdapterInfo->IpAddressList.IpAddress.String);
			ifinfo->ipaddr[15]='\0';

			/*Subnet mask*/
			strcpy(ifinfo->mask,pAdapterInfo->IpAddressList.IpMask.String);
			slen = strlen(ifinfo->mask);
			ifinfo->mask[slen+1] = '\0';

			/*Primary DNS*/
			strcpy(ifinfo->dns[0], pAdapterInfo->PrimaryWinsServer.IpAddress.String);
			slen = strlen(ifinfo->dns[0]);

			/*Secondary DNS*/
			strcpy(ifinfo->dns[1], pAdapterInfo->SecondaryWinsServer.IpAddress.String);
			slen = strlen(ifinfo->dns[1]);
		}
		pAdapterInfo = pAdapterInfo->Next;
	}
#endif
	/*
	* Report back the results
	*/
	ipconfigResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_GET_IP_CONFIG_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)ipconfigResp, respBuf);

	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);
	DPRINT_INFO(WFA_OUT, "%i %i %s %s %s %s %i\n", ipconfigResp->status,
		ifinfo->isDhcp, ifinfo->ipaddr, ifinfo->mask,
		ifinfo->dns[0], ifinfo->dns[1], *respLen);
	return TRUE;
}

/*
* wfaStaSetIpConfig():
*   The function is to set the ip configuration to a wireless I/F.
*   1. IP address
*   2. Mac address
*   3. default gateway
*   4. dns nameserver (pri and sec).
*
* Set the IP address and the mask value only if the the DHCP(ipconfig->isDhcp) 
* is disabled. Otherwise enable the DHCP for the network interface.
*/
int wfaStaSetIpConfig(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	dutCommand_t *setIpConf = (dutCommand_t *)caCmdBuf;
	caStaSetIpConfig_t *ipconfig = &setIpConf->cmdsu.ipconfig;
	dutCmdResponse_t *staSetIpResp = &gGenericResp;

#ifndef WIN32
	pid_t pid;
	int status;
	DPRINT_INFO(WFA_OUT, "interface = %s, ipaddr = %s, dhcp = %d\r\n",ipconfig->intf,ipconfig->ipaddr,ipconfig->isDhcp);
	/* Start: Modified as per BRCM 1.3 ASD */
	if(!ipconfig->isDhcp)
	{
		if (!strlen(ipconfig->intf) || !strlen(ipconfig->ipaddr) || !strlen(ipconfig->mask))
		{
			staSetIpResp->status = STATUS_ERROR;
			wfaEncodeTLV(WFA_STA_SET_IP_CONFIG_RESP_TLV, 4, (BYTE *)staSetIpResp, respBuf);
			*respLen = WFA_TLV_HDR_LEN + 4;
			return TRUE; /* changed to be FALSE? */
		}
		sprintf(gCmdStr, "killall -9 dhclient");
		exec_process(gCmdStr);
		sprintf(gCmdStr, "%s %s %s ", IFCONFIG_PATH, ipconfig->intf, ipconfig->ipaddr);
		if (strlen(ipconfig->mask))
			sprintf(&gCmdStr[strlen(gCmdStr)], "netmask %s ", ipconfig->mask);
		exec_process(gCmdStr);
		DPRINT_INFO(WFA_OUT, "%s\n", "doing ifconfig");
		/* End: Modified as per BRCM 1.3 ASD */

		/* use command 'route add' to set set gatewway (linux specific) */
		if(ipconfig->defGateway[0] != '\0')
		{
			sprintf(gCmdStr, "%s add default gw %s > /dev/null 2>&1", ROUTE_PATH, ipconfig->defGateway);
			exec_process(gCmdStr);
			DPRINT_INFO(WFA_OUT, "%s\n", "doing route add");
		}

		/* set dns (linux specific) */

		/* Start: Modified as per BRCM 1.3 ASD */
                /* if somedata is given as primary-dns then we'll display it
                   else we'll show it as NOTDEF */ 
		if(strcmp(ipconfig->pri_dns, "\0"))
		{
			/* set dns (linux specific) */
			sprintf(gCmdStr, "cp /etc/resolv.conf /tmp/resolv.conf.bk");
			exec_process(gCmdStr);
			sprintf(gCmdStr, "echo nameserver %s > /etc/resolv.conf", ipconfig->pri_dns);
			exec_process(gCmdStr);
                        /* if no secondary-dns is given along with primary-dns
                           then we'll have to show it as NOTDEF */ 
                        if(strcmp(ipconfig->sec_dns, "\0"))        
			    sprintf(gCmdStr, "echo nameserver %s >> /etc/resolv.conf", ipconfig->sec_dns);
                        else
			    sprintf(gCmdStr, "echo nameserver %s >> /etc/resolv.conf", "NOTDEF");
			exec_process(gCmdStr);
		}
                /* In case,no primary or secondary dns is given,it will print them as
                   NOTDEF */   
                else
                {
                                    
			sprintf(gCmdStr, "cp /etc/resolv.conf /tmp/resolv.conf.bk");
			exec_process(gCmdStr);
			sprintf(gCmdStr, "echo nameserver %s > /etc/resolv.conf", "NOTDEF");
			exec_process(gCmdStr);
			sprintf(gCmdStr, "echo nameserver %s >> /etc/resolv.conf", "NOTDEF");
			exec_process(gCmdStr);
		}
	}
	else
	{
		/* dhcp is enabled */
		sprintf(gCmdStr, "killall -9 dhclient");
		exec_process(gCmdStr);
		/* Wait for couple of seconds for dhclient to exit cleanly */
		asd_sleep(2);
		if((pid = fork()) == 0)
		{
			close(gagtSockfd);
			close(g_serv_sock_desc);
			sprintf(gCmdStr, "%s %s",DHCLIENT_PATH, ipconfig->intf);
			/* execl("/sbin/dhclient",gCmdStr,NULL);*/
			exec_process(gCmdStr);
			_exit(0);
		}
		wait(&status);
	}
	/* End: Modified as per BRCM 1.3 ASD */
#endif

	/*
	* report status
	*/
	staSetIpResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_IP_CONFIG_RESP_TLV, 4, (BYTE *)staSetIpResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return TRUE;
}

/*
* wfaStaVerifyIpConnection():
* The function is to verify if the station has IP connection with an AP by
* send ICMP/pings to the AP.
*/

int wfaStaVerifyIpConnection(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	dutCommand_t *verip = (dutCommand_t *)caCmdBuf;
	dutCmdResponse_t *verifyIpResp = &gGenericResp;


#ifdef WIN32
	char tempip[30];
#else
	char *tempip;
	FILE *shell_fpt;
#endif

#ifndef WFA_PING_UDP_ECHO_ONLY

	DPRINT_INFO(WFA_OUT, "Entering wfaStaVerifyIpConnection ...\n");
#ifndef WIN32 
	tempip = (char*)malloc(30);
#endif
	/* set timeout value in case not set */
	if(verip->cmdsu.verifyIp.timeout <= 0)
	{
		verip->cmdsu.verifyIp.timeout = 10;
	}

	if (strlen(verip->cmdsu.verifyIp.dipaddr) == 0 )
	{
		verifyIpResp->status = STATUS_ERROR;
		wfaEncodeTLV(WFA_STA_VERIFY_IP_CONNECTION_RESP_TLV, 4, (BYTE *)&verifyIpResp, respBuf);
		*respLen = WFA_TLV_HDR_LEN + 4;
		DPRINT_ERR(WFA_ERR, "Could not execute %s\n", gCmdStr);
		return FALSE;
	}

	strcpy(tempip,verip->cmdsu.verifyIp.dipaddr);

	strtok(tempip,". ");
	strtok(tempip,". ");
	strtok(tempip,". ");
	strtok(tempip,". ");

	if( atoi(tempip) >= 255 )
	{
		verifyIpResp->status = STATUS_ERROR;
		wfaEncodeTLV(WFA_STA_VERIFY_IP_CONNECTION_RESP_TLV, 4, (BYTE *)&verifyIpResp, respBuf);
		*respLen = WFA_TLV_HDR_LEN + 4;
		return TRUE;
	}

#ifndef WIN32
	/* Start: Modified as per BRCM 1.3 ASD */
	/* execute the ping command  and pipe the result to a tmp file */
	memset(gCmdStr, 0, sizeof(gCmdStr));
	sprintf(gCmdStr, "%s -c 3 -q %s >>%s", PING_PATH, verip->cmdsu.verifyIp.dipaddr, PINGOUT_FILE_PATH);	
	exec_process(gCmdStr);

	asd_sleep(1);
	verifyIpResp->status = STATUS_COMPLETE;
	sprintf(gCmdStr, "cat %s | grep transmitted | awk '{print $4}'>%s 2>&1",
	PINGOUT_FILE_PATH, TMP_FILE_PATH);

	if (system(gCmdStr) < 0) {
		DPRINT_ERR(WFA_ERR, "\n Not able to execute verify ip cmd\n");
		verifyIpResp->cmdru.connected = 0;
	} 


	shell_fpt = fopen(TMP_FILE_PATH, "rb");

	if (shell_fpt == NULL) {
		DPRINT_ERR(WFA_ERR, "\nShell Cmd:File open error\n");
		verifyIpResp->cmdru.connected = 0;
	}

	fread(gCmdStr, sizeof(char), 20, shell_fpt);
	fclose(shell_fpt);

	remove(TMP_FILE_PATH);
	remove(PINGOUT_FILE_PATH);
	if(atoi(gCmdStr) == 0)
		verifyIpResp->cmdru.connected = 0;
	else
		verifyIpResp->cmdru.connected = 1;

	printf("\ngCmdStr is:%s\n", gCmdStr);
#ifdef DEBUG
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
#endif
	/* End: Modified as per BRCM 1.3 ASD */
#else
#endif

#else
	int btSockfd;
	struct pollfd fds[2];
	int timeout = 2000;
	char anyBuf[64];
	struct sockaddr_in toAddr;
	int done = 1, cnt = 0, ret, nbytes;

	verifyIpResp->status = STATUS_COMPLETE;
	verifyIpResp->cmdru.connected = 0;

	btSockfd = wfaCreateUDPSock("127.0.0.1", WFA_UDP_ECHO_PORT);

	if(btSockfd == -1)
	{
		verifyIpResp->status = STATUS_ERROR;
		wfaEncodeTLV(WFA_STA_VERIFY_IP_CONNECTION_RESP_TLV, 4, (BYTE *)verifyIpResp, respBuf);
		*respLen = WFA_TLV_HDR_LEN + 4;
		return FALSE;
	}

	toAddr.sin_family = AF_INET;
	toAddr.sin_addr.s_addr = inet_addr(verip->cmdsu.verifyIp.dipaddr);
	toAddr.sin_port = htons(WFA_UDP_ECHO_PORT);

	while(done)
	{
		wfaTrafficSendTo(btSockfd, (char *)anyBuf, 64, (struct sockaddr *)&toAddr);
		cnt++;

		fds[0].fd = btSockfd;
		fds[0].events = POLLIN | POLLOUT;

		ret = poll(fds, 1, timeout);
		switch(ret)
		{
		case 0:
			/* it is time out, count a packet lost*/
			break;
		case -1:
			/* it is an error */
		default:
			{
				switch(fds[0].revents)
				{
				case POLLIN:
				case POLLPRI:
				case POLLOUT:
					nbytes = wfaTrafficRecv(btSockfd, (char *)anyBuf, (struct sockaddr *)&toAddr);
					if(nbytes != 0)
						verifyIpResp->cmdru.connected = 1;
					done = 0;
					break;
				default:
					/* errors but not care */
					;
				}
			}
		}
		if(cnt == 3)
		{
			done = 0;
		}
	}
#endif

	wfaEncodeTLV(WFA_STA_VERIFY_IP_CONNECTION_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)verifyIpResp, respBuf);

	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);

	return TRUE;
}

/*
* wfaSetEncryption():
*   The function is to set the wireless interface with WEP or none.
*   Input parameters:
*     1. I/F
*     2. ssid
*     3. encpType - wep or none
*     Optional:
*     4. key1
*     5. key2
*     6. key3
*     7. key4
*     8. activeKey Index
*/

int wfaSetEncryption(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetEncryption_t *setEncryp = (caStaSetEncryption_t *)caCmdBuf;
	dutCmdResponse_t *setEncrypResp = &gGenericResp;
	int idx; /* Modified as per BRCM 1.3 ASD */
	/* Start: Modified as per BRCM 1.3 ASD */
	int retVal = TRUE;
	bcmSsidObj_t *bso;
	char * ssidStr;

	DPRINT_INFO(WFA_OUT, "wfaSetEncryption()\n");

	/* Save the settings for when we need them */

	ssidStr = setEncryp->ssid;

	if (!(bso = bcmWfaSsidTblSsidFind(ssidStr))) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidStr))) {
			DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed.\n", ssidStr);
			retVal = FALSE;
			goto exit;
		}
	}

	/* set Key management to NONE (NO WPA) for plaintext or WEP */
	bso->wpa_auth = BCM_WPA_AUTH_DISABLED;

	for(idx = 0; idx < 4; idx++) {
		if(setEncryp->keys[idx][0] != '\0') {
			strcpy(bso->keys[idx], setEncryp->keys[idx]);
		} else {
			memset(bso->keys[idx],0,BCM_WEP_KEY_SIZE_MAX);
		}
	}

	if ((setEncryp->activeKeyIdx > 0) && (setEncryp->activeKeyIdx < 5)) {
		/* move the index range from (1 to 4) to (0 to 3) */
		bso->primary_key = setEncryp->activeKeyIdx - 1;
	}

	bso->wsec = (!setEncryp->encpType) ? 0 : 1;

	if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
		bcmWfaSsidObjPrint(bso);
	}

exit:
	/* End: Modified as per BRCM 1.3 ASD */

	setEncrypResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_ENCRYPTION_RESP_TLV, 4, (BYTE *)setEncrypResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return retVal; /* Modified as per BRCM 1.3 ASD */
}


int wfaSetEncryption1(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetEncryption_t *setEncryp = (caStaSetEncryption_t *)caCmdBuf;
	dutCmdResponse_t *setEncrypResp = &gGenericResp;
	int idx;
	/* Start: Modified as per BRCM 1.3 ASD */
	int retVal = TRUE;
	bcmSsidObj_t *bso;
	char * ssidStr;

	DPRINT_INFO(WFA_OUT, "wfaSetEncryption1()\n");

	/* Save the settings for when we need them */

	ssidStr = setEncryp->ssid;
	/* SetSSID */
	if (!(bso = bcmWfaSsidTblSsidFind(ssidStr))) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidStr))) {
			DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed.\n", ssidStr);
			retVal = FALSE;
			goto exit;
		}
	}

	/* set Key management to NONE (NO WPA) for plaintext or WEP */
	bso->wpa_auth = BCM_WPA_AUTH_DISABLED;

	for(idx = 0; idx < 4; idx++) {
		if(setEncryp->keys[idx][0] != '\0') {
			strcpy(bso->keys[idx], setEncryp->keys[idx]);
		} else {
			memset(bso->keys[idx], 0, BCM_WEP_KEY_SIZE_MAX);
		}
	}

	if ((setEncryp->activeKeyIdx > 0) && (setEncryp->activeKeyIdx < 5)) {
		/* move the index range from (1 to 4) to (0 to 3) */
		bso->primary_key = setEncryp->activeKeyIdx - 1;
	}

	bso->wsec = (!setEncryp->encpType) ? 0 : 1;

	if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
		bcmWfaSsidObjPrint(bso);
	}

exit:
	/* End: Modified as per BRCM 1.3 ASD */

	setEncrypResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_ENCRYPTION_RESP_TLV, 4, (BYTE *)setEncrypResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return retVal; /* Modified as per BRCM 1.3 ASD */
}


/*
* wfaStaSetEapTLS():
*   This is to set
*   1. ssid
*   2. encrypType - tkip or aes-ccmp
*   3. keyManagementType - wpa or wpa2
*   4. trustedRootCA
*   5. clientCertificate
*/
int wfaStaSetEapTLS(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetEapTLS_t *setTLS = (caStaSetEapTLS_t *)caCmdBuf;
	dutCmdResponse_t *setEapTlsResp = &gGenericResp;
	bcmSsidObj_t *bso;
	char ssidTarget[WFA_SSID_NAME_LEN];

	DPRINT_INFO(WFA_OUT, "Entering wfaStaSetEapTLS ...\n");

	memcpy(ssidTarget, setTLS->ssid, WFA_SSID_NAME_LEN);
	bso = bcmWfaSsidTblSsidFind(ssidTarget);
	if (!bso) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidTarget))) {
			DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidTarget);
			return FALSE;
		}
		if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
			bcmWfaSsidObjPrint(bso);
		}

	}
	memcpy(&(bso->eapObj.setEapTLS), setTLS, sizeof(caStaSetEapTLS_t));
	bso->eapType = BCM_EAP_TYPE_TLS;

	if(strstr(bso->eapObj.setEapTLS.encrptype,"aes-ccmp"))
		strncpy(bso->eapObj.setEapTLS.encrptype, AES_ENCPTYPE, AES_LEN) ;
	setEapTlsResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_EAPTLS_RESP_TLV, 4, (BYTE *)setEapTlsResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
	return TRUE;
}

/*
* The function is to set
*   1. ssid
*   2. passPhrase
*   3. keyMangementType - wpa/wpa2
*   4. encrypType - tkip or aes-ccmp
*/

int wfaStaSetPSK(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetPSK_t *setPSK = (caStaSetPSK_t *)caCmdBuf;
	dutCmdResponse_t *setPskResp = &gGenericResp;

	/* Start: Modified as per BRCM 1.3 ASD */
	int retVal = TRUE;
	bcmSsidObj_t *bso;
	char *ssidStr;

	DPRINT_INFO(WFA_OUT, "wfaStaSetPSK()");

	ssidStr = setPSK->ssid;
	if (!(bso = bcmWfaSsidTblSsidFind(ssidStr))) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidStr))) {
			DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed.\n", ssidStr);
			retVal = FALSE;
			goto exit;
		}
	}

	if (!strcmp(setPSK->keyMgmtType, "wpa")) {
		bso->wpa_auth = BCM_WPA_AUTH_PSK; /* WPA-PSK/WPA-Personal */
	} else if (!strcmp(setPSK->keyMgmtType, "wpa2")) {
		bso->wpa_auth = BCM_WPA2_AUTH_PSK; /* WPA2-PSK/WPA2-Personal */
	} else {
		DPRINT_ERR(WFA_OUT, "invalid key_mgmt %s", setPSK->keyMgmtType);
		retVal = FALSE;
		goto exit;
	}

	DPRINT_INFO(WFA_OUT, "wpa_auth %d\n", bso->wpa_auth);

	if (setPSK->encpType == ENCRYPT_TKIP) {
		bso->wsec = 3;
	} else if (setPSK->encpType == ENCRYPT_AESCCMP) {
		bso->wsec = 7;
	} else {
		DPRINT_ERR(WFA_OUT, "invalid encpType %d", setPSK->encpType);
		goto exit;
	}
	DPRINT_INFO(WFA_OUT, "encpType %d wsec %d\n", setPSK->encpType, bso->wsec);


	strncpy((char *)bso->passphrase, (char *)setPSK->passphrase, 64);
	bso->auth = 0;

	if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
		bcmWfaSsidObjPrint(bso);
	}

	retVal = TRUE;

exit:
	/* End: Modified as per BRCM 1.3 ASD */

	setPskResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_PSK_RESP_TLV, 4, (BYTE *)setPskResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return retVal; /*  Modified as per BRCM 1.3 ASD */
}


/*
* wfaStaGetInfo():
* Get vendor specific information in name/value pair by a wireless I/F.
*/
int wfaStaGetInfo(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	dutCmdResponse_t infoResp;
	dutCommand_t *getInfo = (dutCommand_t *)caCmdBuf;
	FILE *tmpfd;
	DPRINT_INFO(WFA_OUT, "Entering wfaStaGetInfo.....\n");
	/*
	* Normally this is called to retrieve the vendor information
	* from a interface, no implement yet
	*/
#ifndef WIN32
	S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s nmode &> %s", rwl_client_path, TEMP_FILE_PATH);
#else
	S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s nmode > %s 2>&1", rwl_client_path, TEMP_FILE_PATH);
#endif
	exec_process(gCmdStr);
	if((tmpfd = fopen(TEMP_FILE_PATH, "r")) == NULL){
		infoResp.status = STATUS_ERROR;
		wfaEncodeTLV(WFA_STA_GET_INFO_RESP_TLV, 4, (BYTE *)&infoResp, respBuf);
		*respLen = WFA_TLV_HDR_LEN + 4;
		return TRUE;
	}
	fgets(gCmdStr, sizeof(gCmdStr), tmpfd);
	Cleanup_File(tmpfd);
/*
 * If it is n mode supported card then it wont reply Unsupported or error 
 */
	if (((strstr(gCmdStr, "Unsupported")) != NULL) ||
	 ((strstr(gCmdStr, "error")) != NULL)) {
		S_N_PRINTF(infoResp.cmdru.info, sizeof(infoResp.cmdru.info), "interface,%s,vendor,Broadcom,cardtype,802.11a/b/g", getInfo->intf);
	}
	else {
		S_N_PRINTF(infoResp.cmdru.info, sizeof(infoResp.cmdru.info), "interface,%s,vendor,Broadcom,cardtype,802.11a/b/g/n", getInfo->intf);
	}
	infoResp.status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_GET_INFO_RESP_TLV, sizeof(infoResp), (BYTE *)&infoResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + sizeof(infoResp);
	return TRUE;
}

int wfaStaGetTestData(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	//    dutCmdResponse_t dataResp;
	//    dutCommand_t *testData = (dutCommand_t *)caCmdBuf;

	/*
	* This is to trasfer the test log (file) back to console
	* It has not decided to use in-band or out of band. Will be updated
	* in a new release soon.
	*/

	return TRUE;
}

/*
* wfaStaSetEapTTLS():
*   This is to set
*   1. ssid
*   2. username
*   3. passwd
*   4. encrypType - tkip or aes-ccmp
*   5. keyManagementType - wpa or wpa2
*   6. trustedRootCA
*/
int wfaStaSetEapTTLS(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{

	caStaSetEapTTLS_t *setTTLS = (caStaSetEapTTLS_t *)caCmdBuf;
	dutCmdResponse_t *setEapTtlsResp = &gGenericResp;
	bcmSsidObj_t *bso;
	char ssidTarget[WFA_SSID_NAME_LEN];

	memcpy(ssidTarget, setTTLS->ssid, WFA_SSID_NAME_LEN);
	bso = bcmWfaSsidTblSsidFind(ssidTarget);
	if (!bso) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidTarget))) {
			DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidTarget);
			return FALSE;
			
		}
		if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
			bcmWfaSsidObjPrint(bso);
		}

	}
		
	memcpy(&(bso->eapObj.setEapTTLS), setTTLS, sizeof(caStaSetEapTTLS_t));
	bso->eapType = BCM_EAP_TYPE_TTLS;

	if(strstr(bso->eapObj.setEapTTLS.encrptype,"aes-ccmp"))
			strncpy(bso->eapObj.setEapTTLS.encrptype, AES_ENCPTYPE, AES_LEN) ;
	setEapTtlsResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_EAPTTLS_RESP_TLV, 4, (BYTE *)setEapTtlsResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return TRUE;
}

/*
* wfaStaSetEapSIM():
*   This is to set
*   1. ssid
*   2. user name
*   3. passwd
*   4. encrypType - tkip or aes-ccmp
*   5. keyMangementType - wpa or wpa2
*/
int wfaStaSetEapSIM(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetEapSIM_t *setSIM = (caStaSetEapSIM_t *)caCmdBuf;
	dutCmdResponse_t *setEapSimResp = &gGenericResp;
	bcmSsidObj_t *bso;
	char ssidTarget[WFA_SSID_NAME_LEN];

	memcpy(ssidTarget, setSIM->ssid, WFA_SSID_NAME_LEN);
	bso = bcmWfaSsidTblSsidFind(ssidTarget);
	if (!bso) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidTarget))) {
			DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidTarget);
			return FALSE;
		}
		if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
			bcmWfaSsidObjPrint(bso);
		}

	}
	
	memcpy(&(bso->eapObj.setEapSIM), setSIM, sizeof(caStaSetEapSIM_t));
	bso->eapType = BCM_EAP_TYPE_SIM;

	if(strstr(bso->eapObj.setEapSIM.encrptype,"aes-ccmp"))
			strncpy(bso->eapObj.setEapSIM.encrptype, AES_ENCPTYPE, AES_LEN) ;
	setEapSimResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_EAPSIM_RESP_TLV, 4, (BYTE *)setEapSimResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return TRUE;
}

/*
* wfaStaSetPEAP()
*   This is to set
*   1. ssid
*   2. user name
*   3. passwd
*   4. encryType - tkip or aes-ccmp
*   5. keyMgmtType - wpa or wpa2
*   6. trustedRootCA
*   7. innerEAP
*   8. peapVersion
*/
int wfaStaSetPEAP(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetEapPEAP_t *setPEAP = (caStaSetEapPEAP_t *)caCmdBuf;
	dutCmdResponse_t *setPeapResp = &gGenericResp;
	bcmSsidObj_t *bso;
	char ssidTarget[WFA_SSID_NAME_LEN];

	memcpy(ssidTarget, setPEAP->ssid, WFA_SSID_NAME_LEN);
	bso = bcmWfaSsidTblSsidFind(ssidTarget);
	if (!bso) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidTarget))) {
			DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidTarget);
			return FALSE;
		}
		if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
			bcmWfaSsidObjPrint(bso);
		}

	}
	
	memcpy(&(bso->eapObj.setEapPEAP), setPEAP, sizeof(caStaSetEapPEAP_t));
	bso->eapType = BCM_EAP_TYPE_PEAP;

	if(strstr(bso->eapObj.setEapPEAP.encrptype,"aes-ccmp"))
			strncpy(bso->eapObj.setEapPEAP.encrptype, AES_ENCPTYPE, AES_LEN) ;
	setPeapResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_PEAP_RESP_TLV, 4, (BYTE *)setPeapResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return TRUE;
}

/*
* wfaStaSetUAPSD()
*    This is to set
*    1. maxSPLength - 0,1,2,or 4
*    2. acBE
*    3. acBK
*    4. acVI
*    5. acVO
*/
int wfaStaSetUAPSD(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	int retVal = TRUE;
	caStaSetUAPSD_t *setUAPSD = (caStaSetUAPSD_t *)caCmdBuf;
	/* char *ifname = setUAPSD->intf; */ /* Removed as per BRCM 1.3 ASD */
	dutCmdResponse_t *setUAPSDResp = &gGenericResp;
	/* Start: Modified as per BRCM 1.3 ASD */
	bcmSsidObj_t *bso;
	char *ssidStr;

	DPRINT_INFO(WFA_OUT, "Entering StaSetUAPSD ...\n");
	DPRINT_INFO(WFA_OUT, "maxSPLength %d acBE %d acBK %d acVI %d acVO %d\n",
		setUAPSD->maxSPLength, setUAPSD->acBE, setUAPSD->acBK, setUAPSD->acVI, setUAPSD->acVO);

	ssidStr = setUAPSD->ssid;

	if (!(bso = bcmWfaSsidTblSsidFind(ssidStr))) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidStr))) {
			DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed.\n", ssidStr);
			retVal = FALSE;
			goto exit;
		}
	}
	
	if (rwl_wifi_flag) {
		/* Use the batching mode */
		asd_sleep(1);
		sprintf (gCmdStr,"%s seq_start",rwl_client_path);
		exec_process (gCmdStr);
	}
	
	/* Get the driver down */
	sprintf (gCmdStr,"%s down",rwl_client_path);
	exec_process (gCmdStr);
	bso->maxSPLength = setUAPSD->maxSPLength;
	bso->acBE = setUAPSD->acBE;
	bso->acBK = setUAPSD->acBK;
	bso->acVI = setUAPSD->acVI;
	bso->acVO = setUAPSD->acVO;
	
	sprintf(gCmdStr,"%s wme_apsd_sta %d %d %d %d %d",rwl_client_path,
			bso->maxSPLength,bso->acBE,bso->acBK,bso->acVI,bso->acVO);
	exec_process(gCmdStr);
	/* Get the driver up*/
	sprintf (gCmdStr,"%s up",rwl_client_path);
	exec_process (gCmdStr);
	
	sleep (1);
	/* Setting up ssid */
	sprintf (gCmdStr,"%s join %s",rwl_client_path,setUAPSD->ssid);
	exec_process(gCmdStr);
	
	if (rwl_wifi_flag) {
		/* End the batching sequence */
		asd_sleep(1);
		sprintf (gCmdStr,"%s seq_stop",rwl_client_path);
		exec_process (gCmdStr);
	}
	
exit:
	/* End: Modified as per BRCM 1.3 ASD */
	setUAPSDResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_UAPSD_RESP_TLV, 4, (BYTE *)setUAPSDResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
	return retVal; /* Modified as per BRCM 1.3 ASD */
}


/*
* This funciton is to retrieve a list of interfaces and return
* the list back to Agent control.
*
*/
int wfaDeviceListIF(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	dutCmdResponse_t *infoResp = &gGenericResp;
	dutCommand_t *ifList = (dutCommand_t *)caCmdBuf;
	caDeviceListIFResp_t *ifListResp = &infoResp->cmdru.ifList;
#ifndef WIN32
	char adapter [10];
#endif
	DPRINT_INFO(WFA_OUT, "Entering wfaDeviceListIF ...\n");

	switch(ifList->cmdsu.iftype)
	{
	case IF_80211:
		infoResp->status = STATUS_COMPLETE;
		ifListResp->iftype = IF_80211;
		/*In case of the WinCE the wireless interface is BCMSDDHD1*/
#ifndef WIN32
		GetWirelessAdapter(adapter);

		strcpy(ifListResp->ifs[0], adapter);
#else
		strcpy(ifListResp->ifs[0], "BCMSDDHD1");
#endif
		strcpy(ifListResp->ifs[1], "NULL");
		strcpy(ifListResp->ifs[2], "NULL");
		break;

	case IF_ETH:
		infoResp->status = STATUS_COMPLETE;
		ifListResp->iftype = IF_ETH;
		/*In case of the WinCE the ethernet interface is VMINI1*/
#ifndef WIN32
		strcpy(ifListResp->ifs[1], "eth0	");
#else
		strcpy(ifListResp->ifs[1], "VMINI1");
#endif
		strcpy(ifListResp->ifs[1], "NULL");
		strcpy(ifListResp->ifs[2], "NULL");
		break;
	default:
		{
			infoResp->status = STATUS_ERROR;
			wfaEncodeTLV(WFA_DEVICE_LIST_IF_RESP_TLV, 4, (BYTE *)infoResp, respBuf);
			*respLen = WFA_TLV_HDR_LEN + 4;

			return TRUE;
		}
	}

	wfaEncodeTLV(WFA_DEVICE_LIST_IF_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)infoResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);

	return TRUE;
}

int wfaStaDebugSet(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	dutCmdResponse_t *debugResp = &gGenericResp;
	dutCommand_t *debugSet = (dutCommand_t *)caCmdBuf;

	DPRINT_INFO(WFA_OUT, "Entering wfaStaDebugSet ...\n");

	if(debugSet->cmdsu.dbg.state == 1) /* enable */
		wfa_defined_debug |= debugSet->cmdsu.dbg.level;
	else
		wfa_defined_debug = (~debugSet->cmdsu.dbg.level & wfa_defined_debug);

	debugResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_GET_INFO_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)debugResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);

	return TRUE;
}



/*
* wfaStaSetIBSS()
*    This is to set
*    1. ssid
*    2. channel
*    3. encrypType - none or wep
*    optional
*    4. key1
*    5. key2
*    6. key3
*    7. key4
*    8. activeIndex - 1, 2, 3, or 4
*/
int wfaStaSetIBSS(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetIBSS_t *setIBSS = (caStaSetIBSS_t *)caCmdBuf;
	dutCmdResponse_t *setIbssResp = &gGenericResp;

	/* Start: Modified as per BRCM 1.3 ASD */
	int retVal = TRUE;
	bcmSsidObj_t *bso;
	int idx;
	char *ssidStr;

	DPRINT_INFO(WFA_OUT, "wfaStaSetIBSS()\n");

	/* Save the settings for when we need them */

	ssidStr = setIBSS->ssid;

	if (!(bso = bcmWfaSsidTblSsidFind(ssidStr))) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidStr))) {
			DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed.\n", ssidStr);
			retVal = FALSE;
			goto exit;
		}
	}

	bso->bssType = BCM_BSS_INDEPENDENT;

	if (setIBSS->channel) {
		bso->channel = setIBSS->channel;
	}

	bso->wsec = (!setIBSS->encpType) ? 0 : 1;

	for(idx = 0; idx < 4; idx++) {
		if(setIBSS->keys[idx][0] != '\0') {
			strcpy(bso->keys[idx], setIBSS->keys[idx]);
		} else {
			memset(bso->keys[idx],0, BCM_WEP_KEY_SIZE_MAX);
		}
	}

	if ((setIBSS->activeKeyIdx > 0) && (setIBSS->activeKeyIdx < 5)) {
		/* move the index range from (1 to 4) to (0 to 3) */
		bso->primary_key = setIBSS->activeKeyIdx - 1;
	}

	if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
		bcmWfaSsidObjPrint(bso);
	}
exit:
	/* End: Modified as per BRCM 1.3 ASD */

	setIbssResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_IBSS_RESP_TLV, 4, (BYTE *)setIbssResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return retVal; /* Modified as per BRCM 1.3 ASD */
}

/*
*  wfaSetMode():
*  The function is to set the wireless interface with a given mode (possible
*  adhoc)
*  Input parameters:
*    1. I/F
*    2. ssid
*    3. mode adhoc or managed
*    4. encType
*    5. channel
*    6. key(s)
*    7. active  key
*/
int wfaStaSetMode(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetMode_t *setmode = (caStaSetMode_t *)caCmdBuf;
	dutCmdResponse_t *SetModeResp = &gGenericResp;
	int i;
	bcmSsidObj_t *bso;
	char *ssidStr;
	int retVal = TRUE;

	DPRINT_INFO(WFA_OUT,"Entering wfaStaSetMode\r\n");

	ssidStr = setmode->ssid;
	if (!(bso = bcmWfaSsidTblSsidFind(ssidStr))) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidStr))) {
			DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed.\n", ssidStr);
			retVal = FALSE;
			goto exit;
		}
		else
		{
			//DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblAdd added: (%s)\n", ssidStr);
		}
	}

	if (setmode->channel) {
		bso->channel = setmode->channel;
		/* Set the channel */
		sprintf(gCmdStr, "%s channel %d",rwl_client_path, setmode->channel);
		exec_process(gCmdStr);
	}

	/* destroy the interface */
	sprintf(gCmdStr, "%s disassoc", rwl_client_path);
	exec_process(gCmdStr);

	/* re-create the interface in the given mode */
	if(setmode->mode)
	{
		bso->bssType = BCM_BSS_INDEPENDENT;
		sprintf(gCmdStr, "%s infra %d", rwl_client_path, setmode->mode);
		exec_process(gCmdStr);
		sprintf(gCmdStr, "%s join %s imode ibss", rwl_client_path, setmode->ssid);
		exec_process(gCmdStr);
	}
	else
	{
		sprintf(gCmdStr, "%s infra %d", rwl_client_path, setmode->mode);
		exec_process(gCmdStr);
		sprintf(gCmdStr, "%s join %s", rwl_client_path, setmode->ssid);
		exec_process(gCmdStr);
	}
	bso->wsec = (!setmode->encpType) ? 0 : 1;
	asd_sleep(3);
	sprintf(gCmdStr, "%s wsec %d", rwl_client_path, bso->wsec);
	exec_process(gCmdStr);

	if(setmode->encpType == ENCRYPT_WEP) {
		for (i = 0; i < 4; i++) {
			if (setmode->keys[i][0] != '\0') {
				strcpy(bso->keys[i], setmode->keys[i]);
				sprintf(gCmdStr, "%s addwep  %d %s", rwl_client_path, i, setmode->keys[i]);
				exec_process(gCmdStr);
			}
			else {
				memset(bso->keys[i],0, BCM_WEP_KEY_SIZE_MAX);
			}
		}
		/* set active key */
		if ((setmode->activeKeyIdx > 0) && (setmode->activeKeyIdx < 5)) {
			/* move the index range from (1 to 4) to (0 to 3) */
			bso->primary_key = setmode->activeKeyIdx - 1;
			sprintf(gCmdStr, "%s primary_key %d", rwl_client_path, bso->primary_key);
			exec_process(gCmdStr);
		}
	}
exit:

	SetModeResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_MODE_RESP_TLV, 4, (BYTE *)SetModeResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return TRUE;
}

/* Following functions are specific to Win XP CA or Linux CA */
/*
* wfaStaGetMacAddress()
*    This function is to retrieve the MAC address of a wireless I/F.
*/
int wfaStaGetMacAddress(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	dutCmdResponse_t *getmacResp = &gGenericResp;

	FILE *tmpfd;

	DPRINT_INFO(WFA_OUT, "Entering wfaStaGetMacAddress ...\n");

	/* Start: Modifed as per BRCM 1.3 ASD*/
#ifndef WIN32
	/* Modified on 28/12/07 after getting wl dump error in 4325*/
	//sprintf(gCmdStr, "ifconfig %s|grep HWaddr|cut -f3 -dr", ifname);
	sprintf(gCmdStr, "%s cur_etheraddr", rwl_client_path);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
#else
	strcpy(gCmdStr,rwl_client_path);
	strcat(gCmdStr," cur_etheraddr >");
#endif
	if((tmpfd = asd_Config(gCmdStr,TEMP_FILE_PATH)) == NULL){
		getmacResp->status = STATUS_ERROR;
		wfaEncodeTLV(WFA_STA_GET_MAC_ADDRESS_RESP_TLV, 4, (BYTE *)getmacResp, respBuf);
		*respLen = WFA_TLV_HDR_LEN + 4;
		DPRINT_ERR(WFA_ERR, "Failed to get mac address\n");
		return FALSE;
	}
	fgets(gCmdStr, 15, tmpfd);
	/*End:Modified on 28/12/07 after getting wl dump error in 4325 */
	fgets(getmacResp->cmdru.mac, sizeof(getmacResp->cmdru.mac), tmpfd);
	getmacResp->cmdru.mac[strlen(getmacResp->cmdru.mac) - 1] = 0;		/* Get rid of NL */
	printf("get_mac_addr: returning mac :%s:\n", getmacResp->cmdru.mac);
	Cleanup_File(tmpfd);

	getmacResp->status = STATUS_COMPLETE;

	wfaEncodeTLV(WFA_STA_GET_MAC_ADDRESS_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)getmacResp, respBuf);

	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);
	return TRUE;
}

int wfaStaSetPwrSave(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
   caStaSetPwrSave_t *setps = (caStaSetPwrSave_t *)caCmdBuf;
   dutCmdResponse_t *SetPSResp = &gGenericResp;

   sprintf(gCmdStr, "%s PM %d", rwl_client_path, setps->mode);
   exec_process(gCmdStr);
   
   SetPSResp->status = STATUS_COMPLETE;
   wfaEncodeTLV(WFA_STA_SET_PWRSAVE_RESP_TLV, 4, (BYTE *)SetPSResp, respBuf);
   *respLen = WFA_TLV_HDR_LEN + 4;

   return TRUE;
}

/*
* wfaStaIsConnected():
*    The function is to check whether the station's wireless I/F has
*    already connected to an AP.
*/
int wfaStaIsConnected(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	/* Removed as per BRCM 1.3 ASD */
	FILE *tmpfd;
	dutCmdResponse_t *staConnectResp = &gGenericResp;
	
#ifdef WIN32
   unsigned int  position;
#endif
	DPRINT_INFO(WFA_OUT, "Entering isConnected ...\n");

	/* Start: Added as per BRCM 1.3 ASD */
	/* Associated gets long response */
#ifndef WIN32
	sprintf(gCmdStr, "%s assoc | wc -l", rwl_client_path);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
#else
	strcpy(gCmdStr, rwl_client_path);
	strcat(gCmdStr, " assoc >");
#endif
	if((tmpfd = asd_Config(gCmdStr,TEMP_FILE_PATH)) == NULL){
		staConnectResp->status = STATUS_ERROR;
		printf("assoc failed\n");
		wfaEncodeTLV(WFA_STA_IS_CONNECTED_RESP_TLV, 4, (BYTE *)staConnectResp, respBuf);
		*respLen = WFA_TLV_HDR_LEN + 4;
		DPRINT_ERR(WFA_ERR, "isconnected failed\n");
		return FALSE;
	}
	
#ifndef WIN32
	fgets(gCmdStr, sizeof(gCmdStr), tmpfd);
	/* Short response means not associated */
	if (atoi(gCmdStr) <= 2)
		staConnectResp->cmdru.connected = 0;
	else
		staConnectResp->cmdru.connected = 1;
	/* End: Added as per BRCM 1.3 ASD */
#else
	if((FileSearch(tmpfd, L"Not associated", &position))!= -1)
	    staConnectResp->cmdru.connected = 0;
	else
		staConnectResp->cmdru.connected = 1;
#endif
	/*
	* Report back the status: Complete or Failed.
	*/
	Cleanup_File(tmpfd);
	staConnectResp->status = STATUS_COMPLETE;

	wfaEncodeTLV(WFA_STA_IS_CONNECTED_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)staConnectResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);
	return TRUE;
}

/*
* wfaStaGetStats():
* The function is to retrieve the statistics of the I/F's layer 2 txFrames,
* rxFrames, txMulticast, rxMulticast, fcsErrors/crc, and txRetries.
* Currently there is not definition how to use these info.
*/
int wfaStaGetStats(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	dutCmdResponse_t *statsResp = &gGenericResp;
	FILE *fd; /* Added as per BRCM 1.3 ASD */
	caStaGetStatsResp_t *castatsResp = &statsResp->cmdru.ifStats; /* Added as per BRCM 1.3 ASD */
#ifdef WIN32
   char cmdStr[256];
   unsigned int position;
#endif
   DPRINT_INFO(WFA_OUT, "Entering wfaStaGetStats ...\n");
#ifndef WIN32
	/* Start: Modified as per BRCM 1.3 ASD */
	sprintf(gCmdStr, "%s counters | grep txframe | awk '{print $2,\"\\n\",$10}'", rwl_client_path);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
	/* wl dump replaced with wl counters to get statistics */
	if ((fd = popen(gCmdStr, "r")) == NULL){
		DPRINT_ERR(WFA_ERR, "Couldn't get txframe stats\n");
		goto wfaStaGetStats_error;
	} else {
		fgets(gCmdStr, sizeof(gCmdStr), fd);	/* line 1: tx frame */
		castatsResp->txFrames =  atoi(gCmdStr);
		fgets(gCmdStr, sizeof(gCmdStr), fd);	/* line 2: rx frame */
		castatsResp->rxFrames =  atoi(gCmdStr);
		pclose(fd);
	}

	sprintf(gCmdStr, "%s counters | grep d11_txmulti | awk '{print $4,\"\\n\",$8}' ", rwl_client_path);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
	if ((fd = popen(gCmdStr,"r")) == NULL){
		DPRINT_ERR(WFA_ERR, "Couldn't get d11_txmulti stats\n");
		goto wfaStaGetStats_error;
	} else {
		fgets(gCmdStr, sizeof(gCmdStr), fd);
		castatsResp->txMulticast = atoi(gCmdStr);
		fgets(gCmdStr, sizeof(gCmdStr), fd);
		castatsResp->txRetries = atoi(gCmdStr);
		pclose(fd);
	}
	sprintf(gCmdStr, "%s counters | grep d11_rxmulti | awk '{print $4}'", rwl_client_path);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
	if ((fd = popen(gCmdStr ,"r")) == NULL){
		DPRINT_ERR(WFA_ERR, "Couldn't get rxMultiFrame stats\n");
		goto wfaStaGetStats_error;
	} else {
		fgets(gCmdStr, sizeof(gCmdStr), fd);
		castatsResp->rxMulticast = atoi(gCmdStr);
		pclose(fd);
	}

	sprintf(gCmdStr, "%s counters | grep rxbadfcs | awk '{print $8}'", rwl_client_path);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
	if ((fd = popen(gCmdStr, "r")) == NULL){
		DPRINT_ERR(WFA_ERR, "Couldn't get rxbadfcs  stats\n");
		goto wfaStaGetStats_error;
	} else {
		fgets(gCmdStr, sizeof(gCmdStr), fd);
		castatsResp->fcsErrors = atoi(gCmdStr);
		pclose(fd);
	}
#else
	strcpy(cmdStr,rwl_client_path);
	strcat(cmdStr," counters >");
	/*Open the file to read the statistics*/
	if((fd = asd_Config(cmdStr,TEMP_FILE_PATH)) == NULL){
		DPRINT_ERR(WFA_ERR, "Couldn't get rxbadfcs  stats\n");
		goto wfaStaGetStats_error;
	}
	else {

		GetStats(fd, L"txframe ", &position," ");
		castatsResp->txFrames =  position;
		
		GetStats(fd, L"rxframe ", &position," ");
		castatsResp->rxFrames =position;
		
		GetStats(fd, L"d11_txmulti ", &position," ");
		castatsResp->txMulticast =position;
		
		GetStats(fd, L"d11_rxmulti ", &position," ");
		castatsResp->rxMulticast = position;
		
		GetStats(fd, L"d11_txretrie ", &position," ");
		castatsResp->txRetries = position;
		
		GetStats(fd, L"rxbadfcs ", &position," ");
		castatsResp->fcsErrors= position ;
	}
		Cleanup_File(fd);
#endif
	/* End: Modified as per BRCM 1.3 ASD */
	statsResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_GET_STATS_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)statsResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);
	return TRUE;

wfaStaGetStats_error:
	statsResp->status = STATUS_ERROR;
	wfaEncodeTLV(WFA_STA_GET_STATS_RESP_TLV, 4, (BYTE *)statsResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
	return FALSE;
}

int wfaDeviceGetInfo(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	dutCmdResponse_t *infoResp = &gGenericResp;
	/*a vendor can fill in the proper info or anything non-disclosure */
	caDeviceGetInfoResp_t dinfo = {"WFA Lab", "DemoUnit", WFA_SYSTEM_VER};
	/* Start: Modified as per BRCM 1.3 ASD */
	FILE *fd;

#ifndef WIN32
	/* get the 7th word in the string(1st line ignored( as it contains the value
	 * for dinfo.version */
	sprintf(gCmdStr,"%s ver | awk '{print $7}'", rwl_client_path);
#ifdef DEBUG
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
#endif
#else
	strcpy(gCmdStr,rwl_client_path);
	strcat(gCmdStr," ver >");
#endif
	if((fd = asd_Config(gCmdStr,TEMP_FILE_PATH)) == NULL){
		printf("Error executing ver\n");
		infoResp->status = STATUS_ERROR;
	}
	else {
#ifndef WIN32
		fgets(gCmdStr, sizeof(gCmdStr), fd);	/* Ignore first line */
		fgets(gCmdStr, sizeof(gCmdStr), fd);
		gCmdStr[strlen(gCmdStr) - 1] = 0;		/* Get rid of NL */
#else
		/* The string next to version contains value for dinfo.version */
		while ((fscanf(fd, "%s\n", gCmdStr)) != EOF) {
			if (strncmp(gCmdStr, "version", sizeof("version")) == 0) {
				fscanf(fd, "%s\n", gCmdStr);
				break;
			}
		}
#endif
	}
	Cleanup_File(fd);
	memset(&dinfo, 0, sizeof(dinfo));
	infoResp->status = STATUS_COMPLETE;
	sprintf(dinfo.vendor, "%.16s", "Broadcom");
	sprintf(dinfo.version, "%.16s", gCmdStr);
	sprintf(dinfo.model, "%.16s", "BRCM");
	
	DPRINT_INFO(WFA_OUT, "Entering wfaDeviceGetInfo ...\n");
	DPRINT_INFO(WFA_OUT, "status,%i,vendor,%s,model,%s,version %s\n", infoResp->status,
			dinfo.vendor,dinfo.model, dinfo.version);
	memcpy(&infoResp->cmdru.devInfo, &dinfo, sizeof(caDeviceGetInfoResp_t));

	infoResp->status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_DEVICE_GET_INFO_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)infoResp, respBuf);

	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);
	/* End: Modified as per BRCM 1.3 ASD */
	return TRUE;
}

/*
*   wfaStaGetBSSID():
*     This function is to retrieve BSSID of a specific wireless I/F.
*/
int wfaStaGetBSSID(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	FILE *tmpfd;
	dutCmdResponse_t *bssidResp = &gGenericResp;
	DPRINT_INFO(WFA_OUT, "Entering wfaStaGetBSSID ...\n");

#ifndef WIN32
	/* Start: Modified for BRCM 1.3 ASD */
	/* Associated gets long response */
	sprintf(gCmdStr, "%s assoc | wc -l", rwl_client_path);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
#else
	memset(gCmdStr, 0, sizeof(gCmdStr));
	strcpy(gCmdStr, rwl_client_path);
	strcat(gCmdStr, " bssid >");
#endif

	if((tmpfd = asd_Config(gCmdStr,TEMP_FILE_PATH)) == NULL){
		printf("BSSID failed\n");
		bssidResp->status = STATUS_ERROR;
		wfaEncodeTLV(WFA_STA_GET_BSSID_RESP_TLV, 4, (BYTE *)bssidResp, respBuf);
		*respLen = WFA_TLV_HDR_LEN + 4;
	}
	fgets(gCmdStr, sizeof(gCmdStr), tmpfd);
	Cleanup_File(tmpfd);

#ifndef WIN32
	/* Short response means not associated */
	if (atoi(gCmdStr) <= 2) {
		strcpy(bssidResp->cmdru.bssid, "00:00:00:00:00:00");
	} else {
		sprintf(gCmdStr, "%s bssid", rwl_client_path);
		DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
		if ((tmpfd = popen(gCmdStr, "r")) == NULL){
			printf("bssid failed\n");
		}
		fgets(gCmdStr, sizeof(gCmdStr), tmpfd);
		pclose(tmpfd);
		gCmdStr[17] = 0;	/* Get rid of CR or NL */
		strcpy(bssidResp->cmdru.bssid, gCmdStr);
	}
#else
	gCmdStr[17] = 0;	/* Get rid of CR or NL */
	if (gCmdStr[2] != ':'){
		strcpy(bssidResp->cmdru.bssid, "00:00:00:00:00:00");
	}
	else {
		strcpy(bssidResp->cmdru.bssid, gCmdStr);
	}
#endif
	bssidResp->status = STATUS_COMPLETE;
	/* End Modified as per BRCM 1.3 ASD */
	wfaEncodeTLV(WFA_STA_GET_BSSID_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)bssidResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);
	return TRUE;
}

/*
 *     exec_addts():
 *     This function will call ./wl cac_addts
 */
int
exec_addts(caStaSetWMM_t *setwmm) 
{
	char pwr_save_str[TSPEC_BUF_SIZE], direction[TSPEC_BUF_SIZE];
	int stat;

	DPRINT_INFO(WFA_OUT, "ADDTS AC PARAMS: \n \
		dialog id: %d, \t TID: %d, \t DIRECTION: %d, \n \
		PSB: %d, \t UP: %d, \t Fixed %d, \n \
		MSDU Size: %d, \t Max MSDU Size %d, \n \
		MIN SERVICE INTERVAL: %d, \t MAX SERVICE INTERVAL: %d, \n \
		INACTIVITY: %d, \t SUSPENSION %d, \n \
		SERVICE START TIME: %d, \t MIN DATARATE: %d, \n \
		MEAN DATA RATE: %d, \t PEAK DATA RATE: %d, \n \
		BURSTSIZE: %d, \t DELAY BOUND: %d, \t PHYRATE: %d, \n \
		SPLUSBW: %f, \t MEDIUM TIME: %d,  \t ACCESSCAT: %d\n", \
		setwmm->actions.addts.dialog_token, \
		setwmm->actions.addts.tspec.tsinfo.TID, \
		setwmm->actions.addts.tspec.tsinfo.direction, \
		setwmm->actions.addts.tspec.tsinfo.PSB, \
		setwmm->actions.addts.tspec.tsinfo.UP, \
		setwmm->actions.addts.tspec.Fixed, \
		setwmm->actions.addts.tspec.size, \
		setwmm->actions.addts.tspec.maxsize, \
		setwmm->actions.addts.tspec.min_srvc, \
		setwmm->actions.addts.tspec.max_srvc, \
		setwmm->actions.addts.tspec.inactivity, \
		setwmm->actions.addts.tspec.suspension, \
		setwmm->actions.addts.tspec.srvc_strt_tim, \
		setwmm->actions.addts.tspec.mindatarate, \
		setwmm->actions.addts.tspec.meandatarate, \
		setwmm->actions.addts.tspec.peakdatarate, \
		setwmm->actions.addts.tspec.burstsize, \
		setwmm->actions.addts.tspec.delaybound, \
		setwmm->actions.addts.tspec.PHYrate, \
		setwmm->actions.addts.tspec.sba, \
		setwmm->actions.addts.tspec.medium_time, \
		setwmm->actions.addts.accesscat);

	if (setwmm->actions.addts.tspec.tsinfo.direction == WMMAC_UPLINK)
		S_N_PRINTF(direction, sizeof(direction), "uplink");
	else if (setwmm->actions.addts.tspec.tsinfo.direction == WMMAC_DOWNLINK)
		S_N_PRINTF(direction, sizeof(direction), "downlink");
	else if (setwmm->actions.addts.tspec.tsinfo.direction == WMMAC_BIDIR)
		S_N_PRINTF(direction, sizeof(direction), "bi-directional");
			
	if (setwmm->actions.addts.tspec.tsinfo.PSB == 1)
		S_N_PRINTF(pwr_save_str, sizeof(pwr_save_str), "U-APSD");
	else if (setwmm->actions.addts.tspec.tsinfo.PSB == 0)
		S_N_PRINTF(pwr_save_str, sizeof(pwr_save_str), "legacy");

	if(setwmm->send_trig) {
		int Sockfd;
    		struct sockaddr_in psToAddr;
		unsigned int TxMsg[512];
       		Sockfd = wfaCreateUDPSock(setwmm->dipaddr, 12346);
		memset(&psToAddr, 0, sizeof(psToAddr));
		psToAddr.sin_family = AF_INET;
		psToAddr.sin_addr.s_addr = inet_addr(setwmm->dipaddr);
		psToAddr.sin_port = htons(12346);
		usleep(becon_int);
   		wfaTGSetPrio(Sockfd, setwmm->trig_ac);
		printf("\r\nSending dummy Hello to %s\n",setwmm->dipaddr);
       		create_apts_msg(APTS_HELLO, TxMsg,0);
		wfaTrafficSendTo(Sockfd, (char *)TxMsg, 256, (struct sockaddr *)&psToAddr);
		asd_closeSocket(Sockfd);
	}

	S_N_PRINTF(gCmdStr, sizeof(gCmdStr), "%s cac_addts %d %d %d %s %s %d %d %d" \
		" %d %d %d %d %d %d %d %d %d %d %d %d", \
		rwl_client_path, \
		TSPEC_VER, \
		setwmm->actions.addts.dialog_token, \
		setwmm->actions.addts.tspec.tsinfo.TID, \
		direction, \
		pwr_save_str, \
		setwmm->actions.addts.tspec.tsinfo.UP, \
		setwmm->actions.addts.tspec.size, \
		setwmm->actions.addts.tspec.Fixed, \
		setwmm->actions.addts.tspec.maxsize, \
		setwmm->actions.addts.tspec.min_srvc, \
		setwmm->actions.addts.tspec.max_srvc, \
		setwmm->actions.addts.tspec.inactivity, \
		setwmm->actions.addts.tspec.suspension, \
		setwmm->actions.addts.tspec.mindatarate, \
		setwmm->actions.addts.tspec.meandatarate, \
		setwmm->actions.addts.tspec.peakdatarate, \
		setwmm->actions.addts.tspec.burstsize, \
		setwmm->actions.addts.tspec.delaybound, \
		(int)setwmm->actions.addts.tspec.sba, \
		setwmm->actions.addts.tspec.PHYrate);
	if ((stat = exec_wmmCmd(gCmdStr))  != 0) {
		return FALSE;
	}
	return TRUE;
}

/*
 *     exec_delts():
 *     This function will call ./wl cac_delts
 */

int
exec_delts(caStaSetWMM_t *setwmm) 
{
	char *token_buf = NULL;
	char temp_buf[WFA_BUFF_128], tsinfo_buf[MAX_TOKENS][TSPEC_BUF_SIZE], temp_resp[WFA_BUFF_128];
	int token_count, stat, nbyte = 0, tsinfo_flag;
	FILE *output_fp, *error_fp;

	DPRINT_INFO(WFA_OUT, "DELTS AC PARAMS: TID: %d\n", setwmm->actions.delts);
	S_N_PRINTF(gCmdStr, sizeof(gCmdStr), "%s cac_tslist", rwl_client_path);

	/* Execute the command "wl cac_tslist" */
	if ((stat = asd_Config_wmm(gCmdStr, TEMP_STD_OUT_FILE)) != 0) {
		if ((error_fp = fopen(TEMP_STD_ERR_FILE, "r")) == NULL) {
			DPRINT_ERR(WFA_ERR, "Error in reading error message. \n");
		}
		memset(temp_resp, 0, sizeof(temp_resp));
       		fgets(temp_resp, sizeof(temp_resp), error_fp);
		DPRINT_ERR(WFA_ERR, "Error in executing wl cac_tslist :: %s \n", temp_resp);
		return FALSE;
	}

	tsinfo_flag = NO_TSINFO;
	if ((output_fp = fopen(TEMP_STD_OUT_FILE, "r")) == NULL) {
		printf("\nTEMP_STD_OUT_FILE::File open error\n");
		return FALSE;
	}
	else {
		while ((feof(output_fp) == 0)) {
			if (fseek(output_fp, nbyte, SEEK_SET) < 0) {
   				tsinfo_flag = NO_TSINFO;
				return FALSE;
			}
			memset(temp_resp, 0, sizeof(temp_resp));
       			fgets(temp_resp, sizeof(temp_resp), output_fp);
			nbyte = nbyte + strlen(temp_resp);

       			/* Get the wl cac_tslist results in temp_resp */

			if (strlen(temp_resp) == 0) {
				DPRINT_ERR(WFA_ERR, "temp_resp length 0. Can't execute wl cac_delts \n");
   				tsinfo_flag = NO_TSINFO;
				break;
			}

			token_buf = (char *)strtok_r(temp_resp, " ", (char **) temp_buf);
			token_count = 0;
			while (token_buf != NULL) {
				token_buf = (char *)strtok_r(NULL, " ", (char **) temp_buf);
				if (token_buf != NULL) {
					S_N_PRINTF(tsinfo_buf[token_count], 
						sizeof(tsinfo_buf[token_count]), "%s", token_buf);
					token_count++;
				}
			}
			/* if tid of cac_tslist matches with tid of sta_set_wmm then delts is performed */	
			if (atoi(tsinfo_buf[TID_INDEX]) == setwmm->actions.delts) {
				S_N_PRINTF(gCmdStr, sizeof(gCmdStr), "%s cac_delts %d %s %s %s", \
					rwl_client_path, TSPEC_VER, tsinfo_buf[BYTE_0], \
					tsinfo_buf[BYTE_1], tsinfo_buf[BYTE_2]);
				/* Execute wl cac_delts  */
				if ((stat = exec_wmmCmd(gCmdStr)) != 0) {
					return FALSE;
				}
				return TRUE;
			}
			else {
   				tsinfo_flag = TID_MISMATCH;
			}
		} /* End of while */
		fclose(output_fp);	
		if (tsinfo_flag == NO_TSINFO) {
			DPRINT_ERR(WFA_ERR, "Error. Cannot Execute wl cac_delts \n");
			return FALSE;
		}
		else if (tsinfo_flag == TID_MISMATCH) {
			DPRINT_ERR(WFA_ERR, "tid did not match. Can't Execute wl cac_delts \n");
			return FALSE;
		}
	}
	return TRUE;
}


/*
 *  wfaStaSetWMM():
 *  The function is to set the WMM related parameters at the DUT.
 *  Currently the function is used for GROUPS WMM-AC and WMM general configuration for setting
 *  RTS Threshhold, Fragmentation threshold and wmm (ON/OFF)
 *  It is expected that this function will set all the WMM related parametrs for a particular GROUP.
*/

int wfaStaSetWMM(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetWMM_t *setwmm = (caStaSetWMM_t *)caCmdBuf;
	char *ifname = setwmm->intf;
	dutCmdResponse_t *setwmmResp = &gGenericResp;
	int stat;
        int Sockfd;
        struct sockaddr_in psToAddr;
        unsigned int TxMsg[512];

	switch(setwmm->group)
	{
	case GROUP_WMMAC:
            if (setwmm->send_trig)
            {
                Sockfd = wfaCreateUDPSock(setwmm->dipaddr, 12346);
                memset(&psToAddr, 0, sizeof(psToAddr));
                psToAddr.sin_family = AF_INET;
                psToAddr.sin_addr.s_addr = inet_addr(setwmm->dipaddr);
                psToAddr.sin_port = htons(12346);
                switch (setwmm->trig_ac)
                {

                case WMMAC_AC_VO:
                    wfaTGSetPrio(Sockfd, 7);
                    create_apts_msg(APTS_CK_VO, TxMsg, 0);
                    printf("\r\nSending AC_VO trigger packet\n");
                break;

                case WMMAC_AC_VI:
                    wfaTGSetPrio(Sockfd, 5);
                    create_apts_msg(APTS_CK_VI, TxMsg, 0);
                    printf("\r\nSending AC_VI trigger packet\n");
                break;

                case WMMAC_AC_BK:
                    wfaTGSetPrio(Sockfd, 2);
                    create_apts_msg(APTS_CK_BK, TxMsg, 0);
                    printf("\r\nSending AC_BK trigger packet\n");
                break;

                default:
                case WMMAC_AC_BE:
                    wfaTGSetPrio(Sockfd, 0);
                    create_apts_msg(APTS_CK_BE, TxMsg, 0);
                    printf("\r\nSending AC_BE trigger packet\n");
                break;
                }
                sendto(Sockfd, TxMsg, 256, 0, (struct sockaddr *)&psToAddr,
                sizeof(struct sockaddr));
		asd_closeSocket(Sockfd);
                usleep(1000000);
            }
            else if (setwmm->action == WMMAC_ADDTS) {
                if ((stat = exec_addts(setwmm)) == FALSE) {
                    setwmmResp->status = STATUS_ERROR;
                    break;
                }
            }
            else if (setwmm->action == WMMAC_DELTS) {
                if ((stat = exec_delts(setwmm))  == FALSE) {
                    setwmmResp->status = STATUS_ERROR;
                    break;
                }
            }
            setwmmResp->status = STATUS_COMPLETE;
        break;

        case GROUP_WMMCONF:
            S_N_PRINTF(gCmdStr, sizeof(gCmdStr), "iwconfig %s rts_thr %d", \
                ifname,setwmm->actions.config.rts_thr);
            exec_process(gCmdStr);
            S_N_PRINTF(gCmdStr, sizeof(gCmdStr), "iwconfig %s frag_thr %d", \
                ifname,setwmm->actions.config.frag_thr);
            exec_process(gCmdStr);
            S_N_PRINTF(gCmdStr, sizeof(gCmdStr), "iwpriv %s wmm %d", \
                ifname,setwmm->actions.config.wmm);
            exec_process(gCmdStr);
            setwmmResp->status = STATUS_COMPLETE;
        break;

        default:
            DPRINT_ERR(WFA_ERR, "The group %d is not supported\n",setwmm->group);
	    setwmmResp->status = STATUS_ERROR;
	break;
	}

	wfaEncodeTLV(WFA_STA_SET_WMM_RESP_TLV, 4, (BYTE *)setwmmResp, respBuf);
	DPRINT_INFO(WFA_OUT, "tag is %d\n",WFA_STA_SET_WMM_RESP_TLV);
	*respLen = WFA_TLV_HDR_LEN + 4;
	return TRUE;
}

/* Start: Added BCM functions as per BRCM 1.3 ASD */
int bcmSsidIsGood(char *ssidStr)
{
	int ssidLen = strlen(ssidStr);

	if ((ssidLen == 0) || (ssidLen > BCM_SSID_LEN_MAX)) {
		return (FALSE);
	} else {
		return (TRUE);
	}
}

bcmSsidObj_t *bcmWfaSsidTblFreeEntry()
{
	bcmSsidObj_t *bso;
	int idx;

	DPRINT_INFO(WFA_OUT, "bcmWfaSsidTblFreeEntry\n");

	for (idx = 0; idx < BCM_SSID_MAX; idx++) {
		bso = &bsotbl.ssidObj[idx];
		if (bcmSsidIsGood(bso->ssidStr) == FALSE) {
			return bso;
		}
	}

	DPRINT_ERR(WFA_OUT, "bcmWfaSsidTblFreeEntry: no free entry available.\n");
	return (NULL);
}

bcmSsidObj_t *bcmWfaSsidTblSsidFind(char *ssidStr)
{
	bcmSsidObj_t *bso;
	bcmSsidObj_t *bsoFound= NULL;
	int idx;

	if (bcmSsidIsGood(ssidStr) == FALSE) {
		return (NULL);
	}

	for (idx = 0; idx < BCM_SSID_MAX; idx++) {
		bso = &bsotbl.ssidObj[idx];
		if (bcmSsidIsGood(ssidStr) == FALSE) {
			continue;
		}

		if (strcmp(ssidStr, bso->ssidStr)) {
			continue;
		} else {
			bsoFound = bso;
			break;
		}
	}

	return (bsoFound);
}

bcmSsidObj_t *bcmWfaSsidObjTblAdd(char *ssidStr)
{
	bcmSsidObj_t *bso;
	int idx;

	DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblAdd: ssidStr %s\n", ssidStr);

	if (bcmSsidIsGood(ssidStr) == FALSE) {
		return (NULL);
	}

	if ((bso = bcmWfaSsidTblSsidFind(ssidStr))) {
		DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s): ssid already exists\n", ssidStr);
		return (bso);
	}

	if (!(bso = bcmWfaSsidTblFreeEntry())) {
		DPRINT_INFO(WFA_OUT, "no free entry\n");
		return (NULL);
	}

	memset(bso,0, sizeof(bcmSsidObj_t));
	strcpy(bso->ssidStr, ssidStr);
	bso->bssType = BCM_BSS_INFRA; /* init it to infrastructure bss */
	bso->primary_key = BCM_PRI_KEY_BAD; /* init it to bad one */
	bso->eapType = BCM_DEFAULT_SEC_MODE; /* init to non-eap mode */ 

	for (idx = 0; idx < 4; idx++) {
		S_N_PRINTF (bso->keys[idx], 2, "%s", "\0");
	}

	bsotbl.addCnt++;
	bsotbl.entries++;

	return (bso);
}

void bcmWfaSsidObjTblDel(char *ssidStr)
{
	bcmSsidObj_t *bso;

	DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblDel: ssidStr %s\n", ssidStr);

	bso = bcmWfaSsidTblSsidFind(ssidStr);
	if (bso == NULL) {
		return;
	}

	DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblDel: deleting bso %p\n", bso);
	memset(bso,0, sizeof(bcmSsidObj_t));
	bsotbl.delCnt++;
	bsotbl.entries--;
}

void bcmWfaSsidObjPrint(bcmSsidObj_t *bso)
{
	int idx;

	if (bcmSsidIsGood(bso->ssidStr) == FALSE) {
		fprintf(WFA_OUT, "bso %p is blank.\n", bso);
		return;
	}

	fprintf(WFA_OUT, "bso %p\n", bso);
	fprintf(WFA_OUT, "\tssid %s", bso->ssidStr);
	fprintf(WFA_OUT, "\tbssType %d\n", bso->bssType);
	fprintf(WFA_OUT, "\tchannel %d\n", bso->channel);
	fprintf(WFA_OUT, "\twsec %d\n", bso->wsec);
	fprintf(WFA_OUT, "\tauth %d\n", bso->auth);
	fprintf(WFA_OUT, "\twpa_auth %d\n", bso->wpa_auth);
	fprintf(WFA_OUT, "\tpowerSave %d\n", bso->powerSave);
	fprintf(WFA_OUT, "\tuapsd %d\n", bso->uapsd);

	for (idx = 0; idx < 4; idx++) {
		fprintf(WFA_OUT, "\tkeys[%d] : %s\n", idx, bso->keys[idx]);
	}
	fprintf(WFA_OUT, "\tprimary_key %d\n", bso->primary_key);
	fprintf(WFA_OUT, "\tpassphrase : %s\n", bso->passphrase);
}

void bcmWfaSsidObjTblPrint(void)
{
	int idx;

	fprintf(WFA_OUT, "entries %d addCnt %d delCnt %d\n",
		bsotbl.entries, bsotbl.addCnt, bsotbl.delCnt);
	for (idx = 0; idx < BCM_SSID_MAX; idx++) {
		bcmWfaSsidObjPrint(&bsotbl.ssidObj[idx]);
	}
}

/*Do the initialisation for the driver */
void bcmWfaInit(void)
{
	memset(&bsotbl,0, sizeof(bsotbl));

	sprintf(gCmdStr, "%s ap 0", rwl_client_path); /* not AP */
	exec_process(gCmdStr);

	sprintf(gCmdStr, "%s radio on", rwl_client_path); /* not AP */
	exec_process(gCmdStr);

	sprintf(gCmdStr, "%s wsec 0", rwl_client_path);
	exec_process(gCmdStr);

	sprintf(gCmdStr, "%s auth 0", rwl_client_path);
	exec_process(gCmdStr);

	sprintf(gCmdStr, "%s wpa_auth 0", rwl_client_path);
	exec_process(gCmdStr);

	sprintf(gCmdStr, "%s sup_wpa 1", rwl_client_path); /* enable in-driver supplicant */
	exec_process(gCmdStr);

	/* Driver should not be made up explicitly  
	 * as we need to execute uapsd command in the beginning. 
	 */
}

/*
 * Implementing set systemtime
 */

int wfaStaSetSystime(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	int retVal = TRUE;
	dutCmdResponse_t *SetSystime = &gGenericResp;
	dutCommand_t *systime = (dutCommand_t *)caCmdBuf;
#ifndef WIN32
	char *month[]= {"NULL","JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
#else
	SYSTEMTIME newtime;
	int err;
#endif
	DPRINT_INFO(WFA_OUT, "Entering set systime ...\n");
#ifndef WIN32
	S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "date -s \"%d %s %d %d:%d:%d\"", systime->cmdsu.stime.date, month[systime->cmdsu.stime.month],
		systime->cmdsu.stime.year, systime->cmdsu.stime.hours, systime->cmdsu.stime.minutes, systime->cmdsu.stime.seconds);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
	exec_process(gCmdStr);
#else
	newtime.wDay = systime->cmdsu.stime.date;
	newtime.wMonth = systime->cmdsu.stime.month;
	newtime.wYear = systime->cmdsu.stime.year;
	newtime.wHour = systime->cmdsu.stime.hours;
	newtime.wMinute = systime->cmdsu.stime.minutes;
	newtime.wSecond = systime->cmdsu.stime.seconds;
	if ((err = SetLocalTime(&newtime)) == 0) {
		DPRINT_ERR(WFA_OUT, "error at set system time % d\n", GetLastError());
		retVal = FALSE;
	}
#endif /* WIN32 */
	/*
	* Then report back to control PC for completion.
	* This does not have failed/error status. The result only tells
	* a completion.
	*/
	if(retVal == TRUE)
		SetSystime->status = STATUS_COMPLETE;
	else
		SetSystime->status = STATUS_ERROR;	
	wfaEncodeTLV(WFA_STA_SET_SYSTIME_RESP_TLV, 4, (BYTE *)SetSystime, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
	return TRUE;
}

/*
 * Part of sigma 11n implementation.
 * Implementing set 1n functionalities
 */
int wfaStaSet11n(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
#ifdef WFA_STA_TB
	int retVal = TRUE; 
	FILE *tmpfd;
	dutCmdResponse_t *Set11nresp = &gGenericResp;
	dutCommand_t *Set11n = (dutCommand_t *)caCmdBuf;
	DPRINT_INFO(WFA_OUT, "Entering set 11n ...\n");
	/* Run the commands in the batching mode in case of wifi transport*/
	if(rwl_wifi_flag) {
		asd_sleep(1);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s seq_start", rwl_client_path);
		exec_process(gCmdStr);
	}
	S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s down", rwl_client_path);
	exec_process(gCmdStr);
	/*
	 * Showing unsupported yet to be implemented
	 * wl mimo_bw_cap need to be implemented by brcm
	 */
	if (Set11n->cmdsu.set11n.width == 20) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s mimo_bw_cap 0", rwl_client_path);
		exec_process(gCmdStr);
	}
	else if((Set11n->cmdsu.set11n.width) == 40 || (Set11n->cmdsu.set11n.width == -1)) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s mimo_bw_cap 1", rwl_client_path);
		exec_process(gCmdStr);
	}
	if (Set11n->cmdsu.set11n.addba_reject == 2) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s ampdu 0", rwl_client_path);
		exec_process(gCmdStr);
	}		
	else if(Set11n->cmdsu.set11n.addba_reject == 1) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s ampdu 1", rwl_client_path);
		exec_process(gCmdStr);
	}
	if (Set11n->cmdsu.set11n.ampdu == 2) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s amsdu 0", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s ampdu 1", rwl_client_path);
		exec_process(gCmdStr);
	}
	else if(Set11n->cmdsu.set11n.ampdu == 1) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s ampdu 0", rwl_client_path);
		exec_process(gCmdStr);
	}
	if (Set11n->cmdsu.set11n.amsdu == 2) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s amsdu 1", rwl_client_path);
		exec_process(gCmdStr);
	}
	else if(Set11n->cmdsu.set11n.amsdu == 1) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s amsdu 0", rwl_client_path);
		exec_process(gCmdStr);
	}
	if (Set11n->cmdsu.set11n.greenfield == 2) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s mimo_preamble 1", rwl_client_path);
		exec_process(gCmdStr);
	}
	else if(Set11n->cmdsu.set11n.greenfield == 1) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s mimo_preamble 0", rwl_client_path);
		exec_process(gCmdStr);
	}
	if (Set11n->cmdsu.set11n.stbc_rx == 0) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s stbc_tx 0", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s stbc_rx 0", rwl_client_path);
		exec_process(gCmdStr);
	}
	else if (Set11n->cmdsu.set11n.stbc_rx > 0) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s stbc_tx 1", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s stbc_rx 1", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s nrate -m 5 -w 2", rwl_client_path);
		exec_process(gCmdStr);
	}
	S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s up", rwl_client_path);
	exec_process(gCmdStr);
	if(rwl_wifi_flag) {
		asd_sleep(1);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s seq_stop", rwl_client_path);
		exec_process(gCmdStr);
	}
	if (Set11n->cmdsu.set11n.intolerant_40 == 2) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s obss_coex 1", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s intol40 1", rwl_client_path);
		exec_process(gCmdStr);
	}		
	else if(Set11n->cmdsu.set11n.intolerant_40 == 1) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s obss_coex 0", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s intol40 0", rwl_client_path);
		exec_process(gCmdStr);
	}

	if (Set11n->cmdsu.set11n.sgi20 == 2) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s sgi_tx %d", rwl_client_path, -1);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s sgi_rx %d", rwl_client_path, 3);
		exec_process(gCmdStr);
	}
	else if(Set11n->cmdsu.set11n.sgi20 == 1) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s sgi_tx %d", rwl_client_path, 0);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s sgi_rx %d", rwl_client_path, 0);
		exec_process(gCmdStr);
	}
	/*
	 * SMPS related commands can be ignored as of now till
	 * mimo_ps command gets implemented
	 */
	if (Set11n->cmdsu.set11n.smps == 1) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s mimo_ps 1", rwl_client_path); /* dynamic */
		exec_process(gCmdStr);
	}
	else if(Set11n->cmdsu.set11n.smps == 2) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s mimo_ps 0", rwl_client_path); /* static */
		exec_process(gCmdStr);
	}
	else if(Set11n->cmdsu.set11n.smps == 3) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s mimo_ps 3", rwl_client_path); /* no limit */
		exec_process(gCmdStr);
	}
	if ((Set11n->cmdsu.set11n.mcs_fixedrate >= 0) && (Set11n->cmdsu.set11n.mcs_fixedrate <= 31)) {

#ifndef WIN32
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s nrate -m %d &> %s", rwl_client_path, Set11n->cmdsu.set11n.mcs_fixedrate, TEMP_FILE_PATH);
#else
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s nrate -m %d > %s 2>&1", rwl_client_path, Set11n->cmdsu.set11n.mcs_fixedrate, TEMP_FILE_PATH);
#endif
		exec_process(gCmdStr);
		if((tmpfd = fopen(TEMP_FILE_PATH, "r")) == NULL){
			Set11nresp->status = STATUS_ERROR;	
			wfaEncodeTLV(WFA_STA_SET_11N_RESP_TLV, 4, (BYTE *)Set11nresp, respBuf);
			*respLen = WFA_TLV_HDR_LEN + 4;
			return TRUE;
		}
		fgets(gCmdStr, sizeof(gCmdStr), tmpfd);
		Cleanup_File(tmpfd);
/*
 * wl rate is issued to check if the 11N supported chip is SISO or MIMO.
 * If the response is 72Mbps then it is SISO,
 * Checking if wl returning saying not in range, then invalid
 */
		if ((strstr(gCmdStr, "Range")) != NULL) {
			DPRINT_INFO(WFA_OUT, "This card Doesnt Support this range\n");
			Set11nresp->status = STATUS_INVALID;	
			wfaEncodeTLV(WFA_STA_SET_11N_RESP_TLV, 4, (BYTE *)Set11nresp, respBuf);
			*respLen = WFA_TLV_HDR_LEN + 4;
			return TRUE;
		}

	}



	/*
	 * Then report back to control PC for completion.
	 * This does not have failed/error status. The result only tells
	 * a completion.
	 */
	if(retVal == TRUE)
		Set11nresp->status = STATUS_COMPLETE;
	else
		Set11nresp->status = STATUS_ERROR;	
	wfaEncodeTLV(WFA_STA_SET_11N_RESP_TLV, 4, (BYTE *)Set11nresp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
#endif /* WFA_STA_TB */
	return TRUE;
}

/*
 * Part of sigma 11n implementation.
 * Implementing RIFS test
 */

int wfaStaSetRifsTest(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
#ifdef WFA_STA_TB
	int retVal = TRUE;
	dutCmdResponse_t *RIFStest = &gGenericResp;
	dutCommand_t *rifstest = (dutCommand_t *)caCmdBuf;
	if(rifstest->cmdsu.action_rifs == 2) { /* enabled */
		if(rwl_wifi_flag) {
			asd_sleep(1);
			S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s seq_start", rwl_client_path);
			exec_process(gCmdStr);
		}
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s down", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s ampdu 0", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s up", rwl_client_path);
		exec_process(gCmdStr);
		if(rwl_wifi_flag) {
			asd_sleep(1);
			S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s seq_stop", rwl_client_path);
			exec_process(gCmdStr);
		}
		/*
		 * nrate support 0-7 in SISO
		 * nrate support 0-31 in MIMO
		 */
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s nrate -m 12", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s rifs 1", rwl_client_path);
		exec_process(gCmdStr);
	}
	else if(rifstest->cmdsu.action_rifs == 1) { /* disable */
		if(rwl_wifi_flag) {
			asd_sleep(1);
			S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s seq_start", rwl_client_path);
			exec_process(gCmdStr);
		}
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s down", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s up", rwl_client_path);
		exec_process(gCmdStr);
		if(rwl_wifi_flag) {
			asd_sleep(1);
			S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s seq_stop", rwl_client_path);
			exec_process(gCmdStr);
		}
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s rifs 0", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s band b", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s rate -1", rwl_client_path);
		exec_process(gCmdStr);
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s band auto", rwl_client_path);
		exec_process(gCmdStr);
	}
	/*
	* Then report back to control PC for completion.
	* This does not have failed/error status. The result only tells
	* a completion.
	*/
	if(retVal == TRUE)
		RIFStest->status = STATUS_COMPLETE;
	else
		RIFStest->status = STATUS_ERROR;	
	wfaEncodeTLV(WFA_STA_SET_RIFS_TEST_RESP_TLV, 4, (BYTE *)RIFStest, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
#endif /* WFA_STA_TB */
	return TRUE;
}

/*
 * Part of sigma 11n implementation.
 * Implementing set wireless utility
 */

int wfaStaSetWireless(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
#ifdef WFA_STA_TB
	int retVal = TRUE;
	dutCmdResponse_t *SetWireless = &gGenericResp;
	dutCommand_t *wireless = (dutCommand_t *)caCmdBuf;
	if(strcasecmp(wireless->cmdsu.wireless_band, "2.4") == 0) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s band b", rwl_client_path);
		exec_process(gCmdStr);
	}
	else if(strcasecmp(wireless->cmdsu.wireless_band, "5") == 0) {
		/*
		 * Band a setting doesnt supported
		 * Gives error -13
		 */
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s band a", rwl_client_path);
		exec_process(gCmdStr);
	}
	else {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s band auto", rwl_client_path);
		exec_process(gCmdStr);
	}
	/*
	* Then report back to control PC for completion.
	* This does not have failed/error status. The result only tells
	* a completion.
	*/
	if(retVal == TRUE)
		SetWireless->status = STATUS_COMPLETE;
	else
		SetWireless->status = STATUS_ERROR;	
	wfaEncodeTLV(WFA_STA_SET_WIRELESS_RESP_TLV, 4, (BYTE *)SetWireless, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
#endif /* WFA_STA_TB */
	return TRUE;
}

int wfaStaResetDefault(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
   caStaResetDefault_t *reset = (caStaResetDefault_t *)caCmdBuf;
   dutCmdResponse_t *ResetResp = &gGenericResp;

   /* need to implement based on program, defaults for each program set. */
   S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s prog %s ", rwl_client_path, reset->prog);
   exec_process(gCmdStr);

   ResetResp->status = STATUS_COMPLETE;
   wfaEncodeTLV(WFA_STA_RESET_DEFAULT_RESP_TLV, 4, (BYTE *)ResetResp, respBuf);
   *respLen = WFA_TLV_HDR_LEN + 4;

   return TRUE;
}

/*
 * Part of sigma 11n implementation.
 * Implementing send addba
 */

int wfaStaSendAddba(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
#ifdef WFA_STA_TB
	int retVal = TRUE;
	dutCmdResponse_t *SendAddba = &gGenericResp;
	dutCommand_t *addba = (dutCommand_t *)caCmdBuf;
	FILE *tmpfd;
	char mac[WFA_MAC_ADDR_STR_LEN];
	if(addba->cmdsu.tid) {
#ifndef WIN32
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s bssid", rwl_client_path);
#else
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s bssid >", rwl_client_path);
#endif
		if((tmpfd = asd_Config(gCmdStr,TEMP_FILE_PATH)) == NULL) {
			DPRINT_ERR(WFA_OUT, "Error executing ssid\n");
			SendAddba->status = STATUS_ERROR;	
			wfaEncodeTLV(WFA_STA_SEND_ADDBA_RESP_TLV, 4, (BYTE *)SendAddba, respBuf);
			*respLen = WFA_TLV_HDR_LEN + 4;
			return TRUE;
		}
		else {
			while((fscanf(tmpfd, "%s\n", gCmdStr)) != EOF) {
				memset(mac, 0, WFA_MAC_ADDR_STR_LEN);
				strncpy(mac, gCmdStr, strlen(gCmdStr));
			}
		}
		Cleanup_File(tmpfd);
		if (mac[2] != ':') /* if STA is not associated */
		strcpy(mac, "00:00:00:00:00:00");
		DPRINT_INFO(WFA_OUT, "MAC %s\n", mac);
		/*
		 * If STA not associated then error -2 displays
		 */
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s ampdu_send_addba %d %s",
			rwl_client_path, addba->cmdsu.tid, mac);
		exec_process(gCmdStr);

	}
	else
		retVal = FALSE;

	/*
	* Then report back to control PC for completion.
	* This does not have failed/error status. The result only tells
	* a completion.
	*/
	if(retVal == TRUE)
		SendAddba->status = STATUS_COMPLETE;
	else
		SendAddba->status = STATUS_ERROR;	
	wfaEncodeTLV(WFA_STA_SEND_ADDBA_RESP_TLV, 4, (BYTE *)SendAddba, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
#endif /* WFA_STA_TB */
	return TRUE;
}


/*
 * Part of sigma 11n implementation.
 * Implementing sending coexist management
 */

int wfaStaSendCoexistMgmt(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
#ifdef WFA_STA_TB
	int retVal = FALSE; /* changed to make sure one of BSS or MHZ value presnt */
	dutCmdResponse_t *CoexistMgmt = &gGenericResp;
	dutCommand_t *coexist = (dutCommand_t *)caCmdBuf;
	int mhz, bss;
	/*
	 * Either of BSS, MHZ value should be present in the option
	 */
	if (coexist->cmdsu.coexistmgmt.Mhz[0] != '\0') {
		mhz = atoi(coexist->cmdsu.coexistmgmt.Mhz);
		retVal = TRUE;
	}
	else {
		mhz = 0;
	}
	if (coexist->cmdsu.coexistmgmt.bss[0] != '\0') {
		bss = atoi(coexist->cmdsu.coexistmgmt.bss);
		retVal = TRUE;
	}
	else {
		bss = 0;
	}
	if (bss > 1 || bss < 0 || mhz >1 || mhz < 0) {
		/* they can only have 0/1 */
		DPRINT_INFO(WFA_OUT, "BSS or MHz can have value 1/0\n");
		retVal = FALSE;
	}
	/*
	 * This command also yet to be implemented from brcm
	 */
	if (coexist->cmdsu.coexistmgmt.ChnlRepo[0] != '\0' && 
		coexist->cmdsu.coexistmgmt.ChnlRepo) {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s obss_coex_action -i %d -w %d -c %s", rwl_client_path, mhz, bss,
			coexist->cmdsu.coexistmgmt.ChnlRepo);
	}
	else {
		S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s obss_coex_action -i %d -w %d", rwl_client_path, mhz, bss);
	}
	if (retVal == TRUE)
		exec_process(gCmdStr);
	else
		DPRINT_INFO(WFA_OUT, "should enter atleast one option in MHZ or BSS\n");
	/*
	* Then report back to control PC for completion.
	* This does not have failed/error status. The result only tells
	* a completion.
	*/
	if(retVal == TRUE)
		CoexistMgmt->status = STATUS_COMPLETE;
	else
		CoexistMgmt->status = STATUS_ERROR;	
	wfaEncodeTLV(WFA_STA_SEND_COEXIST_MGMT_RESP_TLV, 4, (BYTE *)CoexistMgmt, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
#endif /* WFA_STA_TB */
	return TRUE;
}

/*
 * Part of sigma 11n implementation.
 * Implementing disconnect
 */

int wfaStaSetDisconnect(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
#ifdef WFA_STA_TB
	int retVal = TRUE;
	dutCmdResponse_t *Disconnect = &gGenericResp;
	dutCommand_t *discon = (dutCommand_t *)caCmdBuf;
	DPRINT_INFO(WFA_OUT, "Entering set disconnect...\n");
	DPRINT_INFO(WFA_OUT, "interface entered %s\n", discon->intf);

	/*
	* Then report back to control PC for completion.
	* This does not have failed/error status. The result only tells
	* a completion.
	*/
	S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s disassoc", rwl_client_path);
	exec_process(gCmdStr);
	if(retVal == TRUE)
		Disconnect->status = STATUS_COMPLETE;
	else
		Disconnect->status = STATUS_ERROR;	
	wfaEncodeTLV(WFA_STA_DISCONNECT_RESP_TLV, 4, (BYTE *)Disconnect, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
#endif /* WFA_STA_TB */
	return TRUE;
}

/*
 * Part of sigma 11n implementation.
 * Implementing sending neighborhood request
 */

int wfaStaSendNeigreq(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{	
#ifdef WFA_STA_TB
	int retVal = TRUE;
	dutCmdResponse_t *SendNeigreq = &gGenericResp;
	dutCommand_t *neigreq = (dutCommand_t *)caCmdBuf;
	char ssidTarget[WFA_SSID_NAME_LEN];
	bcmSsidObj_t *bso;
	DPRINT_INFO(WFA_OUT, "Entering send neighbourhood request ...\n");
	memcpy(ssidTarget, neigreq->cmdsu.ssid, WFA_SSID_NAME_LEN);
	bso = bcmWfaSsidTblSsidFind(ssidTarget);
	if (!bso) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidTarget))) {
			DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidTarget);
			return FALSE;
		}
	}
	/* 
	 * wl rrm_nbr_req need to have support for ssid parameter, currently it takes 
	 * something else which is not recommended by wi-fi
	 */
	S_N_PRINTF(gCmdStr, WFA_CMD_STR_SZ, "%s rrm_nbr_req %s", rwl_client_path, ssidTarget);
	DPRINT_INFO(WFA_OUT, "%s\n", gCmdStr);
	exec_process(gCmdStr);
	/*
	* Then report back to control PC for completion.
	* This does not have failed/error status. The result only tells
	* a completion.
	*/
	if(retVal == TRUE)
		SendNeigreq->status = STATUS_COMPLETE;
	else
		SendNeigreq->status = STATUS_ERROR;	
	wfaEncodeTLV(WFA_STA_SEND_NEIGREQ_RESP_TLV, 4, (BYTE *)SendNeigreq, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
#endif /* WFA_STA_TB */
	return TRUE;
}

/*
* wfaStaSetFAST()
*   This is to set
*   1. ssid
*   2. user name
*   3. passwd
*   4. encryType - tkip or aes-ccmp
*   5. keyMgmtType - wpa or wpa2
*   6. trustedRootCA
*   7. innerEAP
*   8. validateserver
*   9. PACfile
*/
int wfaStaSetEapFAST(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetEapFAST_t *setFAST = (caStaSetEapFAST_t *)caCmdBuf;
	int retVal = TRUE;
	dutCmdResponse_t *setFastResp = &gGenericResp;
	bcmSsidObj_t *bso;
	char ssidTarget[WFA_SSID_NAME_LEN];

	memcpy(ssidTarget, setFAST->ssid, WFA_SSID_NAME_LEN);
	bso = bcmWfaSsidTblSsidFind(ssidTarget);
	if (!bso) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidTarget))) {
			DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidTarget);
			retVal = FALSE;
		}
		if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
			bcmWfaSsidObjPrint(bso);
		}

	}
	
	memcpy(&(bso->eapObj.setEapFAST), setFAST, sizeof(caStaSetEapFAST_t));
	bso->eapType = BCM_EAP_TYPE_FAST;

	if(strstr(bso->eapObj.setEapFAST.encrptype,"aes-ccmp"))
			strncpy(bso->eapObj.setEapFAST.encrptype, AES_ENCPTYPE, AES_LEN) ;
	if(retVal == TRUE)
		setFastResp->status = STATUS_COMPLETE;
	else
		setFastResp->status = STATUS_ERROR;
	wfaEncodeTLV(WFA_STA_SET_EAPFAST_RESP_TLV, 4, (BYTE *)setFastResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return TRUE;
}

/*
* wfaStaSetEapAKA()
*   This is to set
*   1. ssid
*   2. user name
*   3. passwd
*   4. encryType - tkip or aes-ccmp
*   5. keyMgmtType - wpa or wpa2
*/
int wfaStaSetEapAKA(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caStaSetEapAKA_t *setAKA = (caStaSetEapAKA_t *)caCmdBuf;
	dutCmdResponse_t *setAkaResp = &gGenericResp;
	bcmSsidObj_t *bso;
	int retVal = TRUE;
	char ssidTarget[WFA_SSID_NAME_LEN];

	memcpy(ssidTarget, setAKA->ssid, WFA_SSID_NAME_LEN);
	bso = bcmWfaSsidTblSsidFind(ssidTarget);
	if (!bso) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidTarget))) {
			DPRINT_ERR(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidTarget);
			retVal = FALSE;
		}
		if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
			bcmWfaSsidObjPrint(bso);
		}

	}
	
	memcpy(&(bso->eapObj.setEapAKA), setAKA, sizeof(caStaSetEapAKA_t));
	bso->eapType = BCM_EAP_TYPE_AKA;

	if(strstr(bso->eapObj.setEapAKA.encrptype,"aes-ccmp"))
			strncpy(bso->eapObj.setEapAKA.encrptype, AES_ENCPTYPE, AES_LEN) ;
	if(retVal == TRUE)
		setAkaResp->status = STATUS_COMPLETE;
	else
		setAkaResp->status = STATUS_ERROR;
	wfaEncodeTLV(WFA_STA_SET_EAPAKA_RESP_TLV, 4, (BYTE *)setAkaResp, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;

	return TRUE;
}
