
/****************************************************************************
 *  (c) Copyright 2006 Wi-Fi Alliance.  All Rights Reserved 
 *
 * 
 *  LICENSE
 *
 * License is granted only to Wi-Fi Alliance members and designated Wi-Fi 
 * contractors ("Authorized Licensees").  Authorized Licensees are hereby 
 * granted the limited right to use this software solely for noncommercial 
 * applications and solely for testing Wi-Fi equipment. Authorized Licensees 
 * may embed this software into their proprietary equipment and distribute this
 * software with such equipment under 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.  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.
 *
 * 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.
 *
 * 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 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.
 *
 * 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 EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A 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_ca.c
 *   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 Release by qhu
 *                       replace hardcoded buff size with gloabal 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 release by qhu
 *        
 */ 
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <iwlib.h>
#include <wireless.h>

#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"

/*
 * atheros wireless interface madwifi driver include files
 * You may remove them if using other device interface
 */
#include "xtn/compat.h"
#include "xtn/_ieee80211.h"
#include "xtn/ieee80211_crypto.h"
#include "xtn/ieee80211.h"
#include "xtn/ieee80211_ioctl.h"
#include "xtn/if_athioctl.h"

#define CERTIFICATES_PATH    "/etc/wpa_supplicant"

extern unsigned short wfa_defined_debug;

/* 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_PRI_KEY_BAD		(-1)

typedef struct bcmSsidObj
{
	char ssidStr[BCM_SSID_LEN_MAX];
	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;
} 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);

/*
 * 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;

    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(getverResp), (BYTE *)&getverResp, respBuf);

    *respLen = WFA_TLV_HDR_LEN + sizeof(getverResp);

    return TRUE;
}

extern int gxcSockfd;

/*
 * 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 ret = 0;
	int retVal = TRUE;
	dutCommand_t *assoc = (dutCommand_t *)caCmdBuf;
	char cmdStr[WFA_CMD_STR_SZ];
	int imode; /* 0 for ibss, 1 for infrastructure */
	char ssidTarget[WFA_SSID_NAME_LEN];
	bcmSsidObj_t *bso;
	int idx;

	bcopy(assoc->cmdsu.ssid, ssidTarget, 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(cmdStr, "/tmp/ASD/wl disassoc");
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl down");
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	/* handle WEP keys */
	for(idx = 0; idx < 4; idx++) {
		if(bso->keys[idx][0] != '\0') {
			sprintf(cmdStr, "/tmp/ASD/wl addwep %d %s", idx, bso->keys[idx]);
		} else {
			sprintf(cmdStr, "/tmp/ASD/wl rmwep %d", idx);
		}
		system(cmdStr);
		DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);
	}

	/* set primary key */
	if(bso->primary_key != BCM_PRI_KEY_BAD) {
		sprintf(cmdStr, "/tmp/ASD/wl primary_key %d", bso->primary_key);
		system(cmdStr);
		DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);
	}

	if ((!imode) && bso->channel){
		sprintf(cmdStr, "/tmp/ASD/wl channel %d", bso->channel);
		system(cmdStr);
		DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);
	}

	sprintf(cmdStr, "/tmp/ASD/wl infra %d", imode);
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	/* security */
	sprintf(cmdStr, "/tmp/ASD/wl wsec %d", bso->wsec);
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	if(bso->passphrase[0] != '\0') {
		sprintf(cmdStr, "/tmp/ASD/wl set_pmk %s", bso->passphrase); 
		system(cmdStr);
		DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);
	}

	sprintf(cmdStr, "/tmp/ASD/wl auth %d", bso->auth);
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl wpa_auth %d", bso->wpa_auth);
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	/* Power Save */
	sprintf(cmdStr, "/tmp/ASD/wl wme_apsd_sta %d %d %d %d %d",
		bso->maxSPLength, bso->acBE, bso->acBK, bso->acVI, bso->acVO);
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl up");
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl ssid '%s'", ssidTarget);
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

exit:
	ret = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_ASSOCIATE_RESP_TLV, 4, (BYTE *)&ret, respBuf);   
	*respLen = WFA_TLV_HDR_LEN + 4;
	return retVal; 
}

