/**************************************************************************** | |
* (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 */ | |
} |