swift
testfsdclient.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2018 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
11 #include <QObject>
12 #include <QSignalSpy>
13 #include <QTest>
14 
15 #include "test.h"
16 
17 #include "config/buildconfig.h"
18 #include "core/fsd/fsdclient.h"
23 #include "misc/network/user.h"
24 #include "misc/registermetadata.h"
27 
28 using namespace swift::misc;
29 using namespace swift::misc::aviation;
30 using namespace swift::misc::geo;
31 using namespace swift::misc::physical_quantities;
32 using namespace swift::misc::network;
33 using namespace swift::misc::simulation;
34 using namespace swift::config;
35 using namespace swift::core::fsd;
36 
37 namespace SwiftFsdTest
38 {
40  class CTestFSDClient : public QObject
41  {
42  Q_OBJECT
43 
44  public:
46  explicit CTestFSDClient(QObject *parent = nullptr) : QObject(parent) {}
47 
49  virtual ~CTestFSDClient() {}
50 
51  private slots:
52  void initTestCase();
53  void init();
54  void cleanup();
55  void testConstructor();
56  void testDeleteAtc();
57  void testDeletePilot();
58  void testTextMessage();
59  void testRadioMessage();
60  void testClientQueryAtis();
61  void testClientResponseAtis();
62  void testPilotDataUpdate();
63  void testAtcDataUpdate();
64  void testPong();
65  void testClientResponseEmptyType();
66  void testClientResponseRealName1();
67  void testClientResponseRealName2();
68  void testClientResponseRealName3();
69  void testClientResponseCapabilities();
70  void testPlaneInfoRequestFsinn();
71  void testPlaneInformationFsinn();
72 
73  void testSendPilotLogin();
74  void testSendAtcLogin();
75  void testSendDeletePilot();
76  void testSendDeleteAtc();
77  void testSendPilotDataUpdate1();
78  void testSendPilotDataUpdate2();
79  void testSendPilotDataUpdate3();
80  void testSendAtcDataUpdate();
81  void testSendPing();
82  void testSendPong();
83  void testSendClientResponse1();
84  void testSendClientResponse2();
85  void testSendClientQuery1();
86  void testSendClientQuery2();
87  void testSendClientQuery3();
88  void testSendTextMessage1();
89  void testSendTextMessage2();
90  void testSendRadioMessage1();
91  void testSendRadioMessage2();
92  void testSendFlightPlanFaa();
93  void testSendFlightPlanIcao();
94  void testSendPlaneInfoRequest();
95  void testSendPlaneInformation1();
96  void testSendPlaneInformation2();
97  void testSendPlaneInformation3();
98  void testSendPlaneInformation4();
99  void testSendAircraftConfiguration();
100  void testSendIncrementalAircraftConfiguration();
101  void testCom1FreqQueryResponse();
102  void testPlaneInfoRequestResponse();
103  void testAuth();
104  // void testConnection(); // Connection test disabled as currently no server exist to check the connection
105 
106  private:
107  CFSDClient *m_client = nullptr;
108 
109  const CServer &localTestServer();
110  };
111 
112  void CTestFSDClient::initTestCase() { swift::misc::registerMetadata(); }
113 
114  const CServer &CTestFSDClient::localTestServer()
115  {
116  static const CServer dvp("Testserver", "Client project testserver", "localhost", 6809,
117  CUser("1234567", "Test User", "", "123456"), CFsdSetup(),
118  CEcosystem(CEcosystem::swiftTest()), CServer::FSDServerVatsim);
119  return dvp;
120  }
121 
122  void CTestFSDClient::init()
123  {
124  const CServer server = localTestServer();
125 
126  COwnAircraftProviderDummy::instance()->updateOwnCallsign("ABCD");
127  CLivery livery;
128  livery.setCombinedCode("BER");
129  CAirlineIcaoCode airline("BER");
130  livery.setAirlineIcaoCode(airline);
131  CAircraftModel model("Cessna SP1 Paint2", CAircraftModel::TypeOwnSimulatorModel, CAircraftIcaoCode("B737"),
132  livery);
133 
134  model.setSimulator(CSimulatorInfo::xplane());
135  QString modelDescription("[CSL]");
136  model.setDescription(modelDescription);
137  COwnAircraftProviderDummy::instance()->updateOwnModel(model);
138  // COwnAircraftProviderDummy::instance()->updateOwnIcaoCodes(CAircraftIcaoCode("B737"),
139  // CAirlineIcaoCode("BER"));
140 
141  CFrequency frequency(123.000, CFrequencyUnit::MHz());
142  COwnAircraftProviderDummy::instance()->updateActiveComFrequency(frequency, CComSystem::Com1, {});
143 
144  m_client = new CFSDClient(CClientProviderDummy::instance(), COwnAircraftProviderDummy::instance(),
145  CRemoteAircraftProviderDummy::instance(), this);
146  m_client->setUnitTestMode(true);
147  m_client->setCallsign("ABCD");
148  m_client->setClientName("Test Client");
149  m_client->setVersion(0, 8);
150  m_client->setClientCapabilities(Capabilities::AtcInfo | Capabilities::AircraftInfo |
151  Capabilities::AircraftConfig);
152  m_client->setLoginMode(swift::misc::network::CLoginMode::Pilot);
153  m_client->setServer(server);
154  m_client->setPilotRating(PilotRating::Student);
155  m_client->setSimType(CSimulatorInfo::xplane());
156  m_client->setPilotRating(PilotRating::Student);
157 #ifdef SWIFT_VATSIM_SUPPORT
158  QString key("727d1efd5cb9f8d2c28372469d922bb4");
159  m_client->setClientIdAndKey(0xb9ba, key.toLocal8Bit());
160 #endif
161  }
162 
163  void CTestFSDClient::cleanup() { delete m_client; }
164 
165  void CTestFSDClient::testConstructor() {}
166 
167  void CTestFSDClient::testDeleteAtc()
168  {
169  QSignalSpy spy(m_client, &CFSDClient::deleteAtcReceived);
170  m_client->sendFsdMessage("#DAEDDM_OBS:1234567\r\n");
171 
172  QCOMPARE(spy.count(), 1);
173  QList<QVariant> arguments = spy.takeFirst();
174 
175  QCOMPARE(arguments.at(0).toString(), "1234567");
176  }
177 
178  void CTestFSDClient::testDeletePilot()
179  {
180  QSignalSpy spy(m_client, &CFSDClient::deletePilotReceived);
181  m_client->sendFsdMessage("#DPOEHAB:1234567\r\n");
182 
183  QCOMPARE(spy.count(), 1);
184  QList<QVariant> arguments = spy.takeFirst();
185 
186  QCOMPARE(arguments.at(0).toString(), "1234567");
187  }
188 
189  void CTestFSDClient::testTextMessage()
190  {
191  QSignalSpy spy(m_client, &CFSDClient::textMessagesReceived);
192  m_client->sendFsdMessage("#TMEDMM_CTR:BER721:Hey how are you doing?\r\n");
193  spy.wait(2000); // message consolidation
194 
195  QCOMPARE(spy.count(), 1);
196  QList<QVariant> arguments = spy.takeFirst();
197  CTextMessageList messages = arguments.at(0).value<CTextMessageList>();
198  QCOMPARE(messages.size(), 1);
199  CTextMessage message = messages.front();
200  QCOMPARE(message.getMessage(), "Hey how are you doing?");
201  QCOMPARE(message.getRecipientCallsign(), "BER721");
202  QCOMPARE(message.getSenderCallsign(), "EDMM_CTR");
203  }
204 
205  void CTestFSDClient::testRadioMessage()
206  {
207  // reference
208  const CFrequency frequency(124050, CFrequencyUnit::kHz());
209  const QString text("BER721, Descend F140 when ready");
210 
211  COwnAircraftProviderDummy::instance()->updateActiveComFrequency(CFrequency(124050, CFrequencyUnit::kHz()),
212  CComSystem::Com1, CIdentifier::anonymous());
213 
214  QSignalSpy spy(m_client, &CFSDClient::textMessagesReceived);
215  m_client->sendFsdMessage("#TMEDMM_CTR:@24050:BER721, Descend F140 when ready\r\n");
216 
217  QCOMPARE(spy.count(), 1);
218  QList<QVariant> arguments = spy.takeFirst();
219  CTextMessageList receivedMessages = arguments.at(0).value<CTextMessageList>();
220  QCOMPARE(receivedMessages.size(), 1);
221  CTextMessage message = receivedMessages.front();
222  QCOMPARE(message.getMessage(), text);
223  QCOMPARE(message.getFrequency(), frequency);
224  QCOMPARE(message.getSenderCallsign(), "EDMM_CTR");
225 
226  QSignalSpy spy2(m_client, &CFSDClient::textMessagesReceived);
227  m_client->sendFsdMessage("#TMEDMM_CTR:@24050&@27000:BER721, Descend F140 when ready\r\n");
228 
229  QCOMPARE(spy2.count(), 1);
230  arguments = spy.takeFirst();
231  receivedMessages = arguments.at(0).value<CTextMessageList>();
232  QCOMPARE(receivedMessages.size(), 1);
233  message = receivedMessages.front();
234  QCOMPARE(message.getMessage(), text);
235  QCOMPARE(message.getFrequency(), frequency);
236  QCOMPARE(message.getSenderCallsign(), "EDMM_CTR");
237  }
238 
239  void CTestFSDClient::testClientQueryAtis()
240  {
241  CCallsign callsign("EDLW_TWR");
242 
243  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
244 
245  m_client->sendClientQueryAtis(callsign);
246 
247  QCOMPARE(spy.count(), 1);
248  QList<QVariant> arguments = spy.takeFirst();
249  QCOMPARE(arguments.size(), 1);
250  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
251  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$CQABCD:EDLW_TWR:ATIS");
252  }
253 
254  void CTestFSDClient::testClientResponseAtis()
255  {
256  const CCallsign callsign("EDLW_TWR");
257  m_client->sendClientQueryAtis(callsign);
258 
259  QSignalSpy spyLogoff(m_client, &CFSDClient::atisLogoffTimeReplyReceived);
260  QSignalSpy spyAtis(m_client, &CFSDClient::atisReplyReceived);
261 
262  m_client->sendFsdMessage("$CREDLW_TWR:ABCD:ATIS:V:VoiceRoom"); // still send (checked January 2024)
263  m_client->sendFsdMessage("$CREDLW_TWR:ABCD:ATIS:T:Dortmund Tower");
264  m_client->sendFsdMessage("$CREDLW_TWR:ABCD:ATIS:T:Useful information");
265  m_client->sendFsdMessage("$CREDLW_TWR:ABCD:ATIS:T:More useful information");
266  m_client->sendFsdMessage("$CREDLW_TWR:ABCD:ATIS:Z:2000z");
267  m_client->sendFsdMessage("$CREDLW_TWR:ABCD:ATIS:E:6");
268 
269  // Check logoff
270  QCOMPARE(spyLogoff.count(), 1);
271  QList<QVariant> arguments = spyLogoff.takeFirst();
272  QCOMPARE(arguments.size(), 2);
273  auto receivedCallsign = arguments.at(0).value<swift::misc::aviation::CCallsign>();
274  auto receivedLogoffTime = arguments.at(1).value<QString>();
275  QCOMPARE(callsign, receivedCallsign);
276  QCOMPARE(receivedLogoffTime, "2000z");
277 
278  // Check ATIS itself
279  QCOMPARE(spyAtis.count(), 1);
280  arguments = spyAtis.takeFirst();
281  QCOMPARE(arguments.size(), 2);
282  receivedCallsign = arguments.at(0).value<swift::misc::aviation::CCallsign>();
283  auto atisMessage = arguments.at(1).value<swift::misc::aviation::CInformationMessage>();
284  QCOMPARE(callsign, receivedCallsign);
285  QCOMPARE(atisMessage.toQString(), "Dortmund Tower\nUseful information\nMore useful information");
286  }
287 
288  void CTestFSDClient::testPilotDataUpdate()
289  {
290  QSignalSpy spy(m_client, &CFSDClient::pilotDataUpdateReceived);
291  m_client->sendFsdMessage("@N:ABCD:1200:1:48.353855:11.786155:110:0:4290769188:1\r\n");
292 
293  QCOMPARE(spy.count(), 1);
294  QList<QVariant> arguments = spy.takeFirst();
295  QCOMPARE(arguments.size(), 2);
296  const CAircraftSituation situation = arguments.at(0).value<CAircraftSituation>();
297  const CTransponder transponder = arguments.at(1).value<CTransponder>();
298 
299  QCOMPARE(situation.getCallsign().asString(), "ABCD");
300  QCOMPARE(transponder.getTransponderMode(), CTransponder::ModeC);
301  QCOMPARE(transponder.getTransponderCode(), 1200);
302  QCOMPARE(situation.getPosition().latitude(), CLatitude(48.353855, CAngleUnit::deg()));
303  QCOMPARE(situation.getPosition().longitude(), CLongitude(11.786155, CAngleUnit::deg()));
304  QCOMPARE(situation.getAltitude(), CAltitude(110, CLengthUnit::ft()));
305  QCOMPARE(situation.getPressureAltitude(),
307  QCOMPARE(situation.getGroundSpeed(), CSpeed(0.0, CSpeedUnit::kts()));
308  // TODO
309  // QVERIFY(qAbs(arguments.at(9).toDouble()) < 1.0);
310  // QVERIFY(qAbs(arguments.at(10).toDouble()) < 1.0);
311  // QVERIFY(qAbs(arguments.at(11).toDouble() - 25) < 1.0);
312  // QCOMPARE(arguments.at(12).toBool(), false);
313  }
314 
315  void CTestFSDClient::testAtcDataUpdate()
316  {
317  QSignalSpy spy(m_client, &CFSDClient::atcDataUpdateReceived);
318  m_client->sendFsdMessage("%ZZZZ_APP:28200:5:150:5:48.11028:16.56972:0\r\n");
319  const CCallsign callsign("ZZZZ_APP");
320  const CFrequency freq(128200, CFrequencyUnit::kHz());
321  const CCoordinateGeodetic pos(48.11028, 16.56972, 0.0);
322  const CLength range(150.0, CLengthUnit::NM());
323 
324  QCOMPARE(spy.count(), 1);
325  QList<QVariant> arguments = spy.takeFirst();
326  QCOMPARE(arguments.size(), 4);
327  QCOMPARE(arguments.at(0).value<CCallsign>(), callsign);
328  QCOMPARE(arguments.at(1).value<CFrequency>(), freq);
329  QCOMPARE(arguments.at(2).value<CCoordinateGeodetic>(), pos);
330  QCOMPARE(arguments.at(3).value<CLength>(), range);
331  }
332 
333  void CTestFSDClient::testPong()
334  {
335  QSignalSpy spy(m_client, &CFSDClient::pongReceived);
336  m_client->sendFsdMessage("$POSERVER:BER368:90835991\r\n");
337 
338  QCOMPARE(spy.count(), 1);
339  QList<QVariant> arguments = spy.takeFirst();
340  QCOMPARE(arguments.size(), 2);
341  QCOMPARE(arguments.at(0).toString(), "SERVER");
342  bool ok;
343  arguments.at(1).toDouble(&ok);
344  QVERIFY(ok);
345  }
346 
347  void CTestFSDClient::testClientResponseEmptyType() { m_client->sendFsdMessage("$CRDLH123:BER721::Jon Doe\r\n"); }
348 
349  void CTestFSDClient::testClientResponseRealName1()
350  {
351  QSignalSpy spy(m_client, &CFSDClient::realNameResponseReceived);
352  m_client->sendFsdMessage("$CRDLH123:BER721:RN:Jon Doe\r\n");
353 
354  QCOMPARE(spy.count(), 1);
355  QList<QVariant> arguments = spy.takeFirst();
356  QCOMPARE(arguments.size(), 2);
357  QCOMPARE(arguments.at(0).toString(), "DLH123");
358  QCOMPARE(arguments.at(1).toString(), "Jon Doe");
359  }
360 
361  void CTestFSDClient::testClientResponseRealName2()
362  {
363  QSignalSpy spy(m_client, &CFSDClient::realNameResponseReceived);
364  m_client->sendFsdMessage("$CRDLH123:BER721:RN:Jon Doe:\r\n");
365 
366  QCOMPARE(spy.count(), 1);
367  QList<QVariant> arguments = spy.takeFirst();
368  QCOMPARE(arguments.size(), 2);
369  QCOMPARE(arguments.at(0).toString(), "DLH123");
370  QCOMPARE(arguments.at(1).toString(), "Jon Doe");
371  }
372 
373  void CTestFSDClient::testClientResponseRealName3()
374  {
375  QSignalSpy spy(m_client, &CFSDClient::realNameResponseReceived);
376  m_client->sendFsdMessage("$CRDLH123:BER721:RN:Jon Doe::1\r\n");
377 
378  QCOMPARE(spy.count(), 1);
379  QList<QVariant> arguments = spy.takeFirst();
380  QCOMPARE(arguments.size(), 2);
381  QCOMPARE(arguments.at(0).toString(), "DLH123");
382  QCOMPARE(arguments.at(1).toString(), "Jon Doe");
383  }
384 
385  void CTestFSDClient::testClientResponseCapabilities()
386  {
387  QSignalSpy spy(m_client, &CFSDClient::capabilityResponseReceived);
388  m_client->sendFsdMessage("$CRAUA64MN:DECHK:CAPS:VERSION=1:ATCINFO=1:MODELDESC=1:ACCONFIG=1\r\n");
389 
390  QCOMPARE(spy.count(), 1);
391  QList<QVariant> arguments = spy.takeFirst();
392  QCOMPARE(arguments.size(), 2);
393  CClient::Capabilities caps = arguments.at(1).value<swift::misc::network::CClient::Capabilities>();
394  QVERIFY(caps.testFlag(CClient::FsdWithAircraftConfig));
395  }
396 
397  void CTestFSDClient::testPlaneInfoRequestFsinn()
398  {
399  QSignalSpy spy(m_client, &CFSDClient::planeInformationFsinnReceived);
400  m_client->sendFsdMessage("#SBLHA449:DLH53M:FSIPIR:1::A320:10.05523:0.49785:1320.00000:2.AB13B127.5611C1A2::"
401  "A320-200 Airbus Leipzig Air CFM\r\n");
402 
403  QCOMPARE(spy.count(), 1);
404  QList<QVariant> arguments = spy.takeFirst();
405  QCOMPARE(arguments.size(), 5);
406 
407  // Empty values, REASON ???
408  // const QString cs = arguments.at(0).toString();
409  // const QString un = arguments.at(1).toString();
410  // QCOMPARE(arguments.at(0).toString(), "DLH123");
411  // QCOMPARE(arguments.at(1).toString(), "Jon Doe");
412  }
413 
414  void CTestFSDClient::testPlaneInformationFsinn()
415  {
416  QSignalSpy spy(m_client, &CFSDClient::planeInformationFsinnReceived);
417  m_client->sendFsdMessage("#SBLHA449:AUA89SY:FSIPI:1::A320:10.05523:0.49785:1320.00000:2.AB13B127.5611C1A2::"
418  "A320-200 Airbus Leipzig Air CFM\r\n");
419 
420  QCOMPARE(spy.count(), 1);
421  QList<QVariant> arguments = spy.takeFirst();
422  QCOMPARE(arguments.size(), 5);
423  // QCOMPARE(arguments.at(0).toString(), "DLH123");
424  // QCOMPARE(arguments.at(1).toString(), "Jon Doe");
425  }
426 
427  void CTestFSDClient::testSendPilotLogin()
428  {
429  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
430 
431  m_client->sendLogin();
432 
433  QCOMPARE(spy.count(), 1);
434  QList<QVariant> arguments = spy.takeFirst();
435  QCOMPARE(arguments.size(), 1);
436  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
437  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#APABCD:SERVER:1234567:123456:1:101:16:Test User");
438  }
439 
440  void CTestFSDClient::testSendAtcLogin()
441  {
442  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
443  m_client->setLoginMode(CLoginMode::Observer);
444  m_client->setAtcRating(AtcRating::Controller1);
445  m_client->sendLogin();
446 
447  QCOMPARE(spy.count(), 1);
448  QList<QVariant> arguments = spy.takeFirst();
449  QCOMPARE(arguments.size(), 1);
450  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
451  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#AAABCD:SERVER:Test User:1234567:123456:5:101");
452  }
453 
454  void CTestFSDClient::testSendDeletePilot()
455  {
456  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
457 
458  m_client->sendDeletePilot();
459 
460  QCOMPARE(spy.count(), 1);
461  QList<QVariant> arguments = spy.takeFirst();
462  QCOMPARE(arguments.size(), 1);
463  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
464  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#DPABCD:1234567");
465  }
466 
467  void CTestFSDClient::testSendDeleteAtc()
468  {
469  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
470 
471  m_client->sendDeleteAtc();
472 
473  QCOMPARE(spy.count(), 1);
474  QList<QVariant> arguments = spy.takeFirst();
475  QCOMPARE(arguments.size(), 1);
476  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
477  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#DAABCD:1234567");
478  }
479 
480  void CTestFSDClient::testSendPilotDataUpdate1()
481  {
482  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
483 
484  const geo::CCoordinateGeodetic ownPosition(48.353855, 11.786155);
485  const CHeading heading(25.0, CAngleUnit::deg());
486  const CAngle pitch(1.0, CAngleUnit::deg());
487  const CAngle bank(1.0, CAngleUnit::deg());
488  const CSpeed gs(0.0, CSpeedUnit::kts());
489  CAircraftSituation situation;
490  situation.setPosition(ownPosition);
491  situation.setAltitude(CAltitude(110, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
492  situation.setPressureAltitude(
494  situation.setGroundSpeed(gs);
495  situation.setPitch(pitch);
496  situation.setBank(bank);
497  situation.setHeading(heading);
498  COwnAircraftProviderDummy::instance()->updateOwnSituation(situation);
499  COwnAircraftProviderDummy::instance()->updateCockpit({}, {}, CTransponder(1200, CTransponder::ModeC), {});
500 
501  m_client->sendPilotDataUpdate();
502 
503  QCOMPARE(spy.count(), 2);
504  const QList<QVariant> arguments = spy.takeLast();
505  QCOMPARE(arguments.size(), 1);
506  const CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
507  const QString fsdRawMessage = fsdMessage.getRawMessage();
508 
509  // PilotRating::Student
510  QCOMPARE(fsdRawMessage, "FSD Sent=>@N:ABCD:1200:1:48.35386:11.78616:110:0:4286566684:1");
511  }
512 
513  void CTestFSDClient::testSendPilotDataUpdate2()
514  {
515  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
516 
517  const geo::CCoordinateGeodetic ownPosition(48.353855, 11.786155);
518  const CHeading heading(25.0, CAngleUnit::deg());
519  const CAngle pitch(0.0, CAngleUnit::deg());
520  const CAngle bank(0.0, CAngleUnit::deg());
521  const CSpeed gs(0.0, CSpeedUnit::kts());
522  CAircraftSituation situation;
523  situation.setPosition(ownPosition);
524  situation.setAltitude(CAltitude(110, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
525  situation.setPressureAltitude(
527  situation.setGroundSpeed(gs);
528  situation.setPitch(pitch);
529  situation.setBank(bank);
530  situation.setHeading(heading);
531  COwnAircraftProviderDummy::instance()->updateOwnSituation(situation);
532  COwnAircraftProviderDummy::instance()->updateCockpit({}, {}, CTransponder(1200, CTransponder::ModeC), {});
533 
534  m_client->sendPilotDataUpdate();
535 
536  QCOMPARE(spy.count(), 2);
537  QList<QVariant> arguments = spy.takeLast();
538  QCOMPARE(arguments.size(), 1);
539  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
540 
541  // changed after we changed to PB inversion to *-1
542  // now also Pilot rating to Student
543  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>@N:ABCD:1200:1:48.35386:11.78616:110:0:284:1");
544  // QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>@N:ABCD:1200:0:48.35386:11.78616:110:0:4294963484:1");
545  }
546 
547  void CTestFSDClient::testSendPilotDataUpdate3()
548  {
549  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
550 
551  const geo::CCoordinateGeodetic ownPosition(48.353855, 11.786155);
552  const CHeading heading(25.0, CAngleUnit::deg());
553  const CAngle pitch(-1.0, CAngleUnit::deg());
554  const CAngle bank(-1.0, CAngleUnit::deg());
555  const CSpeed gs(0.0, CSpeedUnit::kts());
556  CAircraftSituation situation;
557  situation.setPosition(ownPosition);
558  situation.setAltitude(CAltitude(110, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
559  situation.setPressureAltitude(
561  situation.setGroundSpeed(gs);
562  situation.setPitch(pitch);
563  situation.setBank(bank);
564  situation.setHeading(heading);
565  COwnAircraftProviderDummy::instance()->updateOwnSituation(situation);
566  COwnAircraftProviderDummy::instance()->updateCockpit({}, {}, CTransponder(1200, CTransponder::ModeC), {});
567 
568  m_client->sendPilotDataUpdate();
569 
570  QCOMPARE(spy.count(), 2);
571  QList<QVariant> arguments = spy.takeLast();
572  QCOMPARE(arguments.size(), 1);
573  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
574 
575  // changed after we changed to PB inversion to *-1
576  // pilot rating now STUDENT
577  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>@N:ABCD:1200:1:48.35386:11.78616:110:0:8397084:1");
578  }
579 
580  void CTestFSDClient::testSendAtcDataUpdate()
581  {
582  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
583  m_client->sendAtcDataUpdate(48.11028, 8.56972);
584 
585  QCOMPARE(spy.count(), 1);
586  QList<QVariant> arguments = spy.takeFirst();
587  QCOMPARE(arguments.size(), 1);
588  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
589  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>%ABCD:99998:0:300:1:48.11028:8.56972:0");
590  }
591 
592  void CTestFSDClient::testSendPing()
593  {
594  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
595  m_client->sendPing("SERVER");
596 
597  QCOMPARE(spy.count(), 1);
598  QList<QVariant> arguments = spy.takeFirst();
599  QCOMPARE(arguments.size(), 1);
600  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
601  QVERIFY(fsdMessage.getRawMessage().contains("FSD Sent=>$PIABCD:SERVER:"));
602  }
603 
604  void CTestFSDClient::testSendPong()
605  {
606  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
607  m_client->sendPong("SERVER", "123456789");
608 
609  QCOMPARE(spy.count(), 1);
610  QList<QVariant> arguments = spy.takeFirst();
611  QCOMPARE(arguments.size(), 1);
612  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
613  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$POABCD:SERVER:123456789");
614  }
615 
616  void CTestFSDClient::testSendClientResponse1()
617  {
618  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
619  m_client->sendClientResponse(ClientQueryType::RealName, "ZZZZ_TWR");
620 
621  QCOMPARE(spy.count(), 1);
622  QList<QVariant> arguments = spy.takeFirst();
623  QCOMPARE(arguments.size(), 1);
624  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
625  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$CRABCD:ZZZZ_TWR:RN:Test User::1");
626  }
627 
628  void CTestFSDClient::testSendClientResponse2()
629  {
630  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
631  m_client->sendClientResponse(ClientQueryType::Capabilities, "ZZZZ_TWR");
632 
633  QCOMPARE(spy.count(), 1);
634  QList<QVariant> arguments = spy.takeFirst();
635  QCOMPARE(arguments.size(), 1);
636  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
637  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$CRABCD:ZZZZ_TWR:CAPS:ATCINFO=1:MODELDESC=1:ACCONFIG=1");
638  }
639 
640  void CTestFSDClient::testSendClientQuery1()
641  {
642  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
643  m_client->sendClientQuery(ClientQueryType::RealName, "ZZZZ_TWR");
644 
645  QCOMPARE(spy.count(), 1);
646  QList<QVariant> arguments = spy.takeFirst();
647  QCOMPARE(arguments.size(), 1);
648  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
649  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$CQABCD:ZZZZ_TWR:RN");
650  }
651 
652  void CTestFSDClient::testSendClientQuery2()
653  {
654  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
655  m_client->sendClientQueryIsValidAtc("EDDM_TWR");
656 
657  QCOMPARE(spy.count(), 1);
658  QList<QVariant> arguments = spy.takeFirst();
659  QCOMPARE(arguments.size(), 1);
660  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
661  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$CQABCD:SERVER:ATC:EDDM_TWR");
662  }
663 
664  void CTestFSDClient::testSendClientQuery3()
665  {
666  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
667  m_client->sendClientQueryAircraftConfig("DLH123");
668 
669  QCOMPARE(spy.count(), 1);
670  QList<QVariant> arguments = spy.takeFirst();
671  QCOMPARE(arguments.size(), 1);
672  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
673  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$CQABCD:DLH123:ACC:{\"request\":\"full\"}");
674  }
675 
676  void CTestFSDClient::testSendTextMessage1()
677  {
678  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
679  m_client->sendTextMessage("ZZZZ_TWR", "hey dude!");
680 
681  QCOMPARE(spy.count(), 1);
682  QList<QVariant> arguments = spy.takeFirst();
683  QCOMPARE(arguments.size(), 1);
684  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
685  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#TMABCD:ZZZZ_TWR:hey dude!");
686  }
687 
688  void CTestFSDClient::testSendTextMessage2()
689  {
690  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
691  m_client->sendTextMessage(TextMessageGroups::AllSups, "Please help!!!");
692 
693  QCOMPARE(spy.count(), 1);
694  QList<QVariant> arguments = spy.takeFirst();
695  QCOMPARE(arguments.size(), 1);
696  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
697  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#TMABCD:*S:Please help!!!");
698  }
699 
700  void CTestFSDClient::testSendRadioMessage1()
701  {
702  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
703  QVector<int> frequencies { 124050 };
704  m_client->sendRadioMessage(frequencies, "hey dude!");
705 
706  QCOMPARE(spy.count(), 1);
707  QList<QVariant> arguments = spy.takeFirst();
708  QCOMPARE(arguments.size(), 1);
709  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
710  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#TMABCD:@24050:hey dude!");
711  }
712 
713  void CTestFSDClient::testSendRadioMessage2()
714  {
715  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
716  QVector<int> frequencies { 124050, 135725 };
717  m_client->sendRadioMessage(frequencies, "hey dude!");
718 
719  QCOMPARE(spy.count(), 1);
720  QList<QVariant> arguments = spy.takeFirst();
721  QCOMPARE(arguments.size(), 1);
722  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
723  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#TMABCD:@24050&@35725:hey dude!");
724  }
725 
726  void CTestFSDClient::testSendFlightPlanFaa()
727  {
728  // Server without ICAOEQ capability is set by default (in init())
729  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
730  QDateTime takeoffTimePlanned = QDateTime::fromString("1530", "hhmm");
731  takeoffTimePlanned.setTimeSpec(Qt::UTC);
732  QDateTime takeoffTimeActual = QDateTime::fromString("1535", "hhmm");
733  takeoffTimeActual.setTimeSpec(Qt::UTC);
734  CAltitude flightLevel(35000, CAltitude::FlightLevel, CLengthUnit::ft());
735  CFlightPlanAircraftInfo info("H/B744/L");
736  CFlightPlan fp({}, info, "EGLL", "KORD", "NONE", takeoffTimePlanned, takeoffTimeActual,
737  CTime(8.25, CTimeUnit::h()), CTime(9.5, CTimeUnit::h()), flightLevel,
738  CSpeed(420, CSpeedUnit::kts()), CFlightPlan::VFR, "EGLL.KORD", "Unit Test");
739  m_client->sendFlightPlan(fp);
740 
741  QCOMPARE(spy.count(), 1);
742  QList<QVariant> arguments = spy.takeFirst();
743  QCOMPARE(arguments.size(), 1);
744  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
745  QCOMPARE(
746  fsdMessage.getRawMessage(),
747  "FSD Sent=>$FPABCD:SERVER:V:H/B744/L:420:EGLL:1530:1535:FL350:KORD:8:15:9:30:NONE:UNIT TEST:EGLL.KORD");
748  }
749 
750  void CTestFSDClient::testSendFlightPlanIcao()
751  {
752  CServer server = localTestServer();
753  server.setFsdSetup(CFsdSetup(CFsdSetup::SendFplWithIcaoEquipment));
754  m_client->setServer(server);
755 
756  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
757  QDateTime takeoffTimePlanned = QDateTime::fromString("1530", "hhmm");
758  takeoffTimePlanned.setTimeSpec(Qt::UTC);
759  QDateTime takeoffTimeActual = QDateTime::fromString("1535", "hhmm");
760  takeoffTimeActual.setTimeSpec(Qt::UTC);
761  CAltitude flightLevel(35000, CAltitude::FlightLevel, CLengthUnit::ft());
762  CFlightPlanAircraftInfo info("B748/H-SDE3FGHIM1M2RWXY/LB1");
763  CFlightPlan fp({}, info, "EGLL", "KORD", "NONE", takeoffTimePlanned, takeoffTimeActual,
764  CTime(8.25, CTimeUnit::h()), CTime(9.5, CTimeUnit::h()), flightLevel,
765  CSpeed(420, CSpeedUnit::kts()), CFlightPlan::VFR, "EGLL.KORD", "Unit Test");
766  m_client->sendFlightPlan(fp);
767 
768  QCOMPARE(spy.count(), 1);
769  QList<QVariant> arguments = spy.takeFirst();
770  QCOMPARE(arguments.size(), 1);
771  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
772  QCOMPARE(
773  fsdMessage.getRawMessage(),
774  "FSD Sent=>$FPABCD:SERVER:V:B748/H-SDE3FGHIM1M2RWXY/LB1:420:EGLL:1530:1535:FL350:KORD:8:15:9:30:NONE:UNIT "
775  "TEST:EGLL.KORD");
776  }
777 
778  void CTestFSDClient::testSendPlaneInfoRequest()
779  {
780  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
781  m_client->sendPlaneInfoRequest("XYZ");
782 
783  QCOMPARE(spy.count(), 1);
784  QList<QVariant> arguments = spy.takeFirst();
785  QCOMPARE(arguments.size(), 1);
786  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
787  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#SBABCD:XYZ:PIR");
788  }
789 
790  void CTestFSDClient::testSendPlaneInformation1()
791  {
792  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
793  m_client->sendPlaneInformation("XYZ", "B744", "BAW");
794 
795  QCOMPARE(spy.count(), 1);
796  QList<QVariant> arguments = spy.takeFirst();
797  QCOMPARE(arguments.size(), 1);
798  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
799  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#SBABCD:XYZ:PI:GEN:EQUIPMENT=B744:AIRLINE=BAW");
800  }
801 
802  void CTestFSDClient::testSendPlaneInformation2()
803  {
804  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
805  m_client->sendPlaneInformation("XYZ", "B744", "BAW", "UNION");
806 
807  QCOMPARE(spy.count(), 1);
808  QList<QVariant> arguments = spy.takeFirst();
809  QCOMPARE(arguments.size(), 1);
810  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
811  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#SBABCD:XYZ:PI:GEN:EQUIPMENT=B744:AIRLINE=BAW:LIVERY=UNION");
812  }
813 
814  void CTestFSDClient::testSendPlaneInformation3()
815  {
816  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
817  m_client->sendPlaneInformation("XYZ", "B744");
818 
819  QCOMPARE(spy.count(), 1);
820  QList<QVariant> arguments = spy.takeFirst();
821  QCOMPARE(arguments.size(), 1);
822  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
823  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#SBABCD:XYZ:PI:GEN:EQUIPMENT=B744");
824  }
825 
826  void CTestFSDClient::testSendPlaneInformation4()
827  {
828  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
829  m_client->sendPlaneInformation("XYZ", "", "", "UNION");
830 
831  QCOMPARE(spy.count(), 1);
832  QList<QVariant> arguments = spy.takeFirst();
833  QCOMPARE(arguments.size(), 1);
834  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
835  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#SBABCD:XYZ:PI:GEN:LIVERY=UNION");
836  }
837 
838  void CTestFSDClient::testSendAircraftConfiguration()
839  {
840  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
841  m_client->sendAircraftConfiguration("XYZ", "{\"request\":\"full\"}");
842 
843  QCOMPARE(spy.count(), 1);
844  QList<QVariant> arguments = spy.takeFirst();
845  QCOMPARE(arguments.size(), 1);
846  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
847  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$CQABCD:XYZ:ACC:{\"request\":\"full\"}");
848  }
849 
850  void CTestFSDClient::testSendIncrementalAircraftConfiguration()
851  {
852  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
853 
854  CAircraftParts parts = COwnAircraftProviderDummy::instance()->getOwnAircraftParts();
855  parts.setGearDown(true);
856  COwnAircraftProviderDummy::instance()->updateOwnParts(parts);
857 
858  m_client->sendIncrementalAircraftConfig();
859 
860  QCOMPARE(spy.count(), 1);
861  QList<QVariant> arguments = spy.takeFirst();
862  QCOMPARE(arguments.size(), 1);
863  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
864  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$CQABCD:@94836:ACC:{\"config\":{\"gear_down\":true}}");
865  }
866 
867  void CTestFSDClient::testCom1FreqQueryResponse()
868  {
869  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
870  m_client->sendFsdMessage("$CQEDMM_CTR:ABCD:C?\r\n");
871 
872  QCOMPARE(spy.count(), 2);
873  QList<QVariant> arguments = spy.takeAt(1);
874  QCOMPARE(arguments.size(), 1);
875  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
876  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>$CRABCD:EDMM_CTR:C?:123.000");
877  }
878 
879  void CTestFSDClient::testPlaneInfoRequestResponse()
880  {
881  QSignalSpy spy(m_client, &CFSDClient::rawFsdMessage);
882  m_client->sendFsdMessage("#SBEDMM_CTR:ABCD:PIR\r\n");
883 
884  QCOMPARE(spy.count(), 2);
885  QList<QVariant> arguments = spy.takeAt(1);
886  QCOMPARE(arguments.size(), 1);
887  CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
888  QCOMPARE(fsdMessage.getRawMessage(), "FSD Sent=>#SBABCD:EDMM_CTR:PI:GEN:EQUIPMENT=B737:AIRLINE=BER");
889  }
890 
891  void CTestFSDClient::testAuth()
892  {
922  }
923 
925  bool pingServer(const CServer &server)
926  {
927  QString m;
928  const CUrl url(server.getAddress(), server.getPort());
929  if (!CNetworkUtils::canConnect(url, m, 2500))
930  {
931  qWarning() << "Skipping unit test as" << url.getFullUrl() << "cannot be connected";
932  return false;
933  }
934  return true;
935  }
936 
937  // void CTestFSDClient::testConnection()
938  // {
939  // const CServer fsdServer = localTestServer();
940  // if (!pingServer(fsdServer)) { QSKIP("Server not reachable."); }
941  //
942  // QSignalSpy spy(m_client, &CFSDClient::connectionStatusChanged);
943  // m_client->setUnitTestMode(false);
944  // m_client->connectToServer();
945  //
946  // if (spy.isEmpty()) { QVERIFY(spy.wait()); }
947  // QList<QVariant> arguments = spy.takeAt(0);
948  // QCOMPARE(arguments.size(), 2);
949  // QCOMPARE(CConnectionStatus::Disconnected,
950  // arguments.at(0).value<CConnectionStatus>().getConnectionStatus()); QCOMPARE(CConnectionStatus::Connecting,
951  // arguments.at(1).value<CConnectionStatus>().getConnectionStatus());
952  //
953  // if (spy.isEmpty()) { QVERIFY(spy.wait()); }
954  // arguments = arguments = spy.takeAt(0);
955  // QCOMPARE(arguments.size(), 2);
956  // QCOMPARE(CConnectionStatus::Connecting, arguments.at(0).value<CConnectionStatus>().getConnectionStatus());
957  // QCOMPARE(CConnectionStatus::Connected, arguments.at(1).value<CConnectionStatus>().getConnectionStatus());
958  //
959  // QSignalSpy pongSpy(m_client, &CFSDClient::pongReceived);
960  // connect(m_client, &CFSDClient::pongReceived, [](const QString &sender, double elapsedTimeM) {
961  // qDebug() << "Received pong from" << sender << "in" << elapsedTimeM << "ms";
962  // });
963  // m_client->sendPing("SERVER");
964  // QVERIFY(pongSpy.wait());
965  //
966  // m_client->disconnectFromServer();
967  // if (spy.isEmpty()) { QVERIFY(spy.wait()); }
968  // arguments = spy.takeAt(0);
969  // QCOMPARE(arguments.size(), 2);
970  // QCOMPARE(CConnectionStatus::Connected, arguments.at(0).value<CConnectionStatus>().getConnectionStatus());
971  // QCOMPARE(CConnectionStatus::Disconnecting,
972  // arguments.at(1).value<CConnectionStatus>().getConnectionStatus());
973  //
974  // if (spy.isEmpty()) { QVERIFY(spy.wait()); }
975  // arguments = spy.takeAt(0);
976  // QCOMPARE(arguments.size(), 2);
977  // QCOMPARE(CConnectionStatus::Disconnecting,
978  // arguments.at(0).value<CConnectionStatus>().getConnectionStatus());
979  // QCOMPARE(CConnectionStatus::Disconnected,
980  // arguments.at(1).value<CConnectionStatus>().getConnectionStatus());
981  // }
982 } // namespace SwiftFsdTest
983 
986 
987 #include "testfsdclient.moc"
988 
CTestFSDClient(QObject *parent=nullptr)
Constructor.
virtual ~CTestFSDClient()
Destructor.
FSD client Todo: Send (interim) data updates automatically Todo Check ':' in FSD messages....
Definition: fsdclient.h:86
static const CIdentifier & anonymous()
Returns an anonymous identifier, which is a valid identifier without name.
Definition: identifier.cpp:78
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
reference front()
Access the first element.
Definition: sequence.h:225
Value object for ICAO classification.
Value object encapsulating information of aircraft's parts.
Definition: aircraftparts.h:26
void setGearDown(bool down)
Set gear down.
Definition: aircraftparts.h:97
Value object encapsulating information of an aircraft's situation.
void setPressureAltitude(const CAltitude &altitude)
Set pressure altitude.
void setGroundSpeed(const physical_quantities::CSpeed &groundspeed)
Set ground speed.
void setBank(const physical_quantities::CAngle &bank)
Set bank (angle)
void setHeading(const CHeading &heading)
Set heading.
void setAltitude(const CAltitude &altitude)
Set altitude.
const CCallsign & getCallsign() const
Corresponding callsign.
const physical_quantities::CSpeed & getGroundSpeed() const
Get ground speed.
const CAltitude & getAltitude() const
Get altitude.
void setPitch(const physical_quantities::CAngle &pitch)
Set pitch.
const CAltitude & getPressureAltitude() const
Get pressure altitude.
const geo::CCoordinateGeodetic & getPosition() const
Get position.
void setPosition(const geo::CCoordinateGeodetic &position)
Set position.
Value object for ICAO classification.
Altitude as used in aviation, can be AGL or MSL altitude.
Definition: altitude.h:52
@ PressureAltitude
Altitude above the standard datum plane.
Definition: altitude.h:82
Value object encapsulating information of a callsign.
Definition: callsign.h:30
const QString & asString() const
Get callsign (normalized)
Definition: callsign.h:96
Flightplan-related information about an aircraft (aircraft ICAO, equipment and WTC)
Value object for a flight plan.
Definition: flightplan.h:148
@ VFR
Visual flight rules.
Definition: flightplan.h:156
Heading as used in aviation, can be true or magnetic heading.
Definition: heading.h:41
Value object encapsulating information message (ATIS, METAR, TAF)
Value object encapsulating information about an airpot.
Definition: livery.h:29
void setCombinedCode(const QString &code)
Combined code.
Definition: livery.h:107
bool setAirlineIcaoCode(const CAirlineIcaoCode &airlineIcao)
Airline ICAO code.
Definition: livery.cpp:81
virtual CLatitude latitude() const
Latitude.
virtual CLongitude longitude() const
Longitude.
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:76
Ecosystem of server belonging together.
Definition: ecosystem.h:21
Value object for a FSD setup.
Definition: fsdsetup.h:24
Value object for a raw FSD message.
Definition: rawfsdmessage.h:25
const QString & getRawMessage() const
Get raw message.
Definition: rawfsdmessage.h:40
Value object encapsulating information of a server.
Definition: server.h:28
int getPort() const
Get port.
Definition: server.h:116
const QString & getAddress() const
Get address.
Definition: server.h:80
void setFsdSetup(const CFsdSetup &setup)
Set FSD setup.
Definition: server.h:143
Value object encapsulating information of a text message.
Definition: textmessage.h:31
const QString & getMessage() const
Get message.
Definition: textmessage.h:78
const aviation::CCallsign & getSenderCallsign() const
Get callsign (from)
Definition: textmessage.h:54
const aviation::CCallsign & getRecipientCallsign() const
Get callsign (to)
Definition: textmessage.h:60
const physical_quantities::CFrequency & getFrequency() const
Get frequency.
Definition: textmessage.h:96
Value object encapsulating a list of text messages.
Value object encapsulating information of a location, kind of simplified CValueObject compliant versi...
Definition: url.h:27
QString getFullUrl(bool withQuery=true) const
Qualified name.
Definition: url.cpp:84
Value object encapsulating information of a user.
Definition: user.h:28
Physical unit angle (radians, degrees)
Definition: angle.h:23
Physical unit length (length)
Definition: length.h:18
Aircraft model (used by another pilot, my models on disk)
Definition: aircraftmodel.h:71
Free functions in swift::misc.
void registerMetadata()
Register all relevant metadata in Misc.
SWIFTTEST_MAIN(SwiftFsdTest::CTestFSDClient)
main
bool pingServer(const CServer &server)
Ping the server.