source: BAORadio/libindi/v1.0.1/libs/indibase/basedriver.cpp@ 654

Last change on this file since 654 was 502, checked in by frichard, 15 years ago

-BAOControl : petite interface permettant de contrôler les antennes via le pilote indi_BAO
-Le pilote indi_BAO utilise désormais indilib v 0.7

File size: 24.7 KB
Line 
1#include <stdlib.h>
2#include <string.h>
3#include <errno.h>
4#include <zlib.h>
5
6#include "basedriver.h"
7#include "baseclient.h"
8#include "indicom.h"
9#include "base64.h"
10
11INDI::BaseDriver::BaseDriver()
12{
13 mediator = NULL;
14 lp = newLilXML();
15}
16
17
18INDI::BaseDriver::~BaseDriver()
19{
20 std::vector<INumberVectorProperty *>::const_iterator numi;
21 std::vector<ISwitchVectorProperty *>::const_iterator switchi;
22 std::vector<ITextVectorProperty *>::const_iterator texti;
23 std::vector<ILightVectorProperty *>::const_iterator lighti;
24 std::vector<IBLOBVectorProperty *>::const_iterator blobi;
25
26 delLilXML (lp);
27 pAll.clear();
28
29 for ( numi = pNumbers.begin(); numi != pNumbers.end(); numi++)
30 delete (*numi);
31
32 for ( switchi = pSwitches.begin(); switchi != pSwitches.end(); switchi++)
33 delete (*switchi);
34
35 for ( texti = pTexts.begin(); texti != pTexts.end(); texti++)
36 delete (*texti);
37
38 for ( lighti = pLights.begin(); lighti != pLights.end(); lighti++)
39 delete (*lighti);
40
41 for ( blobi = pBlobs.begin(); blobi != pBlobs.end(); blobi++)
42 delete (*blobi);
43}
44
45INumberVectorProperty * INDI::BaseDriver::getNumber(const char *name)
46{
47 std::vector<INumberVectorProperty *>::const_iterator numi;
48
49 for ( numi = pNumbers.begin(); numi != pNumbers.end(); numi++)
50 if (!strcmp(name, (*numi)->name))
51 return *numi;
52
53 return NULL;
54
55}
56
57ITextVectorProperty * INDI::BaseDriver::getText(const char *name)
58{
59 std::vector<ITextVectorProperty *>::const_iterator texti;
60
61 for ( texti = pTexts.begin(); texti != pTexts.end(); texti++)
62 if (!strcmp(name, (*texti)->name))
63 return *texti;
64
65 return NULL;
66}
67
68ISwitchVectorProperty * INDI::BaseDriver::getSwitch(const char *name)
69{
70 std::vector<ISwitchVectorProperty *>::const_iterator switchi;
71
72 for ( switchi = pSwitches.begin(); switchi != pSwitches.end(); switchi++)
73 if (!strcmp(name, (*switchi)->name))
74 return *switchi;
75
76 return NULL;
77
78}
79
80ILightVectorProperty * INDI::BaseDriver::getLight(const char *name)
81{
82 std::vector<ILightVectorProperty *>::const_iterator lighti;
83
84 for ( lighti = pLights.begin(); lighti != pLights.end(); lighti++)
85 if (!strcmp(name, (*lighti)->name))
86 return *lighti;
87
88 return NULL;
89
90}
91
92IBLOBVectorProperty * INDI::BaseDriver::getBLOB(const char *name)
93{
94 std::vector<IBLOBVectorProperty *>::const_iterator blobi;
95
96 for ( blobi = pBlobs.begin(); blobi != pBlobs.end(); blobi++)
97 if (!strcmp(name, (*blobi)->name))
98 return *blobi;
99
100 return NULL;
101}
102
103void * INDI::BaseDriver::getProperty(const char *name, INDI_TYPE & type)
104{
105 std::vector<pOrder>::const_iterator orderi;
106
107 INumberVectorProperty *nvp;
108 ITextVectorProperty *tvp;
109 ISwitchVectorProperty *svp;
110 ILightVectorProperty *lvp;
111 IBLOBVectorProperty *bvp;
112 int i=0;
113
114 for (i=0, orderi = pAll.begin(); orderi != pAll.end(); orderi++, i++)
115 {
116 switch ( (*orderi).type)
117 {
118 case INDI_NUMBER:
119 nvp = static_cast<INumberVectorProperty *>((*orderi).p);
120 if (!strcmp(name, nvp->name))
121 {
122 type = INDI_NUMBER;
123 return (*orderi).p;
124 }
125
126 break;
127 case INDI_TEXT:
128 tvp = static_cast<ITextVectorProperty *>((*orderi).p);
129 if (!strcmp(name, tvp->name))
130 {
131 type = INDI_TEXT;
132 return (*orderi).p;
133 }
134 break;
135 case INDI_SWITCH:
136 svp = static_cast<ISwitchVectorProperty *>((*orderi).p);
137 if (!strcmp(name, svp->name))
138 {
139 type = INDI_SWITCH;
140 return (*orderi).p;
141 }
142 break;
143 case INDI_LIGHT:
144 lvp = static_cast<ILightVectorProperty *>((*orderi).p);
145 if (!strcmp(name, lvp->name))
146 {
147 type = INDI_LIGHT;
148 return (*orderi).p;
149 }
150 break;
151 case INDI_BLOB:
152 bvp = static_cast<IBLOBVectorProperty *>((*orderi).p);
153 if (!strcmp(name, bvp->name))
154 {
155 type = INDI_BLOB;
156 return (*orderi).p;
157 }
158 break;
159 }
160 }
161
162 return NULL;
163}
164
165int INDI::BaseDriver::removeProperty(const char *name)
166{
167 std::vector<pOrder>::iterator orderi;
168
169 INumberVectorProperty *nvp;
170 ITextVectorProperty *tvp;
171 ISwitchVectorProperty *svp;
172 ILightVectorProperty *lvp;
173 IBLOBVectorProperty *bvp;
174
175 for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
176 {
177 switch ( (*orderi).type)
178 {
179 case INDI_NUMBER:
180 nvp = static_cast<INumberVectorProperty *>((*orderi).p);
181 if (!strcmp(name, nvp->name))
182 {
183 pAll.erase(orderi);
184 delete (nvp);
185 return 0;
186 }
187 break;
188 case INDI_TEXT:
189 tvp = static_cast<ITextVectorProperty *>((*orderi).p);
190 if (!strcmp(name, tvp->name))
191 {
192 pAll.erase(orderi);
193 delete (tvp);
194 return 0;
195 }
196 break;
197 case INDI_SWITCH:
198 svp = static_cast<ISwitchVectorProperty *>((*orderi).p);
199 if (!strcmp(name, svp->name))
200 {
201 pAll.erase(orderi);
202 delete (svp);
203 return 0;
204 }
205 break;
206 case INDI_LIGHT:
207 lvp = static_cast<ILightVectorProperty *>((*orderi).p);
208 if (!strcmp(name, lvp->name))
209 {
210 pAll.erase(orderi);
211 delete (lvp);
212 return 0;
213 }
214 break;
215 case INDI_BLOB:
216 bvp = static_cast<IBLOBVectorProperty *>((*orderi).p);
217 if (!strcmp(name, bvp->name))
218 {
219 pAll.erase(orderi);
220 delete (bvp);
221 return 0;
222 }
223 break;
224 }
225 }
226
227 return INDI_PROPERTY_INVALID;
228}
229
230void INDI::BaseDriver::buildSkeleton(const char *filename)
231{
232 char errmsg[MAXRBUF];
233 FILE *fp = NULL;
234 XMLEle *root = NULL, *fproot = NULL;
235
236 fp = fopen(filename, "r");
237
238 if (fp == NULL)
239 {
240 IDLog("Unable to build skeleton. Error loading file %s: %s\n", filename, strerror(errno));
241 return;
242 }
243
244 fproot = readXMLFile(fp, lp, errmsg);
245
246 if (fproot == NULL)
247 {
248 IDLog("Unable to parse skeleton XML: %s", errmsg);
249 return;
250 }
251
252 //prXMLEle(stderr, fproot, 0);
253
254 for (root = nextXMLEle (fproot, 1); root != NULL; root = nextXMLEle (fproot, 0))
255 buildProp(root, errmsg);
256
257
258
259 /**************************************************************************/
260
261}
262
263int INDI::BaseDriver::buildProp(XMLEle *root, char *errmsg)
264{
265 IPerm perm;
266 IPState state;
267 ISRule rule;
268 XMLEle *ep = NULL;
269 char *rtag, *rname, *rdev;
270 INDI_TYPE type;
271 double timeout=0;
272
273 rtag = tagXMLEle(root);
274
275 /* pull out device and name */
276 if (crackDN (root, &rdev, &rname, errmsg) < 0)
277 return -1;
278
279 if (!deviceID[0])
280 {
281 if (getenv("INDIDEV"))
282 strncpy(deviceID, getenv("INDIDEV"), MAXINDINAME);
283 else
284 strncpy(deviceID, rdev, MAXINDINAME);
285 }
286
287 if (getProperty(rname, type) != NULL)
288 return INDI::BaseClient::INDI_PROPERTY_DUPLICATED;
289
290 if (crackIPerm(findXMLAttValu(root, "perm"), &perm) < 0)
291 {
292 IDLog("Error extracting %s permission (%s)", rname, findXMLAttValu(root, "perm"));
293 return -1;
294 }
295
296 timeout = atoi(findXMLAttValu(root, "timeout"));
297
298 if (crackIPState (findXMLAttValu(root, "state"), &state) < 0)
299 {
300 IDLog("Error extracting %s state (%s)", rname, findXMLAttValu(root, "state"));
301 return -1;
302 }
303
304 if (!strcmp (rtag, "defNumberVector"))
305 {
306
307 INumberVectorProperty *nvp = new INumberVectorProperty;
308 INumber *np = NULL;
309 int n=0;
310
311 strncpy(nvp->device, deviceID, MAXINDIDEVICE);
312 strncpy(nvp->name, rname, MAXINDINAME);
313 strncpy(nvp->label, findXMLAttValu(root, "label"), MAXINDILABEL);
314 strncpy(nvp->group, findXMLAttValu(root, "group"), MAXINDIGROUP);
315
316 nvp->p = perm;
317 nvp->s = state;
318 nvp->timeout = timeout;
319
320 /* pull out each name/value pair */
321 for (n = 0, ep = nextXMLEle(root,1); ep != NULL; ep = nextXMLEle(root,0), n++)
322 {
323 if (!strcmp (tagXMLEle(ep), "defNumber"))
324 {
325 np = (INumber *) realloc(np, (n+1) * sizeof(INumber));
326
327 np[n].nvp = nvp;
328
329 XMLAtt *na = findXMLAtt (ep, "name");
330
331 if (na)
332 {
333 if (f_scansexa (pcdataXMLEle(ep), &(np[n].value)) < 0)
334 IDLog("%s: Bad format %s\n", rname, pcdataXMLEle(ep));
335 else
336 {
337
338 strncpy(np[n].name, valuXMLAtt(na), MAXINDINAME);
339
340 na = findXMLAtt (ep, "label");
341 if (na)
342 strncpy(np[n].label, valuXMLAtt(na),MAXINDILABEL);
343 na = findXMLAtt (ep, "format");
344 if (na)
345 strncpy(np[n].format, valuXMLAtt(na), MAXINDIFORMAT);
346
347 na = findXMLAtt (ep, "min");
348 if (na)
349 np[n].min = atof(valuXMLAtt(na));
350 na = findXMLAtt (ep, "max");
351 if (na)
352 np[n].max = atof(valuXMLAtt(na));
353 na = findXMLAtt (ep, "step");
354 if (na)
355 np[n].step = atof(valuXMLAtt(na));
356
357 }
358 }
359 }
360 }
361
362 if (n > 0)
363 {
364 nvp->nnp = n;
365 nvp->np = np;
366 pNumbers.push_back(nvp);
367 pOrder o = { INDI_NUMBER, nvp };
368 pAll.push_back(o);
369 IDLog("Adding number property %s to list.\n", nvp->name);
370 }
371 else
372 IDLog("%s: newNumberVector with no valid members\n",rname);
373}
374 else if (!strcmp (rtag, "defSwitchVector"))
375 {
376 ISwitchVectorProperty *svp = new ISwitchVectorProperty;
377 ISwitch *sp = NULL;
378 int n=0;
379
380 strncpy(svp->device, deviceID, MAXINDIDEVICE);
381 strncpy(svp->name, rname, MAXINDINAME);
382 strncpy(svp->label, findXMLAttValu(root, "label"), MAXINDILABEL);
383 strncpy(svp->group, findXMLAttValu(root, "group"), MAXINDIGROUP);
384
385 if (crackISRule(findXMLAttValu(root, "rule"), (&svp->r)) < 0)
386 svp->r = ISR_1OFMANY;
387
388 svp->p = perm;
389 svp->s = state;
390 svp->timeout = timeout;
391
392
393 /* pull out each name/value pair */
394 for (n = 0, ep = nextXMLEle(root,1); ep != NULL; ep = nextXMLEle(root,0), n++)
395 {
396 if (!strcmp (tagXMLEle(ep), "defSwitch"))
397 {
398 sp = (ISwitch *) realloc(sp, (n+1) * sizeof(ISwitch));
399
400 sp[n].svp = svp;
401
402 XMLAtt *na = findXMLAtt (ep, "name");
403
404 if (na)
405 {
406 crackISState(pcdataXMLEle(ep), &(sp[n].s));
407 strncpy(sp[n].name, valuXMLAtt(na), MAXINDINAME);
408
409 na = findXMLAtt (ep, "label");
410 if (na)
411 strncpy(sp[n].label, valuXMLAtt(na),MAXINDILABEL);
412 }
413 }
414 }
415
416 if (n > 0)
417 {
418 svp->nsp = n;
419 svp->sp = sp;
420 pSwitches.push_back(svp);
421 pOrder o = { INDI_SWITCH, svp };
422 pAll.push_back(o);
423 IDLog("Adding Switch property %s to list.\n", svp->name);
424 }
425 else
426 IDLog("%s: newSwitchVector with no valid members\n",rname);
427 }
428
429else if (!strcmp (rtag, "defTextVector"))
430 {
431
432 ITextVectorProperty *tvp = new ITextVectorProperty;
433 IText *tp = NULL;
434 int n=0;
435
436 strncpy(tvp->device, deviceID, MAXINDIDEVICE);
437 strncpy(tvp->name, rname, MAXINDINAME);
438 strncpy(tvp->label, findXMLAttValu(root, "label"), MAXINDILABEL);
439 strncpy(tvp->group, findXMLAttValu(root, "group"), MAXINDIGROUP);
440
441 tvp->p = perm;
442 tvp->s = state;
443 tvp->timeout = timeout;
444
445 /* pull out each name/value pair */
446 for (n = 0, ep = nextXMLEle(root,1); ep != NULL; ep = nextXMLEle(root,0), n++)
447 {
448 if (!strcmp (tagXMLEle(ep), "defText"))
449 {
450 tp = (IText *) realloc(tp, (n+1) * sizeof(IText));
451
452 tp[n].tvp = tvp;
453
454 XMLAtt *na = findXMLAtt (ep, "name");
455
456 if (na)
457 {
458 tp[n].text = (char *) malloc(pcdatalenXMLEle(ep)*sizeof(char));
459 strncpy(tp[n].text, pcdataXMLEle(ep), pcdatalenXMLEle(ep));
460 strncpy(tp[n].name, valuXMLAtt(na), MAXINDINAME);
461
462 na = findXMLAtt (ep, "label");
463 if (na)
464 strncpy(tp[n].label, valuXMLAtt(na),MAXINDILABEL);
465 }
466 }
467 }
468
469 if (n > 0)
470 {
471 tvp->ntp = n;
472 tvp->tp = tp;
473 pTexts.push_back(tvp);
474 pOrder o = { INDI_TEXT, tvp };
475 pAll.push_back(o);
476 IDLog("Adding Text property %s to list.\n", tvp->name);
477 }
478 else
479 IDLog("%s: newTextVector with no valid members\n",rname);
480}
481else if (!strcmp (rtag, "defLightVector"))
482 {
483
484 ILightVectorProperty *lvp = new ILightVectorProperty;
485 ILight *lp = NULL;
486 int n=0;
487
488 strncpy(lvp->device, deviceID, MAXINDIDEVICE);
489 strncpy(lvp->name, rname, MAXINDINAME);
490 strncpy(lvp->label, findXMLAttValu(root, "label"), MAXINDILABEL);
491 strncpy(lvp->group, findXMLAttValu(root, "group"), MAXINDIGROUP);
492
493 lvp->s = state;
494
495 /* pull out each name/value pair */
496 for (n = 0, ep = nextXMLEle(root,1); ep != NULL; ep = nextXMLEle(root,0), n++)
497 {
498 if (!strcmp (tagXMLEle(ep), "defLight"))
499 {
500 lp = (ILight *) realloc(lp, (n+1) * sizeof(ILight));
501
502 lp[n].lvp = lvp;
503
504 XMLAtt *na = findXMLAtt (ep, "name");
505
506 if (na)
507 {
508 crackIPState(pcdataXMLEle(ep), &(lp[n].s));
509 strncpy(lp[n].name, valuXMLAtt(na), MAXINDINAME);
510
511 na = findXMLAtt (ep, "label");
512 if (na)
513 strncpy(lp[n].label, valuXMLAtt(na),MAXINDILABEL);
514
515 }
516 }
517 }
518
519 if (n > 0)
520 {
521 lvp->nlp = n;
522 lvp->lp = lp;
523 pLights.push_back(lvp);
524 pOrder o = { INDI_LIGHT, lvp };
525 pAll.push_back(o);
526 IDLog("Adding Light property %s to list.\n", lvp->name);
527 }
528 else
529 IDLog("%s: newLightVector with no valid members\n",rname);
530}
531else if (!strcmp (rtag, "defBLOBVector"))
532 {
533
534 IBLOBVectorProperty *bvp = new IBLOBVectorProperty;
535 IBLOB *bp = NULL;
536 int n=0;
537
538 strncpy(bvp->device, deviceID, MAXINDIDEVICE);
539 strncpy(bvp->name, rname, MAXINDINAME);
540 strncpy(bvp->label, findXMLAttValu(root, "label"), MAXINDILABEL);
541 strncpy(bvp->group, findXMLAttValu(root, "group"), MAXINDIGROUP);
542
543 bvp->s = state;
544
545 /* pull out each name/value pair */
546 for (n = 0, ep = nextXMLEle(root,1); ep != NULL; ep = nextXMLEle(root,0), n++)
547 {
548 if (!strcmp (tagXMLEle(ep), "defBLOB"))
549 {
550 bp = (IBLOB *) realloc(bp, (n+1) * sizeof(IBLOB));
551
552 bp[n].bvp = bvp;
553
554 XMLAtt *na = findXMLAtt (ep, "name");
555
556 if (na)
557 {
558 strncpy(bp[n].name, valuXMLAtt(na), MAXINDINAME);
559
560 na = findXMLAtt (ep, "label");
561 if (na)
562 strncpy(bp[n].label, valuXMLAtt(na),MAXINDILABEL);
563
564 na = findXMLAtt (ep, "format");
565 if (na)
566 strncpy(bp[n].label, valuXMLAtt(na),MAXINDIBLOBFMT);
567
568 // Initialize everything to zero
569
570 bp[n].blob = NULL;
571 bp[n].size = 0;
572 bp[n].bloblen = 0;
573 }
574
575 }
576 }
577
578 if (n > 0)
579 {
580 bvp->nbp = n;
581 bvp->bp = bp;
582 pBlobs.push_back(bvp);
583 pOrder o = { INDI_BLOB, bvp };
584 pAll.push_back(o);
585 IDLog("Adding BLOB property %s to list.\n", bvp->name);
586 }
587 else
588 IDLog("%s: newBLOBVector with no valid members\n",rname);
589 }
590
591return (0);
592
593}
594
595bool INDI::BaseDriver::isConnected()
596{
597 ISwitchVectorProperty *svp = getSwitch("CONNECTION");
598 if (!svp)
599 return false;
600
601 ISwitch * sp = IUFindSwitch(svp, "CONNECT");
602
603 if (!sp)
604 return false;
605
606 if (sp->s == ISS_ON)
607 return true;
608 else
609 return false;
610
611}
612
613void INDI::BaseDriver::setConnected(bool status)
614{
615 ISwitch *sp = NULL;
616 ISwitchVectorProperty *svp = getSwitch("CONNECTION");
617 if (!svp)
618 return;
619
620 IUResetSwitch(svp);
621
622 // Connect
623 if (status)
624 {
625 sp = IUFindSwitch(svp, "CONNECT");
626 if (!sp)
627 return;
628 sp->s = ISS_ON;
629 }
630 // Disconnect
631 else
632 {
633 sp = IUFindSwitch(svp, "DISCONNECT");
634 if (!sp)
635 return;
636 sp->s = ISS_ON;
637 }
638
639 svp->s = IPS_OK;
640}
641
642/*
643 * return 0 if ok else -1 with reason in errmsg
644 */
645int INDI::BaseDriver::setValue (XMLEle *root, char * errmsg)
646{
647 XMLAtt *ap;
648 XMLEle *ep;
649 char *rtag, *name;
650 double timeout;
651 IPState state;
652 bool stateSet=false, timeoutSet=false;
653
654 rtag = tagXMLEle(root);
655
656 ap = findXMLAtt (root, "name");
657 if (!ap)
658 {
659 snprintf(errmsg, MAXRBUF, "INDI: <%s> unable to find name attribute", tagXMLEle(root));
660 return (-1);
661 }
662
663 name = valuXMLAtt(ap);
664
665 /* set overall property state, if any */
666 ap = findXMLAtt (root, "state");
667 if (ap)
668 {
669 if (crackIPState(valuXMLAtt(ap), &state) != 0)
670 {
671 snprintf(errmsg, MAXRBUF, "INDI: <%s> bogus state %s for %s", tagXMLEle(root),
672 valuXMLAtt(ap), name);
673 return (-1);
674 }
675
676 stateSet = true;
677 }
678
679 /* allow changing the timeout */
680 ap = findXMLAtt (root, "timeout");
681 if (ap)
682 {
683 timeout = atof(valuXMLAtt(ap));
684 timeoutSet = true;
685 }
686
687 if (!strcmp(rtag, "setNumberVector"))
688 {
689 INumberVectorProperty *nvp = getNumber(name);
690 if (nvp == NULL)
691 {
692 snprintf(errmsg, MAXRBUF, "INDI: Could not find property %s in %s", name, deviceID);
693 return -1;
694 }
695
696 if (stateSet)
697 nvp->s = state;
698
699 if (timeoutSet)
700 nvp->timeout = timeout;
701
702 for (ep = nextXMLEle (root, 1); ep != NULL; ep = nextXMLEle (root, 0))
703 {
704 INumber *np = IUFindNumber(nvp, findXMLAttValu(ep, "name"));
705 if (!np)
706 continue;
707
708 np->value = atof(pcdataXMLEle(ep));
709
710 // Permit changing of min/max
711 if (findXMLAtt(ep, "min"))
712 np->min = atof(findXMLAttValu(ep, "min"));
713 if (findXMLAtt(ep, "max"))
714 np->max = atof(findXMLAttValu(ep, "max"));
715 }
716
717 if (mediator)
718 mediator->newNumber(nvp);
719
720 return 0;
721 }
722 else if (!strcmp(rtag, "setTextVector"))
723 {
724 ITextVectorProperty *tvp = getText(name);
725 if (tvp == NULL)
726 return -1;
727
728 if (stateSet)
729 tvp->s = state;
730
731 if (timeoutSet)
732 tvp->timeout = timeout;
733
734 for (ep = nextXMLEle (root, 1); ep != NULL; ep = nextXMLEle (root, 0))
735 {
736 IText *tp = IUFindText(tvp, findXMLAttValu(ep, "name"));
737 if (!tp)
738 continue;
739
740 IUSaveText(tp, pcdataXMLEle(ep));
741 }
742
743 if (mediator)
744 mediator->newText(tvp);
745
746 return 0;
747 }
748 else if (!strcmp(rtag, "setSwitchVector"))
749 {
750 ISState swState;
751 ISwitchVectorProperty *svp = getSwitch(name);
752 if (svp == NULL)
753 return -1;
754
755 if (stateSet)
756 svp->s = state;
757
758 if (timeoutSet)
759 svp->timeout = timeout;
760
761 for (ep = nextXMLEle (root, 1); ep != NULL; ep = nextXMLEle (root, 0))
762 {
763 ISwitch *sp = IUFindSwitch(svp, findXMLAttValu(ep, "name"));
764 if (!sp)
765 continue;
766
767 if (crackISState(pcdataXMLEle(ep), &swState) == 0)
768 sp->s = swState;
769 }
770
771 if (mediator)
772 mediator->newSwitch(svp);
773
774 return 0;
775 }
776 else if (!strcmp(rtag, "setLightVector"))
777 {
778 IPState lState;
779 ILightVectorProperty *lvp = getLight(name);
780 if (lvp == NULL)
781 return -1;
782
783 if (stateSet)
784 lvp->s = state;
785
786 for (ep = nextXMLEle (root, 1); ep != NULL; ep = nextXMLEle (root, 0))
787 {
788 ILight *lp = IUFindLight(lvp, findXMLAttValu(ep, "name"));
789 if (!lp)
790 continue;
791
792 if (crackIPState(pcdataXMLEle(ep), &lState) == 0)
793 lp->s = lState;
794 }
795
796 if (mediator)
797 mediator->newLight(lvp);
798
799 return 0;
800
801 }
802 else if (!strcmp(rtag, "setBLOBVector"))
803 {
804 IBLOBVectorProperty *bvp = getBLOB(name);
805 if (bvp == NULL)
806 return -1;
807
808 if (stateSet)
809 bvp->s = state;
810
811 if (timeoutSet)
812 bvp->timeout = timeout;
813
814 return setBLOB(bvp, root, errmsg);
815 }
816
817 snprintf(errmsg, MAXRBUF, "INDI: <%s> Unable to process tag", tagXMLEle(root));
818 return -1;
819}
820
821/* Set BLOB vector. Process incoming data stream
822 * Return 0 if okay, -1 if error
823*/
824int INDI::BaseDriver::setBLOB(IBLOBVectorProperty *bvp, XMLEle * root, char * errmsg)
825{
826
827 XMLEle *ep;
828 IBLOB *blobEL;
829
830 for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0))
831 {
832 if (strcmp(tagXMLEle(ep), "oneBLOB") == 0)
833 {
834 blobEL = IUFindBLOB(bvp, findXMLAttValu (ep, "name"));
835
836 if (blobEL)
837 return processBLOB(blobEL, ep, errmsg);
838 else
839 {
840 snprintf(errmsg, MAXRBUF, "INDI: set %s.%s.%s not found", bvp->device, bvp->name,
841 findXMLAttValu (ep, "name"));
842 return (-1);
843 }
844 }
845 }
846
847 return -1;
848}
849
850/* Process incoming data stream
851 * Return 0 if okay, -1 if error
852*/
853int INDI::BaseDriver::processBLOB(IBLOB *blobEL, XMLEle *ep, char * errmsg)
854{
855 XMLAtt *ap = NULL;
856 int blobSize=0, r=0;
857 uLongf dataSize=0;
858 char *baseBuffer=NULL, *dataFormat;
859 unsigned char *blobBuffer(NULL), *dataBuffer(NULL);
860 bool iscomp(false);
861
862 ap = findXMLAtt(ep, "size");
863 if (!ap)
864 {
865 snprintf(errmsg, MAXRBUF, "INDI: set %s size not found", blobEL->name);
866 return (-1);
867 }
868
869 dataSize = atoi(valuXMLAtt(ap));
870
871 ap = findXMLAtt(ep, "format");
872 if (!ap)
873 {
874 snprintf(errmsg, MAXRBUF, "INDI: set %s format not found",blobEL->name);
875 return (-1);
876 }
877
878 dataFormat = valuXMLAtt(ap);
879
880 strncpy(blobEL->format, dataFormat, MAXINDIFORMAT);
881
882 baseBuffer = (char *) malloc ( (3*pcdatalenXMLEle(ep)/4) * sizeof (char));
883
884 if (baseBuffer == NULL)
885 {
886 strncpy(errmsg, "Unable to allocate memory for base buffer", MAXRBUF);
887 return (-1);
888 }
889
890 blobSize = from64tobits (baseBuffer, pcdataXMLEle(ep));
891 blobBuffer = (unsigned char *) baseBuffer;
892
893 /* Blob size = 0 when only state changes */
894 if (dataSize == 0)
895 {
896 free (blobBuffer);
897 return (0);
898 }
899 else if (blobSize < 0)
900 {
901 free (blobBuffer);
902 snprintf(errmsg, MAXRBUF, "INDI: %s.%s.%s bad base64", blobEL->bvp->device, blobEL->bvp->name, blobEL->name);
903 return (-1);
904 }
905
906 if (strstr(dataFormat, ".z"))
907 {
908 dataFormat[strlen(dataFormat)-2] = '\0';
909 dataBuffer = (unsigned char *) realloc (dataBuffer, (dataSize * sizeof(unsigned char)));
910
911 if (baseBuffer == NULL)
912 {
913 free (blobBuffer);
914 strncpy(errmsg, "Unable to allocate memory for data buffer", MAXRBUF);
915 return (-1);
916 }
917
918 r = uncompress(dataBuffer, &dataSize, blobBuffer, (uLong) blobSize);
919 if (r != Z_OK)
920 {
921 snprintf(errmsg, MAXRBUF, "INDI: %s.%s.%s compression error: %d", blobEL->bvp->device, blobEL->bvp->name, blobEL->name, r);
922 free (blobBuffer);
923 return -1;
924 }
925 blobEL->size = dataSize;
926 }
927 else
928 {
929 dataBuffer = (unsigned char *) realloc (dataBuffer, (dataSize * sizeof(unsigned char)));
930 memcpy(dataBuffer, blobBuffer, dataSize);
931 blobEL->size = dataSize;
932 }
933
934 blobEL->blob = dataBuffer;
935
936 if (mediator)
937 mediator->newBLOB(blobEL);
938
939 // newBLOB(dataBuffer, dataSize, dataFormat);
940
941 free (blobBuffer);
942 return (0);
943}
944
945void INDI::BaseDriver::setDeviceName(const char *dev)
946{
947 strncpy(deviceID, dev, MAXINDINAME);
948}
949
950const char * INDI::BaseDriver::deviceName()
951{
952 return deviceID;
953}
954
955void INDI::BaseDriver::addMessage(const char *msg)
956{
957 messageQueue.append(msg);
958}
959
Note: See TracBrowser for help on using the repository browser.