Instrument Neutral Distributed Interface INDI  1.9.2
indiuserio.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 2021 by Pawel Soja <kernel32.pl@gmail.com>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #include "indiuserio.h"
19 #include "indiapi.h"
20 #include "indidevapi.h"
21 #include "indicom.h"
22 #include "locale_compat.h"
23 #include "base64.h"
24 
25 #include <stdlib.h>
26 
27 static void s_userio_xml_message_vprintf(const userio *io, void *user, const char *fmt, va_list ap)
28 {
29  char message[MAXINDIMESSAGE];
30  if (fmt)
31  {
32  vsnprintf(message, MAXINDIMESSAGE, fmt, ap);
33 
34  userio_prints (io, user, " message='");
35  userio_xml_escape(io, user, message);
36  userio_prints (io, user, "'\n");
37  }
38 }
39 
40 
41 void IUUserIONumberContext(const userio *io, void *user, const INumberVectorProperty *nvp)
42 {
43  for (int i = 0; i < nvp->nnp; i++)
44  {
45  INumber *np = &nvp->np[i];
46  userio_prints (io, user, " <oneNumber name='");
47  userio_xml_escape(io, user, np->name);
48  userio_prints (io, user, "'>\n");
49  userio_printf (io, user, " %.20g\n", np->value); // safe
50  userio_prints (io, user, " </oneNumber>\n");
51  }
52 }
53 
54 void IUUserIOTextContext(const userio *io, void *user, const ITextVectorProperty *tvp)
55 {
56  for (int i = 0; i < tvp->ntp; i++)
57  {
58  IText *tp = &tvp->tp[i];
59  userio_prints (io, user, " <oneText name='");
60  userio_xml_escape(io, user, tp->name);
61  userio_prints (io, user, "'>\n"
62  " ");
63  if (tp->text)
64  userio_xml_escape(io, user, tp->text);
65  userio_prints (io, user, "\n"
66  " </oneText>\n");
67  }
68 }
69 
70 void IUUserIOSwitchContextOne(const userio *io, void *user, const ISwitch *sp)
71 {
72  userio_prints (io, user, " <oneSwitch name='");
73  userio_xml_escape(io, user, sp->name);
74  userio_prints (io, user, "'>\n"
75  " ");
76  userio_prints (io, user, sstateStr(sp->s));
77  userio_prints (io, user, "\n"
78  " </oneSwitch>\n");
79 }
80 
81 void IUUserIOSwitchContextFull(const userio *io, void *user, const ISwitchVectorProperty *svp)
82 {
83  for (int i = 0; i < svp->nsp; i++)
84  {
85  ISwitch *sp = &svp->sp[i];
86  IUUserIOSwitchContextOne(io, user, sp);
87  }
88 }
89 
90 void IUUserIOSwitchContext(const userio *io, void *user, const ISwitchVectorProperty *svp)
91 {
92  ISwitch *onSwitch = IUFindOnSwitch(svp);
93 
94  if (svp->r == ISR_1OFMANY && onSwitch)
95  IUUserIOSwitchContextOne(io, user, onSwitch);
96  else
97  IUUserIOSwitchContextFull(io, user, svp);
98 }
99 
101  const userio *io, void *user,
102  const char *name, unsigned int size, unsigned int bloblen, const void *blob, const char *format
103 )
104 {
105  unsigned char *encblob;
106  int l;
107 
108  userio_prints (io, user, " <oneBLOB\n"
109  " name='");
110  userio_xml_escape(io, user, name);
111  userio_prints (io, user, "'\n");
112  userio_printf (io, user, " size='%d'\n", size); // safe
113 
114  // If size is zero, we are only sending a state-change
115  if (size == 0)
116  {
117  userio_prints (io, user, " enclen='0'\n"
118  " format='");
119  userio_xml_escape(io, user, format);
120  userio_prints (io, user, "'>\n");
121  }
122  else
123  {
124  size_t sz = 4 * bloblen / 3 + 4;
125  assert_mem(encblob = (unsigned char *)malloc(sz)); // #PS: TODO
126  l = to64frombits_s(encblob, blob, bloblen, sz);
127  if (l == 0) {
128  fprintf(stderr, "%s: Not enough memory for decoding.\n", __func__);
129  exit(1);
130  }
131  userio_printf (io, user, " enclen='%d'\n", l); // safe
132  userio_prints (io, user, " format='");
133  userio_xml_escape(io, user, format);
134  userio_prints (io, user, "'>\n");
135  size_t written = 0;
136 
137  while ((int)written < l)
138  {
139  size_t towrite = ((l - written) > 72) ? 72 : l - written;
140  size_t wr = userio_write(io, user, encblob + written, towrite);
141 
142  if (wr == 0)
143  {
144  free(encblob);
145  return;
146  }
147 
148  written += wr;
149  if ((written % 72) == 0)
150  userio_putc(io, user, '\n');
151  }
152 
153  if ((written % 72) != 0)
154  userio_putc(io, user, '\n');
155 
156  free(encblob);
157  }
158 
159  userio_prints (io, user, " </oneBLOB>\n");
160 }
161 
162 void IUUserIOBLOBContext(const userio *io, void *user, const IBLOBVectorProperty *bvp)
163 {
164  for (int i = 0; i < bvp->nbp; i++)
165  {
166  IBLOB *bp = &bvp->bp[i];
168  io, user,
169  bp->name, bp->size, bp->bloblen, bp->blob, bp->format
170  );
171  }
172 }
173 
174 void IUUserIOLightContext(const userio *io, void *user, const ILightVectorProperty *lvp)
175 {
176  for (int i = 0; i < lvp->nlp; i++)
177  {
178  ILight *lp = &lvp->lp[i];
179  userio_prints (io, user, " <oneLight name='");
180  userio_xml_escape(io, user, lp->name);
181  userio_prints (io, user, "'>\n"
182  " ");
183  userio_prints (io, user, pstateStr(lp->s));
184  userio_prints (io, user, "\n"
185  " </oneLight>\n");
186  }
187 }
188 
189 void IUUserIONewNumber(const userio *io, void *user, const INumberVectorProperty *nvp)
190 {
191  locale_char_t *orig = indi_locale_C_numeric_push();
192 
193  userio_prints (io, user, "<newNumberVector device='");
194  userio_xml_escape(io, user, nvp->device);
195  userio_prints (io, user, "' name='");
196  userio_xml_escape(io, user, nvp->name);
197  userio_prints (io, user, "'>\n");
198 
199  IUUserIONumberContext(io, user, nvp);
200 
201  userio_prints (io, user, "</newNumberVector>\n");
202 
203  indi_locale_C_numeric_pop(orig);
204 }
205 
206 void IUUserIONewText(const userio *io, void *user, const ITextVectorProperty *tvp)
207 {
208  userio_prints (io, user, "<newTextVector device='");
209  userio_xml_escape(io, user, tvp->device);
210  userio_prints (io, user, "' name='");
211  userio_xml_escape(io, user, tvp->name);
212  userio_prints (io, user, "'>\n");
213 
214  IUUserIOTextContext(io, user, tvp);
215 
216  userio_prints (io, user, "</newTextVector>\n");
217 }
218 
219 void IUUserIONewSwitchFull(const userio *io, void *user, const ISwitchVectorProperty *svp)
220 {
221  userio_prints (io, user, "<newSwitchVector device='");
222  userio_xml_escape(io, user, svp->device);
223  userio_prints (io, user, "' name='");
224  userio_xml_escape(io, user, svp->name);
225  userio_prints (io, user, "'>\n");
226  IUUserIOSwitchContextFull(io, user, svp);
227  userio_prints (io, user, "</newSwitchVector>\n");
228 }
229 
230 void IUUserIONewSwitch(const userio *io, void *user, const ISwitchVectorProperty *svp)
231 {
232  userio_prints (io, user, "<newSwitchVector device='");
233  userio_xml_escape(io, user, svp->device);
234  userio_prints (io, user, "' name='");
235  userio_xml_escape(io, user, svp->name);
236  userio_prints (io, user, "'>\n");
237  IUUserIOSwitchContext(io, user, svp);
238  userio_prints (io, user, "</newSwitchVector>\n");
239 }
240 
241 void IUUserIONewBLOB(const userio *io, void *user, const IBLOBVectorProperty *bvp)
242 {
243  IUUserIONewBLOBStart(io, user, bvp->device, bvp->name, NULL);
244 
245  IUUserIOBLOBContext(io, user, bvp);
246 
247  IUUserIONewBLOBFinish(io, user);
248 }
249 
251  const userio *io, void *user,
252  const char *dev, const char *name, const char *timestamp
253 )
254 {
255  userio_prints (io, user, "<newBLOBVector\n"
256  " device='");
257  userio_xml_escape(io, user, dev);
258  userio_prints (io, user, "'\n"
259  " name='");
260  userio_xml_escape(io, user, name);
261  userio_prints (io, user, "'\n");
262  if (timestamp != NULL)
263  {
264  userio_prints (io, user, " timestamp='");
265  userio_xml_escape(io, user, timestamp);
266  userio_prints (io, user, "'\n");
267  }
268  userio_prints (io, user, ">\n");
269 }
270 
271 void IUUserIONewBLOBFinish(const userio *io, void *user)
272 {
273  userio_prints (io, user, "</newBLOBVector>\n");
274 }
275 
277  const userio *io, void *user,
278  const char *dev, const char *name, const char *fmt, va_list ap
279 )
280 {
281  userio_prints (io, user, "<delProperty\n device='");
282  userio_xml_escape(io, user, dev);
283  userio_prints (io, user, "'\n");
284  if (name)
285  {
286  userio_prints (io, user, " name='");
287  userio_xml_escape(io, user, name);
288  userio_prints (io, user, "'\n");
289  }
290  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
291 
292  s_userio_xml_message_vprintf(io, user, fmt, ap);
293 
294  userio_prints (io, user, "/>\n");
295 }
296 
298  const userio *io, void *user,
299  const char *dev, const char *name
300 )
301 {
302  userio_printf (io, user, "<getProperties version='%g'", INDIV); // safe
303  // special case for INDI::BaseClient::listenINDI INDI::BaseClientQt::connectServer
304  if (dev && dev[0])
305  {
306  userio_prints (io, user, " device='");
307  userio_xml_escape(io, user, dev);
308  userio_prints (io, user, "'");
309  }
310  if (name && name[0])
311  {
312  userio_prints (io, user, " name='");
313  userio_xml_escape(io, user, name);
314  userio_prints (io, user, "'");
315  }
316  userio_prints (io, user, "/>\n");
317 }
318 
319 // temporary
320 static const char *s_BLOBHandlingtoString(BLOBHandling bh)
321 {
322  switch (bh)
323  {
324  case B_NEVER: return "Never";
325  case B_ALSO: return "Also";
326  case B_ONLY: return "Only";
327  default: return "Unknown";
328  }
329 }
330 
332  const userio *io, void *user,
333  const char *dev, const char *name, BLOBHandling blobH
334 )
335 {
336  userio_prints(io, user, "<enableBLOB device='");
337  userio_xml_escape(io, user, dev);
338  if (name != NULL)
339  {
340  userio_prints(io, user, "' name='");
341  userio_xml_escape(io, user, name);
342  }
343  userio_prints(io, user, "'>");
344  userio_prints(io, user, s_BLOBHandlingtoString(blobH));
345  userio_prints(io, user, "</enableBLOB>\n");
346 }
347 
349  const userio *io, void *user,
350  const char *dev, const char *fmt, va_list ap
351 )
352 {
353  userio_prints (io, user, "<message\n");
354  if (dev)
355  {
356  userio_prints (io, user, " device='");
357  userio_xml_escape(io, user, dev);
358  userio_prints (io, user, "'\n");
359  }
360  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
361  s_userio_xml_message_vprintf(io, user, fmt, ap);
362  userio_prints (io, user, "/>\n");
363 }
364 
366  const userio *io, void *user,
367  const char *dev, const char *fmt, ...
368 )
369 {
370  va_list ap;
371  va_start(ap, fmt);
372  IDUserIOMessageVA(io, user, dev, fmt, ap);
373  va_end(ap);
374 }
375 
377  const userio *io, void *user, int ctag
378 )
379 {
380  /* Opening tag */
381  if (ctag == 0)
382  {
383  userio_prints(io, user, "<INDIDriver>\n");
384  }
385  /* Closing tag */
386  else
387  {
388  userio_prints(io, user, "</INDIDriver>\n");
389  }
390 }
391 
393  const userio *io, void *user,
394  const ITextVectorProperty *tvp, const char *fmt, va_list ap
395 )
396 {
397  locale_char_t *orig = indi_locale_C_numeric_push();
398  userio_prints (io, user, "<defTextVector\n"
399  " device='");
400  userio_xml_escape(io, user, tvp->device);
401  userio_prints (io, user, "'\n"
402  " name='");
403  userio_xml_escape(io, user, tvp->name);
404  userio_prints (io, user, "'\n"
405  " label='");
406  userio_xml_escape(io, user, tvp->label);
407  userio_prints (io, user, "'\n"
408  " group='");
409  userio_xml_escape(io, user, tvp->group);
410  userio_prints (io, user, "'\n");
411  userio_printf (io, user, " state='%s'\n", pstateStr(tvp->s)); // safe
412  userio_printf (io, user, " perm='%s'\n", permStr(tvp->p)); // safe
413  userio_printf (io, user, " timeout='%g'\n", tvp->timeout); // safe
414  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
415  s_userio_xml_message_vprintf(io, user, fmt, ap);
416  userio_prints (io, user, ">\n");
417 
418  for (int i = 0; i < tvp->ntp; i++)
419  {
420  IText *tp = &tvp->tp[i];
421  userio_prints (io, user, " <defText\n"
422  " name='");
423  userio_xml_escape(io, user, tp->name);
424  userio_prints (io, user, "'\n"
425  " label='");
426  userio_xml_escape(io, user, tp->label);
427  userio_prints (io, user, "'>\n"
428  " ");
429  if (tp->text)
430  userio_xml_escape(io, user, tp->text);
431  userio_prints (io, user, "\n"
432  " </defText>\n");
433  }
434 
435  userio_prints (io, user, "</defTextVector>\n");
436  indi_locale_C_numeric_pop(orig);
437 }
438 
440  const userio *io, void *user,
441  const INumberVectorProperty *n, const char *fmt, va_list ap
442 )
443 {
444  locale_char_t *orig = indi_locale_C_numeric_push();
445  userio_prints (io, user, "<defNumberVector\n"
446  " device='");
447  userio_xml_escape(io, user, n->device);
448  userio_prints (io, user, "'\n"
449  " name='");
450  userio_xml_escape(io, user, n->name);
451  userio_prints (io, user, "'\n"
452  " label='");
453  userio_xml_escape(io, user, n->label);
454  userio_prints (io, user, "'\n"
455  " group='");
456  userio_xml_escape(io, user, n->group);
457  userio_prints (io, user, "'\n");
458  userio_printf (io, user, " state='%s'\n", pstateStr(n->s)); // safe
459  userio_printf (io, user, " perm='%s'\n", permStr(n->p)); // safe
460  userio_printf (io, user, " timeout='%g'\n", n->timeout); // safe
461  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
462  s_userio_xml_message_vprintf(io, user, fmt, ap);
463  userio_prints (io, user, ">\n");
464 
465  for (int i = 0; i < n->nnp; i++)
466  {
467  INumber *np = &n->np[i];
468 
469  userio_prints (io, user, " <defNumber\n"
470  " name='");
471  userio_xml_escape(io, user, np->name);
472  userio_prints (io, user, "'\n"
473  " label='");
474  userio_xml_escape(io, user, np->label);
475  userio_prints (io, user, "'\n"
476  " format='");
477  userio_xml_escape(io, user, np->format);
478  userio_prints (io, user, "'\n");
479  userio_printf (io, user, " min='%.20g'\n", np->min); // safe
480  userio_printf (io, user, " max='%.20g'\n", np->max); // safe
481  userio_printf (io, user, " step='%.20g'>\n", np->step); // safe
482  userio_printf (io, user, " %.20g\n", np->value); // safe
483 
484  userio_prints (io, user, " </defNumber>\n");
485  }
486 
487  userio_prints (io, user, "</defNumberVector>\n");
488  indi_locale_C_numeric_pop(orig);
489 }
490 
492  const userio *io, void *user,
493  const ISwitchVectorProperty *s, const char *fmt, va_list ap
494 )
495 {
496  locale_char_t *orig = indi_locale_C_numeric_push();
497  userio_prints (io, user, "<defSwitchVector\n"
498  " device='");
499  userio_xml_escape(io, user, s->device);
500  userio_prints (io, user, "'\n"
501  " name='");
502  userio_xml_escape(io, user, s->name);
503  userio_prints (io, user, "'\n"
504  " label='");
505  userio_xml_escape(io, user, s->label);
506  userio_prints (io, user, "'\n"
507  " group='");
508  userio_xml_escape(io, user, s->group);
509  userio_prints (io, user, "'\n");
510  userio_printf (io, user, " state='%s'\n", pstateStr(s->s)); // safe
511  userio_printf (io, user, " perm='%s'\n", permStr(s->p)); // safe
512  userio_printf (io, user, " rule='%s'\n", ruleStr(s->r)); // safe
513  userio_printf (io, user, " timeout='%g'\n", s->timeout); // safe
514  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
515  s_userio_xml_message_vprintf(io, user, fmt, ap);
516  userio_prints (io, user, ">\n");
517 
518  for (int i = 0; i < s->nsp; i++)
519  {
520  ISwitch *sp = &s->sp[i];
521  userio_prints (io, user, " <defSwitch\n"
522  " name='");
523  userio_xml_escape(io, user, sp->name);
524  userio_prints (io, user, "'\n"
525  " label='");
526  userio_xml_escape(io, user, sp->label);
527  userio_prints (io, user, "'>\n");
528  userio_printf (io, user, " %s\n", sstateStr(sp->s)); // safe
529  userio_prints (io, user, " </defSwitch>\n");
530  }
531 
532  userio_prints (io, user, "</defSwitchVector>\n");
533  indi_locale_C_numeric_pop(orig);
534 }
535 
537  const userio *io, void *user,
538  const ILightVectorProperty *lvp, const char *fmt, va_list ap
539 )
540 {
541  userio_prints (io, user, "<defLightVector\n"
542  " device='");
543  userio_xml_escape(io, user, lvp->device);
544  userio_prints (io, user, "'\n"
545  " name='");
546  userio_xml_escape(io, user, lvp->name);
547  userio_prints (io, user, "'\n"
548  " label='");
549  userio_xml_escape(io, user, lvp->label);
550  userio_prints (io, user, "'\n"
551  " group='");
552  userio_xml_escape(io, user, lvp->group);
553  userio_prints (io, user, "'\n");
554  userio_printf (io, user, " state='%s'\n", pstateStr(lvp->s)); // safe
555  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
556  s_userio_xml_message_vprintf(io, user, fmt, ap);
557  userio_prints (io, user, ">\n");
558 
559  for (int i = 0; i < lvp->nlp; i++)
560  {
561  ILight *lp = &lvp->lp[i];
562  userio_prints (io, user, " <defLight\n"
563  " name='");
564  userio_xml_escape(io, user, lp->name);
565  userio_prints (io, user, "'\n"
566  " label='");
567  userio_xml_escape(io, user, lp->label);
568  userio_prints (io, user, "'>\n");
569  userio_printf (io, user, " %s\n", pstateStr(lp->s)); // safe
570  userio_prints (io, user, " </defLight>\n");
571  }
572 
573  userio_prints (io, user, "</defLightVector>\n");
574 }
575 
577  const userio *io, void *user,
578  const IBLOBVectorProperty *b, const char *fmt, va_list ap
579 )
580 {
581  locale_char_t *orig = indi_locale_C_numeric_push();
582  userio_prints (io, user, "<defBLOBVector\n"
583  " device='");
584  userio_xml_escape(io, user, b->device);
585  userio_prints (io, user, "'\n"
586  " name='");
587  userio_xml_escape(io, user, b->name);
588  userio_prints (io, user, "'\n"
589  " label='");
590  userio_xml_escape(io, user, b->label);
591  userio_prints (io, user, "'\n"
592  " group='");
593  userio_xml_escape(io, user, b->group);
594  userio_prints (io, user, "'\n");
595  userio_printf (io, user, " state='%s'\n", pstateStr(b->s)); // safe
596  userio_printf (io, user, " perm='%s'\n", permStr(b->p)); // safe
597  userio_printf (io, user, " timeout='%g'\n", b->timeout); // safe
598  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
599  s_userio_xml_message_vprintf(io, user, fmt, ap);
600  userio_prints (io, user, ">\n");
601 
602  for (int i = 0; i < b->nbp; i++)
603  {
604  IBLOB *bp = &b->bp[i];
605  userio_prints (io, user, " <defBLOB\n"
606  " name='");
607  userio_xml_escape(io, user, bp->name);
608  userio_prints (io, user, "'\n"
609  " label='");
610  userio_xml_escape(io, user, bp->label);
611  userio_prints (io, user, "'\n"
612  " />\n");
613  }
614 
615  userio_prints (io, user, "</defBLOBVector>\n");
616  indi_locale_C_numeric_pop(orig);
617 }
618 
620  const userio *io, void *user,
621  const ITextVectorProperty *tvp, const char *fmt, va_list ap
622 )
623 {
624  locale_char_t *orig = indi_locale_C_numeric_push();
625  userio_prints (io, user, "<setTextVector\n"
626  " device='");
627  userio_xml_escape(io, user, tvp->device);
628  userio_prints (io, user, "'\n"
629  " name='");
630  userio_xml_escape(io, user, tvp->name);
631  userio_prints (io, user, "'\n");
632  userio_printf (io, user, " state='%s'\n", pstateStr(tvp->s)); // safe
633  userio_printf (io, user, " timeout='%g'\n", tvp->timeout); // safe
634  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
635  s_userio_xml_message_vprintf(io, user, fmt, ap);
636  userio_prints (io, user, ">\n");
637 
638  IUUserIOTextContext(io, user, tvp);
639 
640  userio_prints (io, user, "</setTextVector>\n");
641  indi_locale_C_numeric_pop(orig);
642 }
643 
645  const userio *io, void *user,
646  const INumberVectorProperty *nvp, const char *fmt, va_list ap
647 )
648 {
649  locale_char_t *orig = indi_locale_C_numeric_push();
650  userio_prints (io, user, "<setNumberVector\n"
651  " device='");
652  userio_xml_escape(io, user, nvp->device);
653  userio_prints (io, user, "'\n"
654  " name='");
655  userio_xml_escape(io, user, nvp->name);
656  userio_prints (io, user, "'\n");
657  userio_printf (io, user, " state='%s'\n", pstateStr(nvp->s)); // safe
658  userio_printf (io, user, " timeout='%g'\n", nvp->timeout); // safe
659  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
660  s_userio_xml_message_vprintf(io, user, fmt, ap);
661  userio_prints (io, user, ">\n");
662 
663  IUUserIONumberContext(io, user, nvp);
664 
665  userio_prints (io, user, "</setNumberVector>\n");
666  indi_locale_C_numeric_pop(orig);
667 }
668 
670  const userio *io, void *user,
671  const ISwitchVectorProperty *svp, const char *fmt, va_list ap
672 )
673 {
674  locale_char_t *orig = indi_locale_C_numeric_push();
675  userio_prints (io, user, "<setSwitchVector\n"
676  " device='");
677  userio_xml_escape(io, user, svp->device);
678  userio_prints (io, user, "'\n"
679  " name='");
680  userio_xml_escape(io, user, svp->name);
681  userio_prints (io, user, "'\n");
682  userio_printf (io, user, " state='%s'\n", pstateStr(svp->s)); // safe
683  userio_printf (io, user, " timeout='%g'\n", svp->timeout); // safe
684  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
685  s_userio_xml_message_vprintf(io, user, fmt, ap);
686  userio_prints (io, user, ">\n");
687 
688  IUUserIOSwitchContextFull(io, user, svp);
689 
690  userio_prints (io, user, "</setSwitchVector>\n");
691  indi_locale_C_numeric_pop(orig);
692 }
693 
695  const userio *io, void *user,
696  const ILightVectorProperty *lvp, const char *fmt, va_list ap
697 )
698 {
699  userio_prints (io, user, "<setLightVector\n"
700  " device='");
701  userio_xml_escape(io, user, lvp->device);
702  userio_prints (io, user, "'\n"
703  " name='");
704  userio_xml_escape(io, user, lvp->name);
705  userio_prints (io, user, "'\n");
706  userio_printf (io, user, " state='%s'\n", pstateStr(lvp->s)); // safe
707  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
708  s_userio_xml_message_vprintf(io, user, fmt, ap);
709  userio_prints (io, user, ">\n");
710 
711  IUUserIOLightContext(io, user, lvp);
712 
713  userio_prints (io, user, "</setLightVector>\n");
714 }
715 
717  const userio *io, void *user,
718  const IBLOBVectorProperty *bvp, const char *fmt, va_list ap
719 )
720 {
721  locale_char_t *orig = indi_locale_C_numeric_push();
722  userio_prints (io, user, "<setBLOBVector\n"
723  " device='");
724  userio_xml_escape(io, user, bvp->device);
725  userio_prints (io, user, "'\n"
726  " name='");
727  userio_xml_escape(io, user, bvp->name);
728  userio_prints (io, user, "'\n");
729  userio_printf (io, user, " state='%s'\n", pstateStr(bvp->s)); // safe
730  userio_printf (io, user, " timeout='%g'\n", bvp->timeout); // safe
731  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
732  s_userio_xml_message_vprintf(io, user, fmt, ap);
733  userio_prints (io, user, ">\n");
734 
735  IUUserIOBLOBContext(io, user, bvp);
736 
737  userio_prints (io, user, "</setBLOBVector>\n");
738  indi_locale_C_numeric_pop(orig);
739 }
740 
742  const userio *io, void *user,
743  const INumberVectorProperty *nvp
744 )
745 {
746  locale_char_t *orig = indi_locale_C_numeric_push();
747  userio_prints (io, user, "<setNumberVector\n"
748  " device='");
749  userio_xml_escape(io, user, nvp->device);
750  userio_prints (io, user, "'\n"
751  " name='");
752  userio_xml_escape(io, user, nvp->name);
753  userio_prints (io, user, "'\n");
754  userio_printf (io, user, " state='%s'\n", pstateStr(nvp->s)); // safe
755  userio_printf (io, user, " timeout='%g'\n", nvp->timeout); // safe
756  userio_printf (io, user, " timestamp='%s'\n", timestamp()); // safe
757  userio_prints (io, user, ">\n");
758 
759  for (int i = 0; i < nvp->nnp; i++)
760  {
761  INumber *np = &nvp->np[i];
762  userio_prints (io, user, " <oneNumber name='");
763  userio_xml_escape(io, user, np->name);
764  userio_prints (io, user, "'\n");
765  userio_printf (io, user, " min='%g'\n", np->min); // safe
766  userio_printf (io, user, " max='%g'\n", np->max); // safe
767  userio_printf (io, user, " step='%g'\n", np->step); // safe
768  userio_prints (io, user, ">\n");
769  userio_printf (io, user, " %g\n", np->value); // safe
770  userio_prints (io, user, " </oneNumber>\n");
771  }
772 
773  userio_prints (io, user, "</setNumberVector>\n");
774  indi_locale_C_numeric_pop(orig);
775 }
to64frombits_s
int to64frombits_s(unsigned char *out, const unsigned char *in, int inlen, size_t outlen)
Convert bytes array to base64.
Definition: base64.c:47
IUUserIOBLOBContextOne
void IUUserIOBLOBContextOne(const userio *io, void *user, const char *name, unsigned int size, unsigned int bloblen, const void *blob, const char *format)
Definition: indiuserio.c:100
_ITextVectorProperty::timeout
double timeout
Definition: indiapi.h:257
IUUserIOSetBLOBVA
void IUUserIOSetBLOBVA(const userio *io, void *user, const IBLOBVectorProperty *bvp, const char *fmt, va_list ap)
Definition: indiuserio.c:716
_IBLOBVectorProperty::device
char device[MAXINDIDEVICE]
Definition: indiapi.h:472
IUUserIOGetProperties
void IUUserIOGetProperties(const userio *io, void *user, const char *dev, const char *name)
Definition: indiuserio.c:297
_IBLOBVectorProperty::nbp
int nbp
Definition: indiapi.h:488
userio_xml_escape
size_t userio_xml_escape(const struct userio *io, void *user, const char *src)
Definition: userio.c:74
ruleStr
const char * ruleStr(ISRule r)
Definition: indicom.c:1280
IUUserIOSetNumberVA
void IUUserIOSetNumberVA(const userio *io, void *user, const INumberVectorProperty *nvp, const char *fmt, va_list ap)
Definition: indiuserio.c:644
IUUserIOTextContext
void IUUserIOTextContext(const userio *io, void *user, const ITextVectorProperty *tvp)
Definition: indiuserio.c:54
_IBLOBVectorProperty::s
IPState s
Definition: indiapi.h:484
_ISwitchVectorProperty::device
char device[MAXINDIDEVICE]
Definition: indiapi.h:368
IDUserIOMessage
void IDUserIOMessage(const userio *io, void *user, const char *dev, const char *fmt,...)
Definition: indiuserio.c:365
IUUserIOSwitchContextOne
void IUUserIOSwitchContextOne(const userio *io, void *user, const ISwitch *sp)
Definition: indiuserio.c:70
_INumberVectorProperty::s
IPState s
Definition: indiapi.h:332
_ILightVectorProperty
Light vector property descriptor.
Definition: indiapi.h:415
ISwitch
One switch descriptor.
indicom.h
Implementations for common driver routines.
locale_compat.h
indiapi.h
Constants and Data structure definitions for the interface to the reference INDI C API implementation...
assert_mem
#define assert_mem(p)
Bails out if memory pointer is 0. Prints file and function.
Definition: indiapi.h:504
INumber
One number descriptor.
_INumberVectorProperty::nnp
int nnp
Definition: indiapi.h:336
B_ONLY
@ B_ONLY
Definition: indidevapi.h:272
_IBLOBVectorProperty
BLOB (Binary Large Object) vector property descriptor.
Definition: indiapi.h:469
permStr
const char * permStr(IPerm p)
Definition: indicom.c:1294
IUUserIOSetLightVA
void IUUserIOSetLightVA(const userio *io, void *user, const ILightVectorProperty *lvp, const char *fmt, va_list ap)
Definition: indiuserio.c:694
_ITextVectorProperty::p
IPerm p
Definition: indiapi.h:255
_ILightVectorProperty::device
char device[MAXINDIDEVICE]
Definition: indiapi.h:418
IUUserIOLightContext
void IUUserIOLightContext(const userio *io, void *user, const ILightVectorProperty *lvp)
Definition: indiuserio.c:174
_ITextVectorProperty::group
char group[MAXINDIGROUP]
Definition: indiapi.h:253
timestamp
const char * timestamp()
Create an ISO 8601 formatted time stamp. The format is YYYY-MM-DDTHH:MM:SS.
Definition: indicom.c:334
indiuserio.h
_ITextVectorProperty::ntp
int ntp
Definition: indiapi.h:263
_ILightVectorProperty::s
IPState s
Definition: indiapi.h:426
IUUserIODeleteVA
void IUUserIODeleteVA(const userio *io, void *user, const char *dev, const char *name, const char *fmt, va_list ap)
Definition: indiuserio.c:276
_IBLOBVectorProperty::bp
IBLOB * bp
Definition: indiapi.h:486
_IBLOBVectorProperty::timeout
double timeout
Definition: indiapi.h:482
_ILightVectorProperty::nlp
int nlp
Definition: indiapi.h:430
sstateStr
const char * sstateStr(ISState s)
Definition: indicom.c:1267
IUUserIODefBLOBVA
void IUUserIODefBLOBVA(const userio *io, void *user, const IBLOBVectorProperty *b, const char *fmt, va_list ap)
Definition: indiuserio.c:576
_ITextVectorProperty::device
char device[MAXINDIDEVICE]
Definition: indiapi.h:247
IUUserIOSwitchContextFull
void IUUserIOSwitchContextFull(const userio *io, void *user, const ISwitchVectorProperty *svp)
Definition: indiuserio.c:81
IUUserIONewBLOBFinish
void IUUserIONewBLOBFinish(const userio *io, void *user)
Definition: indiuserio.c:271
IUUserIONewNumber
void IUUserIONewNumber(const userio *io, void *user, const INumberVectorProperty *nvp)
Definition: indiuserio.c:189
MAXINDIMESSAGE
#define MAXINDIMESSAGE
Definition: indiapi.h:197
_ILightVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:420
IUFindOnSwitch
ISwitch * IUFindOnSwitch(const ISwitchVectorProperty *sp)
Returns the first ON switch it finds in the vector switch property.
Definition: indicom.c:1393
IUUserIODefLightVA
void IUUserIODefLightVA(const userio *io, void *user, const ILightVectorProperty *lvp, const char *fmt, va_list ap)
Definition: indiuserio.c:536
_ITextVectorProperty
Text vector property descriptor.
Definition: indiapi.h:244
userio_write
size_t userio_write(const struct userio *io, void *user, const void *ptr, size_t count)
Definition: userio.c:58
IUUserIOBLOBContext
void IUUserIOBLOBContext(const userio *io, void *user, const IBLOBVectorProperty *bvp)
Definition: indiuserio.c:162
IUUserIONewBLOB
void IUUserIONewBLOB(const userio *io, void *user, const IBLOBVectorProperty *bvp)
Definition: indiuserio.c:241
_ISwitchVectorProperty::label
char label[MAXINDILABEL]
Definition: indiapi.h:372
INDIV
#define INDIV
Definition: indiapi.h:133
_ILightVectorProperty::label
char label[MAXINDILABEL]
Definition: indiapi.h:422
ILight
One light descriptor.
_INumberVectorProperty::timeout
double timeout
Definition: indiapi.h:330
_IBLOBVectorProperty::p
IPerm p
Definition: indiapi.h:480
_ITextVectorProperty::tp
IText * tp
Definition: indiapi.h:261
_INumberVectorProperty
Number vector property descriptor.
Definition: indiapi.h:317
IUUserIOSetSwitchVA
void IUUserIOSetSwitchVA(const userio *io, void *user, const ISwitchVectorProperty *svp, const char *fmt, va_list ap)
Definition: indiuserio.c:669
IUUserIONewText
void IUUserIONewText(const userio *io, void *user, const ITextVectorProperty *tvp)
Definition: indiuserio.c:206
IText
One text descriptor.
pstateStr
const char * pstateStr(IPState s)
Definition: indicom.c:1194
_ISwitchVectorProperty::nsp
int nsp
Definition: indiapi.h:386
indidevapi.h
Interface to the reference INDI C API device implementation on the Device Driver side.
userio_printf
int userio_printf(const struct userio *io, void *user, const char *format,...)
Definition: userio.c:43
B_ALSO
@ B_ALSO
Definition: indidevapi.h:271
userio_prints
int userio_prints(const struct userio *io, void *user, const char *str)
Definition: userio.c:63
_ILightVectorProperty::group
char group[MAXINDIGROUP]
Definition: indiapi.h:424
IUUserIOUpdateMinMax
void IUUserIOUpdateMinMax(const userio *io, void *user, const INumberVectorProperty *nvp)
Definition: indiuserio.c:741
ISR_1OFMANY
@ ISR_1OFMANY
Definition: indiapi.h:172
base64.h
_INumberVectorProperty::np
INumber * np
Definition: indiapi.h:334
IUUserIOConfigTag
void IUUserIOConfigTag(const userio *io, void *user, int ctag)
Definition: indiuserio.c:376
IUUserIONewSwitchFull
void IUUserIONewSwitchFull(const userio *io, void *user, const ISwitchVectorProperty *svp)
Definition: indiuserio.c:219
B_NEVER
@ B_NEVER
Definition: indidevapi.h:270
BLOBHandling
BLOBHandling
How drivers handle BLOBs incoming from snooping drivers.
Definition: indidevapi.h:268
IUUserIONewSwitch
void IUUserIONewSwitch(const userio *io, void *user, const ISwitchVectorProperty *svp)
Definition: indiuserio.c:230
_INumberVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:322
_ITextVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:249
_ITextVectorProperty::label
char label[MAXINDILABEL]
Definition: indiapi.h:251
IUUserIOEnableBLOB
void IUUserIOEnableBLOB(const userio *io, void *user, const char *dev, const char *name, BLOBHandling blobH)
Definition: indiuserio.c:331
IUUserIONumberContext
void IUUserIONumberContext(const userio *io, void *user, const INumberVectorProperty *nvp)
Definition: indiuserio.c:41
userio_putc
int userio_putc(const struct userio *io, void *user, int ch)
Definition: userio.c:68
_IBLOBVectorProperty::label
char label[MAXINDILABEL]
Definition: indiapi.h:476
locale_char_t
char locale_char_t
Definition: locale_compat.h:62
_IBLOBVectorProperty::group
char group[MAXINDIGROUP]
Definition: indiapi.h:478
_INumberVectorProperty::label
char label[MAXINDILABEL]
Definition: indiapi.h:324
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
_ITextVectorProperty::s
IPState s
Definition: indiapi.h:259
_INumberVectorProperty::device
char device[MAXINDIDEVICE]
Definition: indiapi.h:320
_INumberVectorProperty::p
IPerm p
Definition: indiapi.h:328
_ILightVectorProperty::lp
ILight * lp
Definition: indiapi.h:428
_IBLOBVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:474
IUUserIOSetTextVA
void IUUserIOSetTextVA(const userio *io, void *user, const ITextVectorProperty *tvp, const char *fmt, va_list ap)
Definition: indiuserio.c:619
IUUserIODefSwitchVA
void IUUserIODefSwitchVA(const userio *io, void *user, const ISwitchVectorProperty *s, const char *fmt, va_list ap)
Definition: indiuserio.c:491
userio
Definition: userio.h:32
_INumberVectorProperty::group
char group[MAXINDIGROUP]
Definition: indiapi.h:326
_ISwitchVectorProperty::r
ISRule r
Definition: indiapi.h:378
IUUserIOSwitchContext
void IUUserIOSwitchContext(const userio *io, void *user, const ISwitchVectorProperty *svp)
Definition: indiuserio.c:90
_ISwitchVectorProperty::sp
ISwitch * sp
Definition: indiapi.h:384
IDUserIOMessageVA
void IDUserIOMessageVA(const userio *io, void *user, const char *dev, const char *fmt, va_list ap)
Definition: indiuserio.c:348
IUUserIONewBLOBStart
void IUUserIONewBLOBStart(const userio *io, void *user, const char *dev, const char *name, const char *timestamp)
Definition: indiuserio.c:250
_ISwitchVectorProperty::p
IPerm p
Definition: indiapi.h:376
IUUserIODefTextVA
void IUUserIODefTextVA(const userio *io, void *user, const ITextVectorProperty *tvp, const char *fmt, va_list ap)
Definition: indiuserio.c:392
IUUserIODefNumberVA
void IUUserIODefNumberVA(const userio *io, void *user, const INumberVectorProperty *n, const char *fmt, va_list ap)
Definition: indiuserio.c:439
_ISwitchVectorProperty::group
char group[MAXINDIGROUP]
Definition: indiapi.h:374
IBLOB
One Blob (Binary Large Object) descriptor.
_ISwitchVectorProperty::timeout
double timeout
Definition: indiapi.h:380
_ISwitchVectorProperty
Switch vector property descriptor.
Definition: indiapi.h:365
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370