/*
 * 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)
{
	char cmdStr[WFA_CMD_STR_SZ];
	FILE *tmpfd;
	dutCmdResponse_t staConnectResp;

	DPRINT_INFO(WFA_OUT, "Entering isConnected ...\n"); 

	/* Associated gets long response */
	if ((tmpfd = popen("/tmp/ASD/wl assoc | wc -l", "r")) == NULL){
		printf("wc -l failed\n");
	}
	fgets(cmdStr, sizeof(cmdStr), tmpfd);
	pclose(tmpfd);

	/* Short response means not associated */
	if (atoi(cmdStr) <= 2)
		staConnectResp.cmdru.connected = 0;
	else
		staConnectResp.cmdru.connected = 1;

	/*
	 * Report back the status: Complete or Failed.
	 */
	staConnectResp.status = STATUS_COMPLETE;

	wfaEncodeTLV(WFA_STA_IS_CONNECTED_RESP_TLV, sizeof(staConnectResp), 
		(BYTE *)&staConnectResp, respBuf);   
	*respLen = WFA_TLV_HDR_LEN + sizeof(staConnectResp);
	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;
    dutCommand_t *getIpConf = (dutCommand_t *)caCmdBuf;
    dutCmdResponse_t ipconfigResp; 
    char *ifname = getIpConf->intf;
    caStaGetIpConfigResp_t *ifinfo = &ipconfigResp.cmdru.getIfconfig;

    FILE *tmpfd;
    char string[256];

    /* Dhcp */
    if ((tmpfd = popen("ps ax | grep -v grep | grep dhcli | wc -l", "r")) == NULL){
	printf("wc -l failed\n");
    }
    fgets(string, sizeof(string), tmpfd);
    pclose(tmpfd);
    if (atoi(string) >= 1)
       ifinfo->isDhcp = 1;
    else
       ifinfo->isDhcp = 0;

    /* ipaddr */
    sprintf(string, "ifconfig %s | grep 'inet addr' |  cut -d: -f2 | cut -d' ' -f1", ifname);
    if ((tmpfd = popen(string, "r")) == NULL){
	printf("ifconfig addr failed\n");
    }
    ifinfo->ipaddr[0] = 0;
    fgets(ifinfo->ipaddr, WFA_IP_ADDR_STR_LEN, tmpfd);
    ifinfo->ipaddr[strlen(ifinfo->ipaddr) - 1] = 0; /* Purge newline */
    pclose(tmpfd);
    if(ifinfo->ipaddr[0] == 0) 
       strncpy(ifinfo->ipaddr, "none", 15);

    /* mask */
    sprintf(string, "ifconfig %s | grep 'inet addr' |  cut -d: -f4", ifname);
    if ((tmpfd = popen(string, "r")) == NULL){
	printf("ifconfig mask failed\n");
    }
    ifinfo->mask[0] = 0;
    fgets(ifinfo->mask, WFA_IP_MASK_STR_LEN, tmpfd);
    ifinfo->mask[strlen(ifinfo->mask) - 1] = 0; /* Purge newline */
    pclose(tmpfd);

    if(ifinfo->mask[0] == 0) 
       strcpy(ifinfo->mask, "none");

    /* dns */
    if ((tmpfd = popen("cat /etc/resolv.conf | grep nameserver | awk '{print $2}'", "r")) == NULL){
	printf("resolve.conf failed\n");
    }
    for (i = 0; i < WFA_MAX_DNS_NUM; i++){
	    fgets(ifinfo->dns[i], WFA_MAC_ADDR_STR_LEN, tmpfd);
	    if (ifinfo->dns[i][0])
	        ifinfo->dns[i][strlen(ifinfo->dns[i]) - 1] = 0; /* Purge newline */
	    else
    		strcpy(ifinfo->dns[i], "NOTDEF");
    }
    pclose(tmpfd);

     /*
      * 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(caStaGetIpConfigResp_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).  
 */
