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

Last change on this file since 614 was 502, checked in by frichard, 14 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.