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; } }
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; }
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. */ }