blob: d084c4144531e19a63939853197184ccd58df3b1 [file] [log] [blame]
/****************************************************************************
* (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)..AN 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..AN 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..AN Wi-Fi Alliance
* reserves all rights not expressly granted herein..AN
*.AN
* 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.
*.AN
* 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.
*.AN
* 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.AN 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;
}