Ejemplo n.º 1
0
/**
 *  ICmdQClearPort removes all outgoing packets for the current port
 *  and all incoming packets, too.  ACK packets are left alone.
 *
 *  NOTE: 
 *  Make sure that this routine is only called when all communications
 *  are finalized.
 *
 *<!-----------------------------------------------------------------------*/
static T_void ICmdQClearPort(T_void)
{
    T_word16 i ;
    T_cmdQStruct *p_cmdQ ;
    T_cmdQPacketStruct *p_packet ;
    T_packetLong packet ;

    DebugRoutine("ICmdQClearPort") ;

    /* First, read in all the incoming packets (and ignore them). */
    while (PacketGet(&packet) == 0)
        { }

    /* Catch all the outgoing packets. */
    /* Go through all the queues looking for packets to remove. */
    for (i=1; i<PACKET_COMMAND_MAX; i++)  {
        for (;;)  {
            p_cmdQ = &G_activeCmdQList[i] ;
            p_packet = p_cmdQ->last ;
            if (p_packet != NULL)  {
#ifndef NDEBUG
                /* Check for the tag. */
                if (strcmp(p_packet->tag, "CmQ") != 0)  {
                    printf("Bad packet %p\n", p_packet) ;
                    DebugCheck(FALSE) ;
                }
#endif
                /* Found a packet, remove it. */
                p_cmdQ->last = p_packet->prev ;
                if (p_cmdQ->last == NULL)
                    p_cmdQ->first = NULL ;
                else {
                    p_cmdQ->last->next = NULL ;
                }

#ifndef NDEBUG
                /* Mark the packet as gone. */
                strcpy(p_packet->tag, "c_q") ;
                G_packetsFree++ ;
#endif

                /* Delete it. */
                MemFree(p_packet) ;
            } else {
                /* No packet.  Stop looping on this queue. */
                break ;
            }
        }
    }

    DebugEnd() ;
}
Ejemplo n.º 2
0
void I_NetCmd (void)
{
	if (doomcom.command == CMD_SEND)
	{
		PacketSend ();
	}
	else if (doomcom.command == CMD_GET)
	{
		PacketGet ();
	}
	else
		I_Error ("Bad net cmd: %i\n",doomcom.command);
}
Ejemplo n.º 3
0
static int
IterateSummarizeSession(
        OWPDataRec  *rec,
        void        *cdata
        )
{
    OWPStats    stats = cdata;
    OWPPacket   node;
    double      d;
    double      derr;
    long int    i;

    /*
     * Mark the first offset that has a seq greater than currently
     * interested in. This allows the caller to know what offset to
     * use for the "beginning" of the next summary.
     */
    if(!stats->next_oset && (rec->seq_no >= stats->last)){
        stats->next_oset = stats->begin_oset + stats->i * stats->hdr->rec_size;
    }

    /* increase file index */
    stats->i++;

    /*
     * return (cont processing) if this record is not part of this sum-session
     *
     * XXX: This may not be completely correct with respect to reordering...
     * If the first packet of the "next" session takes place before the
     * last packet of the "previous" session - should reordering be counted?
     *
     */ 
    if((rec->seq_no < stats->first) || (rec->seq_no >= stats->last)){
        return 0;
    }

    /*
     * Flush OWPPacket buffer before dealing with this packet so the buffer
     * only holds as many records as is needed.
     *
     */
    if(OWPIsLostRecord(rec)){
        /*
         * if current rec is lost, then all seq nums less than this one
         * can be flushed.
         */
        while(stats->pbegin->seq < rec->seq_no){
            if(!PacketBeginFlush(stats))
                return -1;
        }
    }else{
        /*
         * If this packet is not lost, then compute recv-lossThresh
         * and flush all packets with "sent" before this time.
         */
        OWPNum64    thresh = OWPNum64Sub(rec->recv.owptime,
                stats->hdr->test_spec.loss_timeout);

        while(OWPNum64Cmp(stats->pbegin->schedtime,thresh) < 0){
            if(!PacketBeginFlush(stats))
                return -1;
        }
    }

    /*
     * Fetch current packet record
     */
    if( !(node = PacketGet(stats,rec->seq_no))){
        OWPError(stats->ctx,OWPErrFATAL,EINVAL,
                "IterateSummarizeSession: Unable to fetch packet #%lu",
                rec->seq_no);
        return -1;
    }

    /*
     * Check if in "skip" range. If so, then skip aggregation information
     * for this record.
     */
    i = stats->iskip;
    while(stats->skips && (i < (long int)stats->hdr->num_skiprecs)){
        if((node->seq >= stats->skips[i].begin) &&
                (node->seq <= stats->skips[i].end)){
            return 0;
        }
        i++;
    }

    if( OWPIsLostRecord(rec)){
        /*
         * If this has been seen before, then we have a problem.
         */
        if(node->seen){
            OWPError(stats->ctx,OWPErrFATAL,EINVAL,
                    "IterateSummarizeSession: Unexpected lost packet record");
            return -1;
        }
        node->lost = True;
        stats->sent++;

        /* sync */
        if(!rec->recv.sync){
            stats->sync = 0;
        }

        /*
         * Time error
         */
        derr = OWPGetTimeStampError(&rec->recv);
        stats->maxerr = MAX(stats->maxerr,derr);

        if(stats->output){
            fprintf(stats->output,"seq_no=%-10u *LOST*\n", rec->seq_no);
        }

        return 0;
    }
    else{
        /*
         * If this has already been declared lost, we have a problem.
         */
        if(node->lost){
            OWPError(stats->ctx,OWPErrFATAL,EINVAL,
                    "IterateSummarizeSession: Unexpected duplicate packet record (for lost one)");
            return -1;
        }

        if(!node->seen){
            stats->sent++;
        }
        node->seen++;
    }

    /*
     * j-reordering. See:
     * http://www.internet2.edu/~shalunov/ippm/\
     *                          draft-shalunov-reordering-definition-02.txt
     */
#define rseqindex(x)    ((x) >= 0? x: x + stats->rlistlen)
    for(i=0;i < MIN(stats->rnumseqno,stats->rlistlen) &&
            rec->seq_no < stats->rseqno[rseqindex(stats->rindex-i-1)];i++){
        stats->rn[i]++;
    }
    stats->rseqno[stats->rindex] = rec->seq_no;
    stats->rnumseqno++;
    stats->rindex++;
    stats->rindex %= stats->rlistlen;
#undef rseqindex

    /* sync */
    if(!rec->send.sync || !rec->recv.sync){
        stats->sync = 0;
    }

    /*
     * compute delay for this packet
     */
    d = OWPDelay(&rec->send, &rec->recv);

    /*
     * compute total error from send/recv
     */
    derr = OWPGetTimeStampError(&rec->send) + OWPGetTimeStampError(&rec->recv);
    stats->maxerr = MAX(stats->maxerr,derr);

    /*
     * Print individual packet record
     */
    if(stats->output){
        if(rec->send.sync && rec->recv.sync){
	  if (stats->display_unix_ts == True) {
	    /* print using unix timestamp */
	    double epochdiff = (OWPULongToNum64(OWPJAN_1970))>>32;
	    fprintf(stats->output,
		    "seq_no=%d delay=%e %s (sync, err=%.3g %s) sent=%f recv=%f\n",
		    rec->seq_no, d*stats->scale_factor, stats->scale_abrv,
		    derr*stats->scale_factor, stats->scale_abrv,
		    OWPNum64ToDouble(rec->send.owptime) - epochdiff,
		    OWPNum64ToDouble(rec->recv.owptime) - epochdiff
		    );
	  } 
	  else {
	    /* print the default */
	    fprintf(stats->output,
		    "seq_no=%-10u delay=%.3g %s\t(sync, err=%.3g %s)\n",
		    rec->seq_no, d*stats->scale_factor, stats->scale_abrv,
		    derr*stats->scale_factor,stats->scale_abrv);
	  }
        }
Ejemplo n.º 4
0
static OWPBoolean
PacketBeginFlush(
        OWPStats    stats
        )
{
    OWPPacket   node = stats->pbegin;
    OWPBoolean  keep_parsing = True;

    if(!node){
        OWPError(stats->ctx,OWPErrFATAL,EINVAL,
                "PacketBeginFlush: begin node empty?");
        return False;
    }

    /*
     * Move begin skip to next skip if needed (based on node->seq).
     */
    while(stats->skips && (stats->iskip < (long int)stats->hdr->num_skiprecs) &&
            (node->seq > stats->skips[stats->iskip].end)){
        stats->iskip++;
    }

    /*
     * Check if in "skip" range. If so, then skip aggregation information
     * and flush the packet. (iskip has been forwarded to guarentee the
     * first skip range is the only possible match.)
     */
    if(stats->skips && (stats->iskip < (long int)stats->hdr->num_skiprecs) &&
            (node->seq >= stats->skips[stats->iskip].begin)){
        goto flush;
    }

    /*
     * Loss and Dup Stats Happen Here
     */
    if(node->lost){
        /* count lost packets */
        stats->lost++;
    }
    else if(node->seen){
        /* count dups */
        stats->dups += (node->seen - 1);
    }

flush:

    /* Retain the last scheduled timestamp */
    stats->end_time = node->schedtime;

    if(node->next){
        stats->pbegin = node->next;
    }
    else if((node->seq+1) < stats->last){
        stats->pbegin = PacketGet(stats,node->seq+1);
    }
    else{
        keep_parsing = False;
    }

    PacketFree(stats,node);

    return keep_parsing;
}
Ejemplo n.º 5
0
T_void CmdQUpdateAllReceives(T_void)
{
    T_packetLong packet ;
    T_sword16 status ;
    T_byte8 command ;
    T_byte8 ackCommand ;
    T_word32 packetId ;
    T_packetShort ackPacket ;
    E_Boolean packetOkay;
    T_directTalkUniqueAddress uniqueID;

    DebugRoutine("CmdQUpdateAllReceives") ;
    INDICATOR_LIGHT(260, INDICATOR_GREEN) ;
    DebugCheck(G_init == TRUE) ;

    /* Let's see how many ports there are. */
    DebugCheckValidStack() ;
//    numPorts = CommGetNumberPorts() ;
    DebugCheckValidStack() ;

        /* Set the active port (and any additional information). */
        DebugCheckValidStack() ;

        /* Hunting for a bug... */
        /* ... . */

        DebugCheckValidStack() ;

        DirectTalkGetUniqueAddress(&uniqueID);

        /* Loop while there are packets to get. */
        do {
            DebugCompare("CmdQUpdateAllReceives") ;
            DebugCheckValidStack() ;
            /* Try getting a packet. */
            status = PacketGet(&packet) ;
            DebugCheckValidStack() ;

            /* Did we get a packet? */
            if (status == 0)  {
                /* Yes, we did.  See what command is being issued. */
                command = packet.data[0] ;

                /* Make sure it is a legal commands.  Unfortunately, */
                /* we'll have to ignore those illegal commands. */
                if (command < PACKET_COMMAND_UNKNOWN)  {
                    /* Is it an ACK packet? */


                    //printf("R(%d) %2d %ld %ld\n", CmdQGetActivePortNum(), packet.data[0], packet.header.id, TickerGet()) ;  fflush(stdout) ;
#ifdef COMPILE_OPTION_CREATE_PACKET_DATA_FILE
                    fprintf(G_packetFile, "R(%d) %2d %ld %ld\n", CmdQGetActivePortNum(), packet.data[0], packet.header.id, SyncTimeGet()) ; fflush(G_packetFile) ;
#endif

                    if (command == PACKET_COMMAND_ACK)  {
                        /* Yes, it is an ack.  See what command it is */
                        /* acknowledging. */
                        ackCommand = packet.data[1] ;

                        /* Is that a valid command? */
                        if (ackCommand < PACKET_COMMAND_UNKNOWN)  {
                            INDICATOR_LIGHT(264, INDICATOR_GREEN) ;
                            /* Yes.  But is it a lossless command? */
                            if (G_CmdQTypeCommand[ackCommand] ==
                                PACKET_COMMAND_TYPE_LOSSLESS)  {
                                /* Get the packet id. */
                                packetId = *((T_word32 *)(&(packet.data[2]))) ;
                                /* Is there a list at that point? */
                                if (G_activeCmdQList[ackCommand].last != NULL)  {
                                    /* Yes.  Is there an ack for the same packet */
                                    /* waiting? */
                                    T_cmdQPacketStruct *p = G_activeCmdQList[ackCommand].first;
                                    while (p) {
                                        // Search for a matching packet id
                                        if (p->packet.header.id == packetId)  {
                                            /* Yes. We can now discard it. */
                                            DebugCheckValidStack() ;
                                            ICmdQDiscardPacket(ackCommand, p) ;
                                            DebugCheckValidStack() ;
                                            break;
                                        }
                                        // Walk the complete list of this type of packet
                                        p = p->next;
                                    }
                                }
                            }
                            INDICATOR_LIGHT(264, INDICATOR_RED) ;
                        }
                    } else {
                        /* No, do the normal action. */

                        /** If this is a lossy packet, always call the **/
                        /** callback routine. **/
                        packetOkay = TRUE;

                        /* Is this a lossless command? */
                        if (G_CmdQTypeCommand[command] ==
                                PACKET_COMMAND_TYPE_LOSSLESS)  {
                            INDICATOR_LIGHT(268, INDICATOR_GREEN) ;
                            memset(&ackPacket, 0xFF, sizeof(ackPacket));
                            /* Yes, it is.  We need to send an ACK that */
                            /* we got it. */
                            /* Make an ack packet with the packet's */
                            /* command and id we received. */
                            ackPacket.data[0] = PACKET_COMMAND_ACK ;
                            ackPacket.data[1] = command ;
                            *((T_word32 *)(&ackPacket.data[2])) =
                                packet.header.id ;
                            /* Send it!  Note that we go through our */
                            /* routines. */
                            INDICATOR_LIGHT(272, INDICATOR_GREEN) ;
                            DebugCheckValidStack() ;
                            CmdQSendShortPacket(
                                &ackPacket,
                                &packet.header.sender,
                                140,  /* Once two seconds is plenty fast */
                                0,  /* No extra data since no callback. */
                                NULL) ;  /* No callback. */
                            INDICATOR_LIGHT(272, INDICATOR_RED) ;
                            DebugCheckValidStack() ;

                            INDICATOR_LIGHT(268, INDICATOR_RED) ;
                        }
                        /* IF the packet is a new packet or a lossy one, */
                        /* we'll go ahead and do the appropriate action */
                        /* on this side. */
//printf("Considering %p [%d]\n", G_cmdQActionList[command], command) ;
                        if ((G_cmdQActionList[command] != NULL) &&
                            (packetOkay == TRUE))  {
                            /* Call the appropriate action item. */
                            INDICATOR_LIGHT(276, INDICATOR_GREEN) ;
//printf("Did go: (%d) %d, %p\n", command, packetOkay, G_cmdQActionList[command]) ; fflush(stdout) ;
                            DebugCheckValidStack() ;
                            G_cmdQActionList[command]
                                   ((T_packetEitherShortOrLong *)&packet) ;
                            DebugCheckValidStack() ;
                            INDICATOR_LIGHT(276, INDICATOR_RED) ;
                            DebugCompare("CmdQUpdateAllReceives") ;
                        } else {
//printf("Didn't go: (%d) %d, %p\n", command, packetOkay, G_cmdQActionList[command]) ; fflush(stdout) ;
                        }
                    }
                }
            }
            DebugCheckValidStack() ;
        } while (status == 0) ;
    DebugEnd() ;

    INDICATOR_LIGHT(260, INDICATOR_RED) ;
}