Esempio n. 1
0
E_Boolean ScheduleUpdateEvents(T_void)
{
    T_scheduleEvent *p_event ;
    E_Boolean f_eventOccured = FALSE ;
    TICKER_TIME_ROUTINE_PREPARE() ;

    TICKER_TIME_ROUTINE_START() ;

    DebugRoutine("ScheduleUpdateEvents") ;

    /* Loop while there are events that can be processed. */
    while ((G_firstScheduleEvent != NULL) &&
           (G_firstScheduleEvent->when <= SyncTimeGet()))  {
        /* An event is now going off.  Get that event. */
        p_event = G_firstScheduleEvent ;

        /* Call the handler for this event. */
        DebugCheck(p_event->handler != NULL) ;
        p_event->handler(p_event->data) ;

        /* Remove the event from the list. */
        G_firstScheduleEvent = p_event->next ;
        MemFree(p_event) ;

        /* Note that some event occured. */
        f_eventOccured = TRUE ;
    }

    DebugEnd() ;

    TICKER_TIME_ROUTINE_END(stdout, "ScheduleUpdateEvents", 500) ;
    return f_eventOccured ;
}
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) ;
}
/**
 *  CmdQUpdateAllSends updates the sending of all packets.
 *  Packets that need to be transferred are sent.  Those that don't, don't.
 *  The amount of packets sent depends on the baud rate and the last time
 *  this routine was called.
 *
 *<!-----------------------------------------------------------------------*/
T_void CmdQUpdateAllSends(T_void)
{
    T_byte8 currentCmd;
    T_cmdQPacketStruct *p_packet = NULL;
    T_cmdQPacketStruct *p_next = NULL;
    T_byte8 packetLength;
    T_word32 time;
    T_sword16 status;
    T_word16 bytesused;
    T_word32 maxOutput;
    E_Boolean onceFlag = FALSE;
    E_Boolean sentAny;

    DebugRoutine("CmdQUpdateAllSends") ;

    /* Get the current time. */
    time = TickerGet();

    bytesused = 0;
    maxOutput = 100;
    currentCmd = 0;
    if (bytesused < maxOutput) {
        do {
            sentAny = FALSE;
            p_next = 0;
            p_packet = G_activeCmdQList[currentCmd].first;
            do {
                /* Try sending the command at currentCmd. */
                /* See if there is anything that needs to be sent. */
                if ((p_packet != NULL)
                        && (bytesused < maxOutput)) {
                    DebugCheck(currentCmd < PACKET_COMMAND_UNKNOWN);
                    p_next = p_packet->next;
#ifndef NDEBUG
                    if (strcmp(p_packet->tag, "CmQ") != 0) {
                        printf("Bad packet %p\n", p_packet);
                        DebugCheck(FALSE);
                    }
#endif

                    /* See if it is time to send it. */
                    /** (It's always time to send an ACK.) **/
                    if ((currentCmd == PACKET_COMMAND_ACK)
                            || (p_packet->timeToRetry < time)) {
                        /* Yes, it is time to send it. */
                        packetLength = p_packet->packet.header.packetLength;
                        /* Add the count to the output. */
                        bytesused += packetLength + sizeof(T_packetHeader);

                        /* Make sure this didn't go over the threshold. */
                        if (bytesused >= maxOutput)
                            break;

                        /* Let's send that packet to the given destination. */
                        DirectTalkSetDestination(&p_packet->destination);
                        status =
                                PacketSend(
                                        (T_packetEitherShortOrLong *)(&p_packet->packet));
                        sentAny = TRUE;

#ifdef COMPILE_OPTION_CREATE_PACKET_DATA_FILE
                        fprintf(G_packetFile, "S(%d) cmd=%2d, id=%ld, time=%ld\n", CmdQGetActivePortNum (), p_packet->packet.data[0], p_packet->packet.header.id, SyncTimeGet()); fflush(G_packetFile);
#endif
                        /* Was the packet actually sent? */
                        if (status == 0) {
                            /* Packet was sent correctly (as far as we know). */
                            /* Is this a lossy or lossless command queue? */
                            if ((G_CmdQTypeCommand[currentCmd]
                                    == PACKET_COMMAND_TYPE_LOSSY)
                                    || (DirectTalkIsBroadcastAddress(
                                            &p_packet->destination))) {
                                /* Lossy.  Means we can go ahead and */
                                /* discard this packet. */
                                ICmdQDiscardPacket(currentCmd, p_packet);
                            } else {
                                /* Lossless.  Means we must wait for an ACK */
                                /* packet to confirm that we were sent. */
                                /* Until then, we can't discard the packet. */
                                /* But we might have to resend latter. */
                                /* Set up the retry time. */
                                p_packet->timeToRetry = time
                                        + p_packet->retryTime;
                            }
                        } else {
                            /* Packet was NOT sent correctly. */
                            /** -- IFF the packet is lossless... **/
                            /* We'll have to retry later.  Change the time, */
                            /* but don't remove it from the linked list. */
                            if (G_CmdQTypeCommand[currentCmd]
                                    == PACKET_COMMAND_TYPE_LOSSLESS) {
                                p_packet->timeToRetry = time
                                        + p_packet->retryTime;
                            } else {
                                /* Waste it!  We can't wait around */
                                ICmdQDiscardPacket(currentCmd, p_packet);
                            }
                        }
                    } else {
                        /* Don't loop if it is not time to send. */
                        break;
                    }

                    /** Now, if we aren't checking the ACK queue, we need **/
                    /** to break after the first send.  If we are, we **/
                    /** want to dump everything in the queue. **/
                    if (currentCmd != PACKET_COMMAND_ACK)
                        break;
                }

                // Move to the next packet (if any)
                p_packet = p_next;

                while (!p_packet) {
                    /* Update to the next command. */
                    currentCmd++;
                    if (currentCmd < PACKET_COMMAND_MAX) {
                        // Get the beginning of the list
                        p_packet = G_activeCmdQList[currentCmd].first;
                        if (p_packet)
                            p_next = p_packet->next;
                        else
                            p_next = 0;
                    } else {
                        break;
                    }
                }
            } while (currentCmd < PACKET_COMMAND_MAX);
            // Loop back to the start looking for more to send
            currentCmd = 0;
        } while ((bytesused < maxOutput) && (sentAny == TRUE));
    }

    DebugEnd() ;
}