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