Instrument Neutral Distributed Interface INDI  2.0.2
indidevapi.c
Go to the documentation of this file.
1 #include "indidevapi.h"
2 #include "indicom.h"
3 #include "locale_compat.h"
4 #include "base64.h"
5 #include "userio.h"
6 #include "indiuserio.h"
7 #include "indiutility.h"
8 
9 #include <string.h>
10 #include <stdlib.h>
11 #include <assert.h>
12 
15 void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
16 {
17  IUUserIONewNumber(userio_file(), fp, nvp);
18 }
19 
20 void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
21 {
22  IUUserIONewText(userio_file(), fp, tvp);
23 }
24 
25 void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
26 {
28 }
29 
30 void IUSaveConfigBLOB(FILE *fp, const IBLOBVectorProperty *bvp)
31 {
32  IUUserIONewBLOB(userio_file(), fp, bvp);
33 }
34 
35 /* save malloced copy of newtext in tp->text, reusing if not first time */
36 void IUSaveText(IText *tp, const char *newtext)
37 {
38  /* copy in fresh string */
39  size_t size = strlen(newtext) + 1;
40  tp->text = realloc(tp->text, size);
41  memcpy(tp->text, newtext, size);
42 }
43 
44 int IUSaveBLOB(IBLOB *bp, int size, int blobsize, char *blob, char *format)
45 {
46  bp->bloblen = blobsize;
47  bp->size = size;
48  bp->blob = blob;
49  indi_strlcpy(bp->format, format, MAXINDIFORMAT);
50  return 0;
51 }
52 
55 /* find a member of an IText vector, else NULL */
56 IText *IUFindText(const ITextVectorProperty *tvp, const char *name)
57 {
58  for (int i = 0; i < tvp->ntp; i++)
59  if (strcmp(tvp->tp[i].name, name) == 0)
60  return (&tvp->tp[i]);
61  fprintf(stderr, "No IText '%s' in %s.%s\n", name, tvp->device, tvp->name);
62  return (NULL);
63 }
64 
65 /* find a member of an INumber vector, else NULL */
66 INumber *IUFindNumber(const INumberVectorProperty *nvp, const char *name)
67 {
68  for (int i = 0; i < nvp->nnp; i++)
69  if (strcmp(nvp->np[i].name, name) == 0)
70  return (&nvp->np[i]);
71  fprintf(stderr, "No INumber '%s' in %s.%s\n", name, nvp->device, nvp->name);
72  return (NULL);
73 }
74 
75 /* find a member of an ISwitch vector, else NULL */
76 ISwitch *IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)
77 {
78  for (int i = 0; i < svp->nsp; i++)
79  if (strcmp(svp->sp[i].name, name) == 0)
80  return (&svp->sp[i]);
81  fprintf(stderr, "No ISwitch '%s' in %s.%s\n", name, svp->device, svp->name);
82  return (NULL);
83 }
84 
85 /* find a member of an ILight vector, else NULL */
86 ILight *IUFindLight(const ILightVectorProperty *lvp, const char *name)
87 {
88  for (int i = 0; i < lvp->nlp; i++)
89  if (strcmp(lvp->lp[i].name, name) == 0)
90  return (&lvp->lp[i]);
91  fprintf(stderr, "No ILight '%s' in %s.%s\n", name, lvp->device, lvp->name);
92  return (NULL);
93 }
94 
95 /* find a member of an IBLOB vector, else NULL */
96 IBLOB *IUFindBLOB(const IBLOBVectorProperty *bvp, const char *name)
97 {
98  for (int i = 0; i < bvp->nbp; i++)
99  if (strcmp(bvp->bp[i].name, name) == 0)
100  return (&bvp->bp[i]);
101  fprintf(stderr, "No IBLOB '%s' in %s.%s\n", name, bvp->device, bvp->name);
102  return (NULL);
103 }
104 
105 /* find an ON member of an ISwitch vector, else NULL.
106  * N.B. user must make sense of result with ISRule in mind.
107  */
109 {
110  for (int i = 0; i < svp->nsp; i++)
111  if (svp->sp[i].s == ISS_ON)
112  return (&svp->sp[i]);
113  /*fprintf(stderr, "No ISwitch On in %s.%s\n", svp->device, svp->name);*/
114  return (NULL);
115 }
116 
117 int IUFindIndex(const char *needle, char **hay, unsigned int n)
118 {
119  for (int i = 0; i < (int)n; i++)
120  {
121  if (!strcmp(hay[i], needle))
122  return i;
123  }
124  return -1;
125 }
126 
127 /* Find index of the ON member of an ISwitchVectorProperty */
129 {
130  for (int i = 0; i < svp->nsp; i++)
131  if (svp->sp[i].s == ISS_ON)
132  return i;
133  return -1;
134 }
135 
136 /* Find name the ON member in the given states and names */
137 const char *IUFindOnSwitchName(ISState *states, char *names[], int n)
138 {
139  for (int i = 0; i < n; i++)
140  if (states[i] == ISS_ON)
141  return names[i];
142  return NULL;
143 }
144 
147 /* Set all switches to off */
149 {
150  for (int i = 0; i < svp->nsp; i++)
151  svp->sp[i].s = ISS_OFF;
152 }
153 
158 void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
159 {
160  indi_strlcpy(sp->name, name, sizeof(sp->name));
161 
162  indi_strlcpy(sp->label, label[0] ? label : name, sizeof(sp->label));
163 
164  sp->s = s;
165  sp->svp = NULL;
166  sp->aux = NULL;
167 }
168 
169 void IUFillLight(ILight *lp, const char *name, const char *label, IPState s)
170 {
171  indi_strlcpy(lp->name, name, sizeof(lp->name));
172 
173  indi_strlcpy(lp->label, label[0] ? label : name, sizeof(lp->label));
174 
175  lp->s = s;
176  lp->lvp = NULL;
177  lp->aux = NULL;
178 }
179 
180 void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max,
181  double step, double value)
182 {
183  indi_strlcpy(np->name, name, sizeof(np->name));
184 
185  indi_strlcpy(np->label, label[0] ? label : name, sizeof(np->label));
186 
187  indi_strlcpy(np->format, format, sizeof(np->format));
188 
189  np->min = min;
190  np->max = max;
191  np->step = step;
192  np->value = value;
193  np->nvp = NULL;
194  np->aux0 = NULL;
195  np->aux1 = NULL;
196 }
197 
198 void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
199 {
200  indi_strlcpy(tp->name, name, sizeof(tp->name));
201 
202  indi_strlcpy(tp->label, label[0] ? label : name, sizeof(tp->label));
203 
204  if (tp->text && tp->text[0])
205  free(tp->text);
206  tp->text = NULL;
207 
208  tp->tvp = NULL;
209  tp->aux0 = NULL;
210  tp->aux1 = NULL;
211 
212  if (initialText && initialText[0])
213  IUSaveText(tp, initialText);
214 }
215 
216 void IUFillBLOB(IBLOB *bp, const char *name, const char *label, const char *format)
217 {
218  memset(bp, 0, sizeof(IBLOB));
219 
220  indi_strlcpy(bp->name, name, sizeof(bp->name));
221 
222  indi_strlcpy(bp->label, label[0] ? label : name, sizeof(bp->label));
223 
224  indi_strlcpy(bp->format, format, sizeof(bp->format));
225 
226  bp->blob = 0;
227  bp->bloblen = 0;
228  bp->size = 0;
229  bp->bvp = 0;
230  bp->aux0 = 0;
231  bp->aux1 = 0;
232  bp->aux2 = 0;
233 }
234 
235 void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name,
236  const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
237 {
238  indi_strlcpy(svp->device, dev, sizeof(svp->device));
239 
240  indi_strlcpy(svp->name, name, sizeof(svp->name));
241 
242  indi_strlcpy(svp->label, label[0] ? label : name, sizeof(svp->label));
243 
244  indi_strlcpy(svp->group, group, sizeof(svp->group));
245  svp->timestamp[0] = '\0';
246 
247  svp->p = p;
248  svp->r = r;
249  svp->timeout = timeout;
250  svp->s = s;
251  svp->sp = sp;
252  svp->nsp = nsp;
253 }
254 
255 void IUFillLightVector(ILightVectorProperty *lvp, ILight *lp, int nlp, const char *dev, const char *name,
256  const char *label, const char *group, IPState s)
257 {
258  indi_strlcpy(lvp->device, dev, sizeof(lvp->device));
259 
260  indi_strlcpy(lvp->name, name, sizeof(lvp->name));
261 
262  indi_strlcpy(lvp->label, label[0] ? label : name, sizeof(lvp->label));
263 
264  indi_strlcpy(lvp->group, group, sizeof(lvp->group));
265  lvp->timestamp[0] = '\0';
266 
267  lvp->s = s;
268  lvp->lp = lp;
269  lvp->nlp = nlp;
270 }
271 
272 void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name,
273  const char *label, const char *group, IPerm p, double timeout, IPState s)
274 {
275  indi_strlcpy(nvp->device, dev, sizeof(nvp->device));
276 
277  indi_strlcpy(nvp->name, name, sizeof(nvp->name));
278 
279  indi_strlcpy(nvp->label, label[0] ? label : name, sizeof(nvp->label));
280 
281  indi_strlcpy(nvp->group, group, sizeof(nvp->group));
282  nvp->timestamp[0] = '\0';
283 
284  nvp->p = p;
285  nvp->timeout = timeout;
286  nvp->s = s;
287  nvp->np = np;
288  nvp->nnp = nnp;
289 }
290 
291 void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name,
292  const char *label, const char *group, IPerm p, double timeout, IPState s)
293 {
294  indi_strlcpy(tvp->device, dev, sizeof(tvp->device));
295 
296  indi_strlcpy(tvp->name, name, sizeof(tvp->name));
297 
298  indi_strlcpy(tvp->label, label[0] ? label : name, sizeof(tvp->label));
299 
300  indi_strlcpy(tvp->group, group, sizeof(tvp->group));
301  tvp->timestamp[0] = '\0';
302 
303  tvp->p = p;
304  tvp->timeout = timeout;
305  tvp->s = s;
306  tvp->tp = tp;
307  tvp->ntp = ntp;
308 }
309 
310 void IUFillBLOBVector(IBLOBVectorProperty *bvp, IBLOB *bp, int nbp, const char *dev, const char *name,
311  const char *label, const char *group, IPerm p, double timeout, IPState s)
312 {
313  memset(bvp, 0, sizeof(IBLOBVectorProperty));
314  indi_strlcpy(bvp->device, dev, sizeof(bvp->device));
315 
316  indi_strlcpy(bvp->name, name, sizeof(bvp->name));
317 
318  indi_strlcpy(bvp->label, label[0] ? label : name, sizeof(bvp->label));
319 
320  indi_strlcpy(bvp->group, group, sizeof(bvp->group));
321  bvp->timestamp[0] = '\0';
322 
323  bvp->p = p;
324  bvp->timeout = timeout;
325  bvp->s = s;
326  bvp->bp = bp;
327  bvp->nbp = nbp;
328 }
329 
332 /* crack the snooped driver setNumberVector or defNumberVector message into
333  * the given INumberVectorProperty.
334  * return 0 if type, device and name match and all members are present, else
335  * return -1
336  */
338 {
339  char *dev, *name;
340  XMLEle *ep;
341 
342  /* check and crack type, device, name and state */
343  if (strcmp(tagXMLEle(root) + 3, "NumberVector") || crackDN(root, &dev, &name, NULL) < 0)
344  return (-1);
345  if (strcmp(dev, nvp->device) || strcmp(name, nvp->name))
346  return (-1); /* not this property */
347  (void)crackIPState(findXMLAttValu(root, "state"), &nvp->s);
348 
349  /* match each INumber with a oneNumber */
350  locale_char_t *orig = indi_locale_C_numeric_push();
351  for (int i = 0; i < nvp->nnp; i++)
352  {
353  for (ep = nextXMLEle(root, 1); ep; ep = nextXMLEle(root, 0))
354  {
355  if (!strcmp(tagXMLEle(ep) + 3, "Number") && !strcmp(nvp->np[i].name, findXMLAttValu(ep, "name")))
356  {
357  if (f_scansexa(pcdataXMLEle(ep), &nvp->np[i].value) < 0)
358  {
359  indi_locale_C_numeric_pop(orig);
360  return (-1); /* bad number format */
361  }
362  break;
363  }
364  }
365  if (!ep)
366  {
367  indi_locale_C_numeric_pop(orig);
368  return (-1); /* element not found */
369  }
370  }
371  indi_locale_C_numeric_pop(orig);
372 
373  /* ok */
374  return (0);
375 }
376 
377 /* crack the snooped driver setTextVector or defTextVector message into
378  * the given ITextVectorProperty.
379  * return 0 if type, device and name match and all members are present, else
380  * return -1
381  */
383 {
384  char *dev, *name;
385  XMLEle *ep;
386 
387  /* check and crack type, device, name and state */
388  if (strcmp(tagXMLEle(root) + 3, "TextVector") || crackDN(root, &dev, &name, NULL) < 0)
389  return (-1);
390  if (strcmp(dev, tvp->device) || strcmp(name, tvp->name))
391  return (-1); /* not this property */
392  (void)crackIPState(findXMLAttValu(root, "state"), &tvp->s);
393 
394  /* match each IText with a oneText */
395  for (int i = 0; i < tvp->ntp; i++)
396  {
397  for (ep = nextXMLEle(root, 1); ep; ep = nextXMLEle(root, 0))
398  {
399  if (!strcmp(tagXMLEle(ep) + 3, "Text") && !strcmp(tvp->tp[i].name, findXMLAttValu(ep, "name")))
400  {
401  IUSaveText(&tvp->tp[i], pcdataXMLEle(ep));
402  break;
403  }
404  }
405  if (!ep)
406  return (-1); /* element not found */
407  }
408 
409  /* ok */
410  return (0);
411 }
412 
413 /* crack the snooped driver setLightVector or defLightVector message into
414  * the given ILightVectorProperty. it is not necessary that all ILight names
415  * be found.
416  * return 0 if type, device and name match, else return -1.
417  */
419 {
420  char *dev, *name;
421  XMLEle *ep;
422 
423  /* check and crack type, device, name and state */
424  if (strcmp(tagXMLEle(root) + 3, "LightVector") || crackDN(root, &dev, &name, NULL) < 0)
425  return (-1);
426  if (strcmp(dev, lvp->device) || strcmp(name, lvp->name))
427  return (-1); /* not this property */
428 
429  (void)crackIPState(findXMLAttValu(root, "state"), &lvp->s);
430 
431  /* match each oneLight with one ILight */
432  for (ep = nextXMLEle(root, 1); ep; ep = nextXMLEle(root, 0))
433  {
434  if (!strcmp(tagXMLEle(ep) + 3, "Light"))
435  {
436  const char *name = findXMLAttValu(ep, "name");
437  for (int i = 0; i < lvp->nlp; i++)
438  {
439  if (!strcmp(lvp->lp[i].name, name))
440  {
441  if (crackIPState(pcdataXMLEle(ep), &lvp->lp[i].s) < 0)
442  {
443  return (-1); /* unrecognized state */
444  }
445  break;
446  }
447  }
448  }
449  }
450 
451  /* ok */
452  return (0);
453 }
454 
455 /* crack the snooped driver setSwitchVector or defSwitchVector message into the
456  * given ISwitchVectorProperty. it is not necessary that all ISwitch names be
457  * found.
458  * return 0 if type, device and name match, else return -1.
459  */
461 {
462  char *dev, *name;
463  XMLEle *ep;
464 
465  /* check and crack type, device, name and state */
466  if (strcmp(tagXMLEle(root) + 3, "SwitchVector") || crackDN(root, &dev, &name, NULL) < 0)
467  return (-1);
468  if (strcmp(dev, svp->device) || strcmp(name, svp->name))
469  return (-1); /* not this property */
470  (void)crackIPState(findXMLAttValu(root, "state"), &svp->s);
471 
472  /* match each oneSwitch with one ISwitch */
473  for (ep = nextXMLEle(root, 1); ep; ep = nextXMLEle(root, 0))
474  {
475  if (!strcmp(tagXMLEle(ep) + 3, "Switch"))
476  {
477  const char *name = findXMLAttValu(ep, "name");
478  for (int i = 0; i < svp->nsp; i++)
479  {
480  if (!strcmp(svp->sp[i].name, name))
481  {
482  if (crackISState(pcdataXMLEle(ep), &svp->sp[i].s) < 0)
483  {
484  return (-1); /* unrecognized state */
485  }
486  break;
487  }
488  }
489  }
490  }
491 
492  /* ok */
493  return (0);
494 }
495 
496 /* crack the snooped driver setBLOBVector message into the given
497  * IBLOBVectorProperty. it is not necessary that all IBLOB names be found.
498  * return 0 if type, device and name match, else return -1.
499  * N.B. we assume any existing blob in bvp has been malloced, which we free
500  * and replace with a newly malloced blob if found.
501  */
503 {
504  char *dev, *name;
505  XMLEle *ep;
506 
507  /* check and crack type, device, name and state */
508  if (strcmp(tagXMLEle(root), "setBLOBVector") || crackDN(root, &dev, &name, NULL) < 0)
509  return (-1);
510 
511  if (strcmp(dev, bvp->device) || strcmp(name, bvp->name))
512  return (-1); /* not this property */
513 
514  crackIPState(findXMLAttValu(root, "state"), &bvp->s);
515 
516  for (ep = nextXMLEle(root, 1); ep; ep = nextXMLEle(root, 0))
517  {
518  if (strcmp(tagXMLEle(ep), "oneBLOB") == 0)
519  {
520  XMLAtt *na = findXMLAtt(ep, "name");
521  if (na == NULL)
522  return (-1);
523 
524  IBLOB *bp = IUFindBLOB(bvp, valuXMLAtt(na));
525 
526  if (bp == NULL)
527  return (-1);
528 
529  XMLAtt *fa = findXMLAtt(ep, "format");
530  XMLAtt *sa = findXMLAtt(ep, "size");
531  XMLAtt *ec = findXMLAtt(ep, "enclen");
532  if (fa && sa && ec)
533  {
534  int enclen = atoi(valuXMLAtt(ec));
535  assert_mem(bp->blob = realloc(bp->blob, 3 * enclen / 4));
536  bp->bloblen = from64tobits_fast(bp->blob, pcdataXMLEle(ep), enclen);
537  indi_strlcpy(bp->format, valuXMLAtt(fa), MAXINDIFORMAT);
538  bp->size = atoi(valuXMLAtt(sa));
539  }
540  }
541  }
542 
543  /* ok */
544  return (0);
545 }
546 
549 /* Functions are implemented in defaultdevice.cpp */
550 
553 int crackDN(XMLEle *root, char **dev, char **name, char msg[])
554 {
555  XMLAtt *ap;
556 
557  ap = findXMLAtt(root, "device");
558  if (!ap)
559  {
560  sprintf(msg, "%s requires 'device' attribute", tagXMLEle(root));
561  return (-1);
562  }
563  *dev = valuXMLAtt(ap);
564 
565  ap = findXMLAtt(root, "name");
566  if (!ap)
567  {
568  sprintf(msg, "%s requires 'name' attribute", tagXMLEle(root));
569  return (-1);
570  }
571  *name = valuXMLAtt(ap);
572 
573  return (0);
574 }
575 
576 int crackIPState(const char *str, IPState *ip)
577 {
578  if (!strcmp(str, "Idle"))
579  *ip = IPS_IDLE;
580  else if (!strncmp(str, "Ok", 2))
581  *ip = IPS_OK;
582  else if (!strcmp(str, "Busy"))
583  *ip = IPS_BUSY;
584  else if (!strcmp(str, "Alert"))
585  *ip = IPS_ALERT;
586  else
587  return (-1);
588  return (0);
589 }
590 
591 int crackISState(const char *str, ISState *ip)
592 {
593  if (!strncmp(str, "On", 2))
594  *ip = ISS_ON;
595  else if (!strcmp(str, "Off"))
596  *ip = ISS_OFF;
597  else
598  return (-1);
599  return (0);
600 }
601 
602 int crackIPerm(const char *str, IPerm *ip)
603 {
604  if (!strncmp(str, "rw", 2))
605  *ip = IP_RW;
606  else if (!strncmp(str, "ro", 2))
607  *ip = IP_RO;
608  else if (!strncmp(str, "wo", 2))
609  *ip = IP_WO;
610  else
611  return (-1);
612  return (0);
613 }
614 
615 int crackISRule(const char *str, ISRule *ip)
616 {
617  if (!strcmp(str, "OneOfMany"))
618  *ip = ISR_1OFMANY;
619  else if (!strcmp(str, "AtMostOne"))
620  *ip = ISR_ATMOST1;
621  else if (!strcmp(str, "AnyOfMany"))
622  *ip = ISR_NOFMANY;
623  else
624  return (-1);
625  return (0);
626 }
627 
628 const char *pstateStr(IPState s)
629 {
630  switch (s)
631  {
632  case IPS_IDLE:
633  return "Idle";
634  case IPS_OK:
635  return "Ok";
636  case IPS_BUSY:
637  return "Busy";
638  case IPS_ALERT:
639  return "Alert";
640  default:
641  fprintf(stderr, "Impossible IPState %d\n", s);
642  return NULL;
643  }
644 }
645 
646 const char *sstateStr(ISState s)
647 {
648  switch (s)
649  {
650  case ISS_ON:
651  return "On";
652  case ISS_OFF:
653  return "Off";
654  default:
655  fprintf(stderr, "Impossible ISState %d\n", s);
656  return NULL;
657  }
658 }
659 
660 const char *ruleStr(ISRule r)
661 {
662  switch (r)
663  {
664  case ISR_1OFMANY:
665  return "OneOfMany";
666  case ISR_ATMOST1:
667  return "AtMostOne";
668  case ISR_NOFMANY:
669  return "AnyOfMany";
670  default:
671  fprintf(stderr, "Impossible ISRule %d\n", r);
672  return NULL;
673  }
674 }
675 
676 const char *permStr(IPerm p)
677 {
678  switch (p)
679  {
680  case IP_RO:
681  return "ro";
682  case IP_WO:
683  return "wo";
684  case IP_RW:
685  return "rw";
686  default:
687  fprintf(stderr, "Impossible IPerm %d\n", p);
688  return NULL;
689  }
690 }
691 
692 void xmlv1()
693 {
694  userio_xmlv1(userio_file(), stdout);
695 }
int from64tobits_fast(char *out, const char *in, int inlen)
Definition: base64.c:122
double max(void)
double min(void)
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
#define MAXINDIFORMAT
Definition: indiapi.h:195
#define assert_mem(p)
Bails out if memory pointer is 0. Prints file and function.
Definition: indiapi.h:505
IPerm
Permission hint, with respect to client.
Definition: indiapi.h:183
@ IP_RW
Definition: indiapi.h:186
@ IP_RO
Definition: indiapi.h:184
@ IP_WO
Definition: indiapi.h:185
IPState
Property state.
Definition: indiapi.h:160
@ IPS_BUSY
Definition: indiapi.h:163
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
ISRule
Switch vector rule hint.
Definition: indiapi.h:172
@ ISR_1OFMANY
Definition: indiapi.h:173
@ ISR_NOFMANY
Definition: indiapi.h:175
@ ISR_ATMOST1
Definition: indiapi.h:174
int f_scansexa(const char *str0, double *dp)
convert sexagesimal string str AxBxC to double. x can be anything non-numeric. Any missing A,...
Definition: indicom.c:205
Implementations for common driver routines.
int IUSnoopSwitch(XMLEle *root, ISwitchVectorProperty *svp)
Update a snooped switch vector property from the given XML root element.
Definition: indidevapi.c:460
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition: indidevapi.c:25
const char * ruleStr(ISRule r)
Definition: indidevapi.c:660
void IUFillLight(ILight *lp, const char *name, const char *label, IPState s)
Assign attributes for a light property. The light's auxiliary elements will be set to NULL.
Definition: indidevapi.c:169
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:272
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
Definition: indidevapi.c:66
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 IUFillLightVector(ILightVectorProperty *lvp, ILight *lp, int nlp, const char *dev, const char *name, const char *label, const char *group, IPState s)
Assign attributes for a light vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:255
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
const char * IUFindOnSwitchName(ISState *states, char *names[], int n)
Returns the name of the first ON switch it finds in the supplied arguments.
Definition: indidevapi.c:137
ISwitch * IUFindOnSwitch(const ISwitchVectorProperty *svp)
Returns the first ON switch it finds in the vector switch property.
Definition: indidevapi.c:108
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indidevapi.c:36
int IUFindIndex(const char *needle, char **hay, unsigned int n)
Returns the index of the string in a string array.
Definition: indidevapi.c:117
int IUSnoopBLOB(XMLEle *root, IBLOBVectorProperty *bvp)
Update a snooped BLOB vector property from the given XML root element.
Definition: indidevapi.c:502
int crackDN(XMLEle *root, char **dev, char **name, char msg[])
Extract dev and name attributes from an XML element.
Definition: indidevapi.c:553
int IUSnoopLight(XMLEle *root, ILightVectorProperty *lvp)
Update a snooped light vector property from the given XML root element.
Definition: indidevapi.c:418
int IUSaveBLOB(IBLOB *bp, int size, int blobsize, char *blob, char *format)
Function to save blob metadata in the corresponding blob.
Definition: indidevapi.c:44
void IUSaveConfigBLOB(FILE *fp, const IBLOBVectorProperty *bvp)
Add a BLOB vector property value to the configuration file.
Definition: indidevapi.c:30
int IUSnoopText(XMLEle *root, ITextVectorProperty *tvp)
Update a snooped text vector property from the given XML root element.
Definition: indidevapi.c:382
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition: indidevapi.c:15
int IUSnoopNumber(XMLEle *root, INumberVectorProperty *nvp)
Update a snooped number vector property from the given XML root element.
Definition: indidevapi.c:337
void xmlv1()
print the boilerplate comment introducing xml
Definition: indidevapi.c:692
const char * pstateStr(IPState s)
Definition: indidevapi.c:628
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 IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
Definition: indidevapi.c:180
int crackIPerm(const char *str, IPerm *ip)
Extract property permission state (RW, RO, WO) from the supplied string.
Definition: indidevapi.c:602
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
Definition: indidevapi.c:20
int crackIPState(const char *str, IPState *ip)
Extract property state (Idle, OK, Busy, Alert) from the supplied string.
Definition: indidevapi.c:576
IBLOB * IUFindBLOB(const IBLOBVectorProperty *bvp, const char *name)
Find an IBLOB member in a vector BLOB property.
Definition: indidevapi.c:96
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
IText * IUFindText(const ITextVectorProperty *tvp, const char *name)
Find an IText member in a vector text property.
Definition: indidevapi.c:56
void IUFillBLOBVector(IBLOBVectorProperty *bvp, IBLOB *bp, int nbp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a BLOB vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:310
void IUFillBLOB(IBLOB *bp, const char *name, const char *label, const char *format)
Assign attributes for a BLOB property. The BLOB's data and auxiliary elements will be set to NULL.
Definition: indidevapi.c:216
ILight * IUFindLight(const ILightVectorProperty *lvp, const char *name)
Find an ILight member in a vector Light property.
Definition: indidevapi.c:86
int crackISRule(const char *str, ISRule *ip)
Extract switch rule (OneOfMany, OnlyOne..etc) from the supplied string.
Definition: indidevapi.c:615
const char * sstateStr(ISState s)
Definition: indidevapi.c:646
const char * permStr(IPerm p)
Definition: indidevapi.c:676
int crackISState(const char *str, ISState *ip)
Extract switch state (On or Off) from the supplied string.
Definition: indidevapi.c:591
ISwitch * IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)
Find an ISwitch member in a vector switch property.
Definition: indidevapi.c:76
Interface to the reference INDI C API device implementation on the Device Driver side.
void IUUserIONewBLOB(const userio *io, void *user, const IBLOBVectorProperty *bvp)
Definition: indiuserio.c:251
void IUUserIONewSwitchFull(const userio *io, void *user, const ISwitchVectorProperty *svp)
Definition: indiuserio.c:229
void IUUserIONewText(const userio *io, void *user, const ITextVectorProperty *tvp)
Definition: indiuserio.c:216
void IUUserIONewNumber(const userio *io, void *user, const INumberVectorProperty *nvp)
Definition: indiuserio.c:199
XMLAtt * findXMLAtt(XMLEle *ep, const char *name)
Find an XML attribute within an XML element.
Definition: lilxml.cpp:524
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
Definition: lilxml.cpp:644
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
Definition: lilxml.cpp:606
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
Definition: lilxml.cpp:600
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
Definition: lilxml.cpp:555
char * valuXMLAtt(XMLAtt *ap)
Return the value of an XML attribute.
Definition: lilxml.cpp:624
char locale_char_t
Definition: locale_compat.h:62
One Blob (Binary Large Object) descriptor.
One light descriptor.
One number descriptor.
One switch descriptor.
One text descriptor.
BLOB (Binary Large Object) vector property descriptor.
Definition: indiapi.h:471
char label[MAXINDILABEL]
Definition: indiapi.h:477
char group[MAXINDIGROUP]
Definition: indiapi.h:479
char timestamp[MAXINDITSTAMP]
Definition: indiapi.h:491
char name[MAXINDINAME]
Definition: indiapi.h:475
char device[MAXINDIDEVICE]
Definition: indiapi.h:473
Light vector property descriptor.
Definition: indiapi.h:417
char label[MAXINDILABEL]
Definition: indiapi.h:423
char name[MAXINDINAME]
Definition: indiapi.h:421
char device[MAXINDIDEVICE]
Definition: indiapi.h:419
char group[MAXINDIGROUP]
Definition: indiapi.h:425
char timestamp[MAXINDITSTAMP]
Definition: indiapi.h:433
Number vector property descriptor.
Definition: indiapi.h:319
char group[MAXINDIGROUP]
Definition: indiapi.h:327
char device[MAXINDIDEVICE]
Definition: indiapi.h:321
char name[MAXINDINAME]
Definition: indiapi.h:323
char label[MAXINDILABEL]
Definition: indiapi.h:325
char timestamp[MAXINDITSTAMP]
Definition: indiapi.h:339
Switch vector property descriptor.
Definition: indiapi.h:367
char device[MAXINDIDEVICE]
Definition: indiapi.h:369
char name[MAXINDINAME]
Definition: indiapi.h:371
char label[MAXINDILABEL]
Definition: indiapi.h:373
char group[MAXINDIGROUP]
Definition: indiapi.h:375
char timestamp[MAXINDITSTAMP]
Definition: indiapi.h:389
Text vector property descriptor.
Definition: indiapi.h:246
char label[MAXINDILABEL]
Definition: indiapi.h:252
char device[MAXINDIDEVICE]
Definition: indiapi.h:248
char timestamp[MAXINDITSTAMP]
Definition: indiapi.h:266
char name[MAXINDINAME]
Definition: indiapi.h:250
char group[MAXINDIGROUP]
Definition: indiapi.h:254
const struct userio * userio_file()
Definition: userio.c:39
void userio_xmlv1(const userio *io, void *user)
Definition: userio.c:104