blob: c7369877daa7a51a441898e99f5f539f9db2f3b9 [file] [log] [blame]
/****************************************************************************
* (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 */
}