int wfaStaSetIpConfig(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
   dutCommand_t *setIpConf = (dutCommand_t *)caCmdBuf;
   char cmds[128];
   int ret = 0;
   caStaSetIpConfig_t *ipconfig = &setIpConf->cmdsu.ipconfig;

   DPRINT_INFO(WFA_OUT, "entering wfaStaSetIpConfig ...\n");

   /*
    * Use command 'ifconfig' to configure the interface ip address, mask.
    * (Linux specific).
    */
   if (!strlen(ipconfig->intf) || !strlen(ipconfig->ipaddr)){
	   ret = STATUS_ERROR;
	   wfaEncodeTLV(WFA_STA_SET_IP_CONFIG_RESP_TLV, 4, (BYTE *)&ret, respBuf);   
	   *respLen = WFA_TLV_HDR_LEN + 4;
	   return TRUE;
   }
   sprintf(cmds, "%s %s %s ", IFCONFIG_PATH, ipconfig->intf, ipconfig->ipaddr);
   if (strlen(ipconfig->mask))
   	sprintf(&cmds[strlen(cmds)], "netmask %s ", ipconfig->mask);
   system(cmds);
   DPRINT_INFO(WFA_OUT, "%s\n", "doing ifconfig");

   /* use command 'route add' to set set gatewway (linux specific) */ 
   if(ipconfig->defGateway[0]) {
      sprintf(cmds, "%s add default gw %s > /dev/null 2>&1", ROUTE_PATH, ipconfig->defGateway);
      system(cmds);
      DPRINT_INFO(WFA_OUT, "%s\n", "doing route add");
   }

   /* set dns (linux specific) */
   if (ipconfig->pri_dns[0]){
	   sprintf(cmds, "cp /etc/resolv.conf /tmp/resolv.conf.bk");
	   system(cmds);
	   sprintf(cmds, "echo nameserv %s > /etc/resolv.conf", ipconfig->pri_dns);
	   system(cmds);
	   sprintf(cmds, "echo nameserv %s >> /etc/resolv.conf", ipconfig->sec_dns);
	   system(cmds);
   }

   ret = STATUS_COMPLETE;
   wfaEncodeTLV(WFA_STA_SET_IP_CONFIG_RESP_TLV, 4, (BYTE *)&ret, 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;
   char cmdStr[WFA_CMD_STR_SZ];
   FILE *tmpfile;
   dutCmdResponse_t verifyIpResp;
   dutCommand_t vvv;

   
   DPRINT_INFO(WFA_OUT, "Entering wfaStaVerifyIpConnection ...\n");
   memcpy(&vvv, caCmdBuf, sizeof(dutCommand_t));

   /* set timeout value in case not set */
   if(verip->cmdsu.verifyIp.timeout <= 0)
        verip->cmdsu.verifyIp.timeout = 10;
   
   /* execute the ping command  and pipe the result to a tmp file */
   sprintf(cmdStr, "ping %s -c 3 -W %d | grep '100%%'", verip->cmdsu.verifyIp.dipaddr,  verip->cmdsu.verifyIp.timeout);

   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   if (strlen(verip->cmdsu.verifyIp.dipaddr) == 0 || ((tmpfile = popen(cmdStr, "r")) == NULL)){
      int status = STATUS_ERROR;
      wfaEncodeTLV(WFA_STA_VERIFY_IP_CONNECTION_RESP_TLV, 4, (BYTE *)&status, respBuf);   
      *respLen = WFA_TLV_HDR_LEN + 4;

      DPRINT_ERR(WFA_ERR, "Could not execute %s\n", cmdStr);
      return FALSE;
   }

   verifyIpResp.status = STATUS_COMPLETE;

   if (fgets(cmdStr, sizeof(cmdStr), tmpfile) == NULL){
      verifyIpResp.cmdru.connected = 1;
   } else{
      verifyIpResp.cmdru.connected = 0;
   }
   pclose(tmpfile);
   

   wfaEncodeTLV(WFA_STA_VERIFY_IP_CONNECTION_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)&verifyIpResp, respBuf);   

   *respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t);
   
   return TRUE;
}

