Ejemplo n.º 1
0
static void
IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
{
	const char *errmsg;
	ssize_t nbytes;
	AsyncIO *IO = watcher->data;

	SET_EV_TIME(IO, event_base);
	switch (IO->NextState) {
	case eReadFile:
		nbytes = FileRecvChunked(&IO->IOB, &errmsg);
		if (nbytes < 0)
			StrBufPlain(IO->ErrMsg, errmsg, -1);
		else
		{
			if (IO->IOB.ChunkSendRemain == 0)
			{
				IO->NextState = eSendReply;
				assert(IO->ReadDone);
				ev_io_stop(event_base, &IO->recv_event);
				PostInbound(IO);
				return;
			}
			else
				return;
		}
		break;
	default:
		nbytes = StrBuf_read_one_chunk_callback(IO->RecvBuf.fd,
							0,
							&IO->RecvBuf);
		break;
	}

#ifdef BIGBAD_IODBG
	{
		long nbytes;
		int rv = 0;
		char fn [SIZ];
		FILE *fd;
		const char *pch = ChrPtr(IO->RecvBuf.Buf);
		const char *pchh = IO->RecvBuf.ReadWritePointer;

		if (pchh == NULL)
			pchh = pch;

		nbytes = StrLength(IO->RecvBuf.Buf) - (pchh - pch);
		snprintf(fn, SIZ, "/tmp/foolog_ev_%s.%d",
			 ((CitContext*)(IO->CitContext))->ServiceName,
			 IO->SendBuf.fd);

		fd = fopen(fn, "a+");
		if (fd == NULL) {
			syslog(LOG_EMERG, "failed to open file %s: %s", fn, strerror(errno));
			cit_backtrace();
			exit(1);
		}
		fprintf(fd, "Read: BufSize: %ld BufContent: [",
			nbytes);
		rv = fwrite(pchh, nbytes, 1, fd);
		if (!rv) printf("failed to write debug to %s!\n", fn);
		fprintf(fd, "]\n");
		fclose(fd);
	}
#endif
	if (nbytes > 0) {
		HandleInbound(IO);
	} else if (nbytes == 0) {
		StopClientWatchers(IO, 1);
		SetNextTimeout(IO, 0.01);
		return;
	} else if (nbytes == -1) {
		if (errno != EAGAIN) {
			// FD is gone. kick it. 
			StopClientWatchers(IO, 1);
			EV_syslog(LOG_DEBUG,
				  "IO_recv_callback(): Socket Invalid! [%d] [%s] [%d]\n",
				  errno, strerror(errno), IO->SendBuf.fd);
			StrBufPrintf(IO->ErrMsg,
				     "Socket Invalid! [%s]",
				     strerror(errno));
			SetNextTimeout(IO, 0.01);
		}
		return;
	}
}
Ejemplo n.º 2
0
int FalconATCMessage::Process(uchar autodisp)
{
	AircraftClass *aircraft = (AircraftClass*)vuDatabase->Find(dataBlock.from );
	ObjectiveClass *atc = (ObjectiveClass*)vuDatabase->Find(EntityId());
	runwayQueueStruct *info = NULL;
	FalconRadioChatterMessage *radioMessage = NULL;
	
	if (autodisp)
		return 0;

	float cosAngle=0.0F, dx=0.0F, dy=0.0F, finalHdg=0.0F;
	float finalX=0.0F, finalY=0.0F, baseX=0.0F, baseY=0.0F, x=0.0F ,y=0.0F,z=0.0F, dist=0.0F;
	int	taxiPoint=0, tod=0, time_in_minutes=0;
	int delay = 7 * CampaignSeconds;
	if (!PlayerOptions.PlayerRadioVoice)
	    delay = 500;

	if (aircraft && aircraft->IsAirplane())
	{      
		DigitalBrain *acBrain = aircraft->DBrain();
		ATCBrain*	atcBrain = NULL;

		if(atc)
		{
			atcBrain = atc->brain;
			dx = aircraft->XPos() - atc->XPos();
			dy = aircraft->YPos() - atc->YPos();
			dist = dx*dx + dy*dy;
		}

		switch (dataBlock.type)
		{
		case ContactApproach:
        case RequestClearance:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
			{
				if(aircraft->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
					SendCallToATC(aircraft, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalSession);
				else
					SendCallToATC(aircraft, EntityId(), rcLANDCLEARANCE, FalconLocalSession);
			}
			
			if(atcBrain && atc->IsLocal())
			{
				info = atcBrain->InList(aircraft->Id());
				if( info )
				{
					cosAngle = atcBrain->DetermineAngle(aircraft, acBrain->Runway(), lOnFinal);

					//if(info->status >= tReqTaxi)
					//if(info->status < tReqTaxi) // JB 010802 RTBing AI aircraft won't land. This compare was messed up.  Right? I hope so.
					if(info->status >= tReqTaxi) // JB It appears to work but this was called a bit much for my comfort level. We'll try another approach.
					{
						if(!aircraft->OnGround())
						{
							if(dist < (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
							{
								if(!aircraft->IsPlayer() && aircraft->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
									atcBrain->RequestEmerClearance(aircraft);
								else
									atcBrain->RequestClearance(aircraft);
							}
							else if(dist < APPROACH_RANGE * NM_TO_FT * NM_TO_FT && dist >= (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
							{
								if(!aircraft->IsPlayer() && aircraft->GetCampaignObject()->GetComponentLead() == aircraft)
									HandleInboundFlight( atc, (Flight)aircraft->GetCampaignObject());
								else
									HandleInbound(atc, aircraft);			
							}
							else
							{
								//note this comm should be rcOUTSIDEAIRSPACE, but Joe misnamed it
								radioMessage = CreateCallFromATC(atc, aircraft, rcOUTSIDEAIRSPEED, FalconLocalGame);
								radioMessage->dataBlock.edata[4]	= (short)(rand()%2);
								radioMessage->dataBlock.time_to_play= delay;
								atcBrain->RemoveTraffic(aircraft->Id(), PtHeaderDataTable[info->rwindex].runwayNum);
							}
							info->lastContacted = SimLibElapsedTime;
						}
						break;
					}
					else if(info->rwindex)
					{
						switch(info->status)
						{
						case noATC:

						case lReqClearance:
						case lReqEmerClearance:

						case lIngressing:
						case lTakingPosition:
							ShiWarning("This should never happen!");
							radioMessage = CreateCallFromATC(atc, aircraft, rcCONTINUEINBOUND1, FalconLocalGame);
							//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
							radioMessage->dataBlock.edata[4]	= 32767;
							radioMessage->dataBlock.edata[5]	= (short)atcBrain->GetRunwayName(atcBrain->GetOppositeRunway(info->rwindex));
							if(rand()%2)
								radioMessage->dataBlock.edata[6]	= 4;
							else
								radioMessage->dataBlock.edata[6]	= -1;
							break;

						case lAborted:
							atcBrain->FindAbortPt(aircraft, &x, &y, &z);
							radioMessage = CreateCallFromATC (atc, aircraft, rcATCGOAROUND, FalconLocalSession);
					
							atcBrain->CalculateStandRateTurnToPt(aircraft, x, y, &finalHdg);
							radioMessage->dataBlock.edata[3] = (short)FloatToInt32(finalHdg);
							//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
							radioMessage->dataBlock.edata[4] = 32767;
							break;

						case lEmerHold:
						case lHolding:
							radioMessage = CreateCallFromATC (atc, aircraft, rcATCORBIT2, FalconLocalGame);
							radioMessage->dataBlock.edata[2] = -1; //altitude in thousands
							radioMessage->dataBlock.edata[3] = -1; //altitude in thousands
							break;

						case lFirstLeg:
						case lToBase:
						case lToFinal:
							radioMessage = CreateCallFromATC(atc, aircraft, rcATCLANDSEQUENCE, FalconLocalGame);
							radioMessage->dataBlock.edata[4] = (short)atcBrain->GetLandingNumber(info);
							//atcBrain->SendCmdMessage(aircraft, info);
							break;

						case lOnFinal:
						case lClearToLand:
							if(aircraft->DBrain()->IsSetATC(DigitalBrain::ClearToLand))
							{
								radioMessage = CreateCallFromATC (atc, aircraft, rcCLEAREDLAND, FalconLocalGame);
								radioMessage->dataBlock.edata[4] = (short)atcBrain->GetRunwayName(atcBrain->GetOppositeRunway(acBrain->Runway()));
							}
							else
							{
								radioMessage = CreateCallFromATC(atc, aircraft, rcATCLANDSEQUENCE, FalconLocalGame);
								radioMessage->dataBlock.edata[4] = (short)atcBrain->GetLandingNumber(info);
							}
							break;

						case lLanded:
							radioMessage = CreateCallFromATC (atc, aircraft, rcTAXICLEAR, FalconLocalGame);
							break;

						case lTaxiOff:
							//there isn't anything better to say, oh well :)
							radioMessage = CreateCallFromATC (atc, aircraft, rcTAXICLEAR, FalconLocalGame);
							break;

						case lEmergencyToBase:
						case lEmergencyToFinal:
						case lEmergencyOnFinal:
							atcBrain->RequestClearance(aircraft);
							return 1;
							break;

						case lCrashed:
							radioMessage = CreateCallFromATC (atc, aircraft, rcCLEAREDEMERGLAND, FalconLocalGame);
							radioMessage->dataBlock.edata[3] = -1;

							radioMessage->dataBlock.edata[4] = -1;
							//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
							radioMessage->dataBlock.edata[5] = 32767;
							break;
						}
					}
					else
					{
						radioMessage = CreateCallFromATC(atc, aircraft, rcCONTINUEINBOUND2, FalconLocalGame);

						if(rand()%2)
						{
							radioMessage->dataBlock.edata[3]	= (short)(rand()%3);
						}
						else
						{
							time_in_minutes =  TheCampaign.GetMinutesSinceMidnight();
							if (time_in_minutes < 180)//3am
								tod = 1;
							else if(time_in_minutes < 720 )//noon
								tod = 0;
							else if(time_in_minutes < 1020 ) //5pm
								tod = 2;
							else
								tod = 1;

							radioMessage->dataBlock.edata[3]	= (short)(3 + tod + (rand()%3)*3);
						}

						if(rand()%2)
							radioMessage->dataBlock.edata[4]	= 4;
						else
							radioMessage->dataBlock.edata[4]	= -1;

						atcBrain->SendCmdMessage(aircraft, info);
					}
					if (radioMessage)
					{
						info->lastContacted = SimLibElapsedTime;
						if (PlayerOptions.PlayerRadioVoice)
						    radioMessage->dataBlock.time_to_play= 2 * CampaignSeconds;
						else 
						    radioMessage->dataBlock.time_to_play= delay;
						FalconSendMessage(radioMessage, TRUE);
					}
				}
				else
				{
					if(dist <= (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
					{
						if(aircraft->GetCampaignObject()->GetComponentLead() == aircraft)
						{
							AircraftClass *element = NULL;
							Flight flight = (Flight)aircraft->GetCampaignObject();
							VuListIterator	flightIter(flight->GetComponents());

							element = (AircraftClass*) flightIter.GetFirst();
							while(element)
							{
								runwayQueueStruct *tempinfo = atcBrain->InList(element->Id());
								if(!tempinfo)
								{
									if( !element->IsPlayer() && element->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
									{
										SendCallToATC(element, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalGame);
										atcBrain->RequestEmerClearance(element);
									}
									else
										atcBrain->RequestClearance(element);
								}
								element = (AircraftClass*) flightIter.GetNext();
							}
						}
						else
						{
							if(!aircraft->IsPlayer() && aircraft->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
							{
								SendCallToATC(aircraft, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalGame);
								atcBrain->RequestEmerClearance(aircraft);
							}
							else
								atcBrain->RequestClearance(aircraft);
						}
					}
					else if(dist < APPROACH_RANGE * NM_TO_FT * NM_TO_FT && dist > (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
					{
						if(aircraft->GetCampaignObject()->GetComponentLead() == aircraft)
							HandleInboundFlight( atc, (Flight)aircraft->GetCampaignObject());
						else
							HandleInbound(atc, aircraft);						
					}
					else
					{
						//note this comm should be rcOUTSIDEAIRSPACE, but Joe misnamed it
						radioMessage = CreateCallFromATC(atc, aircraft, rcOUTSIDEAIRSPEED, FalconLocalGame);
						radioMessage->dataBlock.edata[4]	= (short)(rand()%2);
						radioMessage->dataBlock.time_to_play= delay;
						FalconSendMessage(radioMessage, TRUE);
					}
				}
			}
			break;
			
        case RequestEmerClearance:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalSession);
			if(atcBrain && atc->IsLocal())
				atcBrain->RequestEmerClearance(aircraft);			
			break;
		
        case RequestTakeoff:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcREADYFORDERARTURE, FalconLocalSession);
			if(atcBrain && atc->IsLocal())
				atcBrain->RequestTakeoff(aircraft);
			break;
			
        case RequestTaxi:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcREADYFORDERARTURE, FalconLocalSession);
			if(atcBrain && atc->IsLocal())
				atcBrain->RequestTaxi(aircraft);
			break;
// M.N. 2001-12-20
		case AbortApproach:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcABORTAPPROACH, FalconLocalSession);
				atcBrain->AbortApproach(aircraft);//Cobra
			if (atcBrain && atc->IsLocal())
				atcBrain->AbortApproach(aircraft);
			break;

// RAS - 22Jan04 - Set flag for traffic in sight call 
		case TrafficInSight:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcCOPY, FalconLocalSession);
			if (atcBrain && atc->IsLocal())
				atcBrain->trafficInSightFlag = TRUE;
			break;
// TJL 08/16/04 - Set flag for Hotpit Refueling //Cobra 10/31/04 TJL
 		case RequestHotpitRefuel:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
 				SendCallToATC(aircraft, EntityId(), rcCOPY, FalconLocalSession);
				aircraft->requestHotpitRefuel = TRUE; //Cobra 11/13/04 TJL will this make online work?
 			if (atcBrain && atc->IsLocal())
 				aircraft->requestHotpitRefuel = TRUE;
 			break;


		case UpdateStatus:
			if(atcBrain)
			{
				if(atc->IsLocal())
				{
					info = atcBrain->InList(aircraft->Id());
					if(info)
					{
						switch(dataBlock.status)
						{
						case noATC:
							if(info->rwindex)
								atcBrain->RemoveTraffic(aircraft->Id(), PtHeaderDataTable[info->rwindex].runwayNum);
							else
								atcBrain->RemoveInbound(info);
							break;
						case lReqClearance:
						case lReqEmerClearance:
						case tReqTaxi:
						case tReqTakeoff:
						case lIngressing:
						case lTakingPosition:
							break;
						case tFlyOut:
							info->lastContacted = SimLibElapsedTime;
							info->status = noATC;
							break;
						case lCrashed:
							info->lastContacted = SimLibElapsedTime;
							info->status = lCrashed;
							{
								atcBrain->RemoveFromAllOtherATCs(aircraft);
								int Runway = atcBrain->IsOverRunway(aircraft);
								if(GetQueue(Runway) != GetQueue(info->rwindex))
								{
									atcBrain->RemoveTraffic(aircraft->Id(), GetQueue(info->rwindex));
									atcBrain->AddTraffic(aircraft->Id(), lCrashed, Runway, SimLibElapsedTime);
								}
								atcBrain->FindNextEmergency(GetQueue(Runway));
								atcBrain->SetEmergency(GetQueue(Runway));
							}
							break;
						default:
							info->lastContacted = SimLibElapsedTime;
							info->status = (AtcStatusEnum)dataBlock.status;
							break;
						}
					}
					else
					{
						//he thinks we already know about him, orig owner of atc must have dropped
						//offline, so we need to put him into the appropriate list
						switch(dataBlock.status)
						{
							case lIngressing:
								break;
							case lTakingPosition:
							case lAborted:
							case lEmerHold:
							case lHolding:
							case lFirstLeg:
							case lToBase:
							case lToFinal:
							case lOnFinal:
							case lLanded:
							case lTaxiOff:
							case lEmergencyToBase:
							case lEmergencyToFinal:
							case lEmergencyOnFinal:
							case lClearToLand:
								atcBrain->RequestClearance(aircraft);			
								break;
							case lCrashed:
								{
									atcBrain->RemoveFromAllOtherATCs(aircraft);
									int Runway = atcBrain->IsOverRunway(aircraft);
									atcBrain->AddTraffic(aircraft->Id(), lCrashed, Runway, SimLibElapsedTime);
									atcBrain->FindNextEmergency(GetQueue(Runway));
									atcBrain->SetEmergency(GetQueue(Runway));
								}
								break;
							case tEmerStop:
							case tTaxi:
							case tHoldShort:
							case tPrepToTakeRunway:
							case tTakeRunway:
							case tTakeoff:
								atcBrain->RequestTaxi(aircraft);
								break;
							case tFlyOut:
								break;
							default:
								break;
						}
					}
				}

				//update track point, taxi point, timer, status, etc...
				switch(dataBlock.status)
				{
				case noATC:
					break;
				case lClearToLand:
					break;
				case lIngressing:
				case lTakingPosition:
					atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &x, &y);
					acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lTakingPosition));
					break;
				case lEmerHold:
				case lHolding:
					acBrain->SetTrackPoint(aircraft->XPos(), aircraft->YPos(), atcBrain->GetAltitude(aircraft, lHolding));
					break;

				case lFirstLeg:				
					if(acBrain->ATCStatus() != lFirstLeg && acBrain->ATCStatus() <= lOnFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						cosAngle = atcBrain->DetermineAngle(aircraft, acBrain->Runway(), lFirstLeg);
						if(cosAngle < 0.0F)
						{
							atcBrain->FindBasePt(aircraft, acBrain->Runway(), finalX, finalY, &baseX, &baseY);
							atcBrain->FindFirstLegPt(aircraft, acBrain->Runway(), acBrain->RwTime(), baseX, baseY, TRUE, &x, &y);
						}
						else
						{
							atcBrain->FindFirstLegPt(aircraft, acBrain->Runway(), acBrain->RwTime(), finalX, finalY, FALSE, &x, &y);
						}

						acBrain->SetATCStatus(lFirstLeg);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lFirstLeg));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						atcBrain->MakeVectorCall(aircraft, FalconLocalSession);
					}
					break;

				case lToBase:
					if(acBrain->ATCStatus() != lToBase && acBrain->ATCStatus() <= lOnFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						atcBrain->FindBasePt(aircraft, acBrain->Runway(), finalX, finalY, &baseX, &baseY);
						acBrain->SetATCStatus(lToBase);
						acBrain->SetTrackPoint(baseX, baseY, atcBrain->GetAltitude(aircraft, lToBase));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						atcBrain->MakeVectorCall(aircraft, FalconLocalSession);
					}
					break;

				case lToFinal:
					if(acBrain->ATCStatus() != lToFinal && acBrain->ATCStatus() <= lOnFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						acBrain->SetATCStatus(lToFinal);
						acBrain->SetTrackPoint(finalX, finalY, atcBrain->GetAltitude(aircraft, lToFinal));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						atcBrain->MakeVectorCall(aircraft, FalconLocalSession);
					}
					break;

				case lOnFinal:
					TranslatePointData (atc, GetFirstPt(acBrain->Runway()), &x, &y);
					//if we sent the message we already know this				
					if(acBrain->ATCStatus() != lOnFinal && acBrain->ATCStatus() <= lOnFinal)
					{						
						acBrain->SetATCStatus(lOnFinal);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lOnFinal));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						radioMessage = CreateCallFromATC (atc, aircraft, rcTURNTOFINAL, FalconLocalSession);
#if 0
						//MI Turn final for AI fix
						if(atcBrain->CalculateStandRateTurnToPt(aircraft, x, y, &finalHdg) > 0)
							radioMessage->dataBlock.edata[2] = 1;
						else
							radioMessage->dataBlock.edata[2] = 0;
#else
						if(atcBrain->CalculateStandRateTurnToPt(aircraft, x, y, &finalHdg) > 0)
							radioMessage->dataBlock.edata[2] = 0;
						else
							radioMessage->dataBlock.edata[2] = 1;
#endif	
						finalHdg = PtHeaderDataTable[acBrain->Runway()].data + 180.0F;
						if(finalHdg > 360)
							finalHdg -= 360;

						radioMessage->dataBlock.edata[3] = (short)FloatToInt32(finalHdg);
						//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
						radioMessage->dataBlock.edata[4] = 32767; //vector type
						FalconSendMessage(radioMessage, TRUE);
					}
					break;


				case lLanded:
					//if we sent the message we already know this	
					if(acBrain->ATCStatus() != lLanded)
					{
						acBrain->SetATCStatus(lLanded);
						taxiPoint = GetFirstPt(acBrain->Runway());
						TranslatePointData (atc,GetNextPt(taxiPoint) , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lLanded));
					}
					break;

				case lTaxiOff:
					break;

				case lAborted:					
					if(acBrain->ATCStatus() != lAborted)
					{
						atcBrain->FindAbortPt(aircraft, &x, &y, &z);
						acBrain->SetATCStatus(lAborted);					
						acBrain->SetTrackPoint(x, y, z);
					}

					if(atc->IsLocal())
					{
						atcBrain->RemoveTraffic(aircraft->Id(), PtHeaderDataTable[acBrain->Runway()].runwayNum);
					}
					break;

				case lEmergencyToBase:
					if(acBrain->ATCStatus() != lEmergencyToBase)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						atcBrain->FindBasePt(aircraft, acBrain->Runway(), finalX, finalY, &baseX, &baseY);
						acBrain->SetATCStatus(lEmergencyToBase);
						acBrain->SetTrackPoint(baseX, baseY, atcBrain->GetAltitude(aircraft, lEmergencyToBase));
					}
					break;

				case lEmergencyToFinal:
					if(acBrain->ATCStatus() != lEmergencyToFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						acBrain->SetATCStatus(lEmergencyToFinal);
						acBrain->SetTrackPoint(finalX, finalY, atcBrain->GetAltitude(aircraft, lEmergencyToFinal));
					}
					break;

				case lEmergencyOnFinal:
					if(acBrain->ATCStatus() != lEmergencyOnFinal)
					{
						TranslatePointData (atc, GetFirstPt(acBrain->Runway()), &x, &y);
						acBrain->SetATCStatus(lEmergencyOnFinal);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lEmergencyOnFinal));
					}
					break;

				case lCrashed:
					acBrain->SetATCStatus(lCrashed);
					break;

				case tEmerStop:
					acBrain->SetATCStatus(tEmerStop);
					break;

				case tTaxi:
					if(acBrain->ATCStatus() != tTaxi)
					{
						acBrain->SetATCStatus(tTaxi);
						TranslatePointData (atc,acBrain->GetTaxiPoint() , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTaxi));
					}
					break;

				case tHoldShort:
					acBrain->ClearATCFlag(DigitalBrain::PermitRunway);
					acBrain->ClearATCFlag(DigitalBrain::PermitTakeoff);

					if(acBrain->ATCStatus() != tHoldShort)
					{
						acBrain->SetATCStatus(tHoldShort);
						taxiPoint = GetFirstPt(acBrain->Runway());
						taxiPoint = GetNextPt(taxiPoint);
						TranslatePointData (atc,taxiPoint , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tHoldShort));
					}
					break;

				case tPrepToTakeRunway:
					acBrain->SetATCFlag(DigitalBrain::PermitTakeRunway);
					if(acBrain->ATCStatus() != tTaxi)
					{
						acBrain->SetATCStatus(tTaxi);
						if(PtDataTable[acBrain->GetTaxiPoint()].type == TakeoffPt)
							atcBrain->FindTakeoffPt((Flight)aircraft->GetCampaignObject(), aircraft->vehicleInUnit, acBrain->Runway(), &x, &y);
						else
							TranslatePointData (atc,acBrain->GetTaxiPoint() , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTaxi));
					}
					break;

				case tTakeRunway:
					if(acBrain->ATCStatus() != tTakeRunway)
					{
						acBrain->SetATCFlag(DigitalBrain::PermitTakeRunway);
						acBrain->SetATCStatus(tTakeRunway);
						atcBrain->FindTakeoffPt((Flight)aircraft->GetCampaignObject(), aircraft->vehicleInUnit, acBrain->Runway(), &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTakeRunway));
					}
					break;

				case tTakeoff:
					if(acBrain->ATCStatus() != tTakeoff)
					{
						acBrain->SetATCFlag(DigitalBrain::PermitRunway);
						acBrain->SetATCFlag(DigitalBrain::PermitTakeoff);
						acBrain->SetATCStatus(tTakeRunway);
						atcBrain->FindRunwayPt((Flight)aircraft->GetCampaignObject(), aircraft->vehicleInUnit, acBrain->Runway(), &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTakeRunway));
					}
					break;

				case tTaxiBack:
					if(acBrain->ATCStatus() != tTaxiBack)
					{
						acBrain->SetATCStatus(tTaxiBack);
					}
					break;

				case tFlyOut:
					if(acBrain->ATCStatus() != tFlyOut)
					{
						acBrain->ResetATC();
					}
				default:
					break;
				}
			}
			break;
		}
	}
	return 1;
}
Ejemplo n.º 3
0
static void
IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
{
	int rc;
	AsyncIO *IO = watcher->data;
	const char *errmsg = NULL;

	SET_EV_TIME(IO, event_base);
	become_session(IO->CitContext);
#ifdef BIGBAD_IODBG
	{
		int rv = 0;
		char fn [SIZ];
		FILE *fd;
		const char *pch = ChrPtr(IO->SendBuf.Buf);
		const char *pchh = IO->SendBuf.ReadWritePointer;
		long nbytes;

		if (pchh == NULL)
			pchh = pch;

		nbytes = StrLength(IO->SendBuf.Buf) - (pchh - pch);
		snprintf(fn, SIZ, "/tmp/foolog_ev_%s.%d",
			 ((CitContext*)(IO->CitContext))->ServiceName,
			 IO->SendBuf.fd);

		fd = fopen(fn, "a+");
		if (fd == NULL) {
			syslog(LOG_EMERG, "failed to open file %s: %s", fn, strerror(errno));
			cit_backtrace();
			exit(1);
		}
		fprintf(fd, "Send: BufSize: %ld BufContent: [",
			nbytes);
		rv = fwrite(pchh, nbytes, 1, fd);
		if (!rv) printf("failed to write debug to %s!\n", fn);
		fprintf(fd, "]\n");
#endif
		switch (IO->NextState) {
		case eSendFile:
			rc = FileSendChunked(&IO->IOB, &errmsg);
			if (rc < 0)
				StrBufPlain(IO->ErrMsg, errmsg, -1);
			break;
		default:
			rc = StrBuf_write_one_chunk_callback(IO->SendBuf.fd,
							     0,
							     &IO->SendBuf);
		}

#ifdef BIGBAD_IODBG
		fprintf(fd, "Sent: BufSize: %d bytes.\n", rc);
		fclose(fd);
	}
#endif
	if (rc == 0)
	{
		ev_io_stop(event_base, &IO->send_event);
		switch (IO->NextState) {
		case eSendMore:
			assert(IO->SendDone);
			IO->NextState = IO->SendDone(IO);

			if ((IO->NextState == eTerminateConnection) ||
			    (IO->NextState == eAbort) )
				ShutDownCLient(IO);
			else {
				ev_io_start(event_base, &IO->send_event);
			}
			break;
		case eSendFile:
			if (IO->IOB.ChunkSendRemain > 0) {
				ev_io_start(event_base, &IO->recv_event);
				SetNextTimeout(IO, 100.0);

			} else {
				assert(IO->ReadDone);
				IO->NextState = IO->ReadDone(IO);
				switch(IO->NextState) {
				case eSendDNSQuery:
				case eReadDNSReply:
				case eDBQuery:
				case eConnect:
					break;
				case eSendReply:
				case eSendMore:
				case eSendFile:
					ev_io_start(event_base,
						    &IO->send_event);
					break;
				case eReadMessage:
				case eReadMore:
				case eReadPayload:
				case eReadFile:
					break;
				case eTerminateConnection:
				case eAbort:
					break;
				}
			}
			break;
		case eSendReply:
		    if (StrBufCheckBuffer(&IO->SendBuf) != eReadSuccess)
			break;
		    IO->NextState = eReadMore;
		case eReadMore:
		case eReadMessage:
		case eReadPayload:
		case eReadFile:
			if (StrBufCheckBuffer(&IO->RecvBuf) == eBufferNotEmpty)
			{
				HandleInbound(IO);
			}
			else {
				ev_io_start(event_base, &IO->recv_event);
			}

			break;
		case eDBQuery:
			/*
			 * we now live in another queue,
			 * so we have to unregister.
			 */
			ev_cleanup_stop(loop, &IO->abort_by_shutdown);
			break;
		case eSendDNSQuery:
		case eReadDNSReply:
		case eConnect:
		case eTerminateConnection:
		case eAbort:
			break;
		}
	}
	else if (rc < 0) {
		if (errno != EAGAIN) {
			StopClientWatchers(IO, 1);
			EV_syslog(LOG_DEBUG,
				  "IO_send_callback(): Socket Invalid! [%d] [%s] [%d]\n",
				  errno, strerror(errno), IO->SendBuf.fd);
			StrBufPrintf(IO->ErrMsg,
				     "Socket Invalid! [%s]",
				     strerror(errno));
			SetNextTimeout(IO, 0.01);
		}
	}
	/* else : must write more. */
}