Instrument Neutral Distributed Interface INDI  1.9.2
defaultdevice.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2011 Jasem Mutlaq. All rights reserved.
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 *******************************************************************************/
18 
19 #include "defaultdevice.h"
20 #include "defaultdevice_p.h"
21 
22 #include "indicom.h"
23 #include "indiapi.h"
24 
25 #include "indistandardproperty.h"
27 
28 #include <cstdlib>
29 #include <cstring>
30 #include <assert.h>
31 #include <algorithm>
32 
33 const char *COMMUNICATION_TAB = "Communication";
34 const char *MAIN_CONTROL_TAB = "Main Control";
35 const char *CONNECTION_TAB = "Connection";
36 const char *MOTION_TAB = "Motion Control";
37 const char *DATETIME_TAB = "Date/Time";
38 const char *SITE_TAB = "Site Management";
39 const char *OPTIONS_TAB = "Options";
40 const char *FILTER_TAB = "Filter Wheel";
41 const char *FOCUS_TAB = "Focuser";
42 const char *GUIDE_TAB = "Guide";
43 const char *ALIGNMENT_TAB = "Alignment";
44 const char *SATELLITE_TAB = "Satellite";
45 const char *INFO_TAB = "General Info";
46 
47 std::list<INDI::DefaultDevicePrivate*> INDI::DefaultDevicePrivate::devices;
48 std::recursive_mutex INDI::DefaultDevicePrivate::devicesLock;
49 
50 extern "C"
51 {
52 
53  void ISGetProperties(const char *dev)
54  {
55  const std::unique_lock<std::recursive_mutex> lock(INDI::DefaultDevicePrivate::devicesLock);
57  it->defaultDevice->ISGetProperties(dev);
58  }
59 
60  void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
61  {
62  const std::unique_lock<std::recursive_mutex> lock(INDI::DefaultDevicePrivate::devicesLock);
64  if (dev == nullptr || strcmp(dev, it->defaultDevice->getDeviceName()) == 0)
65  it->defaultDevice->ISNewSwitch(dev, name, states, names, n);
66  }
67 
68  void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
69  {
70  const std::unique_lock<std::recursive_mutex> lock(INDI::DefaultDevicePrivate::devicesLock);
72  if (dev == nullptr || strcmp(dev, it->defaultDevice->getDeviceName()) == 0)
73  it->defaultDevice->ISNewNumber(dev, name, values, names, n);
74  }
75 
76  void ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
77  {
78  const std::unique_lock<std::recursive_mutex> lock(INDI::DefaultDevicePrivate::devicesLock);
80  if (dev == nullptr || strcmp(dev, it->defaultDevice->getDeviceName()) == 0)
81  it->defaultDevice->ISNewText(dev, name, texts, names, n);
82  }
83 
84  void ISNewBLOB(const char *dev, const char *name,
85  int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n
86  )
87  {
88  const std::unique_lock<std::recursive_mutex> lock(INDI::DefaultDevicePrivate::devicesLock);
90  if (dev == nullptr || strcmp(dev, it->defaultDevice->getDeviceName()) == 0)
91  it->defaultDevice->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
92  }
93 
94  void ISSnoopDevice(XMLEle *root)
95  {
96  const std::unique_lock<std::recursive_mutex> lock(INDI::DefaultDevicePrivate::devicesLock);
98  it->defaultDevice->ISSnoopDevice(root);
99  }
100 
101 } // extern "C"
102 
103 void timerfunc(void *t)
104 {
105  //fprintf(stderr,"Got a timer hit with %x\n",t);
106  INDI::DefaultDevice *devPtr = static_cast<INDI::DefaultDevice *>(t);
107  if (devPtr != nullptr)
108  {
109  // this was for my device
110  // but we dont have a way of telling
111  // WHICH timer was hit :(
112  devPtr->TimerHit();
113  }
114  return;
115 }
116 
117 
118 namespace INDI
119 {
120 
122  : defaultDevice(defaultDevice)
123 {
124  const std::unique_lock<std::recursive_mutex> lock(DefaultDevicePrivate::devicesLock);
125  devices.push_back(this);
126 }
127 
129 {
130  const std::unique_lock<std::recursive_mutex> lock(DefaultDevicePrivate::devicesLock);
131  devices.remove(this);
132 }
133 
135  : BaseDevice(*new DefaultDevicePrivate(this))
136 {
137  D_PTR(DefaultDevice);
138  d->m_MainLoopTimer.setSingleShot(true);
139  d->m_MainLoopTimer.setInterval(getPollingPeriod());
140  d->m_MainLoopTimer.callOnTimeout(std::bind(&DefaultDevice::TimerHit, this));
141 }
142 
144  : BaseDevice(dd)
145 { }
146 
147 bool DefaultDevice::loadConfig(bool silent, const char *property)
148 {
149  D_PTR(DefaultDevice);
150  char errmsg[MAXRBUF] = {0};
151  d->isConfigLoading = true;
152  bool pResult = IUReadConfig(nullptr, getDeviceName(), property, silent ? 1 : 0, errmsg) == 0 ? true : false;
153  d->isConfigLoading = false;
154 
155  if (!silent)
156  {
157  if (pResult)
158  {
159  LOG_DEBUG("Configuration successfully loaded.");
160  }
161  else
162  LOG_INFO("No previous configuration found. To save driver configuration, click Save Configuration in Options tab.");
163  }
164 
165  // Determine default config file name
166  // Need to be done only once per device.
167  if (d->isDefaultConfigLoaded == false)
168  {
169  d->isDefaultConfigLoaded = IUSaveDefaultConfig(nullptr, nullptr, getDeviceName()) == 0;
170  }
171 
172  return pResult;
173 }
174 
176 {
177  D_PTR(DefaultDevice);
178  d->DebugSP.save(fp);
179  d->PollPeriodNP.save(fp);
180  if (!d->ConnectionModeSP.isEmpty())
181  d->ConnectionModeSP.save(fp);
182 
183  if (d->activeConnection != nullptr)
184  d->activeConnection->saveConfigItems(fp);
185 
187 }
188 
190 {
191  for (const auto &oneProperty : *getProperties())
192  {
193  if (oneProperty->getType() == INDI_SWITCH)
194  {
195  const auto &svp = oneProperty->getSwitch();
196  /* Never save CONNECTION property. Don't save switches with no switches on if the rule is one of many */
197  if (
198  (svp->isNameMatch(INDI::SP::CONNECTION)) ||
199  (svp->getRule() == ISR_1OFMANY && svp->findOnSwitch() == nullptr)
200  )
201  continue;
202  }
203  oneProperty->save(fp);
204  }
205  return true;
206 }
207 
209 {
210  char errmsg[MAXRBUF];
211  if (IUPurgeConfig(nullptr, getDeviceName(), errmsg) == -1)
212  {
213  LOGF_WARN("%s", errmsg);
214  return false;
215  }
216 
217  LOG_INFO("Configuration file successfully purged.");
218  return true;
219 }
220 
221 bool DefaultDevice::saveConfig(bool silent, const char *property)
222 {
223  D_PTR(DefaultDevice);
224  silent = false;
225  char errmsg[MAXRBUF] = {0};
226 
227  FILE *fp = nullptr;
228 
229  if (property == nullptr)
230  {
231  fp = IUGetConfigFP(nullptr, getDeviceName(), "w", errmsg);
232 
233  if (fp == nullptr)
234  {
235  if (!silent)
236  LOGF_WARN("Failed to save configuration. %s", errmsg);
237  return false;
238  }
239 
240  IUSaveConfigTag(fp, 0, getDeviceName(), silent ? 1 : 0);
241 
242  saveConfigItems(fp);
243 
244  IUSaveConfigTag(fp, 1, getDeviceName(), silent ? 1 : 0);
245 
246  fflush(fp);
247  fclose(fp);
248 
249  if (d->isDefaultConfigLoaded == false)
250  {
251  d->isDefaultConfigLoaded = IUSaveDefaultConfig(nullptr, nullptr, getDeviceName()) == 0;
252  }
253 
254  LOG_DEBUG("Configuration successfully saved.");
255  }
256  else
257  {
258  fp = IUGetConfigFP(nullptr, getDeviceName(), "r", errmsg);
259 
260  if (fp == nullptr)
261  {
262  //if (!silent)
263  // LOGF_ERROR("Error saving configuration. %s", errmsg);
264  //return false;
265  // If we don't have an existing file pointer, save all properties.
266  return saveConfig(silent);
267  }
268 
269  LilXML *lp = newLilXML();
270  XMLEle *root = readXMLFile(fp, lp, errmsg);
271 
272  fclose(fp);
273  delLilXML(lp);
274 
275  if (root == nullptr)
276  return false;
277 
278  XMLEle *ep = nullptr;
279  bool propertySaved = false;
280 
281  for (ep = nextXMLEle(root, 1); ep != nullptr; ep = nextXMLEle(root, 0))
282  {
283  const char *elemName = findXMLAttValu(ep, "name");
284  const char *tagName = tagXMLEle(ep);
285 
286  if (strcmp(elemName, property))
287  continue;
288 
289  if (!strcmp(tagName, "newSwitchVector"))
290  {
291  auto svp = getSwitch(elemName);
292  if (svp == nullptr)
293  {
294  delXMLEle(root);
295  return false;
296  }
297 
298  XMLEle *sw = nullptr;
299  for (sw = nextXMLEle(ep, 1); sw != nullptr; sw = nextXMLEle(ep, 0))
300  {
301  auto oneSwitch = svp->findWidgetByName(findXMLAttValu(sw, "name"));
302  if (oneSwitch == nullptr)
303  {
304  delXMLEle(root);
305  return false;
306  }
307  char formatString[MAXRBUF];
308  snprintf(formatString, MAXRBUF, " %s\n", oneSwitch->getStateAsString());
309  editXMLEle(sw, formatString);
310  }
311 
312  propertySaved = true;
313  break;
314  }
315  else if (!strcmp(tagName, "newNumberVector"))
316  {
317  auto nvp = getNumber(elemName);
318  if (nvp == nullptr)
319  {
320  delXMLEle(root);
321  return false;
322  }
323 
324  XMLEle *np = nullptr;
325  for (np = nextXMLEle(ep, 1); np != nullptr; np = nextXMLEle(ep, 0))
326  {
327  auto oneNumber = nvp->findWidgetByName(findXMLAttValu(np, "name"));
328  if (oneNumber == nullptr)
329  return false;
330 
331  char formatString[MAXRBUF];
332  snprintf(formatString, MAXRBUF, " %.20g\n", oneNumber->getValue());
333  editXMLEle(np, formatString);
334  }
335 
336  propertySaved = true;
337  break;
338  }
339  else if (!strcmp(tagName, "newTextVector"))
340  {
341  auto tvp = getText(elemName);
342  if (tvp == nullptr)
343  {
344  delXMLEle(root);
345  return false;
346  }
347 
348  XMLEle *tp = nullptr;
349  for (tp = nextXMLEle(ep, 1); tp != nullptr; tp = nextXMLEle(ep, 0))
350  {
351  auto oneText = tvp->findWidgetByName(findXMLAttValu(tp, "name"));
352  if (oneText == nullptr)
353  return false;
354 
355  char formatString[MAXRBUF];
356  snprintf(formatString, MAXRBUF, " %s\n", oneText->getText() ? oneText->getText() : "");
357  editXMLEle(tp, formatString);
358  }
359 
360  propertySaved = true;
361  break;
362  }
363  }
364 
365  if (propertySaved)
366  {
367  fp = IUGetConfigFP(nullptr, getDeviceName(), "w", errmsg);
368  prXMLEle(fp, root, 0);
369  fflush(fp);
370  fclose(fp);
371  delXMLEle(root);
372  LOGF_DEBUG("Configuration successfully saved for %s.", property);
373  return true;
374  }
375  else
376  {
377  delXMLEle(root);
378  // If property does not exist, save the whole thing
379  return saveConfig(silent);
380  }
381  }
382 
383  return true;
384 }
385 
387 {
388  char configDefaultFileName[MAXRBUF];
389  char errmsg[MAXRBUF];
390  bool pResult = false;
391 
392  if (getenv("INDICONFIG"))
393  snprintf(configDefaultFileName, MAXRBUF, "%s.default", getenv("INDICONFIG"));
394  else
395  snprintf(configDefaultFileName, MAXRBUF, "%s/.indi/%s_config.xml.default", getenv("HOME"), getDeviceName());
396 
397  LOGF_DEBUG("Requesting to load default config with: %s", configDefaultFileName);
398 
399  pResult = IUReadConfig(configDefaultFileName, getDeviceName(), nullptr, 0, errmsg) == 0 ? true : false;
400 
401  if (pResult)
402  LOG_INFO("Default configuration loaded.");
403  else
404  LOGF_INFO("Error loading default configuraiton. %s", errmsg);
405 
406  return pResult;
407 }
408 
409 bool DefaultDevice::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
410 {
411  D_PTR(DefaultDevice);
412  // ignore if not ours //
413  if (strcmp(dev, getDeviceName()))
414  return false;
415 
416  auto svp = getSwitch(name);
417 
418  if (svp == nullptr)
419  return false;
420 
422  // Connection
424  if (svp->isNameMatch(d->ConnectionSP.getName()))
425  {
426  bool rc = false;
427 
428  for (int i = 0; i < n; i++)
429  {
430  if (!strcmp(names[i], "CONNECT") && (states[i] == ISS_ON))
431  {
432  // If disconnected, try to connect.
433  if (isConnected() == false)
434  {
435  rc = Connect();
436 
437  if (rc)
438  {
439  // Connection is successful, set it to OK and updateProperties.
440  setConnected(true, IPS_OK);
442  }
443  else
444  setConnected(false, IPS_ALERT);
445  }
446  else
447  // Already connected, tell client we're connected already.
448  setConnected(true);
449  }
450  else if (!strcmp(names[i], "DISCONNECT") && (states[i] == ISS_ON))
451  {
452  // If connected, try to disconnect.
453  if (isConnected() == true)
454  {
455  rc = Disconnect();
456  // Disconnection is successful, set it IDLE and updateProperties.
457  if (rc)
458  {
459  setConnected(false, IPS_IDLE);
461  }
462  else
463  setConnected(true, IPS_ALERT);
464  }
465  // Already disconnected, tell client we're disconnected already.
466  else
467  setConnected(false, IPS_IDLE);
468  }
469  }
470 
471  return true;
472  }
473 
475  // Connection Mode
477  if (svp->isNameMatch(d->ConnectionModeSP.getName()))
478  {
479  d->ConnectionModeSP.update(states, names, n);
480 
481  int activeConnectionMode = d->ConnectionModeSP.findOnSwitchIndex();
482 
483  if (activeConnectionMode >= 0 && activeConnectionMode < static_cast<int>(d->connections.size()))
484  {
485  d->activeConnection = d->connections[activeConnectionMode];
486  d->activeConnection->Activated();
487 
488  for (Connection::Interface *oneConnection : d->connections)
489  {
490  if (oneConnection == d->activeConnection)
491  continue;
492 
493  oneConnection->Deactivated();
494  }
495 
496  d->ConnectionModeSP.setState(IPS_OK);
497  }
498  else
499  d->ConnectionModeSP.setState(IPS_ALERT);
500 
501  d->ConnectionModeSP.apply();
502 
503  return true;
504  }
505 
507  // Debug
509  if (svp->isNameMatch("DEBUG"))
510  {
511  IUUpdateSwitch(svp, states, names, n);
512 
513  auto sp = svp->findOnSwitch();
514  assert(sp != nullptr);
515 
516  setDebug(sp->isNameMatch("ENABLE") ? true : false);
517 
518  return true;
519  }
520 
522  // Simulation
524  if (svp->isNameMatch("SIMULATION"))
525  {
526  IUUpdateSwitch(svp, states, names, n);
527 
528  auto sp = svp->findOnSwitch();
529  assert(sp != nullptr);
530 
531  setSimulation(sp->isNameMatch("ENABLE") ? true : false);
532 
533  return true;
534  }
535 
537  // Configuration
539  if (svp->isNameMatch("CONFIG_PROCESS"))
540  {
541  IUUpdateSwitch(svp, states, names, n);
542 
543  auto sp = svp->findOnSwitch();
544  svp->reset();
545  bool pResult = false;
546 
547  // Not suppose to happen (all switches off) but let's handle it anyway
548  if (sp == nullptr)
549  {
550  svp->setState(IPS_IDLE);
551  svp->apply();
552  return true;
553  }
554 
555  if (sp->isNameMatch("CONFIG_LOAD"))
556  pResult = loadConfig();
557  else if (sp->isNameMatch("CONFIG_SAVE"))
558  pResult = saveConfig();
559  else if (sp->isNameMatch("CONFIG_DEFAULT"))
560  pResult = loadDefaultConfig();
561  else if (sp->isNameMatch("CONFIG_PURGE"))
562  pResult = purgeConfig();
563 
564  svp->setState(pResult ? IPS_OK : IPS_ALERT);
565  svp->apply();
566  return true;
567  }
568 
570  // Debugging and Logging Levels
572  if (svp->isNameMatch("DEBUG_LEVEL") || svp->isNameMatch("LOGGING_LEVEL") || svp->isNameMatch("LOG_OUTPUT"))
573  {
574  bool rc = Logger::ISNewSwitch(dev, name, states, names, n);
575 
576  if (svp->isNameMatch("LOG_OUTPUT"))
577  {
578  auto sw = svp->findWidgetByName("FILE_DEBUG");
579  if (sw != nullptr && sw->getState() == ISS_ON)
580  DEBUGF(Logger::DBG_SESSION, "Session log file %s", Logger::getLogFile().c_str());
581  }
582 
583  return rc;
584  }
585 
586  bool rc = false;
587  for (Connection::Interface *oneConnection : d->connections)
588  rc |= oneConnection->ISNewSwitch(dev, name, states, names, n);
589 
590  return rc;
591 }
592 
593 bool DefaultDevice::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
594 {
595  D_PTR(DefaultDevice);
597  // Polling Period
599  if (d->PollPeriodNP.isNameMatch(name))
600  {
601  d->PollPeriodNP.update(values, names, n);
602  d->PollPeriodNP.setState(IPS_OK);
603  d->pollingPeriod = static_cast<uint32_t>(d->PollPeriodNP[0].getValue());
604  d->PollPeriodNP.apply();
605  return true;
606  }
607 
608  for (Connection::Interface *oneConnection : d->connections)
609  oneConnection->ISNewNumber(dev, name, values, names, n);
610 
611  return false;
612 }
613 
614 bool DefaultDevice::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
615 {
616  D_PTR(DefaultDevice);
617  for (Connection::Interface *oneConnection : d->connections)
618  oneConnection->ISNewText(dev, name, texts, names, n);
619 
620  return false;
621 }
622 
623 bool DefaultDevice::ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[],
624  char *formats[], char *names[], int n)
625 {
626  D_PTR(DefaultDevice);
627  for (Connection::Interface *oneConnection : d->connections)
628  oneConnection->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
629 
630  return false;
631 }
632 
634 {
635  INDI_UNUSED(root);
636  return false;
637 }
638 
640 {
641  D_PTR(DefaultDevice);
642  registerProperty(d->DebugSP);
643  d->isDebug = false;
644 }
645 
647 {
648  D_PTR(DefaultDevice);
649  registerProperty(d->SimulationSP);
650  d->isSimulation = false;
651 }
652 
654 {
655  D_PTR(DefaultDevice);
656  registerProperty(d->ConfigProcessSP);
657 }
658 
660 {
661  D_PTR(DefaultDevice);
662  registerProperty(d->PollPeriodNP);
663 }
664 
666 {
667  addDebugControl();
671 }
672 
673 void DefaultDevice::setDebug(bool enable)
674 {
675  D_PTR(DefaultDevice);
676  if (d->isDebug == enable)
677  {
678  d->DebugSP.setState(IPS_OK);
679  d->DebugSP.apply();
680  return;
681  }
682 
683  d->DebugSP.reset();
684 
685  auto sp = d->DebugSP.findWidgetByName(enable ? "ENABLE" : "DISABLE");
686  if (sp)
687  {
688  sp->setState(ISS_ON);
689  LOGF_INFO("Debug is %s.", enable ? "enabled" : "disabled");
690  }
691 
692  d->isDebug = enable;
693 
694  // Inform logger
695  if (Logger::updateProperties(enable) == false)
696  DEBUG(Logger::DBG_WARNING, "setLogDebug: Logger error");
697 
698  debugTriggered(enable);
699  d->DebugSP.setState(IPS_OK);
700  d->DebugSP.apply();
701 }
702 
704 {
705  D_PTR(DefaultDevice);
706  if (d->isSimulation == enable)
707  {
708  d->SimulationSP.setState(IPS_OK);
709  d->SimulationSP.apply();
710  return;
711  }
712 
713  d->SimulationSP.reset();
714 
715  auto sp = d->SimulationSP.findWidgetByName(enable ? "ENABLE" : "DISABLE");
716  if (sp)
717  {
718  LOGF_INFO("Simulation is %s.", enable ? "enabled" : "disabled");
719  sp->setState(ISS_ON);
720  }
721 
722  d->isSimulation = enable;
723  simulationTriggered(enable);
724  d->SimulationSP.setState(IPS_OK);
725  d->SimulationSP.apply();
726 }
727 
729 {
730  D_PTR(const DefaultDevice);
731  return d->isDebug;
732 }
733 
735 {
736  D_PTR(const DefaultDevice);
737  return d->isSimulation;
738 }
739 
741 {
742  INDI_UNUSED(enable);
743 }
744 
746 {
747  INDI_UNUSED(enable);
748 }
749 
750 void DefaultDevice::ISGetProperties(const char *dev)
751 {
752  D_PTR(DefaultDevice);
753  if (d->isInit == false)
754  {
755  if (dev != nullptr)
756  setDeviceName(dev);
757  else if (*getDeviceName() == '\0')
758  {
759  char *envDev = getenv("INDIDEV");
760  if (envDev != nullptr)
761  setDeviceName(envDev);
762  else
764  }
765 
766  d->ConnectionSP.setDeviceName(getDeviceName());
767  initProperties();
769 
770  // If we have no connections, move Driver Info to General Info tab
771  if (d->connections.size() == 0)
772  d->DriverInfoTP.setGroupName(INFO_TAB);
773  }
774 
775  for (const auto &oneProperty : *getProperties())
776  {
777  if (d->defineDynamicProperties == false && oneProperty->isDynamic())
778  continue;
779 
780  oneProperty->define();
781  }
782 
783  // Remember debug & logging settings
784  if (d->isInit == false)
785  {
786  loadConfig(true, "DEBUG");
787  loadConfig(true, "DEBUG_LEVEL");
788  loadConfig(true, "LOGGING_LEVEL");
789  loadConfig(true, "POLLING_PERIOD");
790  loadConfig(true, "LOG_OUTPUT");
791  }
792 
793  if (d->ConnectionModeSP.isEmpty())
794  {
795  if (d->connections.size() > 0)
796  {
797  d->ConnectionModeSP.resize(d->connections.size());
798  auto sp = &d->ConnectionModeSP[0];
799  for (Connection::Interface *oneConnection : d->connections)
800  {
801  (sp++)->fill(oneConnection->name(), oneConnection->label(), ISS_OFF);
802  }
803  d->ConnectionModeSP.fill(getDeviceName(), "CONNECTION_MODE", "Connection Mode", CONNECTION_TAB, IP_RW, ISR_1OFMANY, 60,
804  IPS_IDLE);
805 
806  // Try to read config first
807  if (IUGetConfigOnSwitchIndex(getDeviceName(), d->ConnectionModeSP.getName(), &d->m_ConfigConnectionMode) == 0)
808  {
809  d->ConnectionModeSP[d->m_ConfigConnectionMode].setState(ISS_ON);
810  d->activeConnection = d->connections[d->m_ConfigConnectionMode];
811  }
812  // Check if we already have an active connection set.
813  else if (d->activeConnection != nullptr)
814  {
815  auto it = std::find(d->connections.begin(), d->connections.end(), d->activeConnection);
816  if (it != d->connections.end())
817  {
818  int index = std::distance(d->connections.begin(), it);
819  if (index >= 0)
820  d->ConnectionModeSP[index].setState(ISS_ON);
821  }
822  }
823  // Otherwise use connection 0
824  else
825  {
826  d->ConnectionModeSP[0].setState(ISS_ON);
827  d->activeConnection = d->connections[0];
828  }
829 
830  defineProperty(d->ConnectionModeSP);
831  d->activeConnection->Activated();
832  }
833  }
834 
835  d->isInit = true;
836 }
837 
839 {
840  for (auto &oneProperty : *getProperties())
841  {
842  oneProperty->setState(IPS_IDLE);
843  oneProperty->apply();
844  }
845 }
846 
847 void DefaultDevice::setConnected(bool status, IPState state, const char *msg)
848 {
849  auto svp = getSwitch(INDI::SP::CONNECTION);
850  if (!svp)
851  return;
852 
853  svp->at(INDI_ENABLED)->setState(status ? ISS_ON : ISS_OFF);
854  svp->at(INDI_DISABLED)->setState(status ? ISS_OFF : ISS_ON);
855  svp->setState(state);
856 
857  if (msg == nullptr)
858  svp->apply();
859  else
860  svp->apply("%s", msg);
861 }
862 
863 // Set the timeout for the TimerHit function.
864 // This is a single shot timer.
865 int DefaultDevice::SetTimer(uint32_t ms)
866 {
867  D_PTR(DefaultDevice);
868  d->m_MainLoopTimer.start(ms);
869  return 1;
870 }
871 
872 // Remove main timer. ID is not used.
873 // Kept for backward compatiblity
875 {
876  INDI_UNUSED(id);
877  D_PTR(DefaultDevice);
878  d->m_MainLoopTimer.stop();
879  return;
880 }
881 
882 // This is just a placeholder
883 // This function should be overriden by child classes if they use timers
884 // So we should never get here
886 {
887  return;
888 }
889 
891 {
892  // The base device has no properties to update
893  return true;
894 }
895 
897 {
898  D_PTR(DefaultDevice);
899  return d->interfaceDescriptor;
900 }
901 
903 {
904  D_PTR(DefaultDevice);
905  char interfaceStr[16];
906  d->interfaceDescriptor = value;
907  snprintf(interfaceStr, 16, "%d", d->interfaceDescriptor);
908  d->DriverInfoTP[3].setText(interfaceStr);
909 }
910 
912 {
913  D_PTR(DefaultDevice);
914  d->DriverInfoTP.apply();
915 }
916 
918 {
919  D_PTR(DefaultDevice);
920  char versionStr[16];
921  char interfaceStr[16];
922 
923  snprintf(versionStr, 16, "%d.%d", d->majorVersion, d->minorVersion);
924  snprintf(interfaceStr, 16, "%d", d->interfaceDescriptor);
925 
926  d->ConnectionSP[INDI_ENABLED ].fill("CONNECT", "Connect", ISS_OFF);
927  d->ConnectionSP[INDI_DISABLED].fill("DISCONNECT", "Disconnect", ISS_ON);
928  d->ConnectionSP.fill(getDeviceName(), INDI::SP::CONNECTION, "Connection", "Main Control", IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
929  registerProperty(d->ConnectionSP);
930 
931  d->DriverInfoTP[0].fill("DRIVER_NAME", "Name", getDriverName());
932  d->DriverInfoTP[1].fill("DRIVER_EXEC", "Exec", getDriverExec());
933  d->DriverInfoTP[2].fill("DRIVER_VERSION", "Version", versionStr);
934  d->DriverInfoTP[3].fill("DRIVER_INTERFACE", "Interface", interfaceStr);
935  d->DriverInfoTP.fill(getDeviceName(), "DRIVER_INFO", "Driver Info", CONNECTION_TAB, IP_RO, 60, IPS_IDLE);
936  registerProperty(d->DriverInfoTP);
937 
938  d->DebugSP[INDI_ENABLED ].fill("ENABLE", "Enable", ISS_OFF);
939  d->DebugSP[INDI_DISABLED].fill("DISABLE", "Disable", ISS_ON);
940  d->DebugSP.fill(getDeviceName(), "DEBUG", "Debug", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
941 
942  d->SimulationSP[INDI_ENABLED ].fill("ENABLE", "Enable", ISS_OFF);
943  d->SimulationSP[INDI_DISABLED].fill("DISABLE", "Disable", ISS_ON);
944  d->SimulationSP.fill(getDeviceName(), "SIMULATION", "Simulation", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
945 
946  d->ConfigProcessSP[0].fill("CONFIG_LOAD", "Load", ISS_OFF);
947  d->ConfigProcessSP[1].fill("CONFIG_SAVE", "Save", ISS_OFF);
948  d->ConfigProcessSP[2].fill("CONFIG_DEFAULT", "Default", ISS_OFF);
949  d->ConfigProcessSP[3].fill("CONFIG_PURGE", "Purge", ISS_OFF);
950  d->ConfigProcessSP.fill(getDeviceName(), "CONFIG_PROCESS", "Configuration", "Options", IP_RW, ISR_ATMOST1, 0, IPS_IDLE);
951 
952  d->PollPeriodNP[0].fill("PERIOD_MS", "Period (ms)", "%.f", 10, 600000, 1000, d->pollingPeriod);
953  d->PollPeriodNP.fill(getDeviceName(), "POLLING_PERIOD", "Polling", "Options", IP_RW, 0, IPS_IDLE);
954 
956 
957  // Ready the logger
958  std::string logFile = getDriverExec();
959 
961 
962  return true;
963 }
964 
965 bool DefaultDevice::deleteProperty(const char *propertyName)
966 {
967  D_PTR(DefaultDevice);
968  char errmsg[MAXRBUF];
969 
970  if (propertyName == nullptr)
971  {
972  //while(!pAll.empty()) delete bar.back(), bar.pop_back();
973  IDDelete(getDeviceName(), nullptr, nullptr);
974  return true;
975  }
976 
977  // Keep dynamic properties in existing property list so they can be reused
978  if (d->deleteDynamicProperties == false)
979  {
980  INDI::Property *prop = getProperty(propertyName);
981  if (prop && prop->isDynamic())
982  {
983  IDDelete(getDeviceName(), propertyName, nullptr);
984  return true;
985  }
986  }
987 
988  if (removeProperty(propertyName, errmsg) == 0)
989  {
990  IDDelete(getDeviceName(), propertyName, nullptr);
991  return true;
992  }
993  else
994  return false;
995 }
996 
998 {
999  registerProperty(property);
1000  static_cast<PropertyView<INumber>*>(property)->define();
1001 }
1002 
1004 {
1005  registerProperty(property);
1006  static_cast<PropertyView<IText>*>(property)->define();
1007 }
1008 
1010 {
1011  registerProperty(property);
1012  static_cast<PropertyView<ISwitch>*>(property)->define();
1013 }
1014 
1016 {
1017  registerProperty(property);
1018  static_cast<PropertyView<ILight>*>(property)->define();
1019 }
1020 
1022 {
1023  registerProperty(property);
1024  static_cast<PropertyView<IBLOB>*>(property)->define();
1025 }
1026 
1028 {
1029  registerProperty(property);
1030  property.define();
1031 }
1032 
1034 {
1035  defineProperty(nvp);
1036 }
1037 
1039 {
1040  defineProperty(tvp);
1041 }
1042 
1044 {
1045  defineProperty(svp);
1046 }
1047 
1049 {
1050  defineProperty(lvp);
1051 }
1052 
1054 {
1055  defineProperty(bvp);
1056 }
1057 
1059 {
1060  D_PTR(DefaultDevice);
1061  if (isConnected())
1062  return true;
1063 
1064  if (d->activeConnection == nullptr)
1065  {
1066  LOG_ERROR("No active connection defined.");
1067  return false;
1068  }
1069 
1070  bool rc = d->activeConnection->Connect();
1071 
1072  if (rc)
1073  {
1074  if (d->ConnectionModeSP.findOnSwitchIndex() != d->m_ConfigConnectionMode)
1075  saveConfig(true, d->ConnectionModeSP.getName());
1076  if (d->pollingPeriod > 0)
1077  SetTimer(d->pollingPeriod);
1078  }
1079 
1080  return rc;
1081 }
1082 
1084 {
1085  D_PTR(DefaultDevice);
1086  if (isSimulation())
1087  {
1088  DEBUGF(Logger::DBG_SESSION, "%s is offline.", getDeviceName());
1089  return true;
1090  }
1091 
1092  if (d->activeConnection)
1093  {
1094  bool rc = d->activeConnection->Disconnect();
1095  if (rc)
1096  {
1097  DEBUGF(Logger::DBG_SESSION, "%s is offline.", getDeviceName());
1098  return true;
1099  }
1100  else
1101  return false;
1102  }
1103 
1104  return false;
1105 }
1106 
1108 {
1109  D_PTR(DefaultDevice);
1110  d->connections.push_back(newConnection);
1111 }
1112 
1114 {
1115  D_PTR(DefaultDevice);
1116 
1117  auto i = std::begin(d->connections);
1118 
1119  while (i != std::end(d->connections))
1120  {
1121  if (*i == existingConnection)
1122  {
1123  i = d->connections.erase(i);
1124  return true;
1125  }
1126  else
1127  ++i;
1128  }
1129 
1130  return false;
1131 }
1132 
1134 {
1135  D_PTR(DefaultDevice);
1136  d->pollingPeriod = msec;
1137 }
1138 
1140 {
1141  D_PTR(const DefaultDevice);
1142  return d->pollingPeriod;
1143 }
1144 
1146 {
1147  D_PTR(DefaultDevice);
1148  return d->pollingPeriod;
1149 }
1150 
1152 {
1153  D_PTR(const DefaultDevice);
1154  return d->pollingPeriod;
1155 }
1156 
1158 {
1159  D_PTR(DefaultDevice);
1160  d->PollPeriodNP[0].setValue(msec);
1161  d->pollingPeriod = msec;
1162 }
1163 
1164 void DefaultDevice::setPollingPeriodRange(uint32_t minimum, uint32_t maximum)
1165 {
1166  D_PTR(DefaultDevice);
1167 
1168  d->PollPeriodNP[0].setMinMax(minimum, maximum);
1169  d->PollPeriodNP.updateMinMax();
1170 }
1171 
1173 {
1174  D_PTR(DefaultDevice);
1175 
1176  if (existingConnection == d->activeConnection)
1177  return;
1178 
1179  for (Connection::Interface *oneConnection : d->connections)
1180  {
1181  if (oneConnection == d->activeConnection)
1182  {
1183  oneConnection->Deactivated();
1184  break;
1185  }
1186  }
1187 
1188  d->activeConnection = existingConnection;
1189  if (!d->ConnectionModeSP.isEmpty())
1190  {
1191  auto it = std::find(d->connections.begin(), d->connections.end(), d->activeConnection);
1192  if (it != d->connections.end())
1193  {
1194  int index = std::distance(d->connections.begin(), it);
1195  if (index >= 0)
1196  {
1197  d->ConnectionModeSP.reset();
1198  d->ConnectionModeSP[index].setState(ISS_ON);
1199  d->ConnectionModeSP.setState(IPS_OK);
1200  // If property is registerned then send back response to client
1201  INDI::Property *connectionProperty = getProperty(d->ConnectionModeSP.getName(), INDI_SWITCH);
1202  if (connectionProperty && connectionProperty->getRegistered())
1203  d->ConnectionModeSP.apply();
1204  }
1205  }
1206  }
1207 }
1208 
1210 {
1211  return me;
1212 }
1213 
1215 {
1216  return getDefaultName();
1217 }
1218 
1219 void DefaultDevice::setVersion(uint16_t vMajor, uint16_t vMinor)
1220 {
1221  D_PTR(DefaultDevice);
1222  d->majorVersion = vMajor;
1223  d->minorVersion = vMinor;
1224 }
1225 
1227 {
1228  D_PTR(const DefaultDevice);
1229  return d->majorVersion;
1230 }
1231 
1233 {
1234  D_PTR(const DefaultDevice);
1235  return d->minorVersion;
1236 }
1237 
1238 void DefaultDevice::setDynamicPropertiesBehavior(bool defineEnabled, bool deleteEnabled)
1239 {
1240  D_PTR(DefaultDevice);
1241  d->defineDynamicProperties = defineEnabled;
1242  d->deleteDynamicProperties = deleteEnabled;
1243 }
1244 
1246 {
1247  D_PTR(DefaultDevice);
1248  return d->activeConnection;
1249 }
1250 
1252 {
1253  D_PTR(const DefaultDevice);
1254  return static_cast<uint32_t>(d->PollPeriodNP[0].getValue());
1255 }
1256 
1258 {
1259  D_PTR(const DefaultDevice);
1260  return d->isConfigLoading;
1261 }
1262 
1263 }
INDI::BaseDevice::getProperties
Properties getProperties()
Return a list of all properties in the device.
Definition: basedevice.cpp:168
IP_RO
@ IP_RO
Definition: indiapi.h:183
INDI::DefaultDevice::simulationTriggered
virtual void simulationTriggered(bool enable)
Inform driver that the simulation option was triggered. This function is called after setSimulation i...
Definition: defaultdevice.cpp:745
Connection::Interface::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Definition: connectioninterface.cpp:68
INDI::BaseDevice::getText
INDI::PropertyView< IText > * getText(const char *name) const
Definition: basedevice.cpp:104
INDI::DefaultDevice::resetProperties
void resetProperties()
Set all properties to IDLE state.
Definition: defaultdevice.cpp:838
indistandardproperty.h
newLilXML
LilXML * newLilXML()
Create a new lilxml parser.
Definition: lilxml.c:148
Connection::Interface::ISNewText
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Definition: connectioninterface.cpp:78
INDI::Property::getRegistered
bool getRegistered() const
Definition: indiproperty.cpp:223
INDI::DefaultDevice::addAuxControls
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
Definition: defaultdevice.cpp:665
ISNewSwitch
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Update the value of an existing switch vector property.
Definition: defaultdevice.cpp:60
INDI::DefaultDevice::loadDefaultConfig
virtual bool loadDefaultConfig()
Load the default configuration file.
Definition: defaultdevice.cpp:386
IPState
IPState
Property state.
Definition: indiapi.h:158
Connection::Interface::label
virtual std::string label()=0
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
INDI::DefaultDevice::setConnected
virtual void setConnected(bool status, IPState state=IPS_OK, const char *msg=nullptr)
Set connection switch status in the client.
Definition: defaultdevice.cpp:847
_ILightVectorProperty
Light vector property descriptor.
Definition: indiapi.h:415
COMMUNICATION_TAB
const char * COMMUNICATION_TAB
COMMUNICATION_TAB Where all the properties required to connect/disconnect from a device are located....
Definition: defaultdevice.cpp:33
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
indicom.h
Implementations for common driver routines.
MOTION_TAB
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
Definition: defaultdevice.cpp:36
Connection::Interface::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Definition: connectioninterface.cpp:58
INDI::Logger::DBG_WARNING
@ DBG_WARNING
Definition: indilogger.h:193
INDI::DefaultDevice::DefaultDevice
DefaultDevice()
Definition: defaultdevice.cpp:134
indiapi.h
Constants and Data structure definitions for the interface to the reference INDI C API implementation...
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
nextXMLEle
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
Definition: lilxml.c:524
INDI::DefaultDevice::isSimulation
bool isSimulation() const
Definition: defaultdevice.cpp:734
INDI::DefaultDevice::defineProperty
void defineProperty(INumberVectorProperty *property)
Definition: defaultdevice.cpp:997
OPTIONS_TAB
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
Definition: defaultdevice.cpp:39
MAIN_CONTROL_TAB
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
Definition: defaultdevice.cpp:34
_IBLOBVectorProperty
BLOB (Binary Large Object) vector property descriptor.
Definition: indiapi.h:469
INDI::BaseDevice::getNumber
INDI::PropertyView< INumber > * getNumber(const char *name) const
Definition: basedevice.cpp:99
INDI::DefaultDevicePrivate::devicesLock
static std::recursive_mutex devicesLock
Definition: defaultdevice_p.h:110
INDI::DefaultDevice::setDefaultPollingPeriod
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
Definition: defaultdevice.cpp:1157
INDI_UNUSED
#define INDI_UNUSED(x)
Definition: indidevapi.h:799
SATELLITE_TAB
const char * SATELLITE_TAB
SATELLITE_TAB.
Definition: defaultdevice.cpp:44
GUIDE_TAB
const char * GUIDE_TAB
GUIDE_TAB Where all the properties for guiding are located.
Definition: defaultdevice.cpp:42
FILTER_TAB
const char * FILTER_TAB
FILTER_TAB Where all the properties for filter wheels are located.
Definition: defaultdevice.cpp:40
INDI::DefaultDevice::setVersion
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
Definition: defaultdevice.cpp:1219
SITE_TAB
const char * SITE_TAB
SITE_TAB Where all site information setting are located.
Definition: defaultdevice.cpp:38
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
INDI::DefaultDevice::purgeConfig
virtual bool purgeConfig()
purgeConfig Remove config file from disk.
Definition: defaultdevice.cpp:208
FOCUS_TAB
const char * FOCUS_TAB
FOCUS_TAB Where all the properties for focuser are located.
Definition: defaultdevice.cpp:41
INDI::Logger::DBG_SESSION
@ DBG_SESSION
Definition: indilogger.h:194
INDI::DefaultDevice::getDefaultName
virtual const char * getDefaultName()=0
INFO_TAB
const char * INFO_TAB
INFO_TAB Where all the properties for general information are located.
Definition: defaultdevice.cpp:45
IUSaveDefaultConfig
int IUSaveDefaultConfig(const char *source_config, const char *dest_config, const char *dev)
Copies an existing configuration file into a default configuration file.
Definition: indidriver.c:1101
INDI::Logger::updateProperties
static bool updateProperties(bool enable)
Definition: indilogger.cpp:128
INDI::DefaultDevice::addPollPeriodControl
void addPollPeriodControl()
Add Polling period control to the driver.
Definition: defaultdevice.cpp:659
INDI::DefaultDevice::setPollingPeriodRange
void setPollingPeriodRange(uint32_t minimum, uint32_t maximum)
setPollingPeriodRange Set the range permitted by the polling range in milliseconds
Definition: defaultdevice.cpp:1164
INDI::DefaultDevice::getDriverExec
virtual const char * getDriverExec()
Definition: defaultdevice.cpp:1209
DEBUG_CONF
#define DEBUG_CONF(outputFile, configuration, fileVerbosityLevel, screenVerbosityLevel)
Macro to configure the logger. Example of configuration of the Logger: DEBUG_CONF("outputfile",...
Definition: indilogger.h:38
INDI::BaseDevice::getSwitch
INDI::PropertyView< ISwitch > * getSwitch(const char *name) const
Definition: basedevice.cpp:109
INDI::DefaultDevice::defineLight
void defineLight(ILightVectorProperty *lvp) __attribute__((deprecated))
Define light vector to client & register it. Alternatively, IDDeflight can be used but the property w...
Definition: defaultdevice.cpp:1048
INDI::DefaultDevice::unRegisterConnection
bool unRegisterConnection(Connection::Interface *existingConnection)
unRegisterConnection Remove connection from existing pool
Definition: defaultdevice.cpp:1113
LOG_INFO
#define LOG_INFO(txt)
Definition: indilogger.h:74
MAXRBUF
#define MAXRBUF
Definition: indidriver.c:52
INDI::DefaultDevice::TimerHit
virtual void TimerHit()
Callback function to be called once SetTimer duration elapses.
Definition: defaultdevice.cpp:885
DEBUG
#define DEBUG(priority, msg)
Macro to print log messages. Example of usage of the Logger: DEBUG(DBG_DEBUG, "hello " << "world");.
Definition: indilogger.h:56
INDI::DefaultDevice::initProperties
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
Definition: defaultdevice.cpp:917
INDI::DefaultDevice::isConfigLoading
bool isConfigLoading() const
isConfigLoading Check if driver configuration is currently in the process of getting loaded.
Definition: defaultdevice.cpp:1257
INDI::DefaultDevicePrivate::devices
static std::list< DefaultDevicePrivate * > devices
Definition: defaultdevice_p.h:109
INDI::Property
Provides generic container for INDI properties.
Definition: indiproperty.h:43
ISSnoopDevice
void ISSnoopDevice(XMLEle *root)
Function defined by Drivers that is called when another Driver it is snooping (by having previously c...
Definition: defaultdevice.cpp:94
_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
INDI::DefaultDevice::getCurrentPollingPeriod
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
Definition: defaultdevice.cpp:1139
INDI::DefaultDevice::addConfigurationControl
void addConfigurationControl()
Add Configuration control to the driver.
Definition: defaultdevice.cpp:653
INDI::DefaultDevice::defineSwitch
void defineSwitch(ISwitchVectorProperty *svp) __attribute__((deprecated))
Define switch vector to client & register it. Alternatively, IDDefswitch can be used but the property...
Definition: defaultdevice.cpp:1043
INDI::Logger::file_off
static const loggerConf file_off
Definition: indilogger.h:219
LOGF_DEBUG
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
INDI::DefaultDevice::ISSnoopDevice
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
Definition: defaultdevice.cpp:633
Connection::Interface::ISNewBLOB
virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Definition: connectioninterface.cpp:88
INDI::Logger::initProperties
static bool initProperties(INDI::DefaultDevice *device)
Definition: indilogger.cpp:100
begin
JsonIterator begin(JsonValue o)
Definition: gason.h:104
_INumberVectorProperty
Number vector property descriptor.
Definition: indiapi.h:317
INDI::DefaultDevice::SetTimer
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
Definition: defaultdevice.cpp:865
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::DefaultDevice::debugTriggered
virtual void debugTriggered(bool enable)
Inform driver that the debug option was triggered. This function is called after setDebug is triggere...
Definition: defaultdevice.cpp:740
timerfunc
void timerfunc(void *t)
Definition: defaultdevice.cpp:103
IUReadConfig
int IUReadConfig(const char *filename, const char *dev, const char *property, int silent, char errmsg[])
Loads and processes a configuration file.
Definition: indidriver.c:1044
INDI::Logger::saveConfigItems
static bool saveConfigItems(FILE *fp)
Definition: indilogger.cpp:151
ISNewText
void ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Update the value of an existing text vector property.
Definition: defaultdevice.cpp:76
INDI::DefaultDevice::Connect
virtual bool Connect()
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
Definition: defaultdevice.cpp:1058
INDI::DefaultDevice::getMajorVersion
uint16_t getMajorVersion() const
Definition: defaultdevice.cpp:1226
INDI::DefaultDevice::getDriverInterface
virtual uint16_t getDriverInterface() override
Definition: defaultdevice.cpp:896
LOGF_WARN
#define LOGF_WARN(fmt,...)
Definition: indilogger.h:81
INDI::DefaultDevice::getPollingPeriod
uint32_t getPollingPeriod() const
getPollingPeriod Return the polling period.
Definition: defaultdevice.cpp:1251
INDI::DefaultDevice::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
Definition: defaultdevice.cpp:593
INDI::DefaultDevice::syncDriverInfo
void syncDriverInfo()
syncDriverInfo sends the current driver information to the client.
Definition: defaultdevice.cpp:911
editXMLEle
void editXMLEle(XMLEle *ep, const char *pcdata)
set the pcdata of the given element
Definition: lilxml.c:656
ISR_1OFMANY
@ ISR_1OFMANY
Definition: indiapi.h:172
connectionserial.h
IPS_IDLE
@ IPS_IDLE
Definition: indiapi.h:160
INDI::DefaultDevicePrivate
Definition: defaultdevice_p.h:51
INDI::DefaultDevice::defineNumber
void defineNumber(INumberVectorProperty *nvp) __attribute__((deprecated))
Define number vector to client & register it. Alternatively, IDDefNumber can be used but the property...
Definition: defaultdevice.cpp:1033
INDI::DefaultDevicePrivate::~DefaultDevicePrivate
virtual ~DefaultDevicePrivate()
Definition: defaultdevice.cpp:128
Connection::Interface::name
virtual std::string name()=0
INDI::DefaultDevice::registerConnection
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
Definition: defaultdevice.cpp:1107
readXMLFile
XMLEle * readXMLFile(FILE *fp, LilXML *lp, char ynot[])
Handy wrapper to read one xml file.
Definition: lilxml.c:622
tagXMLEle
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
Definition: lilxml.c:569
xml_ele_
Definition: lilxml.c:105
CONNECTION_TAB
const char * CONNECTION_TAB
CONNECTION_TAB Where all device connection settings (serial, usb, ethernet) are defined and controlle...
Definition: defaultdevice.cpp:35
ISR_ATMOST1
@ ISR_ATMOST1
Definition: indiapi.h:173
INDI::DefaultDevice::getDriverName
virtual const char * getDriverName()
Definition: defaultdevice.cpp:1214
INDI::Logger::getLogFile
static std::string getLogFile()
Definition: indilogger.h:225
INDI::DefaultDevice::loadConfig
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
Definition: defaultdevice.cpp:147
defaultdevice.h
IUUpdateSwitch
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:171
INDI::DefaultDevice::isDebug
bool isDebug() const
Definition: defaultdevice.cpp:728
end
JsonIterator end(JsonValue)
Definition: gason.h:108
INDI::BaseDevice::isConnected
bool isConnected() const
Definition: basedevice.cpp:518
INDI::DefaultDevice::setSimulation
void setSimulation(bool enable)
Toggle driver simulation status A driver can run in simulation mode if Simulation option is enabled b...
Definition: defaultdevice.cpp:703
INDI::DefaultDevice::setDebug
void setDebug(bool enable)
Toggle driver debug status A driver can be more verbose if Debug option is enabled by the client.
Definition: defaultdevice.cpp:673
LOG_DEBUG
#define LOG_DEBUG(txt)
Definition: indilogger.h:75
INDI::PropertyView< INumber >
INDI::DefaultDevice::setActiveConnection
void setActiveConnection(Connection::Interface *existingConnection)
setActiveConnection Switch the active connection to the passed connection plugin
Definition: defaultdevice.cpp:1172
LOGF_INFO
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
Connection::Interface::Deactivated
virtual void Deactivated()=0
Deactivated Function called by the framework when the plugin is deactivated. It is usually used to de...
ISGetProperties
void ISGetProperties(const char *dev)
Get Device Properties.
Definition: defaultdevice.cpp:53
LOG_ERROR
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition: indilogger.h:72
INDI::Property::isDynamic
bool isDynamic() const
Definition: indiproperty.cpp:229
ALIGNMENT_TAB
const char * ALIGNMENT_TAB
ALIGNMENT_TAB Where all the properties for guiding are located.
Definition: defaultdevice.cpp:43
INDI::BaseDevice::removeProperty
int removeProperty(const char *name, char *errmsg)
Remove a property.
Definition: basedevice.cpp:180
INDI::BaseDevice::INDI_ENABLED
@ INDI_ENABLED
Definition: basedevice.h:64
defaultdevice_p.h
ISNewNumber
void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Definition: defaultdevice.cpp:68
IDDelete
void void void IDDelete(const char *dev, const char *name, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(3
Function Drivers call to inform Clients a Property is no longer available, or the entire device is go...
INDI::DefaultDevice::ISGetProperties
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Definition: defaultdevice.cpp:750
INDI::Logger::defaultlevel
static const unsigned int defaultlevel
Definition: indilogger.h:210
INDI_SWITCH
@ INDI_SWITCH
Definition: indidriver.c:58
INDI::DefaultDevicePrivate::DefaultDevicePrivate
DefaultDevicePrivate(DefaultDevice *defaultDevice)
Definition: defaultdevice.cpp:121
INDI::DefaultDevice::saveConfig
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
Definition: defaultdevice.cpp:221
INDI
Namespace to encapsulate INDI client, drivers, and mediator classes.
Definition: AlignmentSubsystemForClients.cpp:11
INDI::DefaultDevice::getMinorVersion
uint16_t getMinorVersion() const
Definition: defaultdevice.cpp:1232
INDI::DefaultDevice::ISNewBLOB
virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Process the client newBLOB command.
Definition: defaultdevice.cpp:623
prXMLEle
void prXMLEle(FILE *fp, XMLEle *ep, int level)
Print an XML element.
Definition: lilxml.c:699
DEBUGF
#define DEBUGF(priority, msg,...)
Definition: indilogger.h:57
INDI::DefaultDevice::saveConfigItems
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
Definition: defaultdevice.cpp:175
findXMLAttValu
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
Definition: lilxml.c:613
IP_RW
@ IP_RW
Definition: indiapi.h:185
INDI::DefaultDevice::defineBLOB
void defineBLOB(IBLOBVectorProperty *bvp) __attribute__((deprecated))
Define BLOB vector to client & register it. Alternatively, IDDefBLOB can be used but the property wil...
Definition: defaultdevice.cpp:1053
INDI::DefaultDevice::setCurrentPollingPeriod
void setCurrentPollingPeriod(uint32_t msec)
setCurrentPollingPeriod Change the current polling period to call TimerHit() function in the driver.
Definition: defaultdevice.cpp:1133
INDI::DefaultDevice::saveAllConfigItems
virtual bool saveAllConfigItems(FILE *fp)
saveAllConfigItems Save all the drivers' properties in the configuration file
Definition: defaultdevice.cpp:189
LilXML_
Definition: lilxml.c:91
INDI::DefaultDevice::RemoveTimer
void RemoveTimer(int id)
Remove timer added with SetTimer.
Definition: defaultdevice.cpp:874
IUGetConfigFP
FILE * IUGetConfigFP(const char *filename, const char *dev, const char *mode, char errmsg[])
Open a configuration file for writing and return a configuration file FILE pointer.
Definition: indidriver.c:1555
INDI::BaseDevice::INDI_DISABLED
@ INDI_DISABLED
Definition: basedevice.h:65
ISState
ISState
Switch state.
Definition: indiapi.h:148
Connection::Interface
The Interface class is the base class for all INDI connection plugins.
Definition: connectioninterface.h:51
INDI::DefaultDevice::defineText
void defineText(ITextVectorProperty *tvp) __attribute__((deprecated))
Define text vector to client & register it. Alternatively, IDDefText can be used but the property wil...
Definition: defaultdevice.cpp:1038
INDI::DefaultDevice::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
Definition: defaultdevice.cpp:409
IUGetConfigOnSwitchIndex
int IUGetConfigOnSwitchIndex(const char *dev, const char *property, int *index)
IUGetConfigOnSwitchIndex Opens configuration file and reads single switch property to find ON switch ...
Definition: indidriver.c:1270
INDI::DefaultDevice::addSimulationControl
void addSimulationControl()
Add Simulation control to the driver.
Definition: defaultdevice.cpp:646
me
char * me
Definition: indidriver.c:50
INDI::SP::CONNECTION
const char * CONNECTION
Connect to and disconnect from device.
Definition: indistandardproperty.cpp:63
IUSaveConfigTag
void IUSaveConfigTag(FILE *fp, int ctag, const char *dev, int silent)
Add opening or closing tag to a configuration file.
Definition: indidriver.c:1604
INDI::BaseDevice::registerProperty
void registerProperty(void *p, INDI_PROPERTY_TYPE type)
Definition: basedevice.cpp:883
INDI::DefaultDevice::refCurrentPollingPeriod
uint32_t & refCurrentPollingPeriod() __attribute__((deprecated))
Definition: defaultdevice.cpp:1145
INDI::DefaultDevice::addDebugControl
void addDebugControl()
Add Debug control to the driver.
Definition: defaultdevice.cpp:639
INDI::DefaultDevice::Disconnect
virtual bool Disconnect()
Disconnect from device.
Definition: defaultdevice.cpp:1083
INDI::DefaultDevice
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
Definition: defaultdevice.h:118
IUPurgeConfig
int IUPurgeConfig(const char *filename, const char *dev, char errmsg[])
Definition: indidriver.c:1529
INDI::DefaultDevice::deleteProperty
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
Definition: defaultdevice.cpp:965
ISNewBLOB
void ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Update data of an existing blob vector property.
Definition: defaultdevice.cpp:84
DATETIME_TAB
const char * DATETIME_TAB
DATETIME_TAB Where all date and time setting properties are located.
Definition: defaultdevice.cpp:37
delXMLEle
void delXMLEle(XMLEle *ep)
delXMLEle Delete XML element.
Definition: lilxml.c:165
INDI::Logger::ISNewSwitch
static bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Definition: indilogger.cpp:160
INDI::Logger::screen_on
static const loggerConf screen_on
Definition: indilogger.h:220
INDI::DefaultDevice::ISNewText
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
Definition: defaultdevice.cpp:614
INDI::BaseDevice
Class to provide basic INDI device functionality.
Definition: basedevice.h:45
INDI::DefaultDevice::setDriverInterface
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
Definition: defaultdevice.cpp:902
INDI::DefaultDevice::updateProperties
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: defaultdevice.cpp:890
_ISwitchVectorProperty
Switch vector property descriptor.
Definition: indiapi.h:365
INDI::DefaultDevice::getActiveConnection
Connection::Interface * getActiveConnection()
Definition: defaultdevice.cpp:1245
INDI::DefaultDevice::setDynamicPropertiesBehavior
void setDynamicPropertiesBehavior(bool defineEnabled, bool deleteEnabled)
setDynamicPropertiesBehavior controls handling of dynamic properties. Dyanmic properties are those ge...
Definition: defaultdevice.cpp:1238
ISS_ON
@ ISS_ON
Definition: indiapi.h:151