/*
 * 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;
	FILE *tmpfd;

	DPRINT_INFO(WFA_OUT, "Entering wfaStaGetMacAddress ...\n");

	if ((tmpfd = popen("/tmp/ASD/wl dump | grep perm | awk '{print $4}'", "r")) == NULL){
		int status = STATUS_ERROR;
		wfaEncodeTLV(WFA_STA_GET_MAC_ADDRESS_RESP_TLV, 4, (BYTE *)&status, respBuf);   
		*respLen = WFA_TLV_HDR_LEN + 4;

		DPRINT_ERR(WFA_ERR, "Pipe open for wl dump failed\n");
		return FALSE;
	}
	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);
	pclose (tmpfd);
	getmacResp.status = STATUS_COMPLETE;
 
	wfaEncodeTLV(WFA_STA_GET_MAC_ADDRESS_RESP_TLV, sizeof(getmacResp), 
		(BYTE *)&getmacResp, respBuf);   

	*respLen = WFA_TLV_HDR_LEN + sizeof(getmacResp);
	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)
{
	char cmdStr[WFA_CMD_STR_SZ];
	FILE *tmpfd;
	dutCmdResponse_t bssidResp;

	/* Associated gets long response */
	if ((tmpfd = popen("/tmp/ASD/wl assoc | wc -l", "r")) == NULL){
		printf("wc -l failed\n");
	}
	fgets(cmdStr, sizeof(cmdStr), tmpfd);
	pclose(tmpfd);

	/* Short response means not associated */
	if (atoi(cmdStr) <= 2){
		strcpy(bssidResp.cmdru.bssid, "00:00:00:00:00:00");
	} else {
		if ((tmpfd = popen("/tmp/ASD/wl bssid", "r")) == NULL){
			printf("bassid failed\n");
		}
		fgets(cmdStr, sizeof(cmdStr), tmpfd);
		pclose(tmpfd);
		cmdStr[17] = 0;	/* Get rid of CR or NL */
		strcpy(bssidResp.cmdru.bssid, cmdStr);
	}
	bssidResp.status = STATUS_COMPLETE; 

	wfaEncodeTLV(WFA_STA_GET_BSSID_RESP_TLV, sizeof(bssidResp), 
		(BYTE *)&bssidResp, respBuf);   
	*respLen = WFA_TLV_HDR_LEN + sizeof(bssidResp);
	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)
{
	int ret = 0;
	caStaGetStatsResp_t statsResp;
	FILE *fd;
	char cmdStr[256];

	DPRINT_INFO(WFA_OUT, "Entering wfaStaGetStats ...\n");

	if ((fd = popen("/tmp/ASD/wl dump stats | grep txframe | awk '{print $2,\"\\n\",$10}'", "r")) == NULL){
		DPRINT_ERR(WFA_ERR, "Couldn't get txframe stats\n");
		goto wfaStaGetStats_error;
	} else {
		fgets(cmdStr, sizeof(cmdStr), fd);	/* line 1: tx frame */
		statsResp.txFrames =  atoi(cmdStr);
		fgets(cmdStr, sizeof(cmdStr), fd);	/* line 2: rx frame */
		statsResp.rxFrames =  atoi(cmdStr);
		pclose(fd);
	}

	if ((fd = popen("/tmp/ASD/wl dump stats | grep txmulti | awk '{print $4, \"\\n\", $6 + $8}'", "r")) == NULL){
		DPRINT_ERR(WFA_ERR, "Couldn't get d11_txmulti stats\n");
		goto wfaStaGetStats_error;
	} else {
		fgets(cmdStr, sizeof(cmdStr), fd);	/* line 1: txmulti */
		statsResp.txMulticast = atoi(cmdStr);
		fgets(cmdStr, sizeof(cmdStr), fd);	/* line 2: d11_txretry + d11_txretrie */
		statsResp.txRetries = atoi(cmdStr);
		pclose(fd);
	}

	if ((fd = popen("/tmp/ASD/wl dump stats | grep rxdfrmmcast | awk '{print $6 + $8}'", "r")) == NULL){
		DPRINT_ERR(WFA_ERR, "Couldn't get rxdfrmmcast stats\n");
		goto wfaStaGetStats_error;
	} else {
		fgets(cmdStr, sizeof(cmdStr), fd);	/* data + mngment mcast frames */
		statsResp.rxMulticast = atoi(cmdStr);
		pclose(fd);
	}

	if ((fd = popen("/tmp/ASD/wl dump stats | grep rxbadfcs | awk '{print $8}'", "r")) == NULL){
		DPRINT_ERR(WFA_ERR, "Couldn't get rxbadfcs  stats\n");
		goto wfaStaGetStats_error;
	} else {
		fgets(cmdStr, sizeof(cmdStr), fd);
		statsResp.fcsErrors = atoi(cmdStr);
		pclose(fd);
	}

	statsResp.status = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_GET_STATS_RESP_TLV, sizeof(statsResp), (BYTE *)&statsResp, respBuf);   
	*respLen = WFA_TLV_HDR_LEN + sizeof(statsResp);
	return TRUE;

