Instrument Neutral Distributed Interface INDI 2.2.5
baseclientqt.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 Copyright(c) 2016 Jasem Mutlaq. All rights reserved.
3
4 INDI Qt Client
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library 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 GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*******************************************************************************/
20
21#include "baseclientqt.h"
22#include "baseclientqt_p.h"
23
24#include "abstractbaseclient.h"
26namespace INDI
27{
28
29// BaseClientQtPrivate
30
34
35ssize_t BaseClientQtPrivate::sendData(const void *data, size_t size)
36{
37 return clientSocket.write(static_cast<const char *>(data), size);
38}
39
41{
42 char msg[MAXRBUF];
43
44 if (sConnected == false)
45 return;
46
47 while (clientSocket.bytesAvailable() > 0)
48 {
49 const QByteArray data = clientSocket.readAll();
50
51 auto documents = xmlParser.parseChunk(data.constData(), data.size());
52
53 if (documents.size() == 0)
54 {
56 {
57 IDLog("Bad XML from %s/%d: %s\n%.*s\n", cServer.c_str(), cPort, xmlParser.errorMessage(), static_cast<int>(data.size()),
58 data.constData());
59 }
60 break;
61 }
62
63 for (const auto &doc : documents)
64 {
65 LilXmlElement root = doc.root();
66
67 if (verbose)
68 root.print(stderr, 0);
69
70 int err_code = dispatchCommand(root, msg);
71
72 if (err_code < 0)
73 {
74 // Silently ignore property duplication errors
75 if (err_code != INDI_PROPERTY_DUPLICATED)
76 {
77 IDLog("Dispatch command error(%d): %s\n", err_code, msg);
78 root.print(stderr, 0);
79 }
80 }
81 }
82 }
83}
84
85// BaseClientQt
86
88 : QObject(parent)
90{
91 D_PTR(BaseClientQt);
92 connect(&d->clientSocket, &QTcpSocket::readyRead, this, [d]()
93 {
94 d->listenINDI();
95 });
96
97#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
98 connect(&d->clientSocket, &QTcpSocket::errorOccurred, this, [d, this](QAbstractSocket::SocketError socketError)
99#else
100 connect(&d->clientSocket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, [d,
101 this](QAbstractSocket::SocketError socketError)
102#endif
103 {
104 if (d->sConnected == false)
105 return;
106
107 // TODO Handle what happens on socket failure!
108 INDI_UNUSED(socketError);
109 IDLog("Socket Error: %s\n", d->clientSocket.errorString().toLatin1().constData());
110 fprintf(stderr, "INDI server %s/%d disconnected.\n", d->cServer.c_str(), d->cPort);
111 d->clientSocket.close();
112 // Let client handle server disconnection
113 serverDisconnected(-1);
114 });
115}
116
118{
119 D_PTR(BaseClientQt);
120 d->clear();
121}
122
124{
125 D_PTR(BaseClientQt);
126 d->clientSocket.connectToHost(d->cServer.c_str(), d->cPort);
127
128 if (d->clientSocket.waitForConnected(d->timeout_sec * 1000) == false)
129 {
130 d->sConnected = false;
131 return false;
132 }
133
134 d->clear();
135
136 d->sConnected = true;
137
139
140 d->userIoGetProperties();
141
142 return true;
143}
144
146{
147 D_PTR(BaseClientQt);
148
149 if (d->sConnected == false)
150 return true;
151
152 d->sConnected = false;
153
154 d->clientSocket.close();
155
156 d->clear();
157
158 d->watchDevice.unwatchDevices();
159
160 serverDisconnected(exit_code);
161
162 return true;
163}
164
165}
int dispatchCommand(const INDI::LilXmlElement &root, char *errmsg)
Dispatch command received from INDI server to respective devices handled by the client.
ssize_t sendData(const void *data, size_t size) override
BaseClientQtPrivate(BaseClientQt *parent)
Class to provide basic client functionality based on Qt5 toolkit and is therefore suitable for cross-...
bool disconnectServer(int exit_code=0) override
Disconnect from INDI server. Any devices previously created will be deleted and memory cleared.
bool connectServer() override
Connect to INDI server.
BaseClientQt(QObject *parent=Q_NULLPTR)
virtual void serverDisconnected(int exit_code)
Emmited when the server gets disconnected.
Definition indibase.cpp:36
virtual void serverConnected()
Emmited when the server is connected.
Definition indibase.cpp:33
void print(FILE *f, int level=0) const
Definition indililxml.h:430
const char * errorMessage() const
Definition indililxml.h:505
bool hasErrorMessage() const
Definition indililxml.h:500
std::list< LilXmlDocument > parseChunk(const char *data, size_t size)
Definition indililxml.h:485
@ INDI_PROPERTY_DUPLICATED
void IDLog(const char *fmt,...)
Definition indicom.c:305
#define MAXRBUF
Definition indidriver.c:52
Namespace to encapsulate INDI client, drivers, and mediator classes.