swift
servicetool.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
6 
7 #include "servicetool.h"
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 
12 #include <QChar>
13 #include <QDBusConnection>
14 #include <QDBusConnectionInterface>
15 #include <QDBusError>
16 #include <QDBusMessage>
17 #include <QDBusObjectPath>
18 #include <QDBusPendingReply>
19 #include <QDBusReply>
20 #include <QDBusVariant>
21 #include <QDateTime>
22 #include <QDebug>
23 #include <QElapsedTimer>
24 #include <QFlags>
25 #include <QLatin1Char>
26 #include <QList>
27 #include <QObject>
28 #include <QProcess>
29 #include <QString>
30 #include <QTextStream>
31 #include <QThread>
32 #include <QVariant>
33 #include <QtDebug>
34 
35 #include "core/application.h"
36 #include "misc/dbusserver.h"
37 #include "misc/network/server.h"
38 #include "misc/test/testdata.h"
39 #include "misc/test/testservice.h"
41 
42 using namespace swift::misc;
43 using namespace swift::misc::simulation;
44 using namespace swift::misc::physical_quantities;
45 using namespace swift::misc::aviation;
46 using namespace swift::misc::math;
47 using namespace swift::misc::geo;
48 using namespace swift::misc::network;
49 using namespace swift::misc::simulation::fscommon;
50 using namespace swift::misc::test;
51 using namespace swift::core;
52 
53 namespace swift::sample
54 {
55  void ServiceTool::dataTransferTestServer(CDBusServer *dBusServer, bool verbose)
56  {
57  QDBusConnection sessionBusConnection = QDBusConnection::sessionBus();
58  if (sessionBusConnection.interface()->isServiceRegistered(CTestService::InterfaceName()))
59  {
60  qFatal("Testservice already registed on session bus");
61  }
62 
63  // as this is the receiver side, the slots can be debugged too
64  CTestService *testService =
65  CTestService::registerTestService(sessionBusConnection, verbose, QCoreApplication::instance());
66  dBusServer->addObject(CTestService::ObjectPath(), testService);
67  }
68 
69  void ServiceTool::dataTransferTestClient(const QString &address)
70  {
71  // send data as P2P to server (this can be session bus, too, but usually is P2P)
72  const bool sb = address.startsWith("session", Qt::CaseInsensitive);
73  QDBusConnection connection =
74  sb ? QDBusConnection::sessionBus() : QDBusConnection::connectToPeer(address, "p2pConnection");
75 
76  // qtout << "server connection has interface? " << connection.interface(); // returns 0 with server and a real
77  // interface with session bus qtout << "address: " << address; qtout << "name: " << connection.name();
78 
79  ServiceTool::sendDataToTestservice(connection);
80  }
81 
82  void ServiceTool::sendDataToTestservice(const QDBusConnection &connection)
83  {
84  // on the client's side
85  ITestServiceInterface testServiceInterface(CTestService::InterfaceName(), CTestService::ObjectPath(),
86  connection);
87  QTextStream qtin(stdin);
88  QTextStream qtout(stdout);
89 
90  const QList<double> list { 1.0, 2.0, 3.0 };
91 
92  while (true)
93  {
94  QDBusMessage m = QDBusMessage::createSignal(CTestService::ObjectPath(), CTestService::InterfaceName(),
95  "sendStringMessage");
96 
97  // The << operator is used to add the parameters for the slot
98  const QDateTime dtnow = QDateTime::currentDateTimeUtc();
99  const QString msg = QStringLiteral("Con.: %1, message at %2")
100  .arg(connection.name(), dtnow.toString("MM/dd/yyyy @ hh:mm:ss"));
101  m << msg;
102 
103  // We send this as a non-replying message. This is used for sending errors, replys, signals.
104  // Values can be seen on the receiver side
105  qtout << "----------------- receiver tests ----------------" << Qt::endl;
106 
107  // Low level test
108  if (connection.send(m)) { qtout << "Send via low level method " << Qt::endl; }
109 
110  // same as interface message
111  // but call the slot
112  testServiceInterface.receiveStringMessage(msg);
113  qtout << "Send string via interface " << msg << Qt::endl;
114 
115  // a list
116  testServiceInterface.receiveList(list);
117  qtout << "Send list via interface " << list.size() << Qt::endl;
118 
119  // PQs
120  CSpeed speed(200, CSpeedUnit::km_h());
121  const CSpeed speedNull(0, nullptr);
122 
123  testServiceInterface.receiveSpeed(speed);
124  qtout << "Send speed via interface " << speed << Qt::endl;
125  testServiceInterface.receiveSpeed(speedNull);
126  qtout << "Send null speed via interface " << speedNull << Qt::endl;
127  speed.switchUnit(CSpeedUnit::kts());
128  testServiceInterface.receiveSpeed(speed);
129  qtout << "Send speed via interface " << speed << Qt::endl;
130  speed.switchUnit(CSpeedUnit::km_h());
131  speed.addValueSameUnit(1.0);
132 
133  // Network
134  const CServer trafficServer = CTestData::getTrafficServer();
135  QVariant tsqv = QVariant::fromValue(trafficServer);
136  QDBusVariant tsv(tsqv);
137  testServiceInterface.receiveVariant(tsv, tsqv.userType());
138  qtout << "Send server via interface and variant '" << trafficServer << QLatin1String("' ")
139  << tsqv.userType() << Qt::endl;
140 
141  // Aviation
142  const CComSystem comSystem = CComSystem("DBUS COM1", CPhysicalQuantitiesConstants::FrequencyUnicom(),
143  CPhysicalQuantitiesConstants::FrequencyUnicom());
144  testServiceInterface.receiveComUnit(comSystem);
145  qtout << "Send COM via interface " << comSystem << Qt::endl;
146 
147  CAltitude altitude(1000, CAltitude::MeanSeaLevel, CLengthUnit::ft());
148  QVariant qvAl = QVariant::fromValue(altitude);
149  QDBusVariant qv(qvAl);
150  testServiceInterface.receiveVariant(qv, qvAl.userType());
151  testServiceInterface.receiveAltitude(altitude);
152  qtout << "Send altitude via interface and variant " << altitude << qvAl.userType() << Qt::endl;
153  altitude.addValueSameUnit(1);
154 
155  const CTransponder transponder(7000, CTransponder::ModeC);
156  testServiceInterface.receiveTransponder(transponder);
157  qtout << "Send transponder via interface " << transponder << Qt::endl;
158 
159  const CTrack track(123.45, CTrack::Magnetic, CAngleUnit::deg());
160  testServiceInterface.receiveTrack(track);
161  qtout << "Send track via interface " << track << Qt::endl;
162 
163  const CLength len(33, CLengthUnit::m());
164  testServiceInterface.receiveLength(len);
165  qtout << "Send length via interface " << len << Qt::endl;
166 
167  const CAltitude alt(44, CAltitude::MeanSeaLevel, CLengthUnit::m());
168  testServiceInterface.receiveLength(alt);
169  qtout << "Send altitude via interface " << alt << Qt::endl;
170 
171  const CCallsign callsign = CTestData::getRandomPilotCallsign();
172  testServiceInterface.receiveCallsign(callsign);
173  qtout << "Send callsign via interface " << callsign << Qt::endl;
174 
175  const CAtcStation station = CTestData::getMunichTower();
176  testServiceInterface.receiveAtcStation(station);
177  qtout << "Send ATC " << station << Qt::endl;
178 
179  // Geo
180  const CCoordinateGeodetic geoPos = CTestData::getCoordinateFrankfurtTower();
181  testServiceInterface.receiveGeoPosition(geoPos);
182  qtout << "Send geo position " << geoPos << Qt::endl;
183  CApplication::processEventsFor(1000);
184 
185  qtout << "----------------- variant tests ----------------" << Qt::endl;
186  const CVariantList cvList = CTestData::getCVariantList();
187  testServiceInterface.receiveVariantList(cvList);
188  qtout << "Send " << cvList.size() << " variants via interface as CVariantList" << Qt::endl;
189 
190  const CPropertyIndexVariantMap valueMap = CTestData::getCPropertyIndexVariantMap();
191  testServiceInterface.receiveValueMap(valueMap);
192  qtout << "Send " << valueMap.size() << " index variant map entries" << Qt::endl;
193  CApplication::processEventsFor(1000);
194 
195  qtout << "----------------- pings ----------------" << Qt::endl;
196  const int errors = ITestServiceInterface::pingTests(testServiceInterface, false);
197  qtout << "Ping errors " << errors << Qt::endl;
198  CApplication::processEventsFor(1000);
199 
200  // Performance tools
201  qtout << "----------------- performance ----------------" << Qt::endl;
202 
203  QElapsedTimer timer;
204  timer.start();
205  for (int i = 0; i < 10; i++)
206  {
207  CSpeed speedDummy = testServiceInterface.getSpeed();
208  Q_UNUSED(speedDummy);
209  }
210  qint64 t10 = timer.elapsed(); // ms
211 
212  timer.restart();
213  for (int i = 0; i < 100; i++)
214  {
215  CSpeed speedDummy = testServiceInterface.getSpeed();
216  Q_UNUSED(speedDummy);
217  }
218  qint64 t100 = timer.elapsed(); // ms
219 
220  timer.restart();
221  for (int i = 0; i < 1000; i++)
222  {
223  CSpeed speedDummy = testServiceInterface.getSpeed();
224  Q_UNUSED(speedDummy);
225  }
226  qint64 t1000 = timer.elapsed(); // ms
227  timer.invalidate();
228  qtout << "Reading speed objects 10/100/1000 in ms: " << t10 << " " << t100 << " " << t1000 << Qt::endl;
229 
230  timer.start();
231  for (int i = 0; i < 10; i++)
232  {
233  CAtcStation stationDummy = testServiceInterface.getAtcStation();
234  Q_UNUSED(stationDummy);
235  }
236  t10 = timer.elapsed(); // ms
237  timer.restart();
238  for (int i = 0; i < 100; i++)
239  {
240  CAtcStation stationDummy = testServiceInterface.getAtcStation();
241  Q_UNUSED(stationDummy);
242  }
243  t100 = timer.elapsed(); // ms
244  timer.restart();
245  for (int i = 0; i < 1000; i++)
246  {
247  CAtcStation stationDummy = testServiceInterface.getAtcStation();
248  Q_UNUSED(stationDummy);
249  }
250  t1000 = timer.elapsed(); // ms
251  qtout << "Reading station objects 10/100/1000 in ms: " << t10 << " " << t100 << " " << t1000 << Qt::endl;
252 
253  timer.restart();
254  CAtcStationList atcStationList = testServiceInterface.getAtcStationList(10);
255  if (atcStationList.size() != 10) qtout << "wrong list size" << atcStationList.size() << Qt::endl;
256  t10 = timer.elapsed(); // ms
257  timer.restart();
258  atcStationList = testServiceInterface.getAtcStationList(100);
259  if (atcStationList.size() != 100) qtout << "wrong list size" << atcStationList.size() << Qt::endl;
260  t100 = timer.elapsed(); // ms
261  timer.restart();
262  atcStationList = testServiceInterface.getAtcStationList(1000);
263  if (atcStationList.size() != 1000) qtout << "wrong list size" << atcStationList.size() << Qt::endl;
264  t1000 = timer.elapsed(); // ms
265  qtout << "Reading station list 10/100/1000 in ms: " << t10 << " " << t100 << " " << t1000 << Qt::endl;
266 
267  // test reading model entries with a realistic size
268  timer.restart();
269  CAircraftCfgEntriesList entriesList = testServiceInterface.getAircraftCfgEntriesList(5000);
270  if (entriesList.size() != 5000) qtout << "wrong list size" << entriesList.size() << Qt::endl;
271  qint64 t5000 = timer.elapsed(); // ms
272  qtout << "Reading aircraft cfg entries in ms: " << t5000 << Qt::endl;
273 
274  // object paths
275  timer.restart();
276  QList<QDBusObjectPath> objectPaths = testServiceInterface.getObjectPaths(10);
277  if (objectPaths.size() != 10) qtout << "wrong list size" << objectPaths.size() << Qt::endl;
278  t10 = timer.elapsed(); // ms
279  timer.restart();
280  objectPaths = testServiceInterface.getObjectPaths(100);
281  if (objectPaths.size() != 100) qtout << "wrong list size" << objectPaths.size() << Qt::endl;
282  t100 = timer.elapsed(); // ms
283  timer.restart();
284  objectPaths = testServiceInterface.getObjectPaths(1000);
285  if (objectPaths.size() != 1000) qtout << "wrong list size" << objectPaths.size() << Qt::endl;
286  t1000 = timer.elapsed(); // ms
287  qtout << "Reading paths list 10/100/1000 in ms: " << t10 << " " << t100 << " " << t1000 << Qt::endl;
288  timer.invalidate();
289 
290  // next round?
291  qtout << "---------------------------------------" << Qt::endl;
292  qtout << "Key ....... x to exit" << Qt::endl;
293  QString line = qtin.readLine().toLower().trimmed();
294  if (line.startsWith('x'))
295  {
296  qtout << "Ending!" << Qt::endl;
297  break;
298  }
299  }
300  }
301 } // namespace swift::sample
Custom DBusServer.
Definition: dbusserver.h:34
void addObject(const QString &name, QObject *object)
Add a QObject to be exposed via DBus.
Definition: dbusserver.cpp:226
Specialized value object compliant map for variants, based on indexes.
int size() const
Number of elements.
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
Value object encapsulating a list of variants.
Definition: variantlist.h:29
Altitude as used in aviation, can be AGL or MSL altitude.
Definition: altitude.h:52
Value object encapsulating information about an ATC station.
Definition: atcstation.h:38
Value object for a list of ATC stations.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
COM system (aka "radio")
Definition: comsystem.h:37
Track as used in aviation, can be true or magnetic Track.
Definition: track.h:44
Value object encapsulating information of a server.
Definition: server.h:28
Physical unit length (length)
Definition: length.h:18
PQ & switchUnit(const MU &newUnit)
Change unit, and convert value to maintain the same quantity.
void addValueSameUnit(double value)
Add to the value in the current unit.
Testservice for PQ / CValueObject DBus tests. This part is the callee.
Definition: testservice.h:65
Proxy class for swift::misc::Test::CTestService. This part is the caller.
QDBusPendingReply receiveAtcStation(const swift::misc::aviation::CAtcStation &station)
DBus calls.
QDBusPendingReply receiveStringMessage(const QString &message)
DBus calls.
QDBusPendingReply< swift::misc::simulation::fscommon::CAircraftCfgEntriesList > getAircraftCfgEntriesList(int number)
DBus calls.
QDBusPendingReply receiveSpeed(const swift::misc::physical_quantities::CSpeed &speed)
DBus calls.
QDBusPendingReply receiveVariantList(const swift::misc::CVariantList &list)
DBus calls.
QDBusPendingReply< swift::misc::aviation::CAtcStation > getAtcStation()
DBus calls.
QDBusPendingReply receiveCallsign(const swift::misc::aviation::CCallsign &callsign)
DBus calls.
QDBusPendingReply receiveLength(const swift::misc::physical_quantities::CLength &length)
DBus calls.
QDBusPendingReply receiveList(const QList< double > &list)
DBus calls.
QDBusPendingReply receiveComUnit(const swift::misc::aviation::CComSystem &comUnit)
DBus calls.
QDBusPendingReply receiveGeoPosition(const swift::misc::geo::CCoordinateGeodetic &geo)
DBus calls.
QDBusPendingReply receiveTransponder(const swift::misc::aviation::CTransponder &transponder)
DBus calls.
QDBusPendingReply< swift::misc::aviation::CAltitude > receiveAltitude(const swift::misc::aviation::CAltitude &altitude)
DBus calls.
QDBusPendingReply< QList< QDBusObjectPath > > getObjectPaths(int number)
DBus calls.
QDBusPendingReply< swift::misc::physical_quantities::CSpeed > getSpeed()
DBus calls.
QDBusPendingReply receiveTrack(const swift::misc::aviation::CTrack &track)
DBus calls.
QDBusPendingReply receiveVariant(const QDBusVariant &variant, int localMetyType)
DBus calls.
QDBusPendingReply receiveValueMap(const swift::misc::CPropertyIndexVariantMap &valueMap)
DBus calls.
QDBusPendingReply< swift::misc::aviation::CAtcStationList > getAtcStationList(int number)
DBus calls.
Backend services of the swift project, like dealing with the network or the simulators.
Definition: actionbind.cpp:7
Generate data for testing purposes.
Definition: testdata.h:45
Free functions in swift::misc.