wfaStaGetStats_error:
	ret = STATUS_ERROR;
	wfaEncodeTLV(WFA_STA_GET_STATS_RESP_TLV, 4, (BYTE *)&ret, respBuf);   
	*respLen = WFA_TLV_HDR_LEN + 4;
	return FALSE;
}

/*
 * 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 : 1, 2, 3, or 4
 */
int wfaSetEncryption(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	int ret = 0;
	int retVal = TRUE;
	caStaSetEncryption_t *setEncryp = (caStaSetEncryption_t *)caCmdBuf;
	int idx;
	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 {
			bzero(bso->keys[idx], 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:	
	ret = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_ENCRYPTION_RESP_TLV, 4, (BYTE *)&ret, respBuf);
	*respLen = WFA_TLV_HDR_LEN + 4;
	
	return retVal;
}

/*
 * 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)
{
   int ret = 0;
   caStaSetEapTLS_t *setTLS = (caStaSetEapTLS_t *)caCmdBuf;
   char cmdStr[WFA_CMD_STR_SZ];
   char *ifname = setTLS->intf;

   DPRINT_INFO(WFA_OUT, "Entering wfaStaSetEapTLS ...\n");

   /*
    * need to store the trustedROOTCA and clientCertificate into a file first.
    */
   sprintf(cmdStr, "wpa_cli -i %s disable_network 0", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   /* ssid */
   sprintf(cmdStr, "wpa_cli -i %s set_network 0 ssid '\"%s\"'", ifname, setTLS->ssid);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   /* key management */
   sprintf(cmdStr, "wpa_cli -i %s set_network 0 key_mgmt WPA-EAP", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   /* protocol WPA */
   sprintf(cmdStr, "wpa_cli -i %s set_network 0 proto WPA", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 eap TLS", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 ca_cert '\"%s\"'", ifname, setTLS->trustedRootCA);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 identity '\"wifi-user@wifilabs.local\"'", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 private_key '\"%s/%s\"'", ifname, CERTIFICATES_PATH, setTLS->clientCertificate);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 private_key_passwd '\"wifi\"'", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s enable_network 0", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   ret = STATUS_COMPLETE;
   wfaEncodeTLV(WFA_STA_SET_EAPTLS_RESP_TLV, 4, (BYTE *)&ret, 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)
{
	int ret = 0;
	int retVal = TRUE;
	caStaSetPSK_t *setPSK = (caStaSetPSK_t *)caCmdBuf;
	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);

	strcpy((char *)bso->passphrase, (char *)setPSK->passphrase);
	bso->auth = 0;

	if (wfa_defined_debug & (WFA_DEBUG_ERR | WFA_DEBUG_INFO)) {
		bcmWfaSsidObjPrint(bso);
	}

	retVal = TRUE;

exit:	
	ret = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_PSK_RESP_TLV, 4, (BYTE *)&ret, respBuf);   
	*respLen = WFA_TLV_HDR_LEN + 4;
	
	return retVal; 
}

