Instrument Neutral Distributed Interface INDI  1.9.2
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 
23 #include "base64.h"
24 #include "basedevice.h"
25 #include "locale_compat.h"
26 #include "indistandardproperty.h"
27 
28 #include "indiuserio.h"
29 
30 #include <iostream>
31 #include <string>
32 #include <algorithm>
33 
34 #include <cstdlib>
35 #include <assert.h>
36 
37 #define MAXINDIBUF 49152
38 
39 #if defined(_MSC_VER)
40 #define snprintf _snprintf
41 #pragma warning(push)
42 #pragma warning(disable : 4996)
44 #endif
45 
46 static userio io;
47 
48 INDI::BaseClientQt::BaseClientQt(QObject *parent) : QObject(parent), cServer("localhost"), cPort(7624)
49 {
50  io.write = [](void *user, const void * ptr, size_t count) -> size_t
51  {
52  BaseClientQt *self = static_cast<BaseClientQt *>(user);
53  return self->client_socket.write(static_cast<const char *>(ptr), count);
54  };
55 
56  io.vprintf = [](void *user, const char * format, va_list ap) -> int
57  {
58  BaseClientQt *self = static_cast<BaseClientQt *>(user);
59  char message[MAXRBUF];
60  vsnprintf(message, MAXRBUF, format, ap);
61  return self->client_socket.write(message, strlen(message));
62  };
63 
64  sConnected = false;
65  verbose = false;
66  lillp = nullptr;
67 
68  timeout_sec = 3;
69  timeout_us = 0;
70 
71  connect(&client_socket, SIGNAL(readyRead()), this, SLOT(listenINDI()));
72  connect(&client_socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
73  SLOT(processSocketError(QAbstractSocket::SocketError)));
74 }
75 
77 {
78  clear();
79 }
80 
81 void INDI::BaseClientQt::clear()
82 {
83  while (!cDevices.empty())
84  {
85  delete cDevices.back();
86  cDevices.pop_back();
87  }
88  cDevices.clear();
89  while (!blobModes.empty())
90  {
91  delete blobModes.back();
92  blobModes.pop_back();
93  }
94  blobModes.clear();
95 }
96 
97 void INDI::BaseClientQt::setServer(const char *hostname, unsigned int port)
98 {
99  cServer = hostname;
100  cPort = port;
101 }
102 
103 void INDI::BaseClientQt::watchDevice(const char *deviceName)
104 {
105  // Watch for duplicates. Should have used std::set from the beginning but let's
106  // avoid changing API now.
107  if (std::find(cDeviceNames.begin(), cDeviceNames.end(), deviceName) != cDeviceNames.end())
108  return;
109 
110  cDeviceNames.push_back(deviceName);
111 }
112 
113 void INDI::BaseClientQt::watchProperty(const char *deviceName, const char *propertyName)
114 {
115  watchDevice(deviceName);
116  cWatchProperties[deviceName].insert(propertyName);
117 }
118 
120 {
121  client_socket.connectToHost(cServer.c_str(), cPort);
122 
123  if (client_socket.waitForConnected(timeout_sec * 1000) == false)
124  {
125  sConnected = false;
126  return false;
127  }
128 
129  clear();
130 
131  lillp = newLilXML();
132 
133  sConnected = true;
134 
135  serverConnected();
136 
137  QString getProp;
138  if (cDeviceNames.empty())
139  {
140  IUUserIOGetProperties(&io, this, nullptr, nullptr);
141  if (verbose)
142  IUUserIOGetProperties(userio_file(), stderr, nullptr, nullptr);
143  }
144  else
145  {
146  for (const auto &oneDevice : cDeviceNames)
147  {
148  IUUserIOGetProperties(&io, this, oneDevice.c_str(), nullptr);
149  if (verbose)
150  IUUserIOGetProperties(userio_file(), stderr, oneDevice.c_str(), nullptr);
151 
152  // #PS: missing code? see INDI::BaseClient::listenINDI()
153  }
154  }
155 
156  return true;
157 }
158 
160 {
161  if (sConnected == false)
162  return true;
163 
164  sConnected = false;
165 
166  client_socket.close();
167  if (lillp)
168  {
169  delLilXML(lillp);
170  lillp = nullptr;
171  }
172 
173  clear();
174 
175  cDeviceNames.clear();
176 
177  serverDisconnected(0);
178 
179  return true;
180 }
181 
182 void INDI::BaseClientQt::connectDevice(const char *deviceName)
183 {
184  setDriverConnection(true, deviceName);
185 }
186 
187 void INDI::BaseClientQt::disconnectDevice(const char *deviceName)
188 {
189  setDriverConnection(false, deviceName);
190 }
191 
192 void INDI::BaseClientQt::setDriverConnection(bool status, const char *deviceName)
193 {
194  INDI::BaseDevice *drv = getDevice(deviceName);
195  ISwitchVectorProperty *drv_connection = nullptr;
196 
197  if (drv == nullptr)
198  {
199  IDLog("INDI::BaseClientQt: Error. Unable to find driver %s\n", deviceName);
200  return;
201  }
202 
203  drv_connection = drv->getSwitch(INDI::SP::CONNECTION);
204 
205  if (drv_connection == nullptr)
206  return;
207 
208  // If we need to connect
209  if (status)
210  {
211  // If there is no need to do anything, i.e. already connected.
212  if (drv_connection->sp[0].s == ISS_ON)
213  return;
214 
215  IUResetSwitch(drv_connection);
216  drv_connection->s = IPS_BUSY;
217  drv_connection->sp[0].s = ISS_ON;
218  drv_connection->sp[1].s = ISS_OFF;
219 
220  sendNewSwitch(drv_connection);
221  }
222  else
223  {
224  // If there is no need to do anything, i.e. already disconnected.
225  if (drv_connection->sp[1].s == ISS_ON)
226  return;
227 
228  IUResetSwitch(drv_connection);
229  drv_connection->s = IPS_BUSY;
230  drv_connection->sp[0].s = ISS_OFF;
231  drv_connection->sp[1].s = ISS_ON;
232 
233  sendNewSwitch(drv_connection);
234  }
235 }
236 
238 {
239  for (auto &dev : cDevices)
240  {
241  if (!strcmp(deviceName, dev->getDeviceName()))
242  return dev;
243  }
244  return nullptr;
245 }
246 
248 {
249  (static_cast<INDI::BaseClientQt *>(context))->listenINDI();
250  return nullptr;
251 }
252 
253 void INDI::BaseClientQt::listenINDI()
254 {
255  char buffer[MAXINDIBUF];
256  char errorMsg[MAXRBUF];
257  int err_code = 0;
258 
259  XMLEle **nodes;
260  int inode = 0;
261 
262  if (sConnected == false)
263  return;
264 
265  while (client_socket.bytesAvailable() > 0)
266  {
267  qint64 readBytes = client_socket.read(buffer, MAXINDIBUF - 1);
268  if (readBytes > 0)
269  buffer[readBytes] = '\0';
270 
271  nodes = parseXMLChunk(lillp, buffer, readBytes, errorMsg);
272  if (!nodes)
273  {
274  if (errorMsg[0])
275  {
276  fprintf(stderr, "Bad XML from %s/%ud: %s\n%s\n", cServer.c_str(), cPort, errorMsg, buffer);
277  return;
278  }
279  return;
280  }
281  XMLEle *root = nodes[inode];
282  while (root)
283  {
284  if (verbose)
285  prXMLEle(stderr, root, 0);
286 
287  if ((err_code = dispatchCommand(root, errorMsg)) < 0)
288  {
289  // Silenty ignore property duplication errors
290  if (err_code != INDI_PROPERTY_DUPLICATED)
291  {
292  IDLog("Dispatch command error(%d): %s\n", err_code, errorMsg);
293  prXMLEle(stderr, root, 0);
294  }
295  }
296 
297  delXMLEle(root); // not yet, delete and continue
298  inode++;
299  root = nodes[inode];
300  }
301  free(nodes);
302  inode = 0;
303  }
304 }
305 
307 {
308  if (!strcmp(tagXMLEle(root), "message"))
309  return messageCmd(root, errmsg);
310  else if (!strcmp(tagXMLEle(root), "delProperty"))
311  return delPropertyCmd(root, errmsg);
312  // Just ignore any getProperties we might get
313  else if (!strcmp(tagXMLEle(root), "getProperties"))
315 
316  /* Get the device, if not available, create it */
317  INDI::BaseDevice *dp = findDev(root, 1, errmsg);
318  if (dp == nullptr)
319  {
320  strcpy(errmsg, "No device available and none was created");
321  return INDI_DEVICE_NOT_FOUND;
322  }
323 
324  // Ignore echoed newXXX
325  if (strstr(tagXMLEle(root), "new"))
326  return 0;
327 
328  // If device is set to BLOB_ONLY, we ignore everything else
329  // not related to blobs
330  if (getBLOBMode(dp->getDeviceName()) == B_ONLY)
331  {
332  if (!strcmp(tagXMLEle(root), "defBLOBVector"))
333  return dp->buildProp(root, errmsg);
334  else if (!strcmp(tagXMLEle(root), "setBLOBVector"))
335  return dp->setValue(root, errmsg);
336 
337  // Ignore everything else
338  return 0;
339  }
340 
341  // If we are asked to watch for specific properties only, we ignore everything else
342  if (cWatchProperties.size() > 0)
343  {
344  const char *device = findXMLAttValu(root, "device");
345  const char *name = findXMLAttValu(root, "name");
346  if (device && name)
347  {
348  if (cWatchProperties.find(device) == cWatchProperties.end() ||
349  cWatchProperties[device].find(name) == cWatchProperties[device].end())
350  return 0;
351  }
352  }
353 
354  if ((!strcmp(tagXMLEle(root), "defTextVector")) || (!strcmp(tagXMLEle(root), "defNumberVector")) ||
355  (!strcmp(tagXMLEle(root), "defSwitchVector")) || (!strcmp(tagXMLEle(root), "defLightVector")) ||
356  (!strcmp(tagXMLEle(root), "defBLOBVector")))
357  return dp->buildProp(root, errmsg);
358  else if (!strcmp(tagXMLEle(root), "setTextVector") || !strcmp(tagXMLEle(root), "setNumberVector") ||
359  !strcmp(tagXMLEle(root), "setSwitchVector") || !strcmp(tagXMLEle(root), "setLightVector") ||
360  !strcmp(tagXMLEle(root), "setBLOBVector"))
361  return dp->setValue(root, errmsg);
362 
363  return INDI_DISPATCH_ERROR;
364 }
365 
366 /* delete the property in the given device, including widgets and data structs.
367  * when last property is deleted, delete the device too.
368  * if no property name attribute at all, delete the whole device regardless.
369  * return 0 if ok, else -1 with reason in errmsg[].
370  */
372 {
373  XMLAtt *ap;
374  INDI::BaseDevice *dp;
375 
376  /* dig out device and optional property name */
377  dp = findDev(root, 0, errmsg);
378  if (!dp)
379  return INDI_DEVICE_NOT_FOUND;
380 
381  dp->checkMessage(root);
382 
383  ap = findXMLAtt(root, "name");
384 
385  /* Delete property if it exists, otherwise, delete the whole device */
386  if (ap)
387  {
388  INDI::Property *rProp = dp->getProperty(valuXMLAtt(ap));
389  if (rProp == nullptr)
390  {
391  snprintf(errmsg, MAXRBUF, "Cannot delete property %s as it is not defined yet. Check driver.", valuXMLAtt(ap));
392  return -1;
393  }
394 
395  removeProperty(rProp);
396  int errCode = dp->removeProperty(valuXMLAtt(ap), errmsg);
397 
398  return errCode;
399  }
400  // delete the whole device
401  else
402  return deleteDevice(dp->getDeviceName(), errmsg);
403 }
404 
405 int INDI::BaseClientQt::deleteDevice(const char *devName, char *errmsg)
406 {
407  std::vector<INDI::BaseDevice *>::iterator devicei;
408 
409  for (devicei = cDevices.begin(); devicei != cDevices.end();)
410  {
411  if (!strcmp(devName, (*devicei)->getDeviceName()))
412  {
413  removeDevice(*devicei);
414  delete *devicei;
415  devicei = cDevices.erase(devicei);
416  return 0;
417  }
418  else
419  ++devicei;
420  }
421 
422  snprintf(errmsg, MAXRBUF, "Device %s not found", devName);
423  return INDI_DEVICE_NOT_FOUND;
424 }
425 
426 INDI::BaseDevice *INDI::BaseClientQt::findDev(const char *devName, char *errmsg)
427 {
428  std::vector<INDI::BaseDevice *>::const_iterator devicei;
429 
430  for (devicei = cDevices.begin(); devicei != cDevices.end(); devicei++)
431  {
432  if (!strcmp(devName, (*devicei)->getDeviceName()))
433  return (*devicei);
434  }
435 
436  snprintf(errmsg, MAXRBUF, "Device %s not found", devName);
437  return nullptr;
438 }
439 
440 /* add new device */
442 {
443  //devicePtr dp(new INDI::BaseDriver());
445  XMLAtt *ap;
446  char *device_name;
447 
448  /* allocate new INDI::BaseDriver */
449  ap = findXMLAtt(dep, "device");
450  if (!ap)
451  {
452  strncpy(errmsg, "Unable to find device attribute in XML element. Cannot add device.", MAXRBUF);
453  return nullptr;
454  }
455 
456  device_name = valuXMLAtt(ap);
457 
458  dp->setMediator(this);
459  dp->setDeviceName(device_name);
460 
461  cDevices.push_back(dp);
462 
463  newDevice(dp);
464 
465  /* ok */
466  return dp;
467 }
468 
469 INDI::BaseDevice *INDI::BaseClientQt::findDev(XMLEle *root, int create, char *errmsg)
470 {
471  XMLAtt *ap;
472  INDI::BaseDevice *dp;
473  char *dn;
474 
475  /* get device name */
476  ap = findXMLAtt(root, "device");
477  if (!ap)
478  {
479  snprintf(errmsg, MAXRBUF, "No device attribute found in element %s", tagXMLEle(root));
480  return (nullptr);
481  }
482 
483  dn = valuXMLAtt(ap);
484 
485  if (*dn == '\0')
486  {
487  snprintf(errmsg, MAXRBUF, "Device name is empty! %s", tagXMLEle(root));
488  return (nullptr);
489  }
490 
491  dp = findDev(dn, errmsg);
492 
493  if (dp)
494  return dp;
495 
496  /* not found, create if ok */
497  if (create)
498  return (addDevice(root, errmsg));
499 
500  snprintf(errmsg, MAXRBUF, "INDI: <%s> no such device %s", tagXMLEle(root), dn);
501  return nullptr;
502 }
503 
504 /* a general message command received from the device.
505  * return 0 if ok, else -1 with reason in errmsg[].
506  */
507 int INDI::BaseClientQt::messageCmd(XMLEle *root, char *errmsg)
508 {
509  INDI::BaseDevice *dp = findDev(root, 0, errmsg);
510 
511  if (dp)
512  dp->checkMessage(root);
513 
514  return (0);
515 }
516 
518 {
519  IDLog("%s\n", message.c_str());
520 }
521 
523 {
524  AutoCNumeric locale;
525 
526  tvp->s = IPS_BUSY;
527  IUUserIONewText(&io, this, tvp);
528 }
529 
530 void INDI::BaseClientQt::sendNewText(const char *deviceName, const char *propertyName, const char *elementName,
531  const char *text)
532 {
533  INDI::BaseDevice *drv = getDevice(deviceName);
534 
535  if (drv == nullptr)
536  return;
537 
538  ITextVectorProperty *tvp = drv->getText(propertyName);
539 
540  if (tvp == nullptr)
541  return;
542 
543  IText *tp = IUFindText(tvp, elementName);
544 
545  if (tp == nullptr)
546  return;
547 
548  IUSaveText(tp, text);
549 
550  sendNewText(tvp);
551 }
552 
554 {
555  AutoCNumeric locale;
556 
557  nvp->s = IPS_BUSY;
558  IUUserIONewNumber(&io, this, nvp);
559 }
560 
561 void INDI::BaseClientQt::sendNewNumber(const char *deviceName, const char *propertyName, const char *elementName,
562  double value)
563 {
564  INDI::BaseDevice *drv = getDevice(deviceName);
565 
566  if (drv == nullptr)
567  return;
568 
569  INumberVectorProperty *nvp = drv->getNumber(propertyName);
570 
571  if (nvp == nullptr)
572  return;
573 
574  INumber *np = IUFindNumber(nvp, elementName);
575 
576  if (np == nullptr)
577  return;
578 
579  np->value = value;
580 
581  sendNewNumber(nvp);
582 }
583 
585 {
586  svp->s = IPS_BUSY;
587  IUUserIONewSwitch(&io, this, svp);
588 }
589 
590 void INDI::BaseClientQt::sendNewSwitch(const char *deviceName, const char *propertyName, const char *elementName)
591 {
592  INDI::BaseDevice *drv = getDevice(deviceName);
593 
594  if (drv == nullptr)
595  return;
596 
597  ISwitchVectorProperty *svp = drv->getSwitch(propertyName);
598 
599  if (svp == nullptr)
600  return;
601 
602  ISwitch *sp = IUFindSwitch(svp, elementName);
603 
604  if (sp == nullptr)
605  return;
606 
607  sp->s = ISS_ON;
608 
609  sendNewSwitch(svp);
610 }
611 
612 void INDI::BaseClientQt::startBlob(const char *devName, const char *propName, const char *timestamp)
613 {
614  IUUserIONewBLOBStart(&io, this, devName, propName, timestamp);
615 }
616 
618 {
620  &io, this,
621  bp->name, bp->size, bp->bloblen, bp->blob, bp->format
622  );
623 }
624 
625 void INDI::BaseClientQt::sendOneBlob(const char *blobName, unsigned int blobSize, const char *blobFormat,
626  void *blobBuffer)
627 {
629  &io, this,
630  blobName, blobSize, blobSize, blobBuffer, blobFormat
631  );
632 }
633 
635 {
636  IUUserIONewBLOBFinish(&io, this);
637 }
638 
639 void INDI::BaseClientQt::setBLOBMode(BLOBHandling blobH, const char *dev, const char *prop)
640 {
641  if (!dev[0])
642  return;
643 
644  BLOBMode *bMode = findBLOBMode(std::string(dev), prop ? std::string(prop) : std::string());
645 
646  if (bMode == nullptr)
647  {
648  BLOBMode *newMode = new BLOBMode();
649  newMode->device = std::string(dev);
650  newMode->property = (prop ? std::string(prop) : std::string());
651  newMode->blobMode = blobH;
652  blobModes.push_back(newMode);
653  }
654  else
655  {
656  // If nothing changed, nothing to to do
657  if (bMode->blobMode == blobH)
658  return;
659 
660  bMode->blobMode = blobH;
661  }
662  IUUserIOEnableBLOB(&io, this, dev, prop, blobH);
663 }
664 
665 BLOBHandling INDI::BaseClientQt::getBLOBMode(const char *dev, const char *prop)
666 {
667  BLOBHandling bHandle = B_ALSO;
668 
669  BLOBMode *bMode = findBLOBMode(dev, (prop ? std::string(prop) : std::string()));
670 
671  if (bMode)
672  bHandle = bMode->blobMode;
673 
674  return bHandle;
675 }
676 
677 INDI::BaseClientQt::BLOBMode *INDI::BaseClientQt::findBLOBMode(const std::string &device, const std::string &property)
678 {
679  for (auto &blob : blobModes)
680  {
681  if (blob->device == device && blob->property == property)
682  return blob;
683  }
684 
685  return nullptr;
686 }
687 
688 void INDI::BaseClientQt::processSocketError(QAbstractSocket::SocketError socketError)
689 {
690  if (sConnected == false)
691  return;
692 
693  // TODO Handle what happens on socket failure!
694  INDI_UNUSED(socketError);
695  IDLog("Socket Error: %s\n", client_socket.errorString().toLatin1().constData());
696  fprintf(stderr, "INDI server %s/%d disconnected.\n", cServer.c_str(), cPort);
697  delLilXML(lillp);
698  client_socket.close();
699  // Let client handle server disconnection
700  serverDisconnected(-1);
701 }
702 
703 bool INDI::BaseClientQt::getDevices(std::vector<INDI::BaseDevice *> &deviceList, uint16_t driverInterface )
704 {
705  for (INDI::BaseDevice *device : cDevices)
706  {
707  if (device->getDriverInterface() & driverInterface)
708  deviceList.push_back(device);
709  }
710 
711  return (deviceList.size() > 0);
712 }
713 
715 {
716  return sConnected;
717 }
718 
719 #if defined(_MSC_VER)
720 #undef snprintf
721 #pragma warning(pop)
722 #endif
IUUserIOBLOBContextOne
void IUUserIOBLOBContextOne(const userio *io, void *user, const char *name, unsigned int size, unsigned int bloblen, const void *blob, const char *format)
Definition: indiuserio.c:100
INDI::BaseDevice::getText
INDI::PropertyView< IText > * getText(const char *name) const
Definition: basedevice.cpp:104
indistandardproperty.h
newLilXML
LilXML * newLilXML()
Create a new lilxml parser.
Definition: lilxml.c:148
IUUserIOGetProperties
void IUUserIOGetProperties(const userio *io, void *user, const char *dev, const char *name)
Definition: indiuserio.c:297
INDI::BaseClientQt::connectServer
bool connectServer()
Connect to INDI server.
Definition: baseclientqt.cpp:119
basedevice.h
INDI::BaseClientQt::disconnectDevice
void disconnectDevice(const char *deviceName)
Disconnect INDI driver.
Definition: baseclientqt.cpp:187
INDI::BaseDevice::buildProp
int buildProp(XMLEle *root, char *errmsg)
Build a property given the supplied XML element (defXXX)
Definition: basedevice.cpp:299
INDI::BaseClientQt::~BaseClientQt
virtual ~BaseClientQt()
Definition: baseclientqt.cpp:76
INDI::BaseClientQt::findDev
INDI::BaseDevice * findDev(const char *devName, char *errmsg)
Find and return a particular device.
Definition: baseclientqt.cpp:426
INDI::BaseClientQt::getDevice
INDI::BaseDevice * getDevice(const char *deviceName)
Definition: baseclientqt.cpp:237
_INumberVectorProperty::s
IPState s
Definition: indiapi.h:332
ISwitch
One switch descriptor.
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
locale_compat.h
INumber
One number descriptor.
INDI::BaseClientQt::isServerConnected
bool isServerConnected() const
Definition: baseclientqt.cpp:714
B_ONLY
@ B_ONLY
Definition: indidevapi.h:272
INDI::BaseClientQt::watchDevice
void watchDevice(const char *deviceName)
Add a device to the watch list.
Definition: baseclientqt.cpp:103
INDI::BaseDevice::getNumber
INDI::PropertyView< INumber > * getNumber(const char *name) const
Definition: basedevice.cpp:99
timestamp
const char * timestamp()
Create an ISO 8601 formatted time stamp. The format is YYYY-MM-DDTHH:MM:SS.
Definition: indicom.c:334
INDI::BaseClientQt::getBLOBMode
BLOBHandling getBLOBMode(const char *dev, const char *prop=nullptr)
getBLOBMode Get Binary Large Object policy mode IF set previously by setBLOBMode
Definition: baseclientqt.cpp:665
INDI_UNUSED
#define INDI_UNUSED(x)
Definition: indidevapi.h:799
baseclientqt.h
INDI::BaseClientQt::watchProperty
void watchProperty(const char *deviceName, const char *propertyName)
watchProperties Add a property to the watch list. When communicating with INDI server....
Definition: baseclientqt.cpp:113
indiuserio.h
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
INDI::BaseDevice::setMediator
void setMediator(INDI::BaseMediator *mediator)
Set the driver's mediator to receive notification of news devices and updated property values.
Definition: basedevice.cpp:1019
INDI::BaseClientQt::messageCmd
int messageCmd(XMLEle *root, char *errmsg)
Definition: baseclientqt.cpp:507
INDI::BaseClientQt
Class to provide basic client functionality based on Qt5 toolkit and is therefore suitable for cross-...
Definition: baseclientqt.h:57
INDI::BaseDevice::getSwitch
INDI::PropertyView< ISwitch > * getSwitch(const char *name) const
Definition: basedevice.cpp:109
MAXRBUF
#define MAXRBUF
Definition: indidriver.c:52
IUUserIONewBLOBFinish
void IUUserIONewBLOBFinish(const userio *io, void *user)
Definition: indiuserio.c:271
IUUserIONewNumber
void IUUserIONewNumber(const userio *io, void *user, const INumberVectorProperty *nvp)
Definition: indiuserio.c:189
IUResetSwitch
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indicom.c:1421
IDLog
void void void void void IDLog(const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(1
Function Drivers call to log a message locally.
INDI::Property
Provides generic container for INDI properties.
Definition: indiproperty.h:43
INDI::BaseClientQt::getDevices
const std::vector< INDI::BaseDevice * > & getDevices() const
Definition: baseclientqt.h:123
_ITextVectorProperty
Text vector property descriptor.
Definition: indiapi.h:244
INDI::BaseDevice::getProperty
Property getProperty(const char *name, INDI_PROPERTY_TYPE type=INDI_UNKNOWN) const
Return a property and its type given its name.
Definition: basedevice.cpp:148
IUFindText
IText * IUFindText(const ITextVectorProperty *tvp, const char *name)
Find an IText member in a vector text property.
Definition: indicom.c:1341
device
hid_device * device
Definition: activefocuser_utils.cpp:92
_INumberVectorProperty
Number vector property descriptor.
Definition: indiapi.h:317
INDI::BaseClientQt::BaseClientQt
BaseClientQt(QObject *parent=Q_NULLPTR)
Definition: baseclientqt.cpp:48
delLilXML
void delLilXML(LilXML *lp)
Delete a lilxml parser.
Definition: lilxml.c:157
INDI::BaseDevice::setDeviceName
void setDeviceName(const char *dev)
Set the device name.
Definition: basedevice.cpp:793
INDI::BaseClientQt::sendNewText
void sendNewText(ITextVectorProperty *pp)
Send new Text command to server.
Definition: baseclientqt.cpp:522
IUUserIONewText
void IUUserIONewText(const userio *io, void *user, const ITextVectorProperty *tvp)
Definition: indiuserio.c:206
IText
One text descriptor.
B_ALSO
@ B_ALSO
Definition: indidevapi.h:271
xml_att_
Definition: lilxml.c:120
IPS_BUSY
@ IPS_BUSY
Definition: indiapi.h:162
base64.h
INDI_DEVICE_NOT_FOUND
@ INDI_DEVICE_NOT_FOUND
Definition: indibasetypes.h:57
INDI::BaseClientQt::addDevice
INDI::BaseDevice * addDevice(XMLEle *dep, char *errmsg)
Add a new device.
Definition: baseclientqt.cpp:441
tagXMLEle
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
Definition: lilxml.c:569
xml_ele_
Definition: lilxml.c:105
BLOBHandling
BLOBHandling
How drivers handle BLOBs incoming from snooping drivers.
Definition: indidevapi.h:268
IUUserIONewSwitch
void IUUserIONewSwitch(const userio *io, void *user, const ISwitchVectorProperty *svp)
Definition: indiuserio.c:230
INDI::BaseDevice::checkMessage
void checkMessage(XMLEle *root)
Definition: basedevice.cpp:820
INDI::BaseClientQt::finishBlob
void finishBlob()
Send closing tag for BLOB command to server.
Definition: baseclientqt.cpp:634
INDI::BaseClientQt::delPropertyCmd
int delPropertyCmd(XMLEle *root, char *errmsg)
Delete property command.
Definition: baseclientqt.cpp:371
INDI::BaseClientQt::sendNewSwitch
void sendNewSwitch(ISwitchVectorProperty *pp)
Send new Switch command to server.
Definition: baseclientqt.cpp:584
IUFindNumber
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
Definition: indicom.c:1351
IUUserIOEnableBLOB
void IUUserIOEnableBLOB(const userio *io, void *user, const char *dev, const char *name, BLOBHandling blobH)
Definition: indiuserio.c:331
INDI::BaseDevice::setValue
int setValue(XMLEle *root, char *errmsg)
handle SetXXX commands from client
Definition: basedevice.cpp:532
INDI::BaseDevice::removeProperty
int removeProperty(const char *name, char *errmsg)
Remove a property.
Definition: basedevice.cpp:180
IUSaveText
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indicom.c:1428
parseXMLChunk
XMLEle ** parseXMLChunk(LilXML *lp, char *buf, int size, char ynot[])
Process an XML chunk.
Definition: lilxml.c:213
MAXINDIBUF
#define MAXINDIBUF
Definition: baseclientqt.cpp:37
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
INDI::BaseClientQt::newUniversalMessage
virtual void newUniversalMessage(std::string message)
newUniversalMessage Universal messages are sent from INDI server without a specific device....
Definition: baseclientqt.cpp:517
valuXMLAtt
char * valuXMLAtt(XMLAtt *ap)
Return the value of an XML attribute.
Definition: lilxml.c:593
INDI::BaseClientQt::sendOneBlob
void sendOneBlob(IBLOB *bp)
Send ONE blob content to server. The BLOB data in raw binary format and will be converted to base64 a...
Definition: baseclientqt.cpp:617
_ITextVectorProperty::s
IPState s
Definition: indiapi.h:259
INDI::BaseClientQt::setServer
void setServer(const char *hostname, unsigned int port)
Set the server host name and port.
Definition: baseclientqt.cpp:97
prXMLEle
void prXMLEle(FILE *fp, XMLEle *ep, int level)
Print an XML element.
Definition: lilxml.c:699
userio::write
size_t(* write)(void *user, const void *ptr, size_t count)
Definition: userio.h:34
userio_file
const struct userio * userio_file()
Definition: userio.c:38
verbose
int verbose
Definition: indidriver.c:49
findXMLAttValu
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
Definition: lilxml.c:613
INDI::BaseClientQt::connectDevice
void connectDevice(const char *deviceName)
Connect to INDI driver.
Definition: baseclientqt.cpp:182
INDI::BaseClientQt::disconnectServer
bool disconnectServer()
Disconnect from INDI server.
Definition: baseclientqt.cpp:159
INDI_DISPATCH_ERROR
@ INDI_DISPATCH_ERROR
Definition: indibasetypes.h:60
INDI::BaseClientQt::sendNewNumber
void sendNewNumber(INumberVectorProperty *pp)
Send new Number command to server.
Definition: baseclientqt.cpp:553
userio
Definition: userio.h:32
INDI::BaseClientQt::deleteDevice
int deleteDevice(const char *devName, char *errmsg)
Remove device.
Definition: baseclientqt.cpp:405
IUFindSwitch
ISwitch * IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)
Find an ISwitch member in a vector switch property.
Definition: indicom.c:1361
INDI::BaseClientQt::dispatchCommand
int dispatchCommand(XMLEle *root, char *errmsg)
Dispatch command received from INDI server to respective devices handled by the client.
Definition: baseclientqt.cpp:306
_ISwitchVectorProperty::sp
ISwitch * sp
Definition: indiapi.h:384
INDI::BaseClientQt::startBlob
void startBlob(const char *devName, const char *propName, const char *timestamp)
Send opening tag for BLOB command to server.
Definition: baseclientqt.cpp:612
INDI::SP::CONNECTION
const char * CONNECTION
Connect to and disconnect from device.
Definition: indistandardproperty.cpp:63
IUUserIONewBLOBStart
void IUUserIONewBLOBStart(const userio *io, void *user, const char *dev, const char *name, const char *timestamp)
Definition: indiuserio.c:250
INDI_PROPERTY_DUPLICATED
@ INDI_PROPERTY_DUPLICATED
Definition: indibasetypes.h:59
delXMLEle
void delXMLEle(XMLEle *ep)
delXMLEle Delete XML element.
Definition: lilxml.c:165
INDI::BaseDevice
Class to provide basic INDI device functionality.
Definition: basedevice.h:45
INDI::BaseClientQt::setBLOBMode
void setBLOBMode(BLOBHandling blobH, const char *dev, const char *prop=nullptr)
Set Binary Large Object policy mode.
Definition: baseclientqt.cpp:639
IBLOB
One Blob (Binary Large Object) descriptor.
INDI::BaseClientQt::listenHelper
static void * listenHelper(void *context)
Definition: baseclientqt.cpp:247
findXMLAtt
XMLAtt * findXMLAtt(XMLEle *ep, const char *name)
Find an XML attribute within an XML element.
Definition: lilxml.c:493
userio::vprintf
int(* vprintf)(void *user, const char *format, va_list arg)
Definition: userio.h:35
Aux::buffer
std::vector< uint8_t > buffer
Definition: celestronauxpacket.h:38
_ISwitchVectorProperty
Switch vector property descriptor.
Definition: indiapi.h:365
ISS_ON
@ ISS_ON
Definition: indiapi.h:151