Instrument Neutral Distributed Interface INDI  2.0.2
MathPluginManagement.cpp
Go to the documentation of this file.
1 
9 #include "MathPluginManagement.h"
10 
11 #include <dirent.h>
12 #include <dlfcn.h>
13 #include <cerrno>
14 
15 namespace INDI
16 {
17 namespace AlignmentSubsystem
18 {
19 MathPluginManagement::MathPluginManagement() : CurrentInMemoryDatabase(nullptr),
20  pGetApproximateMountAlignment(&MathPlugin::GetApproximateMountAlignment),
21  pInitialise(&MathPlugin::Initialise),
22  pSetApproximateMountAlignment(&MathPlugin::SetApproximateMountAlignment),
23  pTransformCelestialToTelescope(&MathPlugin::TransformCelestialToTelescope),
24  pTransformTelescopeToCelestial(&MathPlugin::TransformTelescopeToCelestial),
25  pLoadedMathPlugin(&BuiltInPlugin), LoadedMathPluginHandle(nullptr)
26 {
27  memset(&AlignmentSubsystemCurrentMathPlugin, 0, sizeof(IText));
28 }
29 
31 {
32  EnumeratePlugins();
33  AlignmentSubsystemMathPlugins.reset(new ISwitch[MathPluginDisplayNames.size() + 1]);
34  IUFillSwitch(AlignmentSubsystemMathPlugins.get(), "INBUILT_MATH_PLUGIN", "Inbuilt Math Plugin", ISS_ON);
35 
36  for (int i = 0; i < (int)MathPluginDisplayNames.size(); i++)
37  {
38  IUFillSwitch(AlignmentSubsystemMathPlugins.get() + i + 1, MathPluginDisplayNames[i].c_str(),
39  MathPluginDisplayNames[i].c_str(), ISS_OFF);
40  }
41 
42  IUFillSwitchVector(&AlignmentSubsystemMathPluginsV, AlignmentSubsystemMathPlugins.get(),
43  MathPluginDisplayNames.size() + 1, ChildTelescope->getDeviceName(),
44  "ALIGNMENT_SUBSYSTEM_MATH_PLUGINS", "Math Plugins", ALIGNMENT_TAB, IP_RW, ISR_1OFMANY, 60,
45  IPS_IDLE);
46 
47  int configPlugin = -1;
48  IUGetConfigOnSwitchIndex(ChildTelescope->getDeviceName(), "ALIGNMENT_SUBSYSTEM_MATH_PLUGINS", &configPlugin);
49  if (configPlugin > 0 && configPlugin < AlignmentSubsystemMathPluginsV.nsp)
50  {
51  IUResetSwitch(&AlignmentSubsystemMathPluginsV);
52  AlignmentSubsystemMathPluginsV.sp[configPlugin].s = ISS_ON;
53  HandlePluginLoading(ChildTelescope, 0, configPlugin);
54  }
55  // Select nearest if available
56  else
57  {
58  ISwitch *sp = IUFindSwitch(&AlignmentSubsystemMathPluginsV, "Nearest Math Plugin");
59  if (sp)
60  {
61  IUResetSwitch(&AlignmentSubsystemMathPluginsV);
62  for (int i = 0; i < AlignmentSubsystemMathPluginsV.nsp; i++)
63  {
64  if (!strcmp(AlignmentSubsystemMathPluginsV.sp[i].name, sp->name))
65  {
66  sp->s = ISS_ON;
67  HandlePluginLoading(ChildTelescope, 0, i);
68  break;
69  }
70  }
71  }
72  }
73  ChildTelescope->registerProperty(&AlignmentSubsystemMathPluginsV);
74 
75  IUFillSwitch(&AlignmentSubsystemMathPluginInitialise, "ALIGNMENT_SUBSYSTEM_MATH_PLUGIN_INITIALISE", "OK", ISS_OFF);
76  IUFillSwitchVector(&AlignmentSubsystemMathPluginInitialiseV, &AlignmentSubsystemMathPluginInitialise, 1,
77  ChildTelescope->getDeviceName(), "ALIGNMENT_SUBSYSTEM_MATH_PLUGIN_INITIALISE",
78  "(Re)Initialise Plugin", ALIGNMENT_TAB, IP_RW, ISR_ATMOST1, 60, IPS_IDLE);
79  ChildTelescope->registerProperty(&AlignmentSubsystemMathPluginInitialiseV);
80 
81  IUFillSwitch(&AlignmentSubsystemActive, "ALIGNMENT SUBSYSTEM ACTIVE", "Alignment Subsystem Active", ISS_OFF);
82  IUFillSwitchVector(&AlignmentSubsystemActiveV, &AlignmentSubsystemActive, 1, ChildTelescope->getDeviceName(),
83  "ALIGNMENT_SUBSYSTEM_ACTIVE", "Activate alignment subsystem", ALIGNMENT_TAB, IP_RW, ISR_ATMOST1,
84  60, IPS_IDLE);
85  ChildTelescope->registerProperty(&AlignmentSubsystemActiveV);
86 
87  // The following property is used for configuration purposes only and is not exposed to the client.
88  IUFillText(&AlignmentSubsystemCurrentMathPlugin, "ALIGNMENT_SUBSYSTEM_CURRENT_MATH_PLUGIN", "Current Math Plugin",
89  AlignmentSubsystemMathPlugins.get()[0].label);
90  IUFillTextVector(&AlignmentSubsystemCurrentMathPluginV, &AlignmentSubsystemCurrentMathPlugin, 1,
91  ChildTelescope->getDeviceName(), "ALIGNMENT_SUBSYSTEM_CURRENT_MATH_PLUGIN", "Current Math Plugin",
93 }
94 
95 void MathPluginManagement::ProcessTextProperties(Telescope *pTelescope, const char *name, char *texts[], char *names[],
96  int n)
97 {
98  //DEBUGFDEVICE(pTelescope->getDeviceName(), INDI::Logger::DBG_DEBUG, "ProcessTextProperties - name(%s)", name);
99  if (strcmp(name, AlignmentSubsystemCurrentMathPluginV.name) == 0)
100  {
101  AlignmentSubsystemCurrentMathPluginV.s = IPS_OK;
102  IUUpdateText(&AlignmentSubsystemCurrentMathPluginV, texts, names, n);
103 
104  if (0 != strcmp(AlignmentSubsystemMathPlugins.get()[0].label, AlignmentSubsystemCurrentMathPlugin.text))
105  {
106  // Unload old plugin if required
107  if (nullptr != LoadedMathPluginHandle)
108  {
109  typedef void Destroy_t(MathPlugin *);
110  Destroy_t *Destroy = (Destroy_t *)dlsym(LoadedMathPluginHandle, "Destroy");
111  if (nullptr != Destroy)
112  {
113  Destroy(pLoadedMathPlugin);
114  pLoadedMathPlugin = nullptr;
115  if (0 == dlclose(LoadedMathPluginHandle))
116  {
117  LoadedMathPluginHandle = nullptr;
118  }
119  else
120  {
122  "MathPluginManagement - dlclose failed on loaded plugin - %s", dlerror());
123  AlignmentSubsystemMathPluginsV.s = IPS_ALERT;
124  }
125  }
126  else
127  {
129  "MathPluginManagement - cannot get Destroy function - %s", dlerror());
130  AlignmentSubsystemMathPluginsV.s = IPS_ALERT;
131  }
132  }
133  // It is not the built in so try to load it
134  if (nullptr != (LoadedMathPluginHandle = dlopen(AlignmentSubsystemCurrentMathPlugin.text, RTLD_NOW)))
135  {
136  typedef MathPlugin *Create_t();
137  Create_t *Create = (Create_t *)dlsym(LoadedMathPluginHandle, "Create");
138  if (nullptr != Create)
139  {
140  pLoadedMathPlugin = Create();
141 
142  // TODO - Update the client to reflect the new plugin
143  int i = 0;
144 
145  for (i = 0; i < (int)MathPluginFiles.size(); i++)
146  {
147  if (0 == strcmp(AlignmentSubsystemCurrentMathPlugin.text, MathPluginFiles[i].c_str()))
148  break;
149  }
150  if (i < (int)MathPluginFiles.size())
151  {
152  IUResetSwitch(&AlignmentSubsystemMathPluginsV);
153  (AlignmentSubsystemMathPlugins.get() + i + 1)->s = ISS_ON;
154  // Update client
155  IDSetSwitch(&AlignmentSubsystemMathPluginsV, nullptr);
156  }
157  else
158  {
160  "MathPluginManagement - cannot find %s in list of plugins", MathPluginFiles[i].c_str());
161  }
162  }
163  else
164  {
165  DEBUGFDEVICE(pTelescope->getDeviceName(), INDI::Logger::DBG_ERROR, "MathPluginManagement - cannot get Create function - %s",
166  dlerror());
167  }
168  }
169  else
170  {
171  DEBUGFDEVICE(pTelescope->getDeviceName(), INDI::Logger::DBG_ERROR, "MathPluginManagement - cannot load plugin %s error %s",
172  AlignmentSubsystemCurrentMathPlugin.text, dlerror());
173  }
174  }
175  else
176  {
177  // It is the inbuilt plugin
178  // Unload old plugin if required
179  if (nullptr != LoadedMathPluginHandle)
180  {
181  typedef void Destroy_t(MathPlugin *);
182  Destroy_t *Destroy = (Destroy_t *)dlsym(LoadedMathPluginHandle, "Destroy");
183  if (nullptr != Destroy)
184  {
185  Destroy(pLoadedMathPlugin);
186  pLoadedMathPlugin = nullptr;
187  if (0 == dlclose(LoadedMathPluginHandle))
188  {
189  LoadedMathPluginHandle = nullptr;
190  }
191  else
192  {
194  "MathPluginManagement - dlclose failed on loaded plugin - %s", dlerror());
195  AlignmentSubsystemMathPluginsV.s = IPS_ALERT;
196  }
197  }
198  else
199  {
201  "MathPluginManagement - cannot get Destroy function - %s", dlerror());
202  AlignmentSubsystemMathPluginsV.s = IPS_ALERT;
203  }
204  }
205  pLoadedMathPlugin = &BuiltInPlugin;
206  IUResetSwitch(&AlignmentSubsystemMathPluginsV);
207  AlignmentSubsystemMathPlugins.get()->s = ISS_ON;
208  // Update client
209  IDSetSwitch(&AlignmentSubsystemMathPluginsV, nullptr);
210  }
211  }
212 }
213 
214 void MathPluginManagement::ProcessSwitchProperties(Telescope *pTelescope, const char *name, ISState *states,
215  char *names[], int n)
216 {
217  //DEBUGFDEVICE(pTelescope->getDeviceName(), INDI::Logger::DBG_DEBUG, "ProcessSwitchProperties - name(%s)", name);
218  INDI_UNUSED(pTelescope);
219  if (strcmp(name, AlignmentSubsystemMathPluginsV.name) == 0)
220  {
221  int CurrentPlugin = IUFindOnSwitchIndex(&AlignmentSubsystemMathPluginsV);
222  IUUpdateSwitch(&AlignmentSubsystemMathPluginsV, states, names, n);
223  AlignmentSubsystemMathPluginsV.s = IPS_OK; // Assume OK for the time being
224  int NewPlugin = IUFindOnSwitchIndex(&AlignmentSubsystemMathPluginsV);
225  HandlePluginLoading(pTelescope, CurrentPlugin, NewPlugin);
226  // Update client
227  IDSetSwitch(&AlignmentSubsystemMathPluginsV, nullptr);
228  }
229  else if (strcmp(name, AlignmentSubsystemMathPluginInitialiseV.name) == 0)
230  {
231  AlignmentSubsystemMathPluginInitialiseV.s = IPS_OK;
232  IUResetSwitch(&AlignmentSubsystemMathPluginInitialiseV);
233  // Update client display
234  IDSetSwitch(&AlignmentSubsystemMathPluginInitialiseV, nullptr);
235 
236  // Initialise or reinitialise the current math plugin
237  Initialise(CurrentInMemoryDatabase);
238  }
239  else if (strcmp(name, AlignmentSubsystemActiveV.name) == 0)
240  {
241  AlignmentSubsystemActiveV.s = IPS_OK;
242  if (0 == IUUpdateSwitch(&AlignmentSubsystemActiveV, states, names, n))
243  // Update client
244  IDSetSwitch(&AlignmentSubsystemActiveV, nullptr);
245  }
246 }
247 
248 void MathPluginManagement::HandlePluginLoading(Telescope *pTelescope, int CurrentPlugin, int NewPlugin)
249 {
250  if (NewPlugin != CurrentPlugin)
251  {
252  MountAlignment_t currentMountAlignment = GetApproximateMountAlignment();
253  // New plugin requested
254  // Unload old plugin if required
255  if (0 != CurrentPlugin)
256  {
257  typedef void Destroy_t(MathPlugin *);
258  Destroy_t *Destroy = (Destroy_t *)dlsym(LoadedMathPluginHandle, "Destroy");
259  if (nullptr != Destroy)
260  {
261  Destroy(pLoadedMathPlugin);
262  pLoadedMathPlugin = nullptr;
263  if (0 == dlclose(LoadedMathPluginHandle))
264  {
265  LoadedMathPluginHandle = nullptr;
266  }
267  else
268  {
270  "MathPluginManagement - dlclose failed on loaded plugin - %s", dlerror());
271  AlignmentSubsystemMathPluginsV.s = IPS_ALERT;
272  }
273  }
274  else
275  {
277  "MathPluginManagement - cannot get Destroy function - %s", dlerror());
278  AlignmentSubsystemMathPluginsV.s = IPS_ALERT;
279  }
280  }
281  // Load the requested plugin if required
282  if (0 != NewPlugin)
283  {
284  std::string PluginPath(MathPluginFiles[NewPlugin - 1]);
285  if (nullptr != (LoadedMathPluginHandle = dlopen(PluginPath.c_str(), RTLD_NOW)))
286  {
287  typedef MathPlugin *Create_t();
288  Create_t *Create = (Create_t *)dlsym(LoadedMathPluginHandle, "Create");
289  if (nullptr != Create)
290  {
291  pLoadedMathPlugin = Create();
292  SetApproximateMountAlignment(currentMountAlignment);
293  Initialise(CurrentInMemoryDatabase);
294  IUSaveText(&AlignmentSubsystemCurrentMathPlugin, PluginPath.c_str());
295  }
296  else
297  {
298  DEBUGFDEVICE(pTelescope->getDeviceName(), INDI::Logger::DBG_ERROR, "MathPluginManagement - cannot get Create function - %s",
299  dlerror());
300  AlignmentSubsystemMathPluginsV.s = IPS_ALERT;
301  }
302  }
303  else
304  {
305  DEBUGFDEVICE(pTelescope->getDeviceName(), INDI::Logger::DBG_ERROR, "MathPluginManagement - cannot load plugin %s error %s",
306  PluginPath.c_str(), dlerror());
307  AlignmentSubsystemMathPluginsV.s = IPS_ALERT;
308  }
309  }
310  else
311  {
312  // It is in built plugin just set up the pointers
313  pLoadedMathPlugin = &BuiltInPlugin;
314  }
315  }
316 }
317 
319 {
320  AlignmentSubsystemActive.s = enable ? ISS_ON : ISS_OFF;
321  AlignmentSubsystemActiveV.s = IPS_OK;
322  IDSetSwitch(&AlignmentSubsystemActiveV, nullptr);
323 }
324 
326 {
327  IUSaveConfigText(fp, &AlignmentSubsystemCurrentMathPluginV);
328  IUSaveConfigSwitch(fp, &AlignmentSubsystemMathPluginsV);
329  IUSaveConfigSwitch(fp, &AlignmentSubsystemActiveV);
330 }
331 
333 {
334  if (EQUATORIAL == Type)
335  {
336  IGeographicCoordinates Position { 0, 0, 0 };
337  if (CurrentInMemoryDatabase->GetDatabaseReferencePosition(Position))
338  {
339  if (Position.latitude >= 0)
341  else
343  }
344  // If no position found, assume northern hemisphere.
345  else
347  }
348  else
350 }
351 
352 // These must match the function signatures in MathPlugin
353 
355 {
356  return (pLoadedMathPlugin->*pGetApproximateMountAlignment)();
357 }
358 
360 {
361  return (pLoadedMathPlugin->*pInitialise)(pInMemoryDatabase);
362 }
363 
365 {
366  (pLoadedMathPlugin->*pSetApproximateMountAlignment)(ApproximateAlignment);
367 }
368 
369 bool MathPluginManagement::TransformCelestialToTelescope(const double RightAscension, const double Declination,
370  double JulianOffset,
371  TelescopeDirectionVector &ApparentTelescopeDirectionVector)
372 {
373  if (AlignmentSubsystemActive.s == ISS_ON)
374  return (pLoadedMathPlugin->*pTransformCelestialToTelescope)(RightAscension, Declination, JulianOffset,
375  ApparentTelescopeDirectionVector);
376  else
377  return false;
378 }
379 
381  const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination)
382 {
383  if (AlignmentSubsystemActive.s == ISS_ON)
384  return (pLoadedMathPlugin->*pTransformTelescopeToCelestial)(ApparentTelescopeDirectionVector, RightAscension,
385  Declination);
386  else
387  return false;
388 }
389 
390 void MathPluginManagement::EnumeratePlugins()
391 {
392  MathPluginFiles.clear();
393  MathPluginDisplayNames.clear();
394 #ifndef OSX_EMBEDED_MODE
395  dirent *de;
396  DIR *dp;
397 
398  errno = 0;
399  char MATH_PLUGINS_DIRECTORY[2048];
400 #if defined(__APPLE__)
401  const char *indiprefix = getenv("INDIPREFIX");
402  if (indiprefix)
403  snprintf(MATH_PLUGINS_DIRECTORY, 2048 - 1, "%s/Contents/Resources/MathPlugins", indiprefix);
404  else
405  snprintf(MATH_PLUGINS_DIRECTORY, 2048 - 1, INDI_MATH_PLUGINS_DIRECTORY);
406 #else
407  snprintf(MATH_PLUGINS_DIRECTORY, 2048 - 1, INDI_MATH_PLUGINS_DIRECTORY);
408 #endif
409 
410  dp = opendir(MATH_PLUGINS_DIRECTORY);
411  strncat(MATH_PLUGINS_DIRECTORY, "/", 2);
412  if (dp)
413  {
414  while (true)
415  {
416  void *Handle;
417  std::string PluginPath(MATH_PLUGINS_DIRECTORY);
418 
419  errno = 0;
420  de = readdir(dp);
421  if (de == nullptr)
422  break;
423  if (0 == strcmp(de->d_name, "."))
424  continue;
425  if (0 == strcmp(de->d_name, ".."))
426  continue;
427 
428  // Try to load the plugin
429  PluginPath.append(de->d_name);
430  Handle = dlopen(PluginPath.c_str(), RTLD_NOW);
431  if (nullptr == Handle)
432  {
433  IDLog("EnumeratePlugins - cannot load plugin %s error %s\n", PluginPath.c_str(), dlerror());
434  continue;
435  }
436 
437  // Try to get the plugin display name
438  typedef const char *GetDisplayName_t();
439  GetDisplayName_t *GetDisplayNamePtr = (GetDisplayName_t *)dlsym(Handle, "GetDisplayName");
440  if (nullptr == GetDisplayNamePtr)
441  {
442  IDLog("EnumeratePlugins - cannot get plugin %s DisplayName error %s\n", PluginPath.c_str(), dlerror());
443  continue;
444  }
445  IDLog("EnumeratePlugins - found plugin %s\n", GetDisplayNamePtr());
446 
447  MathPluginDisplayNames.push_back(GetDisplayNamePtr());
448  MathPluginFiles.push_back(PluginPath);
449  dlclose(Handle);
450  }
451  closedir(dp);
452  }
453  else
454  {
455  IDLog("EnumeratePlugins - Failed to open %s error %s\n", MATH_PLUGINS_DIRECTORY, strerror(errno));
456  }
457 #endif
458 }
459 
460 } // namespace AlignmentSubsystem
461 } // namespace INDI
This class provides the driver side API to the in memory alignment database.
bool GetDatabaseReferencePosition(IGeographicCoordinates &Position)
Get the database reference position.
void ProcessSwitchProperties(Telescope *pTelescope, const char *name, ISState *states, char *names[], int n)
Call this function from within the ISNewSwitch processing path. The function will handle any math plu...
bool TransformTelescopeToCelestial(const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination)
TransformTelescopeToCelestial Transforms Mount Coords to Celestial (Sky) Coordinates.
void InitProperties(Telescope *pTelescope)
Initialize alignment math plugin properties. It is recommended to call this function within initPrope...
void SaveConfigProperties(FILE *fp)
Call this function to save persistent math plugin properties. This function should be called from wit...
void SetApproximateMountAlignment(MountAlignment_t ApproximateAlignment)
Set the approximate alognment of the mount.
void ProcessTextProperties(Telescope *pTelescope, const char *name, char *texts[], char *names[], int n)
Call this function from within the ISNewText processing path. The function will handle any math plugi...
bool TransformCelestialToTelescope(const double RightAscension, const double Declination, double JulianOffset, TelescopeDirectionVector &ApparentTelescopeDirectionVector)
TransformCelestialToTelescope Transforms Celestial (Sky) Coords to Mount Coordinates.
bool Initialise(InMemoryDatabase *pInMemoryDatabase)
Initialise or re-initialise the math plugin. Re-reading the in memory database as necessary.
MountAlignment_t GetApproximateMountAlignment()
Get the approximate alognment of the mount.
enum INDI::AlignmentSubsystem::MathPluginManagement::MountType MountType_t
void SetAlignmentSubsystemActive(bool enable)
SetAlignmentSubsystemActive Enable or Disable alignment subsystem.
void SetApproximateMountAlignmentFromMountType(MountType_t Type)
Call this function to set the ApproximateMountAlignment property of the current Math Plugin....
Provides alignment subsystem functions to INDI alignment math plugins.
Definition: MathPlugin.h:30
InMemoryDatabase * pInMemoryDatabase
Definition: MathPlugin.h:83
MathPlugin(MountAlignment_t ApproximateAlignment=ZENITH)
Default constructor.
Definition: MathPlugin.h:33
const char * getDeviceName() const
Definition: basedevice.cpp:821
void registerProperty(const INDI::Property &property)
Register the property to be able to observe and update.
Definition: basedevice.cpp:924
int errno
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
@ IP_RW
Definition: indiapi.h:186
@ IP_RO
Definition: indiapi.h:184
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
@ ISR_1OFMANY
Definition: indiapi.h:173
@ ISR_ATMOST1
Definition: indiapi.h:174
void IDLog(const char *fmt,...)
Definition: indicom.c:316
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition: indidevapi.c:25
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indidevapi.c:128
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indidevapi.c:148
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:291
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indidevapi.c:36
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
Definition: indidevapi.c:158
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
Definition: indidevapi.c:198
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
Definition: indidevapi.c:20
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:235
ISwitch * IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)
Find an ISwitch member in a vector switch property.
Definition: indidevapi.c:76
#define INDI_UNUSED(x)
Definition: indidevapi.h:131
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:1308
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1231
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
Definition: indidriver.c:1396
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:711
#define DEBUGFDEVICE(device, priority, msg,...)
Definition: indilogger.h:61
#define ALIGNMENT_TAB
void Destroy(DummyMathPlugin *pPlugin)
DummyMathPlugin * Create()
enum INDI::AlignmentSubsystem::MountAlignment MountAlignment_t
Namespace to encapsulate INDI client, drivers, and mediator classes.
Holds a nomalised direction vector (direction cosines)
Definition: Common.h:69
One switch descriptor.
One text descriptor.
Holds the connection type.
char name[MAXINDINAME]
Definition: indiapi.h:371
char name[MAXINDINAME]
Definition: indiapi.h:250