/*
 * 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;

   /*
    * Normally this is called to retrieve the vendor information
    * from a interface, no implement yet
    */
   sprintf(infoResp.cmdru.info, "interface,%s,vendor,XXX,cardtype,802.11a/b/g", 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);

    DPRINT_INFO(WFA_OUT, "%s\n", infoResp.cmdru.info);

   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)
{
   int ret = 0;
   char cmdStr[WFA_CMD_STR_SZ];
   caStaSetEapTTLS_t *setTTLS = (caStaSetEapTTLS_t *)caCmdBuf;
   char *ifname = setTTLS->intf;

   sprintf(cmdStr, "wpa_cli -i %s disable_network 0", ifname);
   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 ssid '\"%s\"'", ifname, setTTLS->ssid);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 identity '\"%s\"'", ifname, setTTLS->username);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 password '\"%s\"'", ifname, setTTLS->passwd);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 key_mgmt WPA-EAP", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

/* This may not need to set. if it is not set, default to take all */
//   sprintf(cmdStr, "wpa_cli -i %s set_network 0 pairwise '\"%s\"", ifname, setTTLS->encrptype);
//   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 eap TTLS", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 ca_cert '\"%s/%s\"'", ifname, CERTIFICATES_PATH, setTTLS->trustedRootCA);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 proto WPA", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 anonymous_identity '\"anonymous\"'", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 phase2 '\"auth=MSCHAPV2\"'", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s enable_network 0", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   ret = STATUS_COMPLETE;
   wfaEncodeTLV(WFA_STA_SET_EAPTTLS_RESP_TLV, 4, (BYTE *)&ret, 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)
{
   int ret = 0;
   char cmdStr[WFA_CMD_STR_SZ];
   caStaSetEapSIM_t *setSIM = (caStaSetEapSIM_t *)caCmdBuf;
   char *ifname = setSIM->intf;

   sprintf(cmdStr, "wpa_cli -i %s disable_network 0", ifname);
   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 ssid '\"%s\"'", ifname, setSIM->ssid);
   system(cmdStr);


   sprintf(cmdStr, "wpa_cli -i %s set_network 0 identity '\"%s\"'", ifname, setSIM->username);
   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 key_mgmt WPA-EAP", ifname);
   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 pairwise '\"%s\"'", ifname, setSIM->encrptype);
   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 eap SIM", ifname);
   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 proto WPA", ifname);
   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s enable_network 0", ifname);
   system(cmdStr);

   ret = STATUS_COMPLETE;
   wfaEncodeTLV(WFA_STA_SET_EAPSIM_RESP_TLV, 4, (BYTE *)&ret, respBuf);
   *respLen = WFA_TLV_HDR_LEN + 4;

   return ret;
}

/*
 * 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)
{
   int ret = 0;
   char cmdStr[WFA_CMD_STR_SZ];
   caStaSetEapPEAP_t *setPEAP = (caStaSetEapPEAP_t *)caCmdBuf;
   char *ifname = setPEAP->intf;

   sprintf(cmdStr, "wpa_cli -i %s disable_network 0", ifname);
   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 ssid '\"%s\"'", ifname, setPEAP->ssid);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 eap PEAP", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 anonymous_identity '\"anonymous\"' ", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 identity '\"%s\"'", ifname, setPEAP->username);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 password '\"%s\"'", ifname, setPEAP->passwd);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 ca_cert '\"%s/%s\"'", ifname, CERTIFICATES_PATH, setPEAP->trustedRootCA);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   /* if this not set, default to set support all */
   //sprintf(cmdStr, "wpa_cli -i %s set_network 0 pairwise '\"%s\"'", ifname, setPEAP->encrptype);
   //system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 key_mgmt WPA-EAP", ifname);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 phase1 '\"peaplabel=%i\"'", ifname, setPEAP->peapVersion);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s set_network 0 phase2 '\"auth=%s\"'", ifname, setPEAP->innerEAP);
   system(cmdStr);
   DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

