/* * 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; }
/* * 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; }
/* * tgStopPing(): Instruct Traffic Generator to stop ping packets * */ int wfaTGStopPing(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf) { int streamid = *(int *)(caCmdBuf); dutCmdResponse_t *stpResp = &gGenericResp; tgStream_t *myStream; int i; stpResp->status = STATUS_COMPLETE; printf("CS: The length %d\n and the command buff is \n",len); for (i=0;i<8;i++) printf(" %x ",caCmdBuf[i]); printf("\nthe stream id is %d",streamid); if( gtgTransac == streamid&>gSend == streamid) { gtgTransac =0; gtgSend = 0; // gtimeOut = 0; gtgRecv = 0; alarm(0); myStream = findStreamProfile(streamid); if(myStream == NULL) { stpResp->status = STATUS_INVALID; } stpResp->cmdru.pingStp.sendCnt = myStream->stats.txFrames; stpResp->cmdru.pingStp.repliedCnt = myStream->stats.rxFrames; } else { #if 0 if(wfaStopPing(stpResp, streamid)== FALSE) { stpResp->status = STATUS_COMPLETE; wfaEncodeTLV(WFA_TRAFFIC_STOP_PING_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)stpResp, respBuf); *respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t); } #endif if(cmd_traffic_stop_ping(sigma_dut_ptr(), streamid, stpResp) < 0){ stpResp->status = STATUS_ERROR; *respLen = 0; return FALSE; } //wfaStopPing(stpResp, streamid); } wfaEncodeTLV(WFA_TRAFFIC_STOP_PING_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)stpResp, respBuf); *respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t); return TRUE; }
/* * wfaTGConfig: store the traffic profile setting that will be used to * instruct traffic generation. * input: cmd -- not used * response: send success back to controller * return: success or fail * Note: the profile storage is a global space. */ int wfaTGConfig(int len, BYTE *caCmdBuf, int *respLen, BYTE *respBuf) { int ret = FALSE; tgStream_t *myStream = NULL; dutCmdResponse_t *confResp = &gGenericResp; /* if the stream table over maximum, reset it */ if(slotCnt == WFA_MAX_TRAFFIC_STREAMS) slotCnt = 0; if(slotCnt == 0) { printf("resetting stream table\n"); wMEMSET(gStreams, 0, WFA_MAX_TRAFFIC_STREAMS*sizeof(tgStream_t)); } DPRINT_INFO(WFA_OUT, "entering tcConfig ...\n"); myStream = &gStreams[slotCnt++]; wMEMSET(myStream, 0, sizeof(tgStream_t)); wMEMCPY(&myStream->profile, caCmdBuf, len); myStream->id = ++streamId; /* the id start from 1 */ myStream->tblidx = slotCnt-1; #if 0 DPRINT_INFO(WFA_OUT, "profile %i direction %i dest ip %s dport %i source %s sport %i rate %i duration %i size %i class %i delay %i\n", myStream->profile.profile, myStream->profile.direction, myStream->profile.dipaddr, myStream->profile.dport, myStream->profile.sipaddr, myStream->profile.sport, myStream->profile.rate, myStream->profile.duration, myStream->profile.pksize, myStream->profile.trafficClass, myStream->profile.startdelay); #endif confResp->status = STATUS_COMPLETE; confResp->streamId = myStream->id; wfaEncodeTLV(WFA_TRAFFIC_AGENT_CONFIG_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)confResp, respBuf); *respLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t); return ret; }
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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* 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; }
/* * collects the traffic statistics from other threads and * sends the collected information to CA */ void wfaSentStatsResp(int sock, BYTE *buf) { int i, total=0, pkLen; tgStream_t *allStreams = gStreams; dutCmdResponse_t *sendStatsResp = (dutCmdResponse_t *)buf, *first; char buff[WFA_RESP_BUF_SZ]; if(sendStatsResp == NULL) return; first = sendStatsResp; for(i = 0; i < WFA_MAX_TRAFFIC_STREAMS; i++) { if((allStreams->id != 0) && (allStreams->profile.direction == DIRECT_SEND) && (allStreams->state == WFA_STREAM_ACTIVE)) { sendStatsResp->status = STATUS_COMPLETE; sendStatsResp->streamId = allStreams->id; printf("stats stream id %i\n", allStreams->id); wMEMCPY(&sendStatsResp->cmdru.stats, &allStreams->stats, sizeof(tgStats_t)); sendStatsResp++; total++; } allStreams->state = WFA_STREAM_INACTIVE; allStreams++; } #if 1 printf("%u %u %llu %llu\n", first->cmdru.stats.txFrames, first->cmdru.stats.rxFrames, first->cmdru.stats.txPayloadBytes, first->cmdru.stats.rxPayloadBytes); #endif wfaEncodeTLV(WFA_TRAFFIC_AGENT_SEND_RESP_TLV, total*sizeof(dutCmdResponse_t), (BYTE *)first, (BYTE *)buff); pkLen = WFA_TLV_HDR_LEN + total*sizeof(dutCmdResponse_t); printf("pkLen %i\n", pkLen); #if 0 for(i = 0; i< pkLen; i++) printf("%x ", buff[i]); printf("\n"); #endif if(wfaCtrlSend(sock, (BYTE *)buff, pkLen) != pkLen) { DPRINT_WARNING(WFA_WNG, "wfaCtrlSend Error\n"); } return; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
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; }
/* * 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; }
/* RecvStart: instruct traffic generator to start receiving * based on a profile * input: cmd -- not used * response: inform controller for "running" * return: success or failed */ int wfaTGRecvStart(int len, BYTE *parms, int *respLen, BYTE *respBuf) { int status = STATUS_COMPLETE, i; int numStreams = len/4; int streamid; tgProfile_t *theProfile; tgStream_t *myStream; DPRINT_INFO(WFA_OUT, "entering tgRecvStart\n"); /* * The function wfaSetProcPriority called here is to enhance the real-time * performance for packet receiving. It is only for tuning and optional * to implement */ //wfaSetProcPriority(60); for(i=0; i<numStreams; i++) { wMEMCPY(&streamid, parms+(4*i), 4); /* changed from 2 to 4, bug reported by n.ojanen */ myStream = findStreamProfile(streamid); if(myStream == NULL) { status = STATUS_INVALID; return status; } theProfile = &myStream->profile; if(theProfile == NULL) { status = STATUS_INVALID; return status; } /* calculate the frame interval which is used to derive its jitter */ if(theProfile->rate != 0 && theProfile->rate < 5000) myStream->fmInterval = 1000000/theProfile->rate; /* in ms */ else myStream->fmInterval = 0; if(theProfile->direction != DIRECT_RECV) { status = STATUS_INVALID; return status; } wMEMSET(&myStream->stats, 0, sizeof(tgStats_t)); // mark the stream active myStream->state = WFA_STREAM_ACTIVE; switch(theProfile->profile) { #ifdef WFA_WPA2_SINGLE_THREAD case PROF_MCAST: case PROF_FILE_TX: // case PROF_IPTV: btSockfd = wfaCreateUDPSock(theProfile->dipaddr, theProfile->dport); gtgRecv = streamid; if(btSockfd < 0) status = STATUS_ERROR; else { /* get current flags setting */ int ioflags = wFCNTL(btSockfd, F_GETFL, 0); /* set only BLOCKING flag to non-blocking */ wFCNTL(btSockfd, F_SETFL, ioflags | O_NONBLOCK); } break; #else case PROF_TRANSC: case PROF_CALI_RTD: /* Calibrate roundtrip delay */ gtgTransac = streamid; case PROF_MCAST: case PROF_FILE_TX: case PROF_IPTV: gtgRecv = streamid; wmm_thr[usedThread].thr_flag = streamid; wPT_MUTEX_LOCK(&wmm_thr[usedThread].thr_flag_mutex); wPT_COND_SIGNAL(&wmm_thr[usedThread].thr_flag_cond); wPT_MUTEX_UNLOCK(&wmm_thr[usedThread].thr_flag_mutex); printf("Recv Start in thread %i for streamid %i\n", usedThread, streamid); usedThread++; break; #endif case PROF_UAPSD: #ifdef WFA_WMM_PS_EXT status = STATUS_COMPLETE; psSockfd = wfaCreateUDPSock(theProfile->dipaddr, WFA_WMMPS_UDP_PORT); wmmps_info.sta_state = 0; wmmps_info.wait_state = WFA_WAIT_STAUT_00; wMEMSET(&wmmps_info.psToAddr, 0, sizeof(wmmps_info.psToAddr)); wmmps_info.psToAddr.sin_family = AF_INET; wmmps_info.psToAddr.sin_addr.s_addr = inet_addr(theProfile->sipaddr); wmmps_info.psToAddr.sin_port = htons(theProfile->sport); wmmps_info.reset = 0; wmm_thr[usedThread].thr_flag = streamid; wmmps_info.streamid = streamid; wPT_MUTEX_LOCK(&wmm_thr[usedThread].thr_flag_mutex); wPT_COND_SIGNAL(&wmm_thr[usedThread].thr_flag_cond); gtgWmmPS = streamid;; wPT_MUTEX_UNLOCK(&wmm_thr[usedThread].thr_flag_mutex); usedThread++; #endif /* WFA_WMM_PS_EXT */ break; } } /* encode a TLV for response for "complete/error ..." */ wfaEncodeTLV(WFA_TRAFFIC_AGENT_RECV_START_RESP_TLV, sizeof(int), (BYTE *)&status, respBuf); *respLen = WFA_TLV_HDR_LEN + sizeof(int); return TRUE; }
/* * tgRecvStop: instruct traffic generator to stop receiving based on a profile * input: cmd -- not used * response: inform controller for "complete" * return: success or failed */ int wfaTGRecvStop(int len, BYTE *parms, int *respLen, BYTE *respBuf) { int status = STATUS_COMPLETE, i; int numStreams = len/4; unsigned int streamid; tgProfile_t *theProfile; tgStream_t *myStream=NULL; dutCmdResponse_t statResp; BYTE dutRspBuf[WFA_RESP_BUF_SZ]; int id_cnt = 0; DPRINT_INFO(WFA_OUT, "entering tgRecvStop with length %d\n",len); /* in case that send-stream not done yet, an optional delay */ while(sendThrId != 0) sleep(1); /* * After finishing the receiving command, it should lower itself back to * normal level. It is optional implementation if it is not called * while it starts receiving for raising priority level. */ //wfaSetProcPriority(30); wMEMSET(dutRspBuf, 0, WFA_RESP_BUF_SZ); for(i=0; i<numStreams; i++) { wMEMCPY(&streamid, parms+(4*i), 4); printf(" stop stream id %i\n", streamid); myStream = findStreamProfile(streamid); if(myStream == NULL) { status = STATUS_INVALID; wfaEncodeTLV(WFA_TRAFFIC_AGENT_RECV_STOP_RESP_TLV, 4, (BYTE *)&status, respBuf); *respLen = WFA_TLV_HDR_LEN + 4; printf("stream table empty\n"); continue; } theProfile = &myStream->profile; if(theProfile == NULL) { status = STATUS_INVALID; wfaEncodeTLV(WFA_TRAFFIC_AGENT_RECV_STOP_RESP_TLV, 4, (BYTE *)&status, respBuf); *respLen = WFA_TLV_HDR_LEN + 4; return TRUE; } if(theProfile->direction != DIRECT_RECV) { status = STATUS_INVALID; wfaEncodeTLV(WFA_TRAFFIC_AGENT_RECV_STOP_RESP_TLV, 4, (BYTE *)&status, respBuf); *respLen = WFA_TLV_HDR_LEN + 4; return TRUE; } /* reset its flags , close sockets */ switch(theProfile->profile) { case PROF_TRANSC: case PROF_CALI_RTD: gtgTransac = 0; case PROF_MCAST: case PROF_FILE_TX: case PROF_IPTV: gtgRecv = 0; if(tgSockfds[myStream->tblidx] != -1) { wCLOSE(tgSockfds[myStream->tblidx]); tgSockfds[myStream->tblidx] = -1; } break; case PROF_UAPSD: #ifdef WFA_WMM_PS_EXT gtgWmmPS = 0; gtgPsPktRecvd = 0; if(psSockfd != -1) { wCLOSE(psSockfd); psSockfd = -1; } wMEMSET(&wmmps_info, 0, sizeof(wfaWmmPS_t)); wfaSetDUTPwrMgmt(PS_OFF); #endif /* WFA_WMM_PS_EXT */ break; } /* encode a TLV for response for "complete/error ..." */ statResp.status = STATUS_COMPLETE; statResp.streamId = streamid; #if 1 DPRINT_INFO(WFA_OUT, "stream Id %u rx %u total %llu\n", streamid, myStream->stats.rxFrames, myStream->stats.rxPayloadBytes); #endif wMEMCPY(&statResp.cmdru.stats, &myStream->stats, sizeof(tgStats_t)); wMEMCPY((dutRspBuf + i * sizeof(dutCmdResponse_t)), (BYTE *)&statResp, sizeof(dutCmdResponse_t)); id_cnt++; // Not empty it but require to reset the entire table before test starts. //wMEMSET(myStream, 0, sizeof(tgStream_t)); } // mark the stream inactive myStream->state = WFA_STREAM_INACTIVE; printf("Sending back the statistics at recvstop\n"); wfaEncodeTLV(WFA_TRAFFIC_AGENT_RECV_STOP_RESP_TLV, id_cnt * sizeof(dutCmdResponse_t), dutRspBuf, respBuf); /* done here */ *respLen = WFA_TLV_HDR_LEN + numStreams * sizeof(dutCmdResponse_t); return TRUE; }
/* * 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 '\"[email protected]\"'", 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; }
/* * wfaTGSendStart: instruct traffic generator to start sending based on a profile * input: cmd -- not used * response: inform controller for "running" * return: success or failed */ int wfaTGSendStart(int len, BYTE *parms, int *respLen, BYTE *respBuf) { int i=0, streamid=0; int numStreams = len/4; tgProfile_t *theProfile; tgStream_t *myStream = NULL; dutCmdResponse_t staSendResp; DPRINT_INFO(WFA_OUT, "Entering tgSendStart for %i streams ...\n", numStreams); for(i=0; i<numStreams; i++) { wMEMCPY(&streamid, parms+(4*i), 4); myStream = findStreamProfile(streamid); if(myStream == NULL) { staSendResp.status = STATUS_INVALID; wfaEncodeTLV(WFA_TRAFFIC_AGENT_SEND_RESP_TLV, 4, (BYTE *)&staSendResp, respBuf); *respLen = WFA_TLV_HDR_LEN + 4; return TRUE; } theProfile = &myStream->profile; if(theProfile == NULL) { staSendResp.status = STATUS_INVALID; wfaEncodeTLV(WFA_TRAFFIC_AGENT_SEND_RESP_TLV, 4, (BYTE *)&staSendResp, respBuf); *respLen = WFA_TLV_HDR_LEN + 4; return TRUE; } if(theProfile->direction != DIRECT_SEND) { staSendResp.status = STATUS_INVALID; wfaEncodeTLV(WFA_TRAFFIC_AGENT_SEND_RESP_TLV, 4, (BYTE *)&staSendResp, respBuf); *respLen = WFA_TLV_HDR_LEN + 4; return TRUE; } /* * need to reset the stats */ wMEMSET(&myStream->stats, 0, sizeof(tgStats_t)); // mark the stream active; myStream->state = WFA_STREAM_ACTIVE; switch(theProfile->profile) { case PROF_FILE_TX: case PROF_MCAST: case PROF_TRANSC: gtgTransac = streamid; gtgSend = streamid; case PROF_CALI_RTD: gtgCaliRTD = streamid; case PROF_IPTV: gtgSend = streamid; /* * singal the thread to Sending WMM traffic */ //if(usedThread < wmm_thr[usedThread].thr_flag = streamid; wPT_MUTEX_LOCK(&wmm_thr[usedThread].thr_flag_mutex); wPT_COND_SIGNAL(&wmm_thr[usedThread].thr_flag_cond); wPT_MUTEX_UNLOCK(&wmm_thr[usedThread].thr_flag_mutex); usedThread++; //wfaSetProcPriority(90); break; } } *respLen = 0; return TRUE; }
int wfaTGReset(int len, BYTE *parms, int *respLen, BYTE *respBuf) { dutCmdResponse_t *resetResp = &gGenericResp; int i; /* need to reset all traffic socket fds */ if(btSockfd != -1) { wCLOSE(btSockfd); btSockfd = -1; } for(i = 0; i<WFA_MAX_TRAFFIC_STREAMS; i++) { if(tgSockfds[i] != -1) { wCLOSE(tgSockfds[i]); tgSockfds[i] = -1; } } /* reset the timer alarm if it was armed */ wALARM(0); /* just reset the flags for the command */ gtgRecv = 0; gtgSend = 0; gtgTransac = 0; #ifdef WFA_VOICE_EXT gtgCaliRTD = 0; min_rttime = 0xFFFFFFFF; gtgPktRTDelay = 0xFFFFFFFF; #endif totalTranPkts = 0; //gtimeOut = 0; runLoop = 0; usedThread = 0; #ifdef WFA_WMM_PS_EXT gtgWmmPS = 0; gtgPsPktRecvd = 0; if(psSockfd != -1) { wCLOSE(psSockfd); psSockfd = -1; } wMEMSET(&wmmps_info, 0, sizeof(wfaWmmPS_t)); // wfaSetDUTPwrMgmt(PS_OFF); #endif e2eResults[0] = '\0'; /* Also need to clean up WMM streams NOT DONE YET!*/ slotCnt = 0; /* reset stream profile container */ wMEMSET(gStreams, 0, WFA_MAX_TRAFFIC_STREAMS); /* * After be asked to reset, it should lower itself back to * normal level. It is optional implementation if it is not called * while it starts sending/receiving for raising priority level. */ //wfaSetProcPriority(20); /* encode a TLV for response for "complete ..." */ resetResp->status = STATUS_COMPLETE; wfaEncodeTLV(WFA_TRAFFIC_AGENT_RESET_RESP_TLV, 4, (BYTE *)resetResp, respBuf); *respLen = WFA_TLV_HDR_LEN + 4; return TRUE; }
/* This is going to be a blocking SEND till it finishes */ int wfaSendLongFile(int mySockfd, int streamid, BYTE *aRespBuf, int *aRespLen) { tgProfile_t *theProf = NULL; tgStream_t *myStream = NULL; struct sockaddr_in toAddr; char *packBuf; int packLen; int bytesSent; dutCmdResponse_t sendResp; int sleepTime = 0; int throttledRate = 0; struct timeval before, after,af; int difftime = 0, counter = 0; struct timeval stime; int throttled_est_cost; int act_sleep_time; gettimeofday(&af,0); DPRINT_INFO(WFA_OUT, "Entering sendLongFile %i\n", streamid); /* find the profile */ myStream = findStreamProfile(streamid); if(myStream == NULL) { return FALSE; } theProf = &myStream->profile; if(theProf == NULL) { return FALSE; } packLen = theProf->pksize; /* allocate a buf */ packBuf = (char *)malloc(packLen); wMEMSET(packBuf, 1, packLen); /* fill in the header */ wSTRNCPY(packBuf, "1345678", sizeof(tgHeader_t)); /* initialize the destination address */ wMEMSET(&toAddr, 0, sizeof(toAddr)); toAddr.sin_family = AF_INET; toAddr.sin_addr.s_addr = inet_addr(theProf->dipaddr); toAddr.sin_port = htons(theProf->dport); /* if a frame rate and duration are defined, then we know * interval for each packet and how many packets it needs to * send. */ if(theProf->duration != 0) { printf("duration %i\n", theProf->duration); /* * use this to decide periodical interval sleep time and frames to send * int the each interval. * Each device should adopt a own algorithm for better performance */ wfaTxSleepTime(theProf->profile, theProf->rate, &sleepTime, &throttledRate); /* * alright, we need to raise the priority level of the process * to improve the real-time performance of packet sending. * Since this is for tuning purpose, it is optional implementation. */ //wfaSetProcPriority(60); //interval = 1*1000000/theProf->rate ; // in usec; // Here assumes it takes 20 usec to send a packet throttled_est_cost = throttledRate * 20; // MUST estimate the cost per ppk act_sleep_time = sleepTime - adj_latency; if (act_sleep_time <= 0) act_sleep_time = sleepTime; printf("sleep time %i act_sleep_time %i\n", sleepTime, act_sleep_time); runLoop=1; while(runLoop) { counter++; /* fill in the counter */ int2BuffBigEndian(counter, &((tgHeader_t *)packBuf)->hdr[8]); /* * the following code is only used to slow down * over fast traffic flooding the buffer and cause * packet drop or the other end not able to receive due to * some limitations, purely for experiment purpose. * each implementation needs some fine tune to it. */ if(counter ==1) { wGETTIMEOFDAY(&before, NULL); before.tv_usec += sleepTime; if(before.tv_usec > 1000000) { before.tv_usec -= 1000000; before.tv_sec +=1; } } if(throttledRate != 0) { if(counter%throttledRate == 0) { wGETTIMEOFDAY(&after, NULL); difftime = wfa_itime_diff(&after, &before); if(difftime > adj_latency) { // too much time left, go sleep wUSLEEP(difftime-adj_latency); wGETTIMEOFDAY(&after, NULL); difftime = wfa_itime_diff(&after, &before); } // burn the rest to absort latency if(difftime >0) buzz_time(difftime); before.tv_usec += sleepTime; if(before.tv_usec > 1000000) { before.tv_usec -= 1000000; before.tv_sec +=1; } } } // otherwise, it floods /* * Fill the timestamp to the header. */ wGETTIMEOFDAY(&stime, NULL); int2BuffBigEndian(stime.tv_sec, &((tgHeader_t *)packBuf)->hdr[12]); int2BuffBigEndian(stime.tv_usec, &((tgHeader_t *)packBuf)->hdr[16]); bytesSent = wfaTrafficSendTo(mySockfd, packBuf, packLen, (struct sockaddr *)&toAddr); if(bytesSent != -1) { myStream->stats.txPayloadBytes += bytesSent; myStream->stats.txFrames++ ; } else { int errsv = errno; switch(errsv) { case EAGAIN: case ENOBUFS: DPRINT_ERR(WFA_ERR, "send error\n"); wUSLEEP(1000); /* hold for 1 ms */ counter-- ; myStream->stats.txFrames--; break; case ECONNRESET: runLoop = 0; break; case EPIPE: runLoop = 0; break; default: perror("sendto: "); DPRINT_ERR(WFA_ERR, "Packet sent error\n"); } } } /* * lower back to an original level if the process is raised previously * It is optional. */ //wfaSetProcPriority(30); } else /* invalid parameters */ { /* encode a TLV for response for "invalid ..." */ sendResp.status = STATUS_INVALID; wfaEncodeTLV(WFA_TRAFFIC_AGENT_SEND_RESP_TLV, 4, (BYTE *)&sendResp, (BYTE *)aRespBuf); /* done here */ *aRespLen = WFA_TLV_HDR_LEN + 4; return DONE; } gtgSend = 0; /* free the buffer */ wFREE(packBuf); //printf("done sending long\n"); /* return statistics */ sendResp.status = STATUS_COMPLETE; sendResp.streamId = myStream->id; wMEMCPY(&sendResp.cmdru.stats, &myStream->stats, sizeof(tgStats_t)); #if 0 DPRINT_INFO(WFA_OUT, "stream Id %u tx %u total %llu\n", myStream->id, myStream->stats.txFrames, myStream->stats.txPayloadBytes); #endif wfaEncodeTLV(WFA_TRAFFIC_AGENT_SEND_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)&sendResp, (BYTE *)aRespBuf); *aRespLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t); return DONE; }
void * wfa_wmm_thread(void *thr_param) { int myId = ((tgThrData_t *)thr_param)->tid; tgWMM_t *my_wmm = &wmm_thr[myId]; tgStream_t *myStream = NULL; int myStreamId, i=0,rttime=0,difftime=0, rcvCount=0,sendCount=0; int mySock = -1, status, respLen = 0, nbytes = 0, ret=0, j=0; tgProfile_t *myProfile; pthread_attr_t tattr; #ifdef WFA_WMM_PS_EXT tgThrData_t *tdata =(tgThrData_t *) thr_param; StationProcStatetbl_t curr_state; #endif //#ifdef WFA_VOICE_EXT struct timeval lstime, lrtime; int asn = 1; /* everytime it starts from 1, and to ++ */ //#endif wPT_ATTR_INIT(&tattr); wPT_ATTR_SETSCH(&tattr, SCHED_RR); while(1) { int sleepTotal=0,sendFailCount=0; DPRINT_INFO(WFA_OUT, "wfa_wmm_thread::begin while loop for each send/rcv before mutex lock\n"); pthread_mutex_lock(&my_wmm->thr_flag_mutex); /* it needs to reset the thr_flag to wait again */ while(my_wmm->thr_flag == 0) { printf("Mutex wait\n"); /* * in normal situation, the signal indicates the thr_flag changed to * a valid number (stream id), then it will go out the loop and do * work. */ wPT_COND_WAIT(&my_wmm->thr_flag_cond, &my_wmm->thr_flag_mutex); } wPT_MUTEX_UNLOCK(&my_wmm->thr_flag_mutex); myStreamId = my_wmm->thr_flag; my_wmm->thr_flag=0; /* use the flag as a stream id to file the profile */ myStream = findStreamProfile(myStreamId); myProfile = &myStream->profile; if(myProfile == NULL) { status = STATUS_INVALID; wfaEncodeTLV(WFA_TRAFFIC_AGENT_SEND_RESP_TLV, 4, (BYTE *)&status, respBuf); respLen = WFA_TLV_HDR_LEN+4; /* * send it back to control agent. */ continue; } DPRINT_INFO(WFA_OUT, "wfa_wmm_thread::Mutex unlocked\n"); switch(myProfile->direction) { case DIRECT_SEND: mySock = wfaCreateUDPSock(myProfile->sipaddr, myProfile->sport); if (mySock < 0) { DPRINT_INFO(WFA_OUT, "wfa_wmm_thread SEND ERROR failed create UDP socket! \n"); break; } mySock = wfaConnectUDPPeer(mySock, myProfile->dipaddr, myProfile->dport); sendThrId = myId; /* * Set packet/socket priority TOS field */ wfaTGSetPrio(mySock, myProfile->trafficClass); /* * set a proper priority */ wfaSetThreadPrio(myId, myProfile->trafficClass); /* if delay is too long, it must be something wrong */ if(myProfile->startdelay > 0 && myProfile->startdelay<100) { wSLEEP(myProfile->startdelay); } /* * set timer fire up */ if(myProfile->maxcnt == 0) { wSIGNAL(SIGALRM, tmout_stop_send); wALARM(myProfile->duration ); DPRINT_INFO(WFA_OUT, "wfa_wmm_thread SEND set stop alarm for %d sec \n", myProfile->duration); } if(myProfile->profile == PROF_MCAST) { wfaSetSockMcastSendOpt(mySock); } if (myProfile->profile == PROF_IPTV || myProfile->profile == PROF_FILE_TX || myProfile->profile == PROF_MCAST) { int iOptVal, iOptLen; getsockopt(mySock, SOL_SOCKET, SO_SNDBUF, (char *)&iOptVal, (socklen_t *)&iOptLen); iOptVal = iOptVal * 16; setsockopt(mySock, SOL_SOCKET, SO_SNDBUF, (char *)&iOptVal, (socklen_t )iOptLen); if ( (myProfile->rate != 0 ) /* WFA_SEND_FIX_BITRATE_MAX_FRAME_RATE)*/ && (myProfile->pksize * myProfile->rate * 8 < WFA_SEND_FIX_BITRATE_MAX) ) wfaSendBitrateData(mySock, myStreamId, respBuf, &respLen); else { wfaSendLongFile(mySock, myStreamId, respBuf, &respLen); } /* wfaSendLongFile(mySock, myStreamId, respBuf, &respLen); */ if(mySock != -1) { wCLOSE(mySock); mySock = -1; } } else if(myProfile->profile == PROF_TRANSC || myProfile->profile == PROF_START_SYNC || myProfile->profile == PROF_CALI_RTD) { #if 0 struct timeval nxtime, curtime; int ioflags = wFCNTL(mySock, F_GETFL, 0); #endif struct timeval tmout; gtgTransac = myStreamId; sentTranPkts = 0; #if 0 gettimeofday(&nxtime, NULL); nxtime.tv_usec += 20000; /* fixed 20 min sec timeout */ if(nxtime.tv_usec >= 1000000) { nxtime.tv_sec +=1; nxtime.tv_usec -= 1000000; } wFCNTL(mySock, F_SETFL, ioflags | O_NONBLOCK); #endif gettimeofday(&lstime,0); DPRINT_INFO(WFA_OUT, "Start sending traffic,at sec %d usec %d\n", (int )lstime.tv_sec, (int)lstime.tv_usec); tmout.tv_sec = 0; tmout.tv_usec = 15000; // set for 15000 microsec timeout for rcv ret = setsockopt(mySock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tmout, (socklen_t) sizeof(tmout)); rcvCount=0; sendFailCount=0; j=0; sendCount=0; sleepTotal = 0; while(gtgTransac != 0) { gettimeofday(&lstime, NULL); #ifdef WFA_VOICE_EXT /* * If your device is BIG ENDIAN, you need to * modify the the function calls */ int2BuffBigEndian(asn++, &((tgHeader_t *)trafficBuf)->hdr[8]); int2BuffBigEndian(lstime.tv_sec, &((tgHeader_t *)trafficBuf)->hdr[12]); int2BuffBigEndian(lstime.tv_usec, &((tgHeader_t *)trafficBuf)->hdr[16]); #else j++; i=0; do { #endif /* WFA_VOICE_EXT */ if(gtgTransac != 0/* && nbytes <= 0 */) { if(respBuf == NULL) { DPRINT_INFO(WFA_OUT, "wfa_wmm_thread SEND,PROF_TRANSC::a Null respBuf\n"); } memset(respBuf, 0, WFA_RESP_BUF_SZ); respLen = 0; memset(trafficBuf ,0, MAX_UDP_LEN + 1); if(wfaSendShortFile(mySock, myStreamId, trafficBuf, 0, respBuf, &respLen) == DONE) { if(wfaCtrlSend(gxcSockfd, respBuf, respLen) != respLen) { DPRINT_INFO(WFA_OUT, "wfa_wmm_thread SEND,PROF_TRANSC::wfaCtrlSend Error for wfaSendShortFile\n"); } sendFailCount++; i--; usleep(1000); } else { i++; sendCount++; } //sentTranPkts++; /* send routine already incresed this counter */ if((myProfile->maxcnt>0) &&(sendCount == myProfile->maxcnt)) { DPRINT_INFO(WFA_OUT, "wfa_wmm_thread SEND,PROF_TRANSC::meet maxcnt=%d; end loop\n",myProfile->maxcnt); gtgTransac = 0; /* break snd/rcv wile loop */ break; } nbytes = wfaRecvFile(mySock, myStreamId, (char *)trafficBuf); if(nbytes <= 0) {/* Do not print any msg it will slow down process on snd/rcv */ //setsockopt(mySock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tmout, (socklen_t) sizeof(tmout)); //printf("PROF_TRANSC::time out event, wfaRecvFile failed,resend a new packet ...\n"); //tmout.tv_sec = 0; //tmout.tv_usec = 3000; // set for 20 minlsec timeout //setsockopt(mySock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tmout, (socklen_t) sizeof(tmout)); #if 0 /* if your socket APIs does not support "recvfrom" timeout, this is the way to loop the descriptor */ gettimeofday(&curtime, NULL); if(((curtime.tv_sec - nxtime.tv_sec) * 1000000 + (curtime.tv_usec - nxtime.tv_usec)) < 20000) { continue; } nxtime.tv_usec = curtime.tv_usec += 20000; if(nxtime.tv_usec >= 1000000) { nxtime.tv_sec = curtime.tv_sec +=1; nxtime.tv_usec -= 1000000; } #endif //continue; } else { rcvCount++; nbytes = 0; } } /* if gtgTransac != 0 */ #ifdef WFA_VOICE_EXT /* * Roundtrip time delay: * 1. retrieve the timestamp * 2. calculate the Trt(1) roundtrip delay * 3. store the minimum Trt(1) * 4. store Cdut(t1) and Ctm(2) */ gettimeofday(&lrtime, NULL); /* get a round trip time */ rttime = wfa_ftime_diff(&lstime, &lrtime); if(min_rttime > rttime) { min_rttime = rttime; if(gtgCaliRTD != 0) { gtgPktRTDelay = min_rttime; } } if(gtgCaliRTD != 0 ) { usleep(20000); /* wait a few min seconds before retrying the next calibration */ } #else /* not voice case */ /* for do-while loop for frame rate per sec */ }while ((i <= myProfile->rate + myProfile->rate/3) && (myProfile->rate !=0) && (gtgTransac != 0 )); if(myProfile->maxcnt == 0) { gettimeofday(&lrtime, NULL); rttime = wfa_itime_diff(&lstime, &lrtime); /* we cover frame rate = 0 case without any sleep to continue push data */ if (((difftime = 1000000 - rttime) > 0) && (myProfile->rate != 0)) { if ( j < myProfile->duration) { usleep (difftime); sleepTotal = sleepTotal + difftime/1000; } } if (j > myProfile->duration + 2) { /* avoid infinite loop */ DPRINT_INFO(WFA_OUT, "wfa_wmm_thread SEND over time %d sec, stop sending\n",myProfile->duration); break; } } #endif /* WFA_VOICE_EXT */ } /* while */ if(mySock != -1) { wCLOSE(mySock); mySock = -1; } DPRINT_INFO(WFA_OUT, "wfa_wmm_thread SEND::Sending stats back, sendCount=%d rcvCount=%d sleepTotal in mil-sec=%d sendFailCount=%d frmRate=%d do count=%d\n", sendCount,rcvCount,sleepTotal,sendFailCount, myProfile->rate, j); }/* else if(myProfile->profile == PROF_TRANSC || myProfile->profile == PROF_START_SYNC || myProfile->profile == PROF_CALI_RTD) */ wMEMSET(respBuf, 0, WFA_RESP_BUF_SZ); wSLEEP(1); /* * uses thread that is saved at last to pack the items and ships * it to CA. */ if(myId == sendThrId) { wfaSentStatsResp(gxcSockfd, respBuf); printf("done stats\n"); sendThrId = 0; } break; case DIRECT_RECV: /* * Test WMM-PS */ if(myProfile->profile == PROF_UAPSD) { #ifdef WFA_WMM_PS_EXT /* legacy code not used now */ wmmps_info.sta_test = B_D; wmmps_info.ps_thread = myId; wmmps_info.rcv_state = 0; wmmps_info.tdata = tdata; wmmps_info.dscp = wfaTGSetPrio(psSockfd, TG_WMM_AC_BE); tdata->state_num=0; /* * default timer value */ while(gtgWmmPS>0) { if(resetsnd) { tdata->state_num = 0; resetsnd = 0; } if (wmmps_info.sta_test > LAST_TEST) break; tdata->state = stationProcStatetbl[wmmps_info.sta_test]; curr_state = tdata->state[tdata->state_num]; curr_state.statefunc(curr_state.pw_offon,curr_state.sleep_period,&(tdata->state_num)); } #endif /* WFA_WMM_PS_EXT */ } else if (myProfile->profile == PROF_IPTV || myProfile->profile == PROF_FILE_TX || myProfile->profile == PROF_MCAST) { char recvBuf[MAX_RCV_BUF_LEN+1]; int iOptVal, iOptLen; struct timeval tmout; #ifdef WFA_VOICE_EXT struct timeval currtime; FILE *e2eoutp = NULL; char e2eResults[124]; int le2eCnt = 0; #endif mySock = wfaCreateUDPSock(myProfile->dipaddr, myProfile->dport); if(mySock == -1) { printf("Error open socket\n"); continue; } if (myProfile->profile == PROF_MCAST) { int so = wfaSetSockMcastRecvOpt(mySock, myProfile->dipaddr); if(so < 0) { DPRINT_ERR(WFA_ERR, "Join the multicast group failed\n"); wCLOSE(mySock); continue; } } tgSockfds[myStream->tblidx] = mySock; #ifdef WFA_VOICE_EXT /* only for receive stream needs to create a stats storage */ tgE2EStats_t *e2esp = NULL; int totalE2Cnt = 220 * WFA_G_CODEC_RATE; printf("init E2Cnt %i\n", totalE2Cnt); if(myProfile->profile == PROF_IPTV) { e2esp = malloc(totalE2Cnt * sizeof(tgE2EStats_t)); if(e2esp == NULL) { } } #endif /* increase the rec queue size */ getsockopt(mySock, SOL_SOCKET, SO_RCVBUF, (char *)&iOptVal, (socklen_t *)&iOptLen); iOptVal = iOptVal * 10; setsockopt(mySock, SOL_SOCKET, SO_RCVBUF, (char *)&iOptVal, (socklen_t )iOptLen); /* set timeout for blocking receive */ tmout.tv_sec = 0; tmout.tv_usec = 200000; /* set the receive time out to 200 ms */ setsockopt(mySock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tmout, (socklen_t) sizeof(tmout)); wfaSetThreadPrio(myId, TG_WMM_AC_VO); /* try to raise the receiver higher priority than sender */ for(;;) { nbytes = wfaRecvFile(mySock, myStreamId, (char *)recvBuf); if(nbytes <= 0) { /* due to timeout */ if(tgSockfds[myStream->tblidx] >=0 ) continue; break; } #ifdef WFA_VOICE_EXT if(myProfile->profile == PROF_IPTV) { struct timeval ttval, currTimeVal; int sn = bigEndianBuff2Int(&((tgHeader_t *)recvBuf)->hdr[8]); ttval.tv_sec = bigEndianBuff2Int(&((tgHeader_t *)recvBuf)->hdr[12]); ttval.tv_usec = bigEndianBuff2Int(&((tgHeader_t *)recvBuf)->hdr[16]); gettimeofday(&currTimeVal, NULL); /* * take the end2end stats, limit to the max voice pkt number */ if(le2eCnt < totalE2Cnt) { tgE2EStats_t *ep = e2esp + le2eCnt++; ep->seqnum = sn; ep->rsec = ttval.tv_sec; ep->rusec = ttval.tv_usec; ep->lsec = currTimeVal.tv_sec; ep->lusec = currTimeVal.tv_usec; if(ep->lusec < 0) { ep->lsec -=1; ep->lusec += 1000000; } else if(ep->lusec >= 1000000) { ep->lsec += 1; ep->lusec -= 1000000; } } } #endif /* WFA_VOICE_EXT */ wfaSetThreadPrio(myId, TG_WMM_AC_BE); /* put it back down */ } /* while */ my_wmm->thr_flag = 0; #ifdef WFA_VOICE_EXT if(myProfile->profile == PROF_IPTV) { int j; wGETTIMEOFDAY(&currtime, NULL); sprintf(e2eResults, "/tmp/e2e%u-%i.txt", (unsigned int) currtime.tv_sec, myStreamId); printf("file %s cnt %i\n", e2eResults, le2eCnt); e2eoutp = fopen(e2eResults, "w+"); if(e2eoutp != NULL) { fprintf(e2eoutp, "roundtrip delay: %i\n", (int) (1000000*gtgPktRTDelay)); for(j = 0; j< le2eCnt; j++) { tgE2EStats_t *ep = e2esp+j; fprintf(e2eoutp, "%i:%i:%i:%i:%i\n", ep->seqnum, ep->lsec, ep->lusec, ep->rsec, ep->rusec); } fclose(e2eoutp); } if(e2esp != NULL) free(e2esp); } #endif } else if(myProfile->profile == PROF_TRANSC || myProfile->profile == PROF_START_SYNC || myProfile->profile == PROF_CALI_RTD) { struct timeval tmout; mySock = wfaCreateUDPSock(myProfile->sipaddr, myProfile->sport); if(mySock < 0) { /* return error */ my_wmm->thr_flag = 0; continue; } tgSockfds[myStream->tblidx] = mySock; totalTranPkts = 0xFFFFFFF0; gtgTransac = myStreamId; /* set timeout for blocking receive */ tmout.tv_sec = 0; tmout.tv_usec = 400000; /* set the receive time out to 400 ms, 200ms is too short */ setsockopt(mySock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tmout, (socklen_t) sizeof(tmout)); while(gtgTransac != 0) { memset(trafficBuf, 0, sizeof((char*)trafficBuf)); if(mySock != -1) { int i = gtgTransac; nbytes = 0; /* check for data as long as we are in a transaction */ while ((gtgTransac != 0) && (nbytes <= 0)) { nbytes = wfaRecvFile(mySock, i, (char *)trafficBuf); } /* It is the end of a transaction, go out of the loop */ if (gtgTransac == 0) break; } else { break; } #ifdef WFA_VOICE_EXT /* for a transaction receiver, it just needs to send the local time back */ gettimeofday(&lstime, NULL); int2BuffBigEndian(lstime.tv_sec, &((tgHeader_t *)trafficBuf)->hdr[12]); int2BuffBigEndian(lstime.tv_usec, &((tgHeader_t *)trafficBuf)->hdr[16]); #endif memset(respBuf, 0, WFA_RESP_BUF_SZ); respLen = 0; if(wfaSendShortFile(mySock, gtgTransac, trafficBuf, nbytes, respBuf, &respLen) == DONE) { if(wfaCtrlSend(gxcSockfd, (BYTE *)respBuf, respLen)!=respLen) { DPRINT_WARNING(WFA_WNG, "wfaCtrlSend Error\n"); } } } my_wmm->thr_flag = 0; //////////////////// Wifi Alliance Added if(mySock != -1) { wCLOSE(mySock); mySock = -1; } //////////////////// Wifi Alliance Added } break; default: DPRINT_ERR(WFA_ERR, "Unknown covered case\n"); } } }
/* * 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; }
/* * 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; }
/* * 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; }