1 /*
2 * Stellarium Remote Sync plugin
3 * Copyright (C) 2015 Florian Schaukowitsch
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19
20 #include "SyncClient.hpp"
21 #include "SyncClientHandlers.hpp"
22 #include "SyncMessages.hpp"
23
24 #include "StelTranslator.hpp"
25
26 #include <QDateTime>
27 #include <QTcpSocket>
28 #include <QTimerEvent>
29
30 Q_LOGGING_CATEGORY(syncClient,"stel.plugin.remoteSync.client")
31
32 using namespace SyncProtocol;
33
SyncClient(SyncOptions options,const QStringList & excludeProperties,QObject * parent)34 SyncClient::SyncClient(SyncOptions options, const QStringList &excludeProperties, QObject *parent)
35 : QObject(parent),
36 options(options),
37 stelPropFilter(excludeProperties),
38 isConnecting(false),
39 server(Q_NULLPTR),
40 timeoutTimerId(-1)
41 {
42 handlerList.resize(MSGTYPE_SIZE);
43 handlerList[ERROR] = new ClientErrorHandler(this);
44 handlerList[SERVER_CHALLENGE] = new ClientAuthHandler(this);
45 handlerList[SERVER_CHALLENGERESPONSEVALID] = new ClientAuthHandler(this);
46 handlerList[ALIVE] = new ClientAliveHandler();
47
48 //these are the actual sync handlers
49 if(options.testFlag(SyncTime))
50 handlerList[TIME] = new ClientTimeHandler();
51 if(options.testFlag(SyncLocation))
52 handlerList[LOCATION] = new ClientLocationHandler();
53 if(options.testFlag(SyncSelection))
54 handlerList[SELECTION] = new ClientSelectionHandler();
55 if(options.testFlag(SyncStelProperty))
56 handlerList[STELPROPERTY] = new ClientStelPropertyUpdateHandler(options.testFlag(SkipGUIProps), stelPropFilter);
57 if(options.testFlag(SyncView))
58 handlerList[VIEW] = new ClientViewHandler();
59 if(options.testFlag(SyncFov))
60 handlerList[FOV] = new ClientFovHandler();
61
62 //fill unused handlers with dummies
63 for(int t = TIME;t<MSGTYPE_SIZE;++t)
64 {
65 if(!handlerList[t]) handlerList[t] = new DummyMessageHandler();
66 }
67 }
68
~SyncClient()69 SyncClient::~SyncClient()
70 {
71 disconnectFromServer();
72 delete server;
73
74 //delete handlers
75 for (auto* h : handlerList)
76 {
77 if(h)
78 delete h;
79 }
80 handlerList.clear();
81
82 qCDebug(syncClient)<<"Destroyed";
83 }
84
connectToServer(const QString & host,const int port)85 void SyncClient::connectToServer(const QString &host, const int port)
86 {
87 if(server)
88 {
89 disconnectFromServer();
90 }
91
92 QTcpSocket* sock = new QTcpSocket();
93 connect(sock, SIGNAL(connected()), this, SLOT(socketConnected()));
94 server = new SyncRemotePeer(sock, true, handlerList );
95 connect(server, SIGNAL(disconnected(bool)), this, SLOT(serverDisconnected(bool)));
96
97 isConnecting = true;
98 qCDebug(syncClient)<<"Connecting to"<<(host + ":" + QString::number(port))<<", with options"<<options;
99 timeoutTimerId = startTimer(2000,Qt::VeryCoarseTimer); //the connection is checked all 5 seconds
100 sock->connectToHost(host,static_cast<quint16>(port));
101 }
102
disconnectFromServer()103 void SyncClient::disconnectFromServer()
104 {
105 if(server)
106 {
107 server->disconnectPeer();
108 }
109 }
110
timerEvent(QTimerEvent * evt)111 void SyncClient::timerEvent(QTimerEvent *evt)
112 {
113 if(evt->timerId() == timeoutTimerId)
114 {
115 checkTimeout();
116 evt->accept();
117 }
118 }
119
checkTimeout()120 void SyncClient::checkTimeout()
121 {
122 if(!server)
123 return;
124
125 server->checkTimeout();
126 }
127
serverDisconnected(bool clean)128 void SyncClient::serverDisconnected(bool clean)
129 {
130 qCDebug(syncClient)<<"Disconnected from server";
131 if(!clean)
132 errorStr = server->getError();
133 server->deleteLater();
134 server = Q_NULLPTR;
135 emit disconnected(errorStr.isEmpty());
136 }
137
socketConnected()138 void SyncClient::socketConnected()
139 {
140 qCDebug(syncClient)<<"Socket connected";
141 }
142
emitServerError(const QString & errorStr)143 void SyncClient::emitServerError(const QString &errorStr)
144 {
145 this->errorStr = errorStr;
146 }
147