//   sprintf(cmdStr, "wpa_cli -i %s set_network 0 proto WPA", ifname);
//   system(cmdStr);

   sprintf(cmdStr, "wpa_cli -i %s enable_network 0", ifname);
   system(cmdStr);

   ret = STATUS_COMPLETE;
   wfaEncodeTLV(WFA_STA_SET_PEAP_RESP_TLV, 4, (BYTE *)&ret, 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 ret = 0;
	int retVal = TRUE;
	caStaSetUAPSD_t *uapsd = (caStaSetUAPSD_t *)caCmdBuf;
	bcmSsidObj_t *bso;
	char *ssidStr;

	DPRINT_INFO(WFA_OUT, "maxSPLength %d acBE %d acBK %d acVI %d acVO %d\n",
		uapsd->maxSPLength, uapsd->acBE, uapsd->acBK, uapsd->acVI, uapsd->acVO);

	ssidStr = uapsd->ssid;

	if (!(bso = bcmWfaSsidTblSsidFind(ssidStr))) {
		if (!(bso = bcmWfaSsidObjTblAdd(ssidStr))) {
			DPRINT_INFO(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed.\n", ssidStr);
			retVal = FALSE;
			goto exit;
		}
	}

	bso->maxSPLength = uapsd->maxSPLength;
	bso->acBE = uapsd->acBE;
	bso->acBK = uapsd->acBK;
	bso->acVI = uapsd->acVI;
	bso->acVO = uapsd->acVO;

exit:
	ret = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_UAPSD_RESP_TLV, 4, (BYTE *)&ret, respBuf);   
	*respLen = WFA_TLV_HDR_LEN + 4;

	return retVal;
}

/*
 * 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
 */

/* Not sure what the intention is, but I am using this routine
 * as storing info only, no action.  Action is taken when we actually associate */
int wfaStaSetIBSS(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	int ret;
	int retVal = TRUE;
	caStaSetIBSS_t *setIBSS = (caStaSetIBSS_t *)caCmdBuf;
	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 {
			bzero(bso->keys[idx], 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:
	ret = STATUS_COMPLETE;
	wfaEncodeTLV(WFA_STA_SET_IBSS_RESP_TLV, 4, (BYTE *)&ret, respBuf);   
	*respLen = WFA_TLV_HDR_LEN + 4;
	
	return retVal;
}

int wfaDeviceGetInfo(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
	caDeviceGetInfoResp_t dinfo;
	char cmdStr[WFA_CMD_STR_SZ];
	FILE *fd;

	if ((fd = popen("/tmp/ASD/wl ver | awk '{print $7}'", "r")) == NULL){
		printf("Couldn't open either /tmp/ASD/wl or awk\n");
		dinfo.status = STATUS_ERROR;
	} else {
		memset(&dinfo, 0, sizeof(dinfo));

		fgets(cmdStr, sizeof(cmdStr), fd);	/* Ignore first line */
		fgets(cmdStr, sizeof(cmdStr), fd);
		cmdStr[strlen(cmdStr) - 1] = 0;		/* Get rid of NL */
		pclose(fd);

	   dinfo.status = STATUS_COMPLETE;
	   sprintf(dinfo.vendor, "%.16s", "Broadcom");

	   sprintf(dinfo.version, "%.16s", cmdStr);
	   sprintf(dinfo.model, "%.8s", "BRCM");

	   DPRINT_INFO(WFA_OUT, "Entering wfaDeviceGetInfo ...\n");

	   DPRINT_INFO(WFA_OUT, "status %i vendor %s model %s version %s\n", dinfo.status, dinfo.vendor, dinfo.model, dinfo.version);

	   wfaEncodeTLV(WFA_DEVICE_GET_INFO_RESP_TLV, sizeof(dinfo), (BYTE *)&dinfo, respBuf);   
	   *respLen = WFA_TLV_HDR_LEN + sizeof(dinfo);

   }
   return TRUE;

}

/*
 * 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)
{
   int ret;
   dutCommand_t *ifList = (dutCommand_t *)caCmdBuf;
   caDeviceListIFResp_t ifListResp;

   switch(ifList->cmdsu.iftype)
   {
      case IF_80211:
      ifListResp.status = STATUS_COMPLETE;
      ifListResp.iftype = IF_80211; 
      strcpy(ifListResp.ifs[0], "eth1");
      strcpy(ifListResp.ifs[1], "NULL");
      strcpy(ifListResp.ifs[2], "NULL");
      break;
      case IF_ETH:
      ifListResp.status = STATUS_COMPLETE;
      ifListResp.iftype = IF_ETH; 
      strcpy(ifListResp.ifs[0], "eth0");
      strcpy(ifListResp.ifs[1], "NULL");
      strcpy(ifListResp.ifs[2], "NULL");
      break;
      default:
      {
         ret = STATUS_ERROR;
         wfaEncodeTLV(WFA_DEVICE_LIST_IF_RESP_TLV, 4, (BYTE *)&ret, respBuf);   
         *respLen = WFA_TLV_HDR_LEN + 4;

         return TRUE; 
      }
   }
   
   wfaEncodeTLV(WFA_DEVICE_LIST_IF_RESP_TLV, sizeof(ifListResp), (BYTE *)&ifListResp, respBuf);   
   *respLen = WFA_TLV_HDR_LEN + sizeof(ifListResp);

   return TRUE;
}

int wfaStaDebugSet(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf)
{
   dutCmdResponse_t debugResp;
   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(debugResp), (BYTE *)&debugResp, respBuf);   
   *respLen = WFA_TLV_HDR_LEN + sizeof(debugResp);

    DPRINT_INFO(WFA_OUT, "%s\n", debugResp.cmdru.info);

   return TRUE;
}

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;

	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);
	}	

	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 */

	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);

	bzero(bso, 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]);
	}
}

void bcmWfaInit(void)
{
	char cmdStr[WFA_CMD_STR_SZ];
#ifdef BCMWFA_TEST
	int idx;
	char ssidStr[64];
	bcmSsidObj_t *bso;
#endif /* def BCMWFA_TEST */

	bzero(&bsotbl, sizeof(bsotbl));
	sprintf(cmdStr, "/tmp/ASD/wl down");
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl ap 0"); /* not AP */
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl radio on"); /* not AP */
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl wsec 0");
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl auth 0");
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl wpa_auth 0");
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl sup_wpa 1"); /* enable in-driver supplicant */
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

	sprintf(cmdStr, "/tmp/ASD/wl up");
	system(cmdStr);
	DPRINT_INFO(WFA_OUT, "%s\n", cmdStr);

#ifdef BCMWFA_TEST
	bcmWfaSsidObjTblPrint();

	fprintf(WFA_OUT, "add SSIDs\n");
	for (idx = 0; idx < 2 * WFA_SSID_NAME_LEN; idx++) {
		sprintf(ssidStr, "ssid_%d", idx);
		fprintf(WFA_OUT, "adding %s\n", ssidStr);
		if (!(bso = bcmWfaSsidObjTblAdd(ssidStr))) {
			fprintf(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidStr);
		}
	}
	bcmWfaSsidObjTblPrint();

	fprintf(WFA_OUT, "add SSIDs again\n");
	for (idx = 0; idx < 2 * WFA_SSID_NAME_LEN; idx++) {
		sprintf(ssidStr, "ssid_%d", idx);
		fprintf(WFA_OUT, "ssid %s\n", ssidStr);
		if (!(bso = bcmWfaSsidObjTblAdd(ssidStr))) {
			fprintf(WFA_OUT, "bcmWfaSsidObjTblAdd(%s) failed\n", ssidStr);
		}
	}
	bcmWfaSsidObjTblPrint();

	fprintf(WFA_OUT, "delete SSIDs\n");
	for (idx = 2 * WFA_SSID_NAME_LEN; idx >= 0; idx--) {
		sprintf(ssidStr, "ssid_%d", idx);
		bcmWfaSsidObjTblDel(ssidStr);
	}
	bcmWfaSsidObjTblPrint();

	fprintf(WFA_OUT, "delete SSIDs again\n");
	for (idx = 2 * WFA_SSID_NAME_LEN; idx >= 0; idx--) {
		sprintf(ssidStr, "ssid_%d", idx);
		bcmWfaSsidObjTblDel(ssidStr);
	}
	bcmWfaSsidObjTblPrint();
#endif /* def BCMWFA_TEST */
}
