示例#1
0
int wfaGetifAddr(char *ifname, struct sockaddr_in *sa)
{
    struct ifreq ifr;
    int fd = wSOCKET(PF_INET, SOCK_DGRAM, IPPROTO_IP);

    if(fd < 0)
    {
       DPRINT_ERR(WFA_ERR, "socket open error\n");
       return WFA_FAILURE;
    }

    wSTRCPY(ifr.ifr_name, ifname);

    ifr.ifr_addr.sa_family = AF_INET;
    if(wIOCTL(fd, SIOCGIFADDR, &ifr) == 0)
    {
         wMEMCPY(sa, (struct sockaddr_in *)&ifr.ifr_addr, sizeof(struct sockaddr_in));
    }
    else
    {
         return WFA_FAILURE;
    }

    wCLOSE(fd);

    return WFA_FAILURE;
}
示例#2
0
/*
 * 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;
}
示例#3
0
BOOL wfaGetTLVvalue(int value_len, BYTE *tlv_data, BYTE *pvalue)
{
    if(tlv_data == NULL)
      return FALSE;

    wMEMCPY(pvalue, tlv_data+WFA_TLV_HEAD_LEN, value_len);

    return TRUE;
}
/*
 * 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;
}
示例#5
0
/*
 * wfaEncodeTLV(): Encoding a packet to TLV format 
 * input: the_tag - packet type
 *        the_len - the value length
 *        the_value - the value buffer
 *
 * output: tlv_data - encoded TLV packet buffer. Caller must allocate the buffer
 */
BOOL wfaEncodeTLV(WORD the_tag, WORD the_len, BYTE *the_value, BYTE *tlv_data)
{
   void *data = tlv_data;

   ((wfaTLV *)data)->tag = the_tag;
   ((wfaTLV *)data)->len = the_len;
   if(the_value != NULL && the_len != 0)
      wMEMCPY((data+4), (BYTE *)the_value, the_len);

   return TRUE;
}
示例#6
0
BOOL wfaDecodeTLV(BYTE *tlv_data, int tlv_len, WORD *ptag, int *pval_len, BYTE *pvalue)
{ 
   wfaTLV *data = (wfaTLV *)tlv_data;

   if(pvalue == NULL)
   {
        sigma_dut_print(DUT_MSG_ERROR, "Parm buf invalid\n");
       return FALSE;
   }
   *ptag = data->tag; 
   *pval_len = data->len;

   if(tlv_len < *pval_len)
       return FALSE;

   if(*pval_len != 0 && *pval_len < MAX_PARMS_BUFF)
   {
      wMEMCPY(pvalue, tlv_data+4, *pval_len);
   }

   return TRUE;
}
示例#7
0
/* 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;
}
示例#8
0
/*
 * 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;
}
示例#9
0
/*
 * 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;
}
示例#10
0
/* 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;
}
示例#11
0
/* 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;
}