/* * WfaStaWaitStop(): This function sends the stop packet on behalf of the * station, the idea is to keep sending the Stop * till a stop is recd from the console,the functions * quits after stop threshold reaches. */ int WfaStaWaitStop(char psave,int sleep_period,int *state) { int myid=wmmps_info.ps_thread; PRINTF("\n Entering Sendwait"); wUSLEEP(sleep_period); if(!num_stops) { wfaSetDUTPwrMgmt(psave); wfaTGSetPrio(psSockfd, TG_WMM_AC_BE); } num_stops++; create_apts_msg(APTS_STOP, psTxMsg,wmmps_info.my_sta_id); wSENDTO(psSockfd, psTxMsg, msgsize, 0, (struct sockaddr *)&wmmps_info.psToAddr, sizeof(struct sockaddr)); mpx("STA msg",psTxMsg,64); wmm_thr[myid].stop_flag = 1; wPT_MUTEX_LOCK(&wmm_thr[myid].thr_stop_mutex); wPT_COND_SIGNAL(&wmm_thr[myid].thr_stop_cond); wPT_MUTEX_UNLOCK(&wmm_thr[myid].thr_stop_mutex); if(num_stops > MAX_STOPS) { DPRINT_ERR(WFA_ERR, "Too many stops sent\n"); gtgWmmPS = 0; if(psSockfd != -1) { wCLOSE(psSockfd); psSockfd = -1; } wSIGNAL(SIGALRM, SIG_IGN); } return 0; }
/* * sender(): This is a generic function to send a packed for the given dsc * (ac:VI/VO/BE/BK), before sending the packet the function * puts the station into the PS mode indicated by psave and * sends the packet after sleeping for sllep_period */ int sender(char psave,int sleep_period, int userPriority) { int r; PRINTF("\nsender::sleeping for %d userPriority=%d psSockFd=%d",sleep_period, userPriority, psSockfd); wfaSetDUTPwrMgmt(psave); wUSLEEP(sleep_period); create_apts_msg(APTS_DEFAULT, psTxMsg,wmmps_info.my_sta_id); wfaTGSetPrio(psSockfd, userPriority); r = wSENDTO(psSockfd, psTxMsg, msgsize, 0, (struct sockaddr *)&wmmps_info.psToAddr, sizeof(struct sockaddr)); return r; }
/* 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; }
/* this only sends one packet a time */ int wfaSendShortFile(int mySockfd, int streamid, BYTE *sendBuf, int pksize, BYTE *aRespBuf, int *aRespLen) { BYTE *packBuf = sendBuf; struct sockaddr_in toAddr; tgProfile_t *theProf; tgStream_t *myStream; int packLen, bytesSent=-1; dutCmdResponse_t sendResp; if(mySockfd == -1) { /* stop */ gtgTransac = 0; //gtimeOut = 0; gtgRecv = 0; gtgSend = 0; printf("stop short traffic\n"); myStream = findStreamProfile(streamid); if(myStream != NULL) { sendResp.status = STATUS_COMPLETE; sendResp.streamId = streamid; wMEMCPY(&sendResp.cmdru.stats, &myStream->stats, sizeof(tgStats_t)); wfaEncodeTLV(WFA_TRAFFIC_AGENT_SEND_RESP_TLV, sizeof(dutCmdResponse_t), (BYTE *)&sendResp, aRespBuf); *aRespLen = WFA_TLV_HDR_LEN + sizeof(dutCmdResponse_t); } return DONE; } /* find the profile */ myStream = findStreamProfile(streamid); if(myStream == NULL) { return FALSE; } theProf = &myStream->profile; if(theProf == NULL) { return FALSE; } if(pksize == 0) packLen = theProf->pksize; else packLen = pksize; wMEMSET(&toAddr, 0, sizeof(toAddr)); toAddr.sin_family = AF_INET; toAddr.sin_addr.s_addr = inet_addr(theProf->sipaddr); toAddr.sin_port = htons(theProf->sport); if(gtgRecv && gtgTransac) { // printf("mySock %i sipaddr %s sport %i\n", mySockfd, theProf->sipaddr, theProf->sport); toAddr.sin_addr.s_addr = inet_addr(theProf->sipaddr); toAddr.sin_port = htons(theProf->sport); } else if(gtgSend && gtgTransac) { // printf("mySock %i dipaddr %s dport %i\n", mySockfd, theProf->dipaddr, theProf->dport); toAddr.sin_addr.s_addr = inet_addr(theProf->dipaddr); toAddr.sin_port = htons(theProf->dport); } int2BuffBigEndian(myStream->stats.txFrames, &((tgHeader_t *)packBuf)->hdr[8]); if(mySockfd != -1) bytesSent = wfaTrafficSendTo(mySockfd, (char *)packBuf, packLen, (struct sockaddr *)&toAddr); if(bytesSent != -1) { myStream->stats.txFrames++; myStream->stats.txPayloadBytes += bytesSent; } else { int errsv = errno; switch(errsv) { case EAGAIN: case ENOBUFS: DPRINT_ERR(WFA_ERR, "send error\n"); wUSLEEP(1000); /* hold for 1 ms */ myStream->stats.txFrames--; break; default: ;; //perror("sendto: "); } } sentTranPkts++; return TRUE; }