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() ; }