static void OnVolUpButton(WndButton* pWnd){ if(VolMode == VOL) { if(lVolume < 20) lVolume += 1; if(lVolume > 20) lVolume = 20; if (HoldOff ==0) { devPutVolume(devA(), lVolume); devPutVolume(devB(), lVolume); HoldOff = HOLDOFF_TIME; } } else { if(lSquelch < 10) lSquelch += 1; if(lSquelch > 10) lSquelch = 10; SqCnt =0; if (HoldOff ==0) { devPutSquelch(devA(), lSquelch); devPutSquelch(devB(), lSquelch); HoldOff = HOLDOFF_TIME; } } OnUpdate(); }
void LoggerImpl::LoggerDeviceDeclare() { bool found_logger = false; Declaration_t Decl; int i; GetRegistryString(szRegistryPilotName, Decl.PilotName, 64); GetRegistryString(szRegistryAircraftType, Decl.AircraftType, 32); GetRegistryString(szRegistryAircraftRego, Decl.AircraftRego, 32); for (i = 0; task.ValidTaskPoint(i); i++) { Decl.waypoint[i] = &task.getWaypoint(i); } Decl.num_waypoints = i; DeclaredToDevice = false; if (LoggerDeclare(devA(), &Decl)) found_logger = true; if (LoggerDeclare(devB(), &Decl)) found_logger = true; if (!found_logger) { MessageBoxX(gettext(TEXT("No logger connected")), devB()->Name, MB_OK| MB_ICONINFORMATION); DeclaredToDevice = true; // testing only } }
static void OnVolDownButton(WndButton* pWnd){ if(VolMode == VOL) { if(lVolume > 1) lVolume -= 1; if(lVolume < 1) lVolume = 1; if (HoldOff ==0) { devPutVolume(devA(), lVolume); devPutVolume(devB(), lVolume); HoldOff = HOLDOFF_TIME; } } else { if(lSquelch > 1) lSquelch -= 1; if(lSquelch < 1) lSquelch = 1; SqCnt =0; if (HoldOff ==0) { devPutSquelch(devA(), lSquelch); devPutSquelch(devB(), lSquelch); HoldOff = HOLDOFF_TIME; } } OnUpdate(); SendVolSq(); HoldOff = HOLDOFF_TIME; }
static void OnPassiveFreq(WndButton* pWnd){ TCHAR szFreq[8] ; _stprintf(szFreq, _T("%7.3f"),RadioPara.PassiveFrequency); TCHAR Name[20] = _T(" ??? "); dlgNumEntryShowModal(szFreq,8,false); double Frequency = StrToDouble(szFreq,NULL); while(Frequency > 1000) Frequency /=10; if(ValidFrequency(Frequency)) { _stprintf( RadioPara.PassiveName,_T(" ")); int iIdx = SearchStation(Frequency); if(iIdx != 0) { _stprintf(Name,_T("%s"),WayPointList[iIdx].Name); _stprintf( RadioPara.PassiveName,_T("%s"),WayPointList[iIdx].Name); PassiveRadioIndex = iIdx; } devPutFreqStandby(devA(), Frequency,Name); devPutFreqStandby(devB(), Frequency,Name); RadioPara.PassiveFrequency = Frequency; // _stprintf( RadioPara.PassiveName,_T("")); RadioPara.Changed =TRUE; // OnRemoteUpdate(); } OnUpdate(); }
static void OnPassiveButton(WndButton* pWnd){ if (HoldOff ==0) { int res = dlgWayPointSelect(0, 90.0, 1,3); // LKASSERT(res>=0); // LKASSERT(ValidWayPointFast(res)); if(res > RESWP_END ) if(ValidWayPoint(res)) { double Frequency = StrToDouble(WayPointList[res].Freq,NULL); if(Frequency < 100.0) { // DoStatusMessage(_T("No valid Frequency!") ); return; } devPutFreqStandby(devA(), Frequency, WayPointList[res].Name); devPutFreqStandby(devB(), Frequency, WayPointList[res].Name); _stprintf(RadioPara.PassiveName,_T("%s"), WayPointList[res].Name); RadioPara.PassiveFrequency = Frequency; PassiveRadioIndex = res; } OnUpdate(); HoldOff = HOLDOFF_TIME; } }
static void OnBugsData(DataField *Sender, DataField::DataAccessKind_t Mode){ static double lastRead = -1; switch(Mode){ case DataField::daGet: lastRead = BUGS; Sender->Set(BUGS*100); break; case DataField::daChange: case DataField::daPut: if (fabs(lastRead-Sender->GetAsFloat()/100.0) >= 0.005){ lastRead = BUGS = Sender->GetAsFloat()/100.0; GlidePolar::SetBallast(); devPutBugs(devA(), BUGS); devPutBugs(devB(), BUGS); } break; case DataField::daInc: case DataField::daDec: case DataField::daSpecial: break; } }
static void SetBallast(bool updateDevices) { WndProperty* wp; GlidePolar::SetBallast(); if (updateDevices) { devPutBallast(devA(), BALLAST); devPutBallast(devB(), BALLAST); } wp = (WndProperty*)wf->FindByName(TEXT("prpBallastPercent")); if (wp) { wp->GetDataField()->Set(BALLAST*100); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpBallastLitres")); if (wp) { wp->GetDataField()-> SetAsFloat(GlidePolar::BallastLitres); wp->RefreshDisplay(); } wp = (WndProperty*)wf->FindByName(TEXT("prpWingLoading")); if (wp) { wp->GetDataField()-> SetAsFloat(GlidePolar::WingLoading); wp->RefreshDisplay(); } // SetFocus( ((WndButton *)wf->FindByName(TEXT("buttonClose")))->GetHandle()); // not needed }
void MacCreadyProcessing(int UpDown) { if(UpDown==1) { CALCULATED_INFO.AutoMacCready=false; // 091214 disable AutoMacCready when changing MC values MACCREADY += (double)0.1/LIFTMODIFY; // BUGFIX 100102 if (MACCREADY>5.0) { // JMW added sensible limit MACCREADY=5.0; } } else if(UpDown==-1) { CALCULATED_INFO.AutoMacCready=false; // 091214 disable AutoMacCready when changing MC values MACCREADY -= (double)0.1/LIFTMODIFY; // 100102 if(MACCREADY < 0) { MACCREADY = 0; } } else if (UpDown==0) { CALCULATED_INFO.AutoMacCready = !CALCULATED_INFO.AutoMacCready; // JMW toggle automacready } else if (UpDown==-2) { CALCULATED_INFO.AutoMacCready = false; // SDP on auto maccready } else if (UpDown==+2) { CALCULATED_INFO.AutoMacCready = true; // SDP off auto maccready } else if (UpDown==3) { CALCULATED_INFO.AutoMacCready=false; // 091214 disable AutoMacCready when changing MC values MACCREADY += (double)0.5/LIFTMODIFY; // 100102 if (MACCREADY>5.0) MACCREADY=5.0; } else if (UpDown==-3) { CALCULATED_INFO.AutoMacCready=false; // 091214 disable AutoMacCready when changing MC values MACCREADY -= (double)0.5/LIFTMODIFY; // 100102 if (MACCREADY<0) MACCREADY=0; } devPutMacCready(devA(), MACCREADY); devPutMacCready(devB(), MACCREADY); return; }
void LoggerDeviceDeclare() { bool found_logger = false; Declaration_t Decl; int i; #if 0 if (CALCULATED_INFO.Flying) { // LKTOKEN _@M1423_ = "Forbidden during flight!" MessageBoxX(hWndMapWindow, gettext(TEXT("_@M1423_")), _T(""), MB_OK| MB_ICONINFORMATION); return; } #endif _tcscpy(Decl.PilotName, PilotName_Config); // max 64 _tcscpy(Decl.AircraftType,AircraftType_Config); // max 32 _tcscpy(Decl.AircraftRego,AircraftRego_Config); // max 32 _tcscpy(Decl.CompetitionClass,CompetitionClass_Config); // _tcscpy(Decl.CompetitionID,CompetitionID_Config); // max 32 for (i = 0; i < MAXTASKPOINTS; i++) { if (Task[i].Index == -1) break; Decl.waypoint[i] = &WayPointList[Task[i].Index]; } Decl.num_waypoints = i; DeclaredToDevice = false; if (LoggerDeclare(devA(), &Decl)) found_logger = true; if (LoggerDeclare(devB(), &Decl)) found_logger = true; if (!found_logger) { // LKTOKEN _@M474_ = "No logger connected" MessageBoxX(hWndMapWindow, gettext(TEXT("_@M474_")), devB()->Name, MB_OK| MB_ICONINFORMATION); DeclaredToDevice = true; // testing only } }
static void NextPage(int Step){ status_page += Step; if (status_page>=NUMPAGES) { status_page=0; } if (status_page<0) { status_page=NUMPAGES-1; } switch(status_page) { case 0: // LKTOKEN _@M661_ = "Status: Aircraft" wf->SetCaption(gettext(TEXT("_@M661_"))); break; case 1: if (SIMMODE) { TCHAR sysmode[100]; wsprintf(sysmode,_T("%s (%s)"),gettext(TEXT("_@M664_")),gettext(TEXT("_@M1211_")) ); wf->SetCaption(sysmode); } else { // LKTOKEN _@M664_ = "Status: System" wf->SetCaption(gettext(TEXT("_@M664_"))); if( GPS_INFO.FLARM_SW_Version < 0.01) { if(nmeaParser1.isFlarm) devRequestFlarmVersion(devA()); else if(nmeaParser2.isFlarm) devRequestFlarmVersion(devB()); } } break; case 2: // LKTOKEN _@M665_ = "Status: Task" wf->SetCaption(gettext(TEXT("_@M665_"))); break; case 3: // LKTOKEN _@M663_ = "Status: Rules" wf->SetCaption(gettext(TEXT("_@M663_"))); break; case 4: // LKTOKEN _@M666_ = "Status: Times" wf->SetCaption(gettext(TEXT("_@M666_"))); break; case 5: // LKTOKEN _@M662_ = "Status: Ext.Device" wf->SetCaption(gettext(TEXT("_@M662_"))); break; } wStatus0->SetVisible(status_page == 0); wStatus1->SetVisible(status_page == 1); wStatus2->SetVisible(status_page == 2); wStatus3->SetVisible(status_page == 3); wStatus4->SetVisible(status_page == 4); wStatus5->SetVisible(status_page == 5); }
static void OnDualButton(WndButton* pWnd){ TCHAR Name[250]; RadioPara.Dual = !RadioPara.Dual; devPutRadioMode(devA(), (int)RadioPara.Dual); devPutRadioMode(devB(), (int)RadioPara.Dual); if(RadioPara.Dual) _stprintf(Name,_T("Dual Off")); else _stprintf(Name,_T("Dual On")); if(wpnewDual) wpnewDual->SetCaption(Name); }
static void SetBallast(bool updateDevices) { WndProperty* wp; GlidePolar::SetBallast(); if (updateDevices) { devPutBallast(devA(), BALLAST); devPutBallast(devB(), BALLAST); } static double foldBallast = BALLAST; if(fabs (foldBallast - BALLAST) > 0.01) /* update on change only */ { wp = (WndProperty*)wf->FindByName(TEXT("prpBallastPercent")); if (wp) { wp->GetDataField()->Set(BALLAST*100); wp->RefreshDisplay(); foldBallast = BALLAST; } } static double foldLiter = GlidePolar::BallastLitres; if(fabs (foldLiter-GlidePolar::BallastLitres ) > 0.01) /* update on change only */ { wp = (WndProperty*)wf->FindByName(TEXT("prpBallastLitres")); if (wp) { wp->GetDataField()->SetAsFloat(GlidePolar::BallastLitres); wp->RefreshDisplay(); foldLiter = GlidePolar::BallastLitres ; } } static double fOldLoad = GlidePolar::WingLoading; if(fabs (fOldLoad-GlidePolar::WingLoading ) > 0.01) /* update on change only */ { wp = (WndProperty*)wf->FindByName(TEXT("prpWingLoading")); if (wp) { wp->GetDataField()-> SetAsFloat(GlidePolar::WingLoading); wp->RefreshDisplay(); fOldLoad = GlidePolar::WingLoading; } } // SetFocus( ((WndButton *)wf->FindByName(TEXT("buttonClose")))->GetHandle()); // not needed }
static void OnExchange(WndButton* pWnd){ int tmp; TCHAR szTempStr[50]; double fTmp; // if (HoldOff ==0) { tmp = ActiveRadioIndex; ActiveRadioIndex = PassiveRadioIndex; PassiveRadioIndex = tmp; devPutFreqSwap(devA()); devPutFreqSwap(devB()); fTmp = RadioPara.ActiveFrequency; RadioPara.ActiveFrequency = RadioPara.PassiveFrequency; RadioPara.PassiveFrequency= fTmp; _tcscpy( szTempStr, RadioPara.ActiveName); _tcscpy( RadioPara.ActiveName, RadioPara.PassiveName); _tcscpy( RadioPara.PassiveName, szTempStr); OnUpdate(); } }
static void OnRadioFrequencyClicked(WndButton* pWnd){ #ifdef RADIO_ACTIVE TCHAR szFreq[300]; double Ferquency; LKASSERT(SelectedWaypoint>=0); LKASSERT(ValidWayPointFast(SelectedWaypoint)); Ferquency = StrToDouble(WayPointList[SelectedWaypoint].Freq,NULL); devPutFreqActive(devA(), Ferquency, WayPointList[SelectedWaypoint].Name); devPutFreqActive(devB(), Ferquency, WayPointList[SelectedWaypoint].Name); _stprintf(szFreq,_T(" %6.3fMHz ") ,Ferquency); DoStatusMessage(_T(""), WayPointList[SelectedWaypoint].Name ); DoStatusMessage(_T("RADIO:"), szFreq ); retStatus=3; wf->SetModalResult(mrOK); #endif // RADIO_ACTIVE }
static int OnRemoteUpdate(void) { int Idx=0; if(RadioPara.Changed) { RadioPara.Changed =FALSE; TCHAR Name[250]; if(_tcscmp(_T(" "), RadioPara.ActiveName ) == 0) Idx = SearchStation(RadioPara.ActiveFrequency); if(Idx !=0) { _stprintf(RadioPara.ActiveName,_T("%s"),WayPointList[Idx].Name); ActiveRadioIndex = Idx; if( HoldOff ==0) { HoldOff = HOLDOFF_TIME; devPutFreqActive(devA(), RadioPara.ActiveFrequency, WayPointList[Idx].Name); devPutFreqActive(devB(), RadioPara.ActiveFrequency, WayPointList[Idx].Name); } } _stprintf(Name,_T("[%s]"),RadioPara.ActiveName); if(wpnewActive) wpnewActive->SetCaption(Name); _stprintf(Name,_T("%6.03f"),RadioPara.ActiveFrequency); if(wpnewActiveFreq) wpnewActiveFreq->SetCaption(Name); if(_tcscmp(_T(" "), RadioPara.PassiveName ) == 0) Idx = SearchStation(RadioPara.PassiveFrequency); if(Idx !=0) { _stprintf(RadioPara.PassiveName,_T("%s"),WayPointList[Idx].Name); PassiveRadioIndex = Idx; if( HoldOff ==0) { HoldOff = HOLDOFF_TIME; devPutFreqStandby(devA(), RadioPara.PassiveFrequency, WayPointList[Idx].Name); devPutFreqStandby(devB(), RadioPara.PassiveFrequency, WayPointList[Idx].Name); } } _stprintf(Name,_T("[%s]"),RadioPara.PassiveName); if(wpnewPassive) wpnewPassive->SetCaption(Name); _stprintf(Name,_T("%6.03f"),RadioPara.PassiveFrequency); if(wpnewPassiveFreq) wpnewPassiveFreq->SetCaption(Name); /* if( lSquelch != RadioPara.Squelch) { VolMode = SQL; SqCnt =0; } */ if( lVolume != RadioPara.Volume) VolMode = VOL; lSquelch = RadioPara.Squelch; lVolume = RadioPara.Volume; if(wpnewVol) { if(VolMode == VOL) _stprintf(Name,_T("V[%i]"),RadioPara.Volume); else _stprintf(Name,_T("S [%i]"),RadioPara.Squelch); wpnewVol->SetCaption(Name); } if(RadioPara.Dual) _stprintf(Name,_T("[Dual Off]")); else _stprintf(Name,_T("[Dual On]")); if(wpnewDual) wpnewDual->SetCaption(Name); return 1; } return 0; }
// // Run every 5 seconds, approx. // This is the hearth of LK. Questions? Ask Paolo.. // THIS IS RUNNING WITH LockComm from ConnectionProcessTimer . // void NMEAParser::UpdateMonitor(void) { short active=0; // active port number for gps static short lastactive=0; static bool lastvalidBaro=false; static bool wasSilent[2]={false,false}; short invalidGps=0; short invalidBaro=0; short validBaro=0; // does anyone have GPS? if (nmeaParser1.gpsValid || nmeaParser2.gpsValid) { if (nmeaParser1.gpsValid && nmeaParser2.gpsValid) { // both valid, just use first nmeaParser2.activeGPS = false; nmeaParser1.activeGPS = true; active=1; } else { // only one valid, pick it up nmeaParser1.activeGPS = nmeaParser1.gpsValid; nmeaParser2.activeGPS = nmeaParser2.gpsValid; active= nmeaParser1.activeGPS ? 1 : 2; } } else { // No valid fix on any port. We use the first port with at least some data going through! // This will keep probably at least the time updated since the gps may still be receiving a // valid time, good for us. if ( (LKHearthBeats-ComPortHB[0])<10 ) { // It is not granted that devA is really a GPS source. // Very unlikely, but possible.. if (devIsGPSSource(devA())) active=1; } else { if ( (LKHearthBeats-ComPortHB[1])<10 ) { // portB is really active, although there is no valid fix on it. // Before electing it to gps, lets be sure it really has one! // LKEXT1 and other instruments do not provide GPS source in fact. if (devIsGPSSource(devB())) active=2; } else { // nothing coming in from any port, recently. if (devIsGPSSource(devA())) active=1; // lets keep waiting for the first port } } switch(active) { case 0: nmeaParser1.activeGPS = false; nmeaParser2.activeGPS = false; break; case 1: nmeaParser1.activeGPS = true; nmeaParser2.activeGPS = false; break; case 2: nmeaParser1.activeGPS = false; nmeaParser2.activeGPS = true; break; default: nmeaParser1.activeGPS = false; nmeaParser2.activeGPS = false; LKASSERT(0); break; } } if (nmeaParser2.activeGPS==true && active==1) { StartupStore(_T(".... GPS Update error: port 1 and 2 are active! %s%s"),WhatTimeIsIt(),NEWLINE); nmeaParser2.activeGPS=false; // force it off active=1; } // wait for some seconds before monitoring, after startup if (LKHearthBeats<20) return; /* check if Flarm disappeared after 30 seconds no activity */ if (GPS_INFO.FLARM_Available && ((GPS_INFO.Time -LastFlarmCommandTime)> 30) ) { static unsigned short MessageCnt =0; if(MessageCnt <10) { MessageCnt++; StartupStore(_T(". FLARM lost! Disable FLARM functions !%s"),NEWLINE); DoStatusMessage(gettext(TEXT("_@M947_"))); // _@M947_ "FLARM SIGNAL LOST" } GPS_INFO.FLARM_Available = false; GPS_INFO.FLARM_HW_Version =0.0; GPS_INFO.FLARM_SW_Version =0.0; } // Check Port 1 with no serial activity in last seconds if ( (LKHearthBeats-ComPortHB[0])>10 ) { #ifdef DEBUGNPM StartupStore(_T("... GPS Port 1 : no activity LKHB=%u CBHB=%u %s"),LKHearthBeats, ComPortHB[0],NEWLINE); #endif // if this is active and supposed to have a valid fix.., but no HB.. if ( (active==1) && (nmeaParser1.gpsValid) ) { StartupStore(_T("... GPS Port 1 no hearthbeats, but still gpsValid: forced invalid %s%s"),WhatTimeIsIt(),NEWLINE); } nmeaParser1.gpsValid=false; invalidGps=1; // We want to be sure that if this device is silent, and it was providing Baro altitude, // now it is set to off. if (GPS_INFO.BaroAltitudeAvailable==TRUE) { if ( devA() == pDevPrimaryBaroSource || nmeaParser1.RMZAvailable || nmeaParser1.TASAvailable ) { invalidBaro=1; } } nmeaParser1._Reset(); nmeaParser1.activeGPS=false; // because Reset is setting it to true // We reset some flags globally only once in case of device gone silent if (!devIsDisabled(0) && !wasSilent[0]) { GPS_INFO.AirspeedAvailable=false; GPS_INFO.VarioAvailable=false; GPS_INFO.NettoVarioAvailable=false; GPS_INFO.AccelerationAvailable = false; EnableExternalTriggerCruise = false; wasSilent[0]=true; } } else { wasSilent[0]=false; // We have hearth beats, is baro available? if ( devIsBaroSource(devA()) || nmeaParser1.RMZAvailable || nmeaParser1.TASAvailable ) // 100411 validBaro++; } // now check also port 2 if ( (LKHearthBeats-ComPortHB[1])>10 ) { #ifdef DEBUGNPM StartupStore(_T("... GPS Port 2 : no activity LKHB=%u CBHB=%u %s"),LKHearthBeats, ComPortHB[1],NEWLINE); #endif if ( (active==2) && (nmeaParser2.gpsValid) ) { StartupStore(_T("... GPS port 2 no hearthbeats, but still gpsValid: forced invalid %s%s"),WhatTimeIsIt(),NEWLINE); } nmeaParser2.gpsValid=false; invalidGps++; if (GPS_INFO.BaroAltitudeAvailable==TRUE) { if ( devB() == pDevPrimaryBaroSource || nmeaParser2.RMZAvailable || nmeaParser2.TASAvailable ) { invalidBaro++; } } nmeaParser2._Reset(); nmeaParser2.activeGPS=false; // because Reset is setting it to true if (!devIsDisabled(1) && !wasSilent[1]) { GPS_INFO.AirspeedAvailable=false; GPS_INFO.VarioAvailable=false; GPS_INFO.NettoVarioAvailable=false; GPS_INFO.AccelerationAvailable = false; EnableExternalTriggerCruise = false; wasSilent[1]=true; } } else { wasSilent[1]=false; // We have hearth beats, is baro available? if ( devIsBaroSource(devB()) || nmeaParser2.RMZAvailable || nmeaParser2.TASAvailable ) // 100411 validBaro++; } #ifdef DEBUGNPM if (invalidGps==2) { StartupStore(_T("... GPS no gpsValid available on port 1 and 2, active=%d @%s%s"),active,WhatTimeIsIt(),NEWLINE); } if (invalidBaro>0) { StartupStore(_T("... Baro altitude just lost, current status=%d @%s%s"),GPS_INFO.BaroAltitudeAvailable,WhatTimeIsIt(),NEWLINE); } #endif // do we really still have a baro altitude available? // If some baro source disappeared, let's reset it for safety. Parser will re-enable them immediately if available. // Assuming here that if no Baro is available, no airdata is available also // if (validBaro==0) { if ( GPS_INFO.BaroAltitudeAvailable ) { StartupStore(_T("... GPS no active baro source, and still BaroAltitudeAvailable, forced off %s%s"),WhatTimeIsIt(),NEWLINE); if (EnableNavBaroAltitude && active) { // LKTOKEN _@M122_ = "BARO ALTITUDE NOT AVAILABLE, USING GPS ALTITUDE" DoStatusMessage(MsgToken(122)); PortMonitorMessages++; } else { // LKTOKEN _@M121_ = "BARO ALTITUDE NOT AVAILABLE" DoStatusMessage(MsgToken(121)); } GPS_INFO.BaroAltitudeAvailable=FALSE; // We alse reset these values, just in case we are through a mux GPS_INFO.AirspeedAvailable=false; GPS_INFO.VarioAvailable=false; GPS_INFO.NettoVarioAvailable=false; GPS_INFO.AccelerationAvailable = false; EnableExternalTriggerCruise = false; nmeaParser1._Reset(); nmeaParser2._Reset(); // 120824 Check this situation better> Reset is setting activeGPS true for both devices! lastvalidBaro=false; } } else { if ( lastvalidBaro==false) { #if DEBUGBARO TCHAR devname[50]; if (pDevPrimaryBaroSource) { LK_tcsncpy(devname,pDevPrimaryBaroSource->Name,49); } else { _tcscpy(devname,_T("unknown")); } StartupStore(_T("... GPS baro source back available from <%s>%s"),devname,NEWLINE); #endif if (GotFirstBaroAltitude) { if (EnableNavBaroAltitude) { DoStatusMessage(MsgToken(1796)); // USING BARO ALTITUDE } else { DoStatusMessage(MsgToken(1795)); // BARO ALTITUDE IS AVAILABLE } StartupStore(_T("... GPS baro source back available %s%s"),WhatTimeIsIt(),NEWLINE); lastvalidBaro=true; } else { static bool said=false; if (!said) { StartupStore(_T("... GPS BARO SOURCE PROBLEM, umnanaged port activity. Wrong device? %s%s"),WhatTimeIsIt(),NEWLINE); said=true; } } } else { // last baro was Ok, currently we still have a validbaro, but no HBs... // Probably it is a special case when no gps fix was found on the secondary baro source. if (invalidBaro||!GotFirstBaroAltitude) { GPS_INFO.BaroAltitudeAvailable=FALSE; #ifdef DEBUGNPM StartupStore(_T(".... We still have valid baro, resetting BaroAltitude OFF %s\n"),WhatTimeIsIt()); #endif } } } // Very important check for multiplexers: if RMZ did not get through in the past seconds, we want to // be very sure that there still is one incoming, otherwise we shall be UpdatingBaroSource using the old one, // never really updated!! This is because GGA and RMC are using RMZAvailable to UpdateBaroSource, no matter if // there was a real RMZ in the NMEA stream lately. // Normally RMZAvailable, RMCAvailable, GGA etc.etc. are reset to false when the com port is silent. // But RMZ is special, because it can be sent through the multiplexer from a flarm box. if ( (nmeaParser1.RMZAvailable || nmeaParser2.RMZAvailable) && (LKHearthBeats > (LastRMZHB+5))) { #if DEBUGBARO StartupStore(_T(".... RMZ not updated recently, resetting HB\n")); #endif nmeaParser1.RMZAvailable = FALSE; nmeaParser2.RMZAvailable = FALSE; } // Check baro altitude problems. This can happen for several reasons: mixed input on baro on same port, // faulty device, etc. The important thing is that we shall not be using baro altitude for navigation in such cases. // So we do this check only for the case we are actually using baro altitude. // A typical case is: mixed devices on same port, baro altitude disappearing because of mechanical switch, // but other traffic still incoming, so hearthbeats are ok. static double lastBaroAltitude=-1, lastGPSAltitude=-1; static unsigned int counterSameBaro=0, counterSameHGPS=0; static unsigned short firstrecovery=0; if (GPS_INFO.BaroAltitudeAvailable && EnableNavBaroAltitude && !GPS_INFO.NAVWarning) { if (GPS_INFO.BaroAltitude==lastBaroAltitude) { counterSameBaro++; } else { lastBaroAltitude=GPS_INFO.BaroAltitude; counterSameBaro=0; } if (GPS_INFO.Altitude==lastGPSAltitude) { counterSameHGPS++; } else { lastGPSAltitude=GPS_INFO.Altitude; counterSameHGPS=0; } // This is suspicious enough, because the baro altitude is a floating value, should not be the same.. // but ok, lets assume it is filtered. // if HBAR is steady for some time ... and HGPS is not steady unsigned short timethreshold=15; // first three times, timeout at about 1 minute if (firstrecovery>=3) timethreshold=40; // then about every 3 minutes if ( ((counterSameBaro > timethreshold) && (counterSameHGPS<2)) && (fabs(GPS_INFO.Altitude-GPS_INFO.BaroAltitude)>100.0) && !CALCULATED_INFO.OnGround ) { DoStatusMessage(MsgToken(122)); // Baro not available, Using GPS ALTITUDE EnableNavBaroAltitude=false; StartupStore(_T("... WARNING, NavBaroAltitude DISABLED due to possible fault: baro steady at %f, HGPS=%f @%s%s"), GPS_INFO.BaroAltitude, GPS_INFO.Altitude,WhatTimeIsIt(),NEWLINE); lastBaroAltitude=-1; lastGPSAltitude=-1; counterSameBaro=0; counterSameHGPS=0; // We do only ONE attempt to recover a faulty device, to avoid flipflopping. // In case of big problems, we shall have disabled the use of the faulty baro altitude, and keep it // incoming sporadically. if (firstrecovery<3) { GPS_INFO.BaroAltitudeAvailable=FALSE; // We alse reset these values, just in case we are through a mux GPS_INFO.AirspeedAvailable=false; GPS_INFO.VarioAvailable=false; GPS_INFO.NettoVarioAvailable=false; GPS_INFO.AccelerationAvailable = false; EnableExternalTriggerCruise = false; nmeaParser1._Reset(); nmeaParser2._Reset(); // 120824 Check this situation better> Reset is setting activeGPS true for both devices! lastvalidBaro=false; GotFirstBaroAltitude=false; firstrecovery++; } } } // Set some fine tuning parameters here, depending on device/situation/mode if (ISCAR) trackbearingminspeed=0; // trekking mode/car mode, min speed >0 else trackbearingminspeed=1; // flymode, min speed >1 knot // // Following is for diagnostics only // // Nothing has changed? No need to give new alerts. We might have no active gps at all, also. // In this case, active and lastactive are 0, nothing we can do about it. if (active == lastactive) return; if (active!=0) StartupStore(_T(". GPS NMEA source changed to port %d %s%s"),active,WhatTimeIsIt(),NEWLINE); else StartupStore(_T("... GPS NMEA source PROBLEM, no active GPS! %s%s"),WhatTimeIsIt(),NEWLINE); if (PortMonitorMessages<15) { // do not overload pilot with messages! // do not say anything if we never got the first port, on startup essentially if ((lastactive!=0) && (nmeaParser1.gpsValid || nmeaParser2.gpsValid)){ TCHAR vbuf[100]; _stprintf(vbuf,_T("%s %d"), MsgToken(277),active); // FALLBACK USING GPS ON PORT .. DoStatusMessage(vbuf); PortMonitorMessages++; } } else { if (PortMonitorMessages==15) { StartupStore(_T("... GOING SILENT on too many Com reportings. %s%s"),WhatTimeIsIt(),NEWLINE); DoStatusMessage(MsgToken(317)); // GOING SILENT ON COM REPORTING PortMonitorMessages++; // we go to 16, and never be back here } } lastactive=active; }
BOOL PVCOMParseString(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *info) { TCHAR device[250]; TCHAR cmd[220]; TCHAR dir[220]; TCHAR para1[250]; TCHAR para2[250]; if (!NMEAParser::NMEAChecksum(String) ) { // DoStatusMessage(_T("RADIO Checksum Error!") ); return FALSE; } NMEAParser::ExtractParameter(String,device,0); if(_tcsncmp(_T("$PEYI"), device, 5) == 0) return PVCOM_ProcessPEYI(d, String + 6, info); if ((_tcsncmp(_T("$PVCOM"), device,5) == 0) ) { NMEAParser::ExtractParameter(String,dir,1); if(_tcscmp(_T("A"), dir) == 0) { RadioPara.Changed = TRUE; if(RadioPara.Enabled == FALSE) { DoStatusMessage(_T("RADIO Detected!") ); PVCOMRequestAllData(devA()) ; PVCOMRequestAllData(devB()) ; RadioPara.Enabled = TRUE; } NMEAParser::ExtractParameter(String,cmd,2); if(_tcscmp(_T("AF"), cmd) == 0) { NMEAParser::ExtractParameter(String,para1,3); NMEAParser::ExtractParameter(String,para2,4); RadioPara.ActiveFrequency = StrToDouble(para1,NULL); _stprintf(RadioPara.ActiveName,_T("%s"),para2); } else if(_tcscmp(_T("PF"), cmd) == 0) { NMEAParser::ExtractParameter(String,para1,3); NMEAParser::ExtractParameter(String,para2,4); RadioPara.PassiveFrequency = StrToDouble(para1,NULL); _stprintf(RadioPara.PassiveName,_T("%s"),para2); } else if(_tcscmp(_T("VOL"), cmd) == 0) { NMEAParser::ExtractParameter(String,para1,3); RadioPara.Volume = (int)StrToDouble(para1,NULL); } else if(_tcscmp(_T("SQL"), cmd) == 0) { NMEAParser::ExtractParameter(String,para1,3); RadioPara.Squelch = (int)StrToDouble(para1,NULL); } else if(_tcscmp(_T("CHG"), cmd) == 0) { NMEAParser::ExtractParameter(String,para1,3); NMEAParser::ExtractParameter(String,para2,4); RadioPara.ActiveFrequency = StrToDouble(para1,NULL); _stprintf(RadioPara.ActiveName,_T("%s"),para2); NMEAParser::ExtractParameter(String,para1,5); NMEAParser::ExtractParameter(String,para2,6); RadioPara.PassiveFrequency = StrToDouble(para1,NULL); _stprintf(RadioPara.PassiveName,_T("%s"),para2); } else if(_tcscmp(_T("STA"), cmd) == 0) { NMEAParser::ExtractParameter(String,para1,3); if(_tcsncmp(_T("DUAL_ON"), para1, 7) == 0) RadioPara.Dual = TRUE; if(_tcsncmp(_T("DUAL_OFF"), para1, 8) == 0) RadioPara.Dual = FALSE; if(_tcsncmp(_T("8_33KHZ"), para1, 8) == 0) RadioPara.Enabled8_33 = TRUE; if(_tcsncmp(_T("25KHZ"), para1, 8) == 0) RadioPara.Enabled8_33 = FALSE; if(_tcsncmp(_T("8_33KHZ"), para1, 6) == 0) RadioPara.Enabled8_33 = TRUE; if(_tcsncmp(_T("25KHZ"), para1, 4) == 0) RadioPara.Enabled8_33 = FALSE; if(_tcsncmp(_T("BAT_LOW"), para1, 7) == 0) RadioPara.lowBAT = TRUE; if(_tcsncmp(_T("BAT_OK"), para1, 6) == 0) RadioPara.lowBAT = FALSE; if(_tcsncmp(_T("RX_ON"), para1, 5) == 0) RadioPara.RX = TRUE; if(_tcsncmp(_T("RX_OFF"), para1, 6) == 0) RadioPara.RX = FALSE; if(_tcsncmp(_T("TX_ON"), para1, 5) == 0) RadioPara.TX = TRUE; if(_tcsncmp(_T("RX_TX_OFF"), para1, 9) == 0) { RadioPara.RX = FALSE; RadioPara.TX = FALSE; RadioPara.TXtimeout = FALSE; RadioPara.RX_active = FALSE; RadioPara.RX_standy = FALSE; } if(_tcsncmp(_T("TE_ON"), para1, 5) == 0) RadioPara.TXtimeout = TRUE; if(_tcsncmp(_T("RX_AF"), para1, 5) == 0) RadioPara.RX_active = TRUE; if(_tcsncmp(_T("RX_SF"), para1, 5) == 0) RadioPara.RX_standy = TRUE; } } } return RadioPara.Changed; }
BOOL NMEAParser::PFLAU(TCHAR *String, TCHAR **params, size_t nparams, NMEA_INFO *pGPS) { static int old_flarm_rx = 0; static bool sayflarmavailable=true; // 100325 static bool conflict=false; // It can happen that both port auto/exclude themselves, or one will succeed to survive. // In either cases, there is a bad problem going on. Recovery should not be a choice. if (conflict) return FALSE; // // We want to be sure that we are not going to elect as Flarm two simultaneous ports. // We let it happen once, and give warning. Then only one of the two will remain. // It is a real borderline situation, due to conflict on comm ports, normally virtual com ports. if (nmeaParser1.gpsValid && nmeaParser2.gpsValid) { if (nmeaParser1.isFlarm && nmeaParser2.isFlarm) { DoStatusMessage(_T("FLARM DETECTED ON TWO COM PORTS! AUTO-EXCLUDING.")); StartupStore(_T("......... WARNING! FLARM DETECTED ON TWO COM PORTS! %s\n"), WhatTimeIsIt()); pGPS->FLARM_Available = false; isFlarm = false; conflict=true; return FALSE; } } if(!pGPS->FLARM_Available) sayflarmavailable = true; pGPS->FLARM_Available = true; LastFlarmCommandTime = pGPS->Time; isFlarm = true; if ( sayflarmavailable ) { pGPS->FLARM_SW_Version =0.0; pGPS->FLARM_HW_Version =0.0; static int MessageCnt =0; if(MessageCnt < 10) { MessageCnt++; DoStatusMessage(gettext(TEXT("_@M279_"))); // FLARM DETECTED } sayflarmavailable=false; if(nmeaParser1.isFlarm) { devRequestFlarmVersion(devA()); } else { if(nmeaParser2.isFlarm) devRequestFlarmVersion(devB()); } } // calculate relative east and north projection to lat/lon double delta_lat = 0.01; double delta_lon = 0.01; double dlat; DistanceBearing(pGPS->Latitude, pGPS->Longitude, pGPS->Latitude+delta_lat, pGPS->Longitude, &dlat, NULL); double dlon; DistanceBearing(pGPS->Latitude, pGPS->Longitude, pGPS->Latitude, pGPS->Longitude+delta_lon, &dlon, NULL); if ((fabs(dlat)>0.0)&&(fabs(dlon)>0.0)) { FLARM_NorthingToLatitude = delta_lat / dlat; FLARM_EastingToLongitude = delta_lon / dlon; } else { FLARM_NorthingToLatitude=0.0; FLARM_EastingToLongitude=0.0; } swscanf(String, TEXT("%hu,%hu,%hu,%hu"), &pGPS->FLARM_RX, // number of received FLARM devices &pGPS->FLARM_TX, // Transmit status &pGPS->FLARM_GPS, // GPS status &pGPS->FLARM_AlarmLevel); // Alarm level of FLARM (0-3) // process flarm updates if ((pGPS->FLARM_RX) && (old_flarm_rx==0)) { // traffic has appeared.. InputEvents::processGlideComputer(GCE_FLARM_TRAFFIC); } if (pGPS->FLARM_RX > old_flarm_rx) { // re-set suppression of gauge, as new traffic has arrived // GaugeFLARM::Suppress = false; } if ((pGPS->FLARM_RX==0) && (old_flarm_rx)) { // traffic has disappeared.. InputEvents::processGlideComputer(GCE_FLARM_NOTRAFFIC); } // TODO feature: add another event for new traffic. old_flarm_rx = pGPS->FLARM_RX; return FALSE; }
BOOL devInit(LPTSTR CommandLine){ int i; TCHAR DeviceName[DEVNAMESIZE+1]; PDeviceDescriptor_t pDevNmeaOut = NULL; static bool doinit=true; for (i=0; i<NUMDEV; i++){ DeviceList[i].Port = -1; DeviceList[i].fhLogFile = NULL; DeviceList[i].Name[0] = '\0'; DeviceList[i].ParseNMEA = NULL; DeviceList[i].PutMacCready = NULL; DeviceList[i].DirectLink = NULL; DeviceList[i].PutBugs = NULL; DeviceList[i].PutBallast = NULL; DeviceList[i].Open = NULL; DeviceList[i].Close = NULL; DeviceList[i].Init = NULL; DeviceList[i].LinkTimeout = NULL; DeviceList[i].Declare = NULL; DeviceList[i].IsLogger = devIsFalseReturn; DeviceList[i].IsGPSSource = devIsFalseReturn; DeviceList[i].IsBaroSource = devIsFalseReturn; DeviceList[i].IsRadio = devIsFalseReturn; DeviceList[i].PutVoice = (int (*)(struct DeviceDescriptor_t *,TCHAR *))devIsFalseReturn; DeviceList[i].PortNumber = i; DeviceList[i].PutQNH = NULL; DeviceList[i].OnSysTicker = NULL; DeviceList[i].pDevPipeTo = NULL; DeviceList[i].PutVolume = NULL; DeviceList[i].PutFreqActive = NULL; DeviceList[i].PutFreqStandby = NULL; DeviceList[i].IsCondor = devIsFalseReturn; DeviceList[i].Disabled = true; ComPortStatus[i]=CPS_UNUSED; // 100210 ComPortHB[i]=0; // counter if (doinit) { ComPortRx[i]=0; ComPortTx[i]=0; ComPortErrTx[i]=0; ComPortErrRx[i]=0; ComPortErrors[i]=0; doinit=false; } } pDevPrimaryBaroSource = NULL; pDevSecondaryBaroSource=NULL; ReadDeviceSettings(0, DeviceName); #ifdef DEBUG_DEVSETTING StartupStore(_T(".......... ReadDeviceSetting 0, DeviceName=<%s>\n"),DeviceName); #endif PortIndex1 = 0; SpeedIndex1 = 2; Bit1Index=(BitIndex_t)bit8N1; ReadPort1Settings(&PortIndex1,&SpeedIndex1,&Bit1Index); //if (_tcslen(DeviceName)>0) // removed 110530 if (wcscmp(DeviceName,_T(DEV_DISABLED_NAME))!=0) { DeviceList[0].Disabled=false; StartupStore(_T(". Device A is <%s> Port=%s%s"),DeviceName,COMMPort[PortIndex1],NEWLINE); } else { DeviceList[0].Disabled=true; StartupStore(_T(". Device A is DISABLED.%s"),NEWLINE); } for (i=DeviceRegisterCount-1; i>=0; i--) { if (DeviceList[0].Disabled) break; if ((_tcscmp(DeviceRegister[i].Name, DeviceName) == 0)) { ComPort *Com = new ComPort(0); // remember: Port1 is the port used by device A, port1 may be Com3 or Com1 etc // this is port 1, so index 0 for us. if (!Com->Initialize(COMMPort[PortIndex1], dwSpeed[SpeedIndex1],Bit1Index,0)) { delete Com; ComPortStatus[0]=CPS_OPENKO; break; } ComPortStatus[0]=CPS_OPENOK; DeviceRegister[i].Installer(devA()); if ((pDevNmeaOut == NULL) && (DeviceRegister[i].Flags & (1l << dfNmeaOut))){ pDevNmeaOut = devA(); } devA()->Com = Com; devInit(devA()); devOpen(devA(), 0); if (devIsBaroSource(devA())) { if (pDevPrimaryBaroSource == NULL){ pDevPrimaryBaroSource = devA(); } else if (pDevSecondaryBaroSource == NULL){ pDevSecondaryBaroSource = devA(); } } break; } } ReadDeviceSettings(1, DeviceName); #ifdef DEBUG_DEVSETTING StartupStore(_T(".......... ReadDeviceSetting 1, DeviceName=<%s>\n"),DeviceName); #endif PortIndex2 = 0; SpeedIndex2 = 2, Bit2Index=(BitIndex_t)bit8N1; ReadPort2Settings(&PortIndex2,&SpeedIndex2, &Bit2Index); //if (_tcslen(DeviceName)>0) // removed 110530 if (wcscmp(DeviceName,_T(DEV_DISABLED_NAME))!=0) { DeviceList[1].Disabled=false; StartupStore(_T(". Device B is <%s> Port=%s%s"),DeviceName,COMMPort[PortIndex2],NEWLINE); } else { DeviceList[1].Disabled=true; StartupStore(_T(". Device B is DISABLED.%s"),NEWLINE); } for (i=DeviceRegisterCount-1; i>=0; i--) { if (PortIndex1 == PortIndex2) break; if (DeviceList[1].Disabled) break; if ((_tcscmp(DeviceRegister[i].Name, DeviceName) == 0)) { ComPort *Com = new ComPort(1); // this is port 2, so index 1 for us if (!Com->Initialize(COMMPort[PortIndex2], dwSpeed[SpeedIndex2],Bit2Index,1)) { // 100210 delete Com; ComPortStatus[1]=CPS_OPENKO; break; } ComPortStatus[1]=CPS_OPENOK; DeviceRegister[i].Installer(devB()); if ((pDevNmeaOut == NULL) && (DeviceRegister[i].Flags & (1l << dfNmeaOut))){ pDevNmeaOut = devB(); } devB()->Com = Com; devInit(devB()); devOpen(devB(), 1); if (devIsBaroSource(devB())) { if (pDevPrimaryBaroSource == NULL){ pDevPrimaryBaroSource = devB(); } else if (pDevSecondaryBaroSource == NULL){ pDevSecondaryBaroSource = devB(); } } break; } } if (pDevNmeaOut != NULL){ if (pDevNmeaOut == devA()){ devB()->pDevPipeTo = devA(); } if (pDevNmeaOut == devB()){ devA()->pDevPipeTo = devB(); } } return(TRUE); }
//#define DEBUGNPM 1 // run every 5 seconds, approx. void NMEAParser::UpdateMonitor(void) { short active; static short lastactive=0; static bool lastvalidBaro=false; short invalidGps=0; short invalidBaro=0; short validBaro=0; // does anyone have GPS? if (nmeaParser1.gpsValid || nmeaParser2.gpsValid) { if (nmeaParser1.gpsValid && nmeaParser2.gpsValid) { // both valid, just use first nmeaParser2.activeGPS = false; nmeaParser1.activeGPS = true; active=1; } else { nmeaParser1.activeGPS = nmeaParser1.gpsValid; nmeaParser2.activeGPS = nmeaParser2.gpsValid; active= nmeaParser1.activeGPS ? 1 : 2; } } else { // assume device 1 is active nmeaParser2.activeGPS = false; nmeaParser1.activeGPS = true; active=1; } #if 1 // TODO better check if ok if (nmeaParser2.activeGPS==true && active==1) { StartupStore(_T("... GPS Update error: port 1 and 2 are active!%s"),NEWLINE); FailStore(_T("... GPS Update error: port 1 and 2 are active!%s"),NEWLINE); nmeaParser2.activeGPS=false; // force it off active=1; } #endif // wait for some seconds before monitoring, after startup if (LKHearthBeats<20) return; // Check Port 1 with no serial activity in last seconds if ( (LKHearthBeats-ComPortHB[0])>10 ) { #ifdef DEBUGNPM StartupStore(_T("... GPS Port 1 : no activity LKHB=%.0f CBHB=%.0f %s"),LKHearthBeats, ComPortHB[0],NEWLINE); #endif // if this is active and supposed to have a valid fix.., but no HB.. if ( (active==1) && (nmeaParser1.gpsValid) ) { StartupStore(_T("... GPS Port 1 no hearthbeats, but still gpsValid: forced invalid%s"),NEWLINE); } nmeaParser1.gpsValid=false; invalidGps=1; #if DUALBARO // We want to be sure that if this device is silent, and it was providing Baro altitude, // now it is set to off. if (GPS_INFO.BaroAltitudeAvailable==TRUE) { if ( devA() == pDevPrimaryBaroSource || nmeaParser1.RMZAvailable || nmeaParser1.RMAAvailable || nmeaParser1.TASAvailable ) { invalidBaro=1; } } #endif } else { // We have hearth beats, is baro available? if ( devIsBaroSource(devA()) || nmeaParser1.RMZAvailable || nmeaParser1.RMAAvailable || nmeaParser1.TASAvailable ) // 100411 validBaro++; } // now check also port 2 if ( (LKHearthBeats-ComPortHB[1])>10 ) { #ifdef DEBUGNPM StartupStore(_T("... GPS Port 2 : no activity LKHB=%.0f CBHB=%.0f %s"),LKHearthBeats, ComPortHB[1],NEWLINE); #endif if ( (active==2) && (nmeaParser2.gpsValid) ) { StartupStore(_T("... GPS port 2 no hearthbeats, but still gpsValid: forced invalid%s"),NEWLINE); } nmeaParser2.gpsValid=false; invalidGps++; #if DUALBARO if (GPS_INFO.BaroAltitudeAvailable==TRUE) { if ( devB() == pDevPrimaryBaroSource || nmeaParser2.RMZAvailable || nmeaParser2.RMAAvailable || nmeaParser2.TASAvailable ) { invalidBaro++; } } #endif } else { // We have hearth beats, is baro available? if ( devIsBaroSource(devB()) || nmeaParser2.RMZAvailable || nmeaParser2.RMAAvailable || nmeaParser2.TASAvailable ) // 100411 validBaro++; } #ifdef DEBUGNPM if (invalidGps==2) { StartupStore(_T("... GPS no gpsValid available on port 1 and 2, active=%d%s"),active,NEWLINE); } if (invalidBaro>0) { StartupStore(_T("... Baro altitude just lost, current status=%d%s"),GPS_INFO.BaroAltitudeAvailable,NEWLINE); } #endif // do we really still have a baro altitude available? // If some baro source disappeared, let's reset it for safety. Parser will re-enable them immediately if available. // Assuming here that if no Baro is available, no airdata is available also // if (validBaro==0) { if ( GPS_INFO.BaroAltitudeAvailable ) { StartupStore(_T("... GPS no active baro source, and still BaroAltitudeAvailable, forced off%s"),NEWLINE); if (EnableNavBaroAltitude) { // LKTOKEN _@M122_ = "BARO ALTITUDE NOT AVAILABLE, USING GPS ALTITUDE" DoStatusMessage(gettext(TEXT("_@M122_"))); PortMonitorMessages++; // 100911 } else // LKTOKEN _@M121_ = "BARO ALTITUDE NOT AVAILABLE" DoStatusMessage(gettext(TEXT("_@M121_"))); GPS_INFO.BaroAltitudeAvailable=false; GPS_INFO.AirspeedAvailable=false; GPS_INFO.VarioAvailable=false; GPS_INFO.NettoVarioAvailable=false; lastvalidBaro=false; } } else { if ( lastvalidBaro==false) { StartupStore(_T("... GPS baro source back available%s"),NEWLINE); if (EnableNavBaroAltitude) // LKTOKEN _@M755_ = "USING AVAILABLE BARO ALTITUDE" DoStatusMessage(gettext(TEXT("_@M755_"))); else // LKTOKEN _@M120_ = "BARO ALTITUDE IS AVAILABLE" DoStatusMessage(gettext(TEXT("_@M120_"))); lastvalidBaro=true; } #if DUALBARO else { // last baro was Ok, currently we still have a validbaro, but no HBs... // Probably it is a special case when no gps fix was found on the secondary baro source. if (invalidBaro) { GPS_INFO.BaroAltitudeAvailable=FALSE; #ifdef DEBUGNPM StartupStore(_T(".... We still have valid baro, resetting BaroAltitude OFF\n")); #endif } } #endif } // Following diagnostics only if (active == lastactive) return; if (lastactive==0) { lastactive=active; StartupStore(_T(". GPS NMEA init delegated to port %d%s"),active,NEWLINE); return; } lastactive=active; // in case of no gps at all, port 1 is selected but we dont want to tell unless really working if (PortMonitorMessages<10) { // 100221 do not overload pilot with messages! StartupStore(_T("... GPS NMEA source changed to port %d %s"),active,NEWLINE); if (nmeaParser1.gpsValid || nmeaParser2.gpsValid){ TCHAR vbuf[100]; _stprintf(vbuf,_T("%s %d"), // LKTOKEN _@M277_ = "FALLBACK USING GPS ON PORT" gettext(TEXT("_@M277_")),active); DoStatusMessage(vbuf); } PortMonitorMessages++; } else { if (PortMonitorMessages==10) { // 100221 StartupStore(_T("... GOING SILENT on too many Com reportings.%s"),NEWLINE); // LKTOKEN _@M317_ = "GOING SILENT ON COM REPORTING" DoStatusMessage(gettext(TEXT("_@M317_"))); PortMonitorMessages++; } else PortMonitorMessages++; } }
BOOL devInit(LPCTSTR CommandLine) { TCHAR DeviceName[DEVNAMESIZE + 1]; PDeviceDescriptor_t pDevNmeaOut = NULL; TCHAR Port[MAX_PATH] = {_T('\0')}; DWORD SpeedIndex = 2; DWORD BitIndex = (BitIndex_t) bit8N1; static bool doinit = true; pDevPrimaryBaroSource = NULL; pDevSecondaryBaroSource = NULL; std::set<std::wstring> UsedPort; // list of already used port for (unsigned i = 0; i < NUMDEV; i++) { DeviceList[i].InitStruct(i); ComPortStatus[i] = CPS_UNUSED; // 100210 ComPortHB[i] = 0; // counter if (doinit) { ComPortRx[i] = 0; ComPortTx[i] = 0; ComPortErrTx[i] = 0; ComPortErrRx[i] = 0; ComPortErrors[i] = 0; doinit = false; } if (SIMMODE){ continue; } ReadDeviceSettings(i, DeviceName); DeviceList[i].Disabled = (wcscmp(DeviceName, _T(DEV_DISABLED_NAME)) == 0); if (DeviceList[i].Disabled) { StartupStore(_T(". Device %c is DISABLED.%s"), (_T('A') + i), NEWLINE); continue; } DeviceRegister_t* pDev = std::find_if(&DeviceRegister[0], &DeviceRegister[DeviceRegisterCount], devNameCompare(DeviceName)); if (pDev == &DeviceRegister[DeviceRegisterCount]) { DeviceList[i].Disabled = true; StartupStore(_T(". Device %c : invalide drivers name <%s>%s"), (_T('A') + i), DeviceName, NEWLINE); continue; } if(_tcscmp(pDev->Name,TEXT("Internal")) == 0) { _tcscpy(Port, _T("GPSID")); } else { Port[0] = _T('\0'); SpeedIndex = 2; BitIndex = (BitIndex_t) bit8N1; ReadPortSettings(i, Port, &SpeedIndex, &BitIndex); } // remember: Port1 is the port used by device A, port1 may be Com3 or Com1 etc if(std::find(UsedPort.begin(), UsedPort.end(), Port) != UsedPort.end()) { StartupStore(_T(". Port <%s> Already used, Device %c Disabled ! %s"), Port, (_T('A') + i), NEWLINE); continue; } UsedPort.insert(Port); // remember: Port1 is the port used by device A, port1 may be Com3 or Com1 etc StartupStore(_T(". Device %c is <%s> Port=%s%s"), (_T('A') + i), DeviceName, Port, NEWLINE); ComPort *Com = NULL; if (_tcsncmp(Port, _T("BT:"), 3) == 0) { CBtHandler* pBtHandler = CBtHandler::Get(); StartupStore(_T(".. Initialise Bluetooth Device %s%s"), Port, NEWLINE); if (pBtHandler && pBtHandler->IsOk()) { if (pBtHandler->StartHW()) { Com = new BthPort(i, &Port[3]); } } } else if (_tcscmp(Port, _T("GPSID")) == 0) { Com = new GpsIdPort(i, Port); } else { Com = new SerialPort(i, Port, dwSpeed[SpeedIndex], (BitIndex_t)BitIndex, PollingMode); } if (Com && Com->Initialize()) { ComPortStatus[i] = CPS_OPENOK; pDev->Installer(&DeviceList[i]); if ((pDevNmeaOut == NULL) && (pDev->Flags & (1l << dfNmeaOut))) { pDevNmeaOut = &DeviceList[i]; } DeviceList[i].Com = Com; devInit(&DeviceList[i]); devOpen(&DeviceList[i], i); if (devIsBaroSource(&DeviceList[i])) { if (pDevPrimaryBaroSource == NULL) { pDevPrimaryBaroSource = &DeviceList[i]; } else if (pDevSecondaryBaroSource == NULL) { pDevSecondaryBaroSource = &DeviceList[i]; } } } else { delete Com; ComPortStatus[i] = CPS_OPENKO; } } if (pDevNmeaOut != NULL) { if (pDevNmeaOut == devA()) { devB()->pDevPipeTo = devA(); } if (pDevNmeaOut == devB()) { devA()->pDevPipeTo = devB(); } } return (TRUE); }
// handle custom keys. Input: key pressed (center, left etc.) // Returns true if handled successfully, false if not // // Passthrough mode for keys>=1000 (custom menu keys) // bool CustomKeyHandler(const int key) { int ckeymode; static bool doinit=true; static int oldModeIndex; if (doinit) { oldModeIndex=LKMODE_INFOMODE;; doinit=false; } if (key>=1000) { ckeymode=key-1000; LKASSERT((ckeymode>=0 && ckeymode<ckTOP)); goto passthrough; } switch(key) { case CKI_BOTTOMCENTER: ckeymode=CustomKeyModeCenter; break; case CKI_BOTTOMLEFT: ckeymode=CustomKeyModeLeft; break; case CKI_BOTTOMRIGHT: ckeymode=CustomKeyModeRight; break; case CKI_BOTTOMICON: ckeymode=CustomKeyModeAircraftIcon; break; case CKI_TOPLEFT: ckeymode=CustomKeyModeLeftUpCorner; break; case CKI_TOPRIGHT: ckeymode=CustomKeyModeRightUpCorner; break; case CKI_CENTERSCREEN: ckeymode=CustomKeyModeCenterScreen; break; default: DoStatusMessage(_T("ERR-725 UNKNOWN CUSTOMKEY")); return false; break; } passthrough: switch(ckeymode) { case ckDisabled: break; case ckZoomIn: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif MapWindow::zoom.EventScaleZoom(1); return true; break; case ckZoomInMore: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif MapWindow::zoom.EventScaleZoom(2); return true; break; case ckZoomOut: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif MapWindow::zoom.EventScaleZoom(-1); return true; break; case ckZoomOutMore: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif MapWindow::zoom.EventScaleZoom(-2); return true; break; case ckMenu: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif ShowMenu(); return true; case ckBackMode: PreviousModeIndex(); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckToggleMap: //TODO if (ModeIndex==LKMODE_MAP) SetModeIndex(oldModeIndex); else { oldModeIndex=ModeIndex; SetModeIndex(LKMODE_MAP); } MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckTrueWind: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::setMode(_T("TrueWind")); return true; case ckTeamCode: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventSetup(_T("Teamcode")); return true; case ckToggleOverlays: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif ToggleMultimapOverlays(); return true; case ckToggleMapLandable: if (ModeIndex==LKMODE_MAP) SetModeIndex(LKMODE_WP); else SetModeIndex(LKMODE_MAP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckLandables: SetModeIndex(LKMODE_WP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckToggleMapCommons: if (ModeIndex==LKMODE_MAP) SetModeIndex(LKMODE_NAV); else SetModeIndex(LKMODE_MAP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckCommons: SetModeIndex(LKMODE_NAV); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckToggleMapTraffic: if (ModeIndex==LKMODE_MAP) SetModeIndex(LKMODE_TRF); else SetModeIndex(LKMODE_MAP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckTraffic: SetModeIndex(LKMODE_TRF); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckInvertColors: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventInvertColor(NULL); return true; case ckTimeGates: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventTimeGates(NULL); return true; case ckMarkLocation: InputEvents::eventMarkLocation(_T("")); return true; case ckAutoZoom: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventZoom(_T("auto toggle")); InputEvents::eventZoom(_T("auto show")); return true; case ckActiveMap: // NO MORE USED BUT KEPT FOR OPTIMIZING COMPILER return true; case ckBooster: DoStatusMessage(_T("FEEL THE THERMAL")); if (EnableSoundModes) LKSound(_T("LK_BOOSTER.WAV")); return true; case ckGoHome: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if (ValidWayPoint(HomeWaypoint)) { if ( (ValidTaskPoint(ActiveWayPoint)) && (Task[ActiveWayPoint].Index == HomeWaypoint )) { // LKTOKEN _@M82_ = "Already going home" DoStatusMessage(gettext(TEXT("_@M82_"))); } else { GotoWaypoint(HomeWaypoint); } } else // LKTOKEN _@M465_ = "No Home to go!" DoStatusMessage(gettext(TEXT("_@M465_"))); return true; case ckPanorama: if (PGZoomTrigger==false) PGZoomTrigger=true; else LastZoomTrigger=0; #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif return true; case ckMultitargetRotate: RotateOvertarget(); return true; case ckMultitargetMenu: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::setMode(_T("MTarget")); return true; case ckBaroToggle: ToggleBaroAltitude(); return true; case ckBasicSetup: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventSetup(_T("Basic")); return true; case ckSimMenu: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::setMode(_T("SIMMENU")); return true; case ckToggleMapAirspace: if (ModeIndex==LKMODE_MAP) SetModeType(LKMODE_WP,WP_AIRSPACES); else SetModeIndex(LKMODE_MAP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckAirspaceAnalysis: SetModeType(LKMODE_MAP,MP_MAPASP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckOptimizeRoute: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif PGOptimizeRoute=!PGOptimizeRoute; if (ISPARAGLIDER && PGOptimizeRoute) { AATEnabled = true; ClearOptimizedTargetPos(); } return true; case ckLockScreen: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventService(_T("LOCKMODE")); return true; case ckWhereAmI: // no sound here, chime is played by service event InputEvents::eventService(_T("ORACLE")); return true; case ckUseTotalEnergy: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventService(_T("TOTALEN")); return true; case ckNotepad: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventChecklist(_T("")); return true; case ckTerrainColors: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventService(_T("TERRCOL")); return true; case ckNearestAirspace: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventNearestAirspaceDetails(NULL); return true; case ckOlcAnalysis: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventSetup(_T("OlcAnalysis")); return true; case ckTerrainColorsBack: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventService(_T("TERRCOLBACK")); return true; case ckForceFreeFlightRestart: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if (!CALCULATED_INFO.Flying) { DoStatusMessage(MsgToken(922)); // NOT FLYING } else { if (MessageBoxX(hWndMapWindow, MsgToken(1754), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) { LKSW_ForceFreeFlightRestart=true; } } return true; case ckCustomMenu1: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif extern void dlgCustomMenuShowModal(void); InputEvents::eventMode(_T("MYMODE")); return true; case ckTaskCalc: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventCalculator(NULL); return true; case ckTaskTarget: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventSetup(_T("Target")); return true; case ckArmAdvance: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventArmAdvance(_T("toggle")); InputEvents::eventArmAdvance(_T("show")); return true; case ckMessageRepeat: InputEvents::eventRepeatStatusMessage(NULL); return true; case ckWaypointLookup: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventWaypointDetails(_T("select")); return true; case ckPan: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventPan(_T("toggle")); return true; case ckWindRose: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif UseWindRose=!UseWindRose; return true; case ckFlarmRadar: SetModeType(LKMODE_MAP,MP_RADAR); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckDeviceA: if(devA() && devA()->Config) { devA()->Config(devA()); } return true; case ckDeviceB: if(devB() && devB()->Config) { devB()->Config(devB()); } return true; case ckResetOdometer: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if (MessageBoxX(hWndMapWindow, MsgToken(2229), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) { LKSW_ResetOdometer=true; } return true; case ckForceLanding: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if ( !CALCULATED_INFO.Flying ) { DoStatusMessage(MsgToken(922)); // NOT FLYING } else { if ( (GPS_INFO.Speed > TakeOffSpeedThreshold) && (!GPS_INFO.NAVWarning) ) { DoStatusMessage(MsgToken(1799)); // STOP MOVING! } else { if (MessageBoxX(hWndMapWindow, MsgToken(2230), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) { LKSW_ForceLanding=true; } } } return true; case ckResetTripComputer: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if (MessageBoxX(hWndMapWindow, MsgToken(2236), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) { LKSW_ResetTripComputer=true; } return true; case ckSonarToggle: SonarWarning = !SonarWarning; TCHAR sonarmsg[60]; _stprintf(sonarmsg,_T("%s "),MsgToken(1293)); // SONAR if (SonarWarning) _tcscat(sonarmsg,MsgToken(1643)); // ENABLED else _tcscat(sonarmsg,MsgToken(1600)); // DISABLED DoStatusMessage(sonarmsg,NULL,false); if (EnableSoundModes) { if (SonarWarning) LKSound(TEXT("LK_TONEUP.WAV")); else LKSound(TEXT("LK_TONEDOWN.WAV")); } return true; case ckResetView: ModeType[LKMODE_MAP] = MP_MOVING; ModeType[LKMODE_INFOMODE]= IM_CRUISE; ModeType[LKMODE_WP] = WP_AIRPORTS; ModeType[LKMODE_NAV] = NV_COMMONS; ModeType[LKMODE_TRF] = TF_LIST; SetModeType(LKMODE_MAP,MP_MOVING); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckMapOrient: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif TCHAR MapOrientMsg[60]; if (MapSpaceMode==MSM_MAP) { DisplayOrientation++; if(DisplayOrientation > NORTHSMART) DisplayOrientation = 0; MapWindow::SetAutoOrientation(true); // 101008 reset it switch(DisplayOrientation) { case TRACKUP : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M737_"))) ; break; // _@M737_ "Track up" case NORTHUP : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M483_"))) ; break; // _@M483_ "North up" case NORTHCIRCLE : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M482_"))) ; break; // _@M482_ "North circling" case TRACKCIRCLE : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M682_"))) ; break; // _@M682_ "Target circling" _@M485_ "NorthUp above " case NORTHTRACK : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M484_"))) ; break; // _@M484_ "North/track" case NORTHSMART : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M481_"))) ; break; // _@M481_ "North Smart" } DoStatusMessage(MapOrientMsg,NULL,false); } else { SetMMNorthUp(GetSideviewPage(), (GetMMNorthUp(GetSideviewPage())+1)%2); } return true; case ckResetComm: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventRestartCommPorts(NULL); return true; default: DoStatusMessage(_T("ERR-726 INVALID CUSTOMKEY")); StartupStore(_T("... ERR-726 INVALID CUSTOMKEY=%d\n"),ckeymode); break; } return false; }
static BOOL devInit(LPCTSTR CommandLine) { int i; PDeviceDescriptor_t pDevNmeaOut = NULL; for (i=0; i<NUMDEV; i++){ DeviceList[i].Port = -1; DeviceList[i].fhLogFile = NULL; DeviceList[i].Name[0] = '\0'; DeviceList[i].Driver = NULL; DeviceList[i].pDevPipeTo = NULL; } pDevPrimaryBaroSource = NULL; pDevSecondaryBaroSource=NULL; DWORD PortIndex1, PortIndex2, SpeedIndex1, SpeedIndex2; #ifdef GNAV PortIndex1 = 2; SpeedIndex1 = 5; PortIndex2 = 0; SpeedIndex2 = 5; #else PortIndex1 = 0; SpeedIndex1 = 2; PortIndex2 = 0; SpeedIndex2 = 2; #endif ReadPort1Settings(&PortIndex1,&SpeedIndex1); ReadPort2Settings(&PortIndex2,&SpeedIndex2); devInitOne(devA(), 0, COMMPort[PortIndex1], dwSpeed[SpeedIndex1], pDevNmeaOut); if (PortIndex1 != PortIndex2) devInitOne(devB(), 1, COMMPort[PortIndex2], dwSpeed[SpeedIndex2], pDevNmeaOut); CommandLine = LOGGDEVCOMMANDLINE; if (CommandLine != NULL){ TCHAR *pC, *pCe; TCHAR wcLogFileName[MAX_PATH]; TCHAR sTmp[128]; pC = _tcsstr(CommandLine, TEXT("-logA=")); if (pC != NULL){ pC += strlen("-logA="); if (*pC == '"'){ pC++; pCe = pC; while (*pCe != '"' && *pCe != '\0') pCe++; } else{ pCe = pC; while (*pCe != ' ' && *pCe != '\0') pCe++; } if (pCe != NULL && pCe-1 > pC){ _tcsncpy(wcLogFileName, pC, pCe-pC); wcLogFileName[pCe-pC] = '\0'; if (devOpenLog(devA(), wcLogFileName)){ _stprintf(sTmp, TEXT("Device A logs to\r\n%s"), wcLogFileName); MessageBoxX (sTmp, gettext(TEXT("Information")), MB_OK|MB_ICONINFORMATION); } else { _stprintf(sTmp, TEXT("Unable to open log\r\non device A\r\n%s"), wcLogFileName); MessageBoxX (sTmp, gettext(TEXT("Error")), MB_OK|MB_ICONWARNING); } } } pC = _tcsstr(CommandLine, TEXT("-logB=")); if (pC != NULL){ pC += strlen("-logA="); if (*pC == '"'){ pC++; pCe = pC; while (*pCe != '"' && *pCe != '\0') pCe++; } else{ pCe = pC; while (*pCe != ' ' && *pCe != '\0') pCe++; } if (pCe != NULL && pCe > pC){ _tcsncpy(wcLogFileName, pC, pCe-pC); wcLogFileName[pCe-pC] = '\0'; if (devOpenLog(devB(), wcLogFileName)){ _stprintf(sTmp, TEXT("Device B logs to\r\n%s"), wcLogFileName); MessageBoxX (sTmp, gettext(TEXT("Information")), MB_OK|MB_ICONINFORMATION); } else { _stprintf(sTmp, TEXT("Unable to open log\r\non device B\r\n%s"), wcLogFileName); MessageBoxX (sTmp, gettext(TEXT("Error")), MB_OK|MB_ICONWARNING); } } } } if (pDevNmeaOut != NULL){ if (pDevNmeaOut == devA()){ devB()->pDevPipeTo = devA(); } if (pDevNmeaOut == devB()){ devA()->pDevPipeTo = devB(); } } return(